# 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.6.0-test3 -> 1.1241 # drivers/net/8139too.c 1.61 -> 1.62 # arch/sparc64/kernel/entry.S 1.26 -> 1.27 # include/asm-ppc64/smp.h 1.11 -> 1.12 # include/asm-generic/tlb.h 1.18 -> 1.19 # arch/um/vmlinux.lds.S 1.1 -> 1.2 arch/um/kernel/vmlinux.lds.S (moved) # fs/nfsd/nfs3xdr.c 1.36 -> 1.37 # arch/sparc64/kernel/pci.c 1.38 -> 1.39 # include/linux/ppp-comp.h 1.3 -> 1.4 # sound/oss/gus_card.c 1.6 -> 1.7 # drivers/char/ipmi/ipmi_kcs_intf.c 1.9 -> 1.11 # sound/oss/ac97_plugin_ad1980.c 1.2 -> 1.3 # drivers/char/drm/drm_agpsupport.h 1.21 -> 1.22 # include/asm-i386/mpspec.h 1.14 -> 1.15 # kernel/power/console.c 1.2 -> 1.3 # arch/alpha/kernel/core_wildfire.c 1.6 -> 1.7 # arch/sparc64/kernel/smp.c 1.56 -> 1.57 # drivers/scsi/megaraid.c 1.51 -> 1.53 # drivers/char/drm/i810_drm.h 1.8 -> 1.9 # drivers/i2c/chips/Makefile 1.7 -> 1.8 # arch/x86_64/kernel/pci-nommu.c 1.2 -> 1.3 # Documentation/DocBook/kernel-api.tmpl 1.26 -> 1.27 # include/pcmcia/ds.h 1.11 -> 1.12 # drivers/net/eexpress.c 1.13 -> 1.14 # include/asm-x86_64/smp.h 1.10 -> 1.11 # include/asm-i386/mmu_context.h 1.17 -> 1.18 # include/linux/acpi.h 1.26 -> 1.27 # drivers/char/specialix_io8.h 1.4 -> 1.5 # arch/i386/kernel/cpuid.c 1.11 -> 1.12 # drivers/ide/legacy/hd.c 1.22 -> 1.23 # drivers/scsi/sym53c8xx_2/sym_hipd.c 1.8 -> 1.9 # drivers/char/esp.c 1.24 -> 1.25 # drivers/video/matrox/matroxfb_maven.c 1.13 -> 1.14 # sound/oss/opl3sa2.c 1.21 -> 1.22 # arch/sparc64/solaris/entry64.S 1.5 -> 1.6 # include/asm-um/smp.h 1.2 -> 1.3 # drivers/block/as-iosched.c 1.10 -> 1.14 # drivers/scsi/ips.c 1.62 -> 1.67 # sound/oss/cs46xx.c 1.33 -> 1.34 # net/ipv4/ipvs/ip_vs_core.c 1.2 -> 1.3 # drivers/base/firmware_class.c 1.4 -> 1.5 # arch/s390/kernel/smp.c 1.26 -> 1.27 # include/asm-ppc/pmac_feature.h 1.9 -> 1.10 # drivers/scsi/scsi_error.c 1.59 -> 1.61 # sound/oss/dmasound/dmasound_q40.c 1.11 -> 1.12 # fs/sysfs/Makefile 1.6 -> 1.7 # arch/sparc64/solaris/systbl.S 1.2 -> 1.4 # kernel/rcupdate.c 1.5 -> 1.6 # fs/reiserfs/file.c 1.21 -> 1.22 # drivers/usb/misc/tiglusb.c 1.20 -> 1.21 # fs/befs/btree.c 1.5 -> 1.6 # fs/afs/volume.c 1.1 -> 1.2 # include/asm-i386/agp.h 1.1 -> 1.2 # drivers/acpi/sleep/main.c 1.27 -> 1.29 # kernel/ksyms.c 1.213 -> 1.214 # kernel/power/process.c 1.4 -> 1.5 # drivers/isdn/hardware/avm/avm_cs.c 1.9 -> 1.10 # arch/sparc64/kernel/us3_cpufreq.c 1.7 -> 1.8 # drivers/i2c/chips/adm1021.c 1.19 -> 1.21 # drivers/net/wan/z85230.c 1.8 -> 1.9 # arch/i386/kernel/cpu/cpufreq/powernow-k7.c 1.23 -> 1.24 # drivers/pci/quirks.c 1.32 -> 1.33 # fs/nfsd/nfsxdr.c 1.24 -> 1.25 # include/asm-i386/mach-visws/mach_apic.h 1.5 -> 1.6 # arch/alpha/kernel/sys_sio.c 1.7 -> 1.8 # sound/oss/dmabuf.c 1.6 -> 1.7 # net/ipv4/ipvs/ip_vs_sched.c 1.1 -> 1.2 # arch/alpha/kernel/core_t2.c 1.8 -> 1.9 # include/asm-i386/mach-es7000/mach_apic.h 1.1 -> 1.2 # arch/i386/kernel/acpi/acpitable.h 1.1 -> (deleted) # include/asm-s390/bitops.h 1.12 -> 1.13 # sound/oss/trix.c 1.4 -> 1.5 # drivers/serial/8250_pnp.c 1.12 -> 1.13 # drivers/char/isicom.c 1.24 -> 1.25 # arch/arm/vmlinux.lds.S 1.2 -> 1.3 arch/arm/kernel/vmlinux.lds.S (moved) # arch/i386/math-emu/fpu_trig.c 1.3 -> 1.4 # arch/x86_64/ia32/ia32_binfmt.c 1.16 -> 1.17 # include/scsi/scsi_device.h 1.3 -> 1.5 # drivers/mtd/devices/blkmtd.c 1.33 -> 1.35 # fs/xfs/pagebuf/page_buf.c 1.59 -> 1.60 # include/asm-sparc64/ttable.h 1.7 -> 1.8 # net/sunrpc/auth_gss/gss_krb5_crypto.c 1.2 -> 1.3 # include/linux/mm.h 1.126 -> 1.128 # fs/sysfs/file.c 1.7 -> 1.10 # arch/x86_64/kernel/setup.c 1.18 -> 1.19 # drivers/scsi/aha152x.c 1.35 -> 1.36 # drivers/net/arcnet/arc-rimi.c 1.7 -> 1.8 # drivers/char/agp/sis-agp.c 1.27 -> 1.29 # net/ipv4/ipconfig.c 1.27 -> 1.29 # arch/i386/mach-generic/probe.c 1.1 -> 1.2 # drivers/scsi/hosts.c 1.83 -> 1.89 # arch/x86_64/vmlinux.lds.S 1.18 -> 1.19 arch/x86_64/kernel/vmlinux.lds.S (moved) # arch/i386/kernel/apm.c 1.54 -> 1.55 # arch/alpha/boot/bootpz.c 1.1 -> 1.2 # net/Kconfig 1.16 -> 1.17 # arch/i386/mach-generic/default.c 1.3 -> 1.4 # fs/xfs/xfs_dir2_leaf.h 1.3 -> 1.4 # net/ipv6/ip6_output.c 1.39 -> 1.43 # drivers/acpi/toshiba_acpi.c 1.11 -> 1.12 # drivers/scsi/cpqfcTSinit.c 1.40 -> 1.41 # net/sunrpc/sysctl.c 1.5 -> 1.6 # drivers/base/core.c 1.70 -> 1.73 # drivers/block/Kconfig.iosched 1.1 -> 1.2 # sound/oss/emu10k1/efxmgr.c 1.6 -> 1.7 # drivers/usb/serial/io_edgeport.c 1.46 -> 1.47 # arch/i386/oprofile/op_model_p4.c 1.6 -> 1.7 # net/ipv6/ip6_tunnel.c 1.4 -> 1.6 # arch/i386/kernel/irq.c 1.38 -> 1.39 # arch/ppc/syslib/Makefile 1.8 -> 1.9 # mm/page_alloc.c 1.167 -> 1.168 # arch/alpha/kernel/pci.c 1.35 -> 1.36 # drivers/scsi/aic7xxx/aic7xxx_osm.c 1.45 -> 1.46 # drivers/scsi/scsi_proc.c 1.29 -> 1.34 # drivers/net/wan/comx-proto-lapb.c 1.6 -> 1.7 # drivers/char/random.c 1.34 -> 1.35 # arch/sparc/vmlinux.lds.S 1.17 -> 1.18 arch/sparc/kernel/vmlinux.lds.S (moved) # include/asm-sparc/unistd.h 1.21 -> 1.24 # arch/i386/kernel/smp.c 1.32 -> 1.33 # drivers/base/interface.c 1.15 -> 1.18 # arch/alpha/kernel/core_marvel.c 1.13 -> 1.14 # arch/s390/kernel/setup.c 1.24 -> 1.25 # fs/jbd/revoke.c 1.14 -> 1.15 # drivers/usb/serial/generic.c 1.6 -> 1.7 # drivers/acpi/pci_link.c 1.15 -> 1.16 # include/asm-i386/highmem.h 1.11 -> 1.12 # drivers/scsi/lasi700.c 1.14 -> 1.15 # include/linux/init_task.h 1.26 -> 1.27 # arch/i386/kernel/head.S 1.27 -> 1.29 # include/linux/sched.h 1.159 -> 1.161 # net/sunrpc/svcsock.c 1.55 -> 1.56 # kernel/fork.c 1.134 -> 1.136 # drivers/ide/ppc/pmac.c 1.14 -> 1.15 # drivers/block/ll_rw_blk.c 1.203 -> 1.205 # kernel/sys.c 1.52 -> 1.53 # sound/oss/wf_midi.c 1.8 -> 1.9 # drivers/net/wireless/airo.c 1.67 -> 1.70 # net/ipv4/xfrm4_tunnel.c 1.7 -> 1.8 # drivers/usb/serial/keyspan.c 1.47 -> 1.48 # arch/ppc64/kernel/open_pic.h 1.1 -> 1.2 # drivers/media/video/bttv-if.c 1.14 -> 1.15 # include/asm-ia64/unistd.h 1.30 -> 1.32 # drivers/net/smc-mca.c 1.9 -> 1.10 # net/ipv4/xfrm4_input.c 1.8 -> 1.9 # drivers/base/platform.c 1.10 -> 1.11 # arch/ppc/platforms/4xx/Kconfig 1.4 -> 1.5 # include/asm-x86_64/nmi.h 1.3 -> 1.4 # sound/core/seq/seq_clientmgr.c 1.19 -> 1.20 # drivers/scsi/NCR_Q720.c 1.3 -> 1.4 # drivers/ieee1394/sbp2.c 1.39.1.1 -> 1.42 # mm/vmscan.c 1.165 -> 1.166 # arch/ia64/kernel/setup.c 1.55 -> 1.56 # arch/mips/kernel/irq.c 1.12 -> 1.13 # fs/proc/proc_misc.c 1.84 -> 1.85 # drivers/scsi/NCR_D700.c 1.16 -> 1.17 # drivers/scsi/dc395x.c 1.13 -> 1.20 # arch/sparc/Makefile 1.26 -> 1.27 # arch/sparc/kernel/process.c 1.29 -> 1.30 # drivers/scsi/arm/scsi.h 1.6 -> 1.7 # drivers/i2c/i2c-core.c 1.42 -> 1.43 # drivers/net/sk98lin/skge.c 1.23 -> 1.24 # arch/x86_64/kernel/apic.c 1.21 -> 1.22 # drivers/net/loopback.c 1.7 -> 1.8 # drivers/block/floppy.c 1.82 -> 1.84 # arch/i386/Kconfig 1.67 -> 1.71 # sound/oss/dmasound/dmasound_core.c 1.15 -> 1.16 # include/scsi/scsi_host.h 1.5 -> 1.8 # include/asm-mips/smp.h 1.4 -> 1.5 # drivers/scsi/53c700.c 1.39 -> 1.40 # drivers/base/node.c 1.14 -> 1.15 # include/asm-sparc64/bitops.h 1.13 -> 1.14 # drivers/net/arcnet/com20020-pci.c 1.15 -> 1.16 # arch/x86_64/kernel/x8664_ksyms.c 1.17 -> 1.18 # include/asm-ppc/macio_asic.h 1.1 -> 1.2 include/asm-ppc/macio.h (moved) # drivers/i2c/busses/i2c-nforce2.c 1.4 -> 1.5 # fs/jbd/journal.c 1.61 -> 1.62 # net/ipv4/udp.c 1.45 -> 1.46 # include/asm-sparc64/unistd.h 1.20 -> 1.23 # arch/x86_64/kernel/msr.c 1.8 -> 1.9 # drivers/mca/mca-device.c 1.1 -> 1.2 # fs/devfs/base.c 1.98 -> 1.100 # arch/mips/kernel/smp.c 1.13 -> 1.14 # arch/i386/kernel/traps.c 1.55 -> 1.56 # include/asm-i386/topology.h 1.6 -> 1.7 # include/linux/lockd/lockd.h 1.6 -> 1.7 # arch/i386/kernel/Makefile 1.46 -> 1.48 # drivers/base/Kconfig 1.3 -> 1.4 # arch/alpha/kernel/setup.c 1.35 -> 1.36 # fs/nls/Makefile 1.7 -> 1.8 # drivers/mca/mca-bus.c 1.4 -> 1.5 # drivers/usb/class/usblp.c 1.56 -> 1.57 # include/asm-ppc/smp.h 1.12 -> 1.14 # kernel/pm.c 1.10 -> 1.12 kernel/power/pm.c (moved) # arch/alpha/kernel/sys_dp264.c 1.10 -> 1.11 # drivers/ide/legacy/qd65xx.c 1.6 -> 1.7 # drivers/ide/legacy/umc8672.c 1.7 -> 1.8 # include/asm-i386/mach-summit/mach_ipi.h 1.3 -> 1.4 # drivers/pnp/core.c 1.12 -> 1.13 # arch/sparc64/kernel/Makefile 1.25 -> 1.26 # drivers/ide/legacy/ali14xx.c 1.6 -> 1.7 # include/asm-ia64/sn/nodepda.h 1.6 -> 1.7 # fs/xfs/xfs_vfsops.c 1.38 -> 1.39 # drivers/scsi/scsi_sysfs.c 1.26 -> 1.31 # arch/i386/vmlinux.lds.S 1.31 -> 1.32 arch/i386/kernel/vmlinux.lds.S (moved) # drivers/md/raid5.c 1.75 -> 1.76 # drivers/char/agp/nvidia-agp.c 1.12 -> 1.14 # sound/oss/ite8172.c 1.18 -> 1.20 # drivers/serial/sunsu.c 1.38 -> 1.39 # drivers/input/serio/pcips2.c 1.2 -> 1.3 # crypto/blowfish.c 1.3 -> 1.4 # kernel/Makefile 1.31 -> 1.32 # sound/drivers/opl3/opl3_lib.c 1.10 -> 1.11 # drivers/media/dvb/dvb-core/dvbdev.c 1.13 -> 1.14 # arch/i386/kernel/cpu/cyrix.c 1.10 -> 1.11 # net/sctp/Kconfig 1.5 -> 1.6 # net/netrom/sysctl_net_netrom.c 1.5 -> 1.6 # arch/ia64/kernel/time.c 1.30 -> 1.31 # arch/x86_64/kernel/acpi/boot.c 1.3 -> 1.4 # arch/alpha/kernel/proto.h 1.15 -> 1.16 # arch/alpha/kernel/sys_noritake.c 1.5 -> 1.6 # drivers/atm/eni.c 1.18 -> 1.19 # include/linux/xfrm.h 1.18 -> 1.19 # include/asm-x86_64/pci-direct.h 1.1 -> 1.2 # include/linux/blkdev.h 1.122 -> 1.123 # drivers/block/nbd.c 1.67 -> 1.68 # drivers/ide/pci/trm290.c 1.12 -> 1.13 # arch/i386/kernel/microcode.c 1.20 -> 1.21 # drivers/block/cciss_scsi.c 1.17 -> 1.18 # drivers/message/fusion/mptbase.c 1.13 -> 1.14 # arch/um/kernel/smp.c 1.7 -> 1.8 # arch/alpha/kernel/irq_alpha.c 1.11 -> 1.12 # drivers/scsi/ips.h 1.31 -> 1.34 # arch/x86_64/kernel/ioport.c 1.7 -> 1.9 # sound/oss/btaudio.c 1.18 -> 1.19 # net/ipv4/devinet.c 1.19 -> 1.20 # sound/oss/pas2_pcm.c 1.5 -> 1.6 # drivers/usb/core/message.c 1.33 -> 1.35 # drivers/net/rrunner.c 1.18 -> 1.20 # drivers/base/bus.c 1.48 -> 1.50 # include/asm-sparc/smp.h 1.6 -> 1.7 # net/ipv4/Makefile 1.20 -> 1.21 # kernel/softirq.c 1.43 -> 1.44 # drivers/net/wireless/Kconfig 1.12 -> 1.13 # arch/ia64/kernel/smpboot.c 1.36 -> 1.37 # drivers/net/wan/comx-hw-munich.c 1.11 -> 1.12 # include/linux/ethtool.h 1.18 -> 1.19 # arch/sparc64/kernel/pci_common.c 1.21 -> 1.22 # drivers/scsi/sr.c 1.87 -> 1.89 # arch/x86_64/kernel/smp.c 1.16 -> 1.17 # sound/oss/gus_wave.c 1.10 -> 1.12 # arch/um/kernel/skas/process_kern.c 1.4 -> 1.5 # include/linux/suspend.h 1.16 -> 1.18 # kernel/power/swsusp.c 1.50 -> 1.53 # arch/mips/kernel/proc.c 1.4 -> 1.5 # drivers/net/irda/irtty.c 1.20 -> 1.23 # arch/i386/mach-visws/mpparse.c 1.5 -> 1.6 # include/linux/rcupdate.h 1.2 -> 1.3 # drivers/atm/lanai.c 1.12 -> 1.15 # arch/ia64/kernel/entry.S 1.46 -> 1.47 # drivers/usb/storage/usb.c 1.74 -> 1.76 # drivers/net/wireless/atmel.c 1.2 -> 1.3 # include/asm-i386/atomic.h 1.4 -> 1.5 # arch/i386/kernel/entry.S 1.66 -> 1.67 # include/linux/mca.h 1.6 -> 1.7 # net/ipv4/ipvs/Kconfig 1.4 -> 1.5 # drivers/scsi/scsi_module.c 1.5 -> 1.6 # arch/i386/mach-generic/bigsmp.c 1.2 -> 1.3 # drivers/char/mwave/mwavedd.c 1.9 -> 1.10 # arch/i386/kernel/cpu/intel.c 1.19 -> 1.20 # crypto/proc.c 1.2 -> 1.3 # include/linux/crypto.h 1.28 -> 1.29 # drivers/eisa/eisa-bus.c 1.8 -> 1.10 # include/linux/if_tun.h 1.4 -> 1.5 # arch/m68knommu/kernel/Makefile 1.5 -> 1.6 # arch/x86_64/kernel/setup64.c 1.15 -> 1.16 # drivers/net/Makefile 1.66 -> 1.67 # arch/alpha/kernel/smp.c 1.36 -> 1.37 # drivers/ide/ide.c 1.83 -> 1.86 # arch/alpha/kernel/core_titan.c 1.18 -> 1.19 # sound/oss/via82cxxx_audio.c 1.30 -> 1.32 # sound/oss/dmasound/dmasound_atari.c 1.10 -> 1.11 # drivers/net/wan/comx-proto-fr.c 1.11 -> 1.12 # drivers/ide/legacy/dtc2278.c 1.6 -> 1.7 # arch/i386/kernel/reboot.c 1.8 -> 1.11 # drivers/i2c/busses/i2c-piix4.c 1.13 -> 1.16 # net/ipv6/icmp.c 1.37 -> 1.40 # crypto/serpent.c 1.2 -> 1.3 # fs/partitions/ldm.h 1.8 -> 1.9 # drivers/usb/serial/visor.c 1.66 -> 1.68 # arch/ppc64/kernel/rtasd.c 1.10 -> 1.11 # drivers/net/arcnet/com20020.c 1.6 -> 1.7 # arch/parisc/kernel/Makefile 1.13 -> 1.14 # include/asm-i386/mach-es7000/mach_ipi.h 1.1 -> 1.2 # arch/i386/kernel/mpparse.c 1.44 -> 1.47 # drivers/isdn/hisax/sedlbauer_cs.c 1.10 -> 1.11 # arch/x86_64/kernel/mpparse.c 1.10 -> 1.11 # drivers/usb/media/ov511.c 1.46 -> 1.49 # drivers/net/arcnet/com90io.c 1.8 -> 1.9 # drivers/char/agp/Makefile 1.25 -> 1.26 # fs/reiserfs/inode.c 1.79 -> 1.80 # net/ipv4/tcp_ipv4.c 1.64 -> 1.65 # drivers/usb/core/hcd.h 1.32 -> 1.33 # fs/xfs/linux/xfs_iops.c 1.31 -> 1.32 # include/asm-sparc64/smp.h 1.13 -> 1.14 # arch/i386/kernel/io_apic.c 1.76 -> 1.78 # drivers/char/drm/i810.h 1.9 -> 1.10 # fs/char_dev.c 1.21 -> 1.22 # drivers/ide/ide-tape.c 1.23 -> 1.26 # arch/sparc64/defconfig 1.97 -> 1.98 # sound/pci/ice1712/ice1712.c 1.17 -> 1.18 # sound/oss/skeleton.c 1.4 -> 1.5 # mm/filemap.c 1.201 -> 1.203 # arch/mips/vmlinux.lds.S 1.11 -> 1.12 arch/mips/kernel/vmlinux.lds.S (moved) # arch/sparc64/kernel/setup.c 1.39 -> 1.40 # drivers/char/drm/i810_dma.c 1.28 -> 1.29 # include/asm-ppc64/tlb.h 1.8 -> 1.9 # sound/oss/ad1889.c 1.5 -> 1.6 # Documentation/kbuild/kconfig-language.txt 1.3 -> 1.4 # drivers/usb/serial/whiteheat.c 1.38 -> 1.39 # sound/oss/dmasound/dmasound_awacs.c 1.12 -> 1.13 # arch/m68k/vmlinux.lds.S 1.2 -> 1.3 arch/m68k/kernel/vmlinux.lds.S (moved) # drivers/char/agp/generic.c 1.55 -> 1.57 # drivers/char/drm/r128.h 1.10 -> 1.11 # drivers/net/wan/sbni.c 1.18 -> 1.19 # drivers/input/gameport/lightning.c 1.6 -> 1.7 # drivers/ieee1394/pcilynx.c 1.34 -> 1.35 # sound/oss/forte.c 1.2 -> 1.3 # arch/i386/Makefile 1.54 -> 1.55 # drivers/ide/pci/alim15x3.c 1.12 -> 1.14 # include/asm-ppc64/mmu_context.h 1.5 -> 1.6 # arch/s390/vmlinux.lds.S 1.14 -> 1.15 arch/s390/kernel/vmlinux.lds.S (moved) # sound/oss/pas2_mixer.c 1.4 -> 1.5 # drivers/net/wan/lapbether.c 1.10 -> 1.11 # drivers/ide/pci/siimage.c 1.12 -> 1.13 # net/netrom/nr_in.c 1.7 -> 1.8 # arch/alpha/kernel/core_tsunami.c 1.12 -> 1.13 # drivers/char/agp/sworks-agp.c 1.34 -> 1.37 # ipc/sem.c 1.21 -> 1.22 # net/xfrm/xfrm_algo.c 1.10 -> 1.11 # drivers/media/video/bttvp.h 1.13 -> 1.14 # arch/i386/kernel/dmi_scan.c 1.37 -> 1.39 # include/linux/sysfs.h 1.29 -> 1.32 # arch/i386/kernel/acpi/acpitable.c 1.1 -> (deleted) # drivers/base/base.h 1.27 -> 1.29 # fs/nfs/nfs2xdr.c 1.27 -> 1.28 # include/linux/ide.h 1.64 -> 1.66 # fs/exec.c 1.93 -> 1.94 # init/do_mounts.c 1.50 -> 1.54 # arch/i386/mach-voyager/voyager_smp.c 1.14 -> 1.15 # drivers/usb/media/ov511.h 1.10 -> 1.12 # drivers/scsi/aacraid/linit.c 1.20 -> 1.21 # drivers/char/watchdog/advantechwdt.c 1.17 -> 1.18 # mm/fadvise.c 1.5 -> 1.7 # drivers/acpi/tables.c 1.14 -> 1.15 # net/ipv6/raw.c 1.37 -> 1.41 # kernel/signal.c 1.93 -> 1.94 # drivers/isdn/hisax/st5481_b.c 1.11 -> 1.12 # fs/reiserfs/ioctl.c 1.11 -> 1.12 # drivers/scsi/pcmcia/nsp_cs.h 1.10 -> 1.11 # drivers/bluetooth/dtl1_cs.c 1.10 -> 1.11 # drivers/message/fusion/mptscsih.c 1.25 -> 1.26 # drivers/char/keyboard.c 1.33 -> 1.34 # drivers/char/rtc.c 1.28 -> 1.29 # sound/oss/awe_wave.c 1.13 -> 1.14 # sound/parisc/harmony.c 1.1 -> 1.2 # drivers/mtd/devices/Kconfig 1.3 -> 1.4 # crypto/aes.c 1.3 -> 1.4 # Documentation/binfmt_misc.txt 1.2 -> 1.3 # net/netsyms.c 1.90 -> 1.94 # fs/afs/super.c 1.4 -> 1.5 # include/asm-i386/mach-bigsmp/mach_ipi.h 1.2 -> 1.3 # include/asm-x86_64/bitops.h 1.9 -> 1.11 # include/linux/irq.h 1.8 -> 1.9 # drivers/ide/ide-disk.c 1.56 -> 1.59 # include/linux/pci_ids.h 1.113 -> 1.115 # drivers/usb/serial/usb-serial.c 1.87 -> 1.89 # include/asm-x86_64/io.h 1.8 -> 1.9 # include/net/irda/irlap.h 1.8 -> 1.10 # arch/m68knommu/vmlinux.lds.S 1.11 -> 1.12 arch/m68knommu/kernel/vmlinux.lds.S (moved) # include/asm-i386/mach-numaq/mach_apic.h 1.20 -> 1.21 # drivers/md/linear.c 1.35 -> 1.36 # arch/mips/kernel/Makefile 1.13 -> 1.14 # fs/sysfs/dir.c 1.6 -> 1.9 # include/asm-x86_64/pci.h 1.10 -> 1.11 # arch/alpha/kernel/Makefile 1.27.1.2 -> 1.29 # security/selinux/include/objsec.h 1.1 -> 1.2 # drivers/char/agp/agp.h 1.72 -> 1.75 # arch/i386/kernel/msr.c 1.12 -> 1.14 # drivers/scsi/cpqfcTSstructs.h 1.14 -> 1.15 # arch/x86_64/ia32/sys_ia32.c 1.35 -> 1.36 # arch/sparc64/kernel/process.c 1.44 -> 1.46 # arch/sparc64/kernel/systbls.S 1.40 -> 1.44 # arch/x86_64/kernel/irq.c 1.16 -> 1.17 # arch/x86_64/kernel/pci-gart.c 1.15 -> 1.17 # include/linux/usb.h 1.84 -> 1.87 # include/asm-i386/mach-summit/mach_mpparse.h 1.8 -> 1.9 # arch/ppc64/kernel/irq.c 1.30 -> 1.31 # sound/oss/midibuf.c 1.7 -> 1.8 # sound/oss/nm256_audio.c 1.14 -> 1.15 # sound/oss/sonicvibes.c 1.26 -> 1.27 # arch/x86_64/ia32/ia32entry.S 1.22 -> 1.23 # drivers/net/tun.c 1.22 -> 1.25 # fs/xfs/xfs_da_btree.h 1.3 -> 1.4 # include/linux/hdreg.h 1.25 -> 1.26 # crypto/crypto_null.c 1.2 -> 1.3 # drivers/acpi/pci_irq.c 1.18.1.2 -> 1.21 # fs/binfmt_elf.c 1.50 -> 1.51 # sound/pci/ice1712/ice1724.c 1.8 -> 1.9 # mm/memory.c 1.128 -> 1.129 # include/asm-x86_64/mpspec.h 1.6 -> 1.7 # drivers/md/multipath.c 1.53 -> 1.54 # include/asm-s390/mmu_context.h 1.5 -> 1.6 # drivers/usb/serial/pl2303.c 1.44 -> 1.45 # arch/x86_64/kernel/nmi.c 1.15 -> 1.16 # drivers/scsi/sg.c 1.60 -> 1.62 # fs/aio.c 1.34 -> 1.35 # scripts/makeman 1.1 -> 1.2 # drivers/char/riscom8.c 1.21 -> 1.22 # drivers/net/hamradio/bpqether.c 1.9 -> 1.11 # drivers/isdn/hisax/st5481_d.c 1.10 -> 1.11 # fs/compat.c 1.12 -> 1.14 # arch/ia64/kernel/efivars.c 1.12 -> 1.14 # drivers/usb/serial/digi_acceleport.c 1.34 -> 1.35 # arch/sparc/kernel/entry.S 1.13 -> 1.14 # drivers/usb/core/hub.c 1.76 -> 1.77 # drivers/ide/Kconfig 1.25 -> 1.26 # drivers/net/8139cp.c 1.41 -> 1.42 # drivers/net/acenic.c 1.36 -> 1.37 # arch/cris/Makefile 1.17 -> 1.18 # arch/arm26/kernel/Makefile 1.2 -> 1.3 # drivers/video/matrox/i2c-matroxfb.c 1.9 -> 1.10 # include/linux/compat.h 1.11 -> 1.13 # arch/ia64/kernel/mca.c 1.36 -> 1.37 # arch/ia64/kernel/iosapic.c 1.30 -> 1.31 # arch/ppc64/kernel/setup.c 1.29 -> 1.30 # net/irda/irda_device.c 1.19 -> 1.20 # arch/i386/kernel/ioport.c 1.8 -> 1.9 # drivers/net/hydra.c 1.8 -> 1.9 # drivers/char/watchdog/sc520_wdt.c 1.11 -> 1.14 # arch/i386/kernel/setup.c 1.88 -> 1.91 # arch/ia64/kernel/process.c 1.44 -> 1.45 # drivers/isdn/hisax/elsa_cs.c 1.7 -> 1.8 # drivers/i2c/scx200_i2c.c 1.3 -> 1.4 # drivers/media/video/bttv-cards.c 1.20 -> 1.21 # drivers/usb/core/hcd-pci.c 1.19 -> 1.20 # arch/i386/kernel/acpi/Makefile 1.2 -> 1.3 # arch/i386/kernel/smpboot.c 1.61 -> 1.64 # drivers/bluetooth/bluecard_cs.c 1.11 -> 1.12 # sound/oss/sys_timer.c 1.5 -> 1.6 # arch/mips/sibyte/sb1250/smp.c 1.2 -> 1.3 # drivers/scsi/NCR53c406a.c 1.24 -> 1.25 # drivers/char/agp/intel-agp.c 1.46 -> 1.48 # include/asm-ia64/smp.h 1.11 -> 1.12 # sound/oss/soundcard.c 1.21 -> 1.22 # drivers/scsi/scsi_syms.c 1.44 -> 1.45 # arch/i386/kernel/summit.c 1.1 -> 1.2 # crypto/hmac.c 1.3 -> 1.4 # drivers/scsi/scsi_lib.c 1.105.2.1 -> 1.110 # fs/sysfs/bin.c 1.10 -> 1.11 # drivers/usb/core/devio.c 1.52 -> 1.53 # net/netrom/af_netrom.c 1.28 -> 1.36 # drivers/sbus/char/riowatchdog.c 1.5 -> 1.6 # drivers/net/wireless/atmel_cs.c 1.2 -> 1.5 # include/asm-s390/smp.h 1.9 -> 1.10 # sound/oss/sequencer.c 1.6 -> 1.7 # net/xfrm/Kconfig 1.1 -> 1.2 # net/ipv6/ipcomp6.c 1.6 -> 1.7 # arch/sparc/kernel/systbls.S 1.18 -> 1.21 # drivers/ide/arm/icside.c 1.9 -> 1.10 # drivers/net/irda/irda-usb.c 1.42 -> 1.43 # kernel/compat.c 1.20 -> 1.21 # drivers/ide/ide-dma.c 1.20 -> 1.21 # arch/x86_64/kernel/io_apic.c 1.11 -> 1.12 # net/ipv6/Kconfig 1.7 -> 1.8 # net/core/dev.c 1.91 -> 1.93 # drivers/ide/legacy/pdc4030.c 1.12 -> 1.14 # arch/alpha/kernel/sys_miata.c 1.8 -> 1.9 # drivers/usb/core/usb.c 1.134 -> 1.136 # drivers/scsi/scsi.c 1.120 -> 1.123 # crypto/cipher.c 1.14 -> 1.15 # arch/alpha/vmlinux.lds.S 1.22 -> 1.23 arch/alpha/kernel/vmlinux.lds.S (moved) # drivers/char/agp/uninorth-agp.c 1.5 -> 1.7 # fs/xfs/linux/xfs_file.c 1.16 -> 1.17 # drivers/scsi/pcmcia/qlogic_stub.c 1.17 -> 1.19 # Documentation/DMA-mapping.txt 1.16 -> 1.17 # drivers/usb/net/usbnet.c 1.65 -> 1.68 # sound/oss/swarm_cs4297a.c 1.2 -> 1.3 # fs/xfs/xfs_log_recover.c 1.28 -> 1.29 # drivers/md/raid1.c 1.68 -> 1.69 # include/net/netrom.h 1.3 -> 1.6 # fs/pipe.c 1.27 -> 1.28 # drivers/video/cfbimgblt.c 1.27 -> 1.28 # fs/xfs/pagebuf/page_buf_locking.c 1.9 -> 1.10 # include/asm-i386/numaq.h 1.10 -> 1.11 # drivers/md/raid0.c 1.34 -> 1.35 # arch/ppc64/Kconfig 1.25 -> 1.26 # drivers/pnp/isapnp/core.c 1.40 -> 1.41 # drivers/input/input.c 1.32 -> 1.33 # drivers/pci/pci-sysfs.c 1.5 -> 1.6 # arch/ppc64/kernel/xics.c 1.25 -> 1.26 # drivers/net/tg3.c 1.80 -> 1.81 # include/linux/smp.h 1.25 -> 1.26 # include/linux/prctl.h 1.4 -> 1.5 # drivers/scsi/aic7xxx/aic79xx_osm.c 1.48 -> 1.49 # arch/sh/vmlinux.lds.S 1.12 -> 1.13 arch/sh/kernel/vmlinux.lds.S (moved) # Documentation/BK-usage/bk-kernel-howto.txt 1.6 -> 1.7 # net/ipv6/tcp_ipv6.c 1.68 -> 1.71 # drivers/pcmcia/tcic.c 1.31 -> 1.32 # drivers/usb/serial/kl5kusb105.c 1.23 -> 1.24 # Documentation/dnotify.txt 1.3 -> 1.4 # arch/h8300/kernel/Makefile 1.1 -> 1.2 # net/xfrm/xfrm_user.c 1.35 -> 1.36 # drivers/input/gameport/fm801-gp.c 1.6 -> 1.7 # drivers/net/amd8111e.c 1.8 -> 1.9 # drivers/ide/pci/hpt366.c 1.20 -> 1.21 # drivers/usb/media/dabusb.c 1.30 -> 1.32 # include/asm-i386/genapic.h 1.3 -> 1.4 # fs/Kconfig 1.27 -> 1.28 # drivers/block/loop.c 1.103 -> 1.105 # fs/Makefile 1.58 -> 1.59 # drivers/char/agp/Kconfig 1.22 -> 1.24 # mm/vmalloc.c 1.26 -> 1.27 # arch/i386/kernel/cpu/mtrr/generic.c 1.7 -> 1.8 # drivers/ide/ide-probe.c 1.56 -> 1.58 # drivers/usb/core/hcd.c 1.71 -> 1.72 # net/ipv4/esp4.c 1.33 -> 1.35 # arch/ppc64/kernel/open_pic.c 1.15 -> 1.16 # arch/ppc64/mm/init.c 1.49 -> 1.50 # arch/ppc64/kernel/htab.c 1.34 -> 1.35 # drivers/usb/serial/belkin_sa.c 1.36 -> 1.37 # sound/oss/cs4232.c 1.11 -> 1.12 # arch/alpha/kernel/core_cia.c 1.14 -> 1.16 # Documentation/networking/8139too.txt 1.15 -> 1.16 # fs/xfs/pagebuf/page_buf.h 1.31 -> 1.32 # sound/pci/azt3328.c 1.2 -> 1.3 # include/linux/skbuff.h 1.28 -> 1.29 # drivers/scsi/ppa.c 1.25 -> 1.26 # arch/cris/kernel/Makefile 1.15 -> 1.16 # include/asm-i386/smp.h 1.27 -> 1.28 # fs/xfs/xfs_attr.c 1.7 -> 1.8 # drivers/input/gameport/emu10k1-gp.c 1.11 -> 1.12 # drivers/net/tulip/tulip_core.c 1.46 -> 1.47 # drivers/scsi/pcmcia/fdomain_stub.c 1.18 -> 1.20 # arch/sh/kernel/Makefile 1.13 -> 1.14 # include/linux/pm.h 1.4 -> 1.9 # arch/h8300/vmlinux.lds.S 1.2 -> 1.3 arch/h8300/kernel/vmlinux.lds.S (moved) # MAINTAINERS 1.162 -> 1.166 # fs/jffs/inode-v23.c 1.49 -> 1.50 # drivers/pcmcia/yenta_socket.c 1.37 -> 1.38 # drivers/acpi/bus.c 1.32 -> 1.33 # arch/ia64/ia32/sys_ia32.c 1.70 -> 1.71 # drivers/ieee1394/nodemgr.c 1.33 -> 1.34 # drivers/scsi/scsi_debug.c 1.42 -> 1.44 # arch/alpha/kernel/core_mcpcia.c 1.7 -> 1.8 # drivers/block/cryptoloop.c 1.2 -> 1.4 # fs/partitions/acorn.c 1.9 -> 1.10 # net/ipv4/netfilter/ipt_MASQUERADE.c 1.8 -> 1.9 # sound/oss/ad1848.c 1.20 -> 1.23 # sound/oss/ymfpci.c 1.34 -> 1.35 # drivers/char/watchdog/w83877f_wdt.c 1.17 -> 1.20 # drivers/scsi/gdth.c 1.33 -> 1.34 # sound/core/timer.c 1.20 -> 1.21 # fs/lockd/svc.c 1.24 -> 1.25 # arch/i386/pci/acpi.c 1.10 -> 1.11 # drivers/s390/char/sclp.c 1.8 -> 1.9 # drivers/isdn/hisax/st5481_usb.c 1.17 -> 1.19 # net/ipv6/esp6.c 1.21 -> 1.23 # arch/sparc64/kernel/sys_sparc32.c 1.78 -> 1.79 # drivers/net/tokenring/ibmtr.c 1.16 -> 1.17 # arch/v850/vmlinux.lds.S 1.13 -> 1.14 arch/v850/kernel/vmlinux.lds.S (moved) # drivers/base/power.c 1.24 -> 1.28 drivers/base/power/shutdown.c (moved) # drivers/usb/class/cdc-acm.c 1.48 -> 1.49 # include/linux/compiler.h 1.17 -> 1.18 # include/asm-i386/mach-summit/mach_apic.h 1.29 -> 1.30 # sound/oss/sscape.c 1.9 -> 1.10 # include/asm-x86_64/ia32_unistd.h 1.5 -> 1.6 # drivers/scsi/st.c 1.68 -> 1.69 # drivers/scsi/ide-scsi.c 1.27 -> 1.30 # sound/oss/sb_card.c 1.18 -> 1.19 # drivers/scsi/eata_pio.c 1.20 -> 1.21 # include/asm-i386/unistd.h 1.28 -> 1.29 # fs/xfs/xfs_dinode.h 1.2 -> 1.3 # include/asm-i386/bitops.h 1.16 -> 1.17 # drivers/char/agp/ali-agp.c 1.26 -> 1.28 # init/do_mounts.h 1.5 -> 1.6 # sound/oss/au1000.c 1.1 -> 1.2 # drivers/char/drm/radeon_drm.h 1.16 -> 1.17 # arch/x86_64/kernel/sys_x86_64.c 1.9 -> 1.10 # drivers/usb/serial/keyspan_pda.c 1.31 -> 1.32 # drivers/net/wan/comx-hw-locomx.c 1.7 -> 1.8 # arch/ppc/platforms/pmac_setup.c 1.29 -> 1.30 # Makefile 1.419.1.1 -> 1.421 # drivers/isdn/hisax/avma1_cs.c 1.6 -> 1.7 # include/asm-i386/io_apic.h 1.13 -> 1.14 # drivers/usb/serial/mct_u232.c 1.38 -> 1.39 # Documentation/hw_random.txt 1.7 -> 1.8 # drivers/scsi/sym53c8xx.c 1.39 -> 1.41 # drivers/scsi/zalon.c 1.6 -> 1.7 # arch/i386/defconfig 1.99 -> 1.100 # arch/i386/kernel/timers/timer_tsc.c 1.22 -> 1.23 # drivers/usb/media/stv680.c 1.27 -> 1.28 # arch/um/kernel/Makefile 1.19 -> 1.20 # include/asm-x86_64/unistd.h 1.16 -> 1.17 # drivers/scsi/qlogicpti.c 1.19 -> 1.20 # mm/page-writeback.c 1.72 -> 1.73 # arch/x86_64/defconfig 1.24 -> 1.25 # net/ipv6/ah6.c 1.21 -> 1.23 # drivers/acpi/processor.c 1.40 -> 1.41 # drivers/scsi/scsi_priv.h 1.17 -> 1.22 # drivers/char/watchdog/sbc60xxwdt.c 1.27 -> 1.33 # drivers/ide/legacy/ide-cs.c 1.11 -> 1.12 # sound/oss/pas2_midi.c 1.5 -> 1.6 # include/asm-x86_64/percpu.h 1.8 -> 1.9 # include/asm-x86_64/topology.h 1.3 -> 1.4 # include/linux/topology.h 1.2 -> 1.3 # drivers/char/agp/backend.c 1.83 -> 1.84 # arch/i386/kernel/ldt.c 1.13 -> 1.14 # sound/oss/pas2_card.c 1.7 -> 1.8 # Documentation/crypto/api-intro.txt 1.12 -> 1.15 # include/linux/ipv6.h 1.10 -> 1.11 # drivers/char/vt_ioctl.c 1.28 -> 1.29 # CREDITS 1.92 -> 1.94 # fs/partitions/efi.h 1.5 -> 1.6 # arch/arm26/vmlinux.lds.S 1.1 -> 1.2 arch/arm26/kernel/vmlinux.lds.S (moved) # include/linux/timer.h 1.14 -> 1.15 # arch/ppc64/kernel/prom.c 1.30 -> 1.31 # include/acpi/acpi_drivers.h 1.15 -> 1.16 # net/ipv6/ipv6_syms.c 1.16 -> 1.17 # kernel/module.c 1.90 -> 1.91 # drivers/eisa/virtual_root.c 1.3 -> 1.4 # Documentation/firmware_class/README 1.1 -> 1.2 # net/core/skbuff.c 1.28 -> 1.29 # arch/sparc64/kernel/us2e_cpufreq.c 1.3 -> 1.4 # drivers/mca/mca-proc.c 1.1 -> 1.2 # sound/usb/usbaudio.c 1.43 -> 1.44 # drivers/scsi/qlogicfc.c 1.34 -> 1.37 # drivers/input/evdev.c 1.26 -> 1.27 # net/netrom/nr_timer.c 1.9 -> 1.10 # net/ipv4/sysctl_net_ipv4.c 1.11 -> 1.12 # sound/oss/maui.c 1.5 -> 1.6 # arch/ppc64/kernel/smp.c 1.40 -> 1.41 # scripts/split-man 1.1 -> 1.2 # arch/x86_64/kernel/Makefile 1.21 -> 1.23 # drivers/char/watchdog/alim7101_wdt.c 1.7 -> 1.10 # security/selinux/avc.c 1.1 -> 1.2 # sound/oss/nec_vrc5477.c 1.16 -> 1.17 # drivers/net/hamradio/yam.c 1.16 -> 1.18 # arch/x86_64/kernel/aperture.c 1.4 -> 1.5 # include/asm-i386/mach-numaq/mach_ipi.h 1.2 -> 1.3 # sound/oss/es1371.c 1.30 -> 1.31 # net/ipv6/route.c 1.53 -> 1.57 # include/acpi/acconfig.h 1.41 -> 1.42 # fs/minix/bitmap.c 1.10 -> 1.11 # drivers/scsi/sd.c 1.129 -> 1.132 # drivers/net/tulip/Kconfig 1.4 -> 1.5 # sound/oss/mad16.c 1.11 -> 1.12 # arch/i386/kernel/mca.c 1.13 -> 1.14 # arch/ppc64/vmlinux.lds.S 1.17 -> 1.18 arch/ppc64/kernel/vmlinux.lds.S (moved) # fs/reiserfs/hashes.c 1.6 -> 1.7 # drivers/media/video/bttv-driver.c 1.31 -> 1.32 # sound/oss/i810_audio.c 1.42 -> 1.44 # sound/oss/trident.c 1.44 -> 1.45 # drivers/pcmcia/ds.c 1.36 -> 1.37 # net/ipv6/Makefile 1.14 -> 1.15 # arch/ppc64/kernel/pacaData.c 1.7 -> 1.8 # drivers/block/DAC960.c 1.63 -> 1.65 # drivers/block/DAC960.h 1.22 -> 1.23 # arch/alpha/Kconfig 1.24 -> 1.25 # net/ipv4/Kconfig 1.10 -> 1.11 # arch/m68k/kernel/Makefile 1.10 -> 1.11 # sound/oss/opl3sa.c 1.4 -> 1.5 # drivers/i2c/i2c-dev.c 1.34 -> 1.35 # drivers/usb/storage/unusual_devs.h 1.50 -> 1.51 # sound/oss/hal2.c 1.2 -> 1.3 # drivers/net/tokenring/olympic.c 1.23 -> 1.24 # fs/xfs/xfs_da_btree.c 1.7 -> 1.8 # drivers/input/serio/i8042.h 1.6 -> 1.7 # include/net/irda/irtty.h 1.2 -> 1.3 # sound/oss/harmony.c 1.3 -> 1.4 # drivers/block/elevator.c 1.49 -> 1.50 # drivers/scsi/cpqfcTSworker.c 1.17 -> 1.18 # include/linux/eisa.h 1.5 -> 1.6 # drivers/usb/serial/ftdi_sio.c 1.48 -> 1.49 # drivers/input/gameport/vortex.c 1.6 -> 1.7 # fs/xfs/xfsidbg.c 1.29 -> 1.30 # drivers/scsi/scsi_scan.c 1.99 -> 1.103 # arch/um/kernel/um_arch.c 1.11 -> 1.12 # arch/alpha/lib/ev6-stxncpy.S 1.5 -> 1.6 # sound/oss/ali5455.c 1.2 -> 1.3 # kernel/sched.c 1.204 -> 1.207 # net/bridge/br_stp_bpdu.c 1.6 -> 1.7 # include/asm-parisc/smp.h 1.4 -> 1.5 # drivers/media/video/planb.c 1.15 -> 1.16 # kernel/power/Makefile 1.5 -> 1.7 # drivers/Makefile 1.38 -> 1.39 # crypto/tcrypt.c 1.24 -> 1.27 # drivers/block/paride/pd.c 1.50 -> 1.51 # drivers/usb/host/ehci-q.c 1.51 -> 1.52 # drivers/ide/legacy/ht6560b.c 1.6 -> 1.7 # drivers/block/Makefile 1.20 -> 1.21 # init/Kconfig 1.19 -> 1.20 # drivers/usb/storage/sddr09.c 1.25 -> 1.26 # drivers/acpi/osl.c 1.41 -> 1.42 # drivers/net/meth.c 1.1 -> 1.2 # include/net/ipv6.h 1.23 -> 1.25 # drivers/scsi/sim710.c 1.18 -> 1.19 # scripts/Makefile.build 1.38 -> 1.39 # arch/um/kernel/irq.c 1.9 -> 1.10 # drivers/scsi/st.h 1.14 -> 1.15 # fs/sysfs/sysfs.h 1.2 -> 1.4 # arch/mips/sibyte/cfe/smp.c 1.2 -> 1.3 # arch/ppc/kernel/irq.c 1.30 -> 1.31 # arch/alpha/kernel/sys_marvel.c 1.6 -> 1.7 # kernel/params.c 1.4 -> 1.5 # arch/alpha/kernel/core_lca.c 1.5 -> 1.7 # arch/x86_64/mm/numa.c 1.5 -> 1.6 # drivers/usb/serial/ipaq.c 1.31 -> 1.32 # net/ipv6/udp.c 1.44 -> 1.47 # drivers/base/Makefile 1.22 -> 1.23 # drivers/input/gameport/ns558.c 1.16 -> 1.17 # arch/sparc64/kernel/sparc64_ksyms.c 1.52 -> 1.53 # arch/um/kernel/tt/process_kern.c 1.7 -> 1.8 # kernel/timer.c 1.63 -> 1.66 # include/net/xfrm.h 1.50 -> 1.51 # arch/x86_64/kernel/reboot.c 1.7 -> 1.8 # drivers/net/Makefile.lib 1.8 -> 1.9 # drivers/char/agp/via-agp.c 1.47 -> 1.49 # drivers/input/misc/uinput.c 1.11 -> 1.13 # sound/pci/cs46xx/dsp_spos.c 1.14 -> 1.15 # include/linux/pfkeyv2.h 1.8 -> 1.9 # arch/ia64/vmlinux.lds.S 1.36 -> 1.37 arch/ia64/kernel/vmlinux.lds.S (moved) # drivers/net/Kconfig 1.38 -> 1.40 # arch/sparc64/vmlinux.lds.S 1.19 -> 1.20 arch/sparc64/kernel/vmlinux.lds.S (moved) # drivers/pci/setup-res.c 1.20 -> 1.21 # net/ipv4/ipcomp.c 1.14 -> 1.16 # lib/string.c 1.10 -> 1.12 # drivers/usb/serial/kobil_sct.c 1.11 -> 1.12 # drivers/telephony/ixj_pcmcia.c 1.5 -> 1.6 # arch/i386/kernel/acpi/boot.c 1.24 -> 1.26 # arch/sparc/kernel/Makefile 1.16 -> 1.17 # drivers/video/leo.c 1.3 -> 1.5 # drivers/macintosh/Makefile 1.11 -> 1.12 # fs/afs/volume.h 1.1 -> 1.2 # sound/oss/maestro.c 1.34 -> 1.35 # net/ipv4/ah4.c 1.26 -> 1.27 # arch/alpha/kernel/process.c 1.28 -> 1.29 # arch/ia64/kernel/irq.c 1.26 -> 1.27 # drivers/usb/serial/omninet.c 1.30 -> 1.31 # include/asm-x86_64/proto.h 1.13 -> 1.14 # arch/i386/kernel/cpu/cpufreq/speedstep-lib.c 1.2 -> 1.3 # include/linux/reiserfs_fs.h 1.50 -> 1.51 # fs/xfs/xfs_dir_leaf.c 1.9 -> 1.11 # include/asm-i386/acpi.h 1.6 -> 1.7 # drivers/char/specialix.c 1.22 -> 1.23 # arch/i386/kernel/cpu/proc.c 1.11 -> 1.12 # drivers/pcmcia/i82365.c 1.42 -> 1.43 # include/asm-i386/mach-default/mach_ipi.h 1.2 -> 1.3 # arch/sparc64/kernel/ioctl32.c 1.66 -> 1.67 # net/core/net-sysfs.c 1.9 -> 1.13 # drivers/scsi/pcmcia/aha152x_stub.c 1.17 -> 1.19 # drivers/char/drm/radeon.h 1.13 -> 1.14 # fs/hugetlbfs/inode.c 1.29 -> 1.31 # arch/ppc/kernel/Makefile 1.37 -> 1.38 # fs/xfs/linux/xfs_aops.c 1.43 -> 1.44 # sound/oss/ad1816.c 1.12 -> 1.13 # include/asm-ia64/bitops.h 1.13 -> 1.14 # arch/arm/kernel/Makefile 1.18 -> 1.19 # drivers/media/dvb/ttusb-dec/ttusb_dec.c 1.2 -> 1.3 # sound/oss/kahlua.c 1.3 -> 1.4 # include/linux/device.h 1.102 -> 1.106 # drivers/input/joystick/joydump.c 1.2 -> 1.3 # drivers/usb/serial/cyberjack.c 1.28 -> 1.29 # arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 1.16 -> 1.17 # arch/alpha/kernel/pci_impl.h 1.10 -> 1.11 # arch/alpha/kernel/err_titan.c 1.4 -> 1.5 # fs/partitions/check.c 1.116 -> 1.117 # arch/ppc/platforms/pmac_feature.c 1.17 -> 1.18 # crypto/tcrypt.h 1.13 -> 1.15 # scripts/genksyms/Makefile 1.2 -> 1.3 # fs/xfs/linux/xfs_super.c 1.56 -> 1.58 # net/netrom/nr_dev.c 1.6 -> 1.9 # drivers/char/drm/gamma_dma.c 1.14 -> 1.15 # security/selinux/ss/global.h 1.1 -> 1.2 # fs/xfs/xfs_bmap.c 1.13 -> 1.14 # include/net/dst.h 1.15 -> 1.16 # arch/x86_64/kernel/ldt.c 1.10 -> 1.11 # sound/oss/mpu401.c 1.13 -> 1.14 # arch/x86_64/kernel/pci-dma.c 1.6 -> 1.7 # arch/sparc64/kernel/irq.c 1.31 -> 1.32 # net/irda/irlap.c 1.22 -> 1.24 # include/asm-alpha/smp.h 1.10 -> 1.11 # net/ipv6/addrconf.c 1.60 -> 1.63 # drivers/scsi/3w-xxxx.c 1.35 -> 1.37 # arch/ia64/kernel/perfmon.c 1.53 -> 1.54 # crypto/Kconfig 1.16 -> 1.18 # drivers/bluetooth/hci_usb.c 1.29 -> 1.30 # net/core/Makefile 1.16 -> 1.17 # drivers/net/ppp_generic.c 1.36 -> 1.37 # fs/Kconfig.binfmt 1.2 -> 1.3 # include/asm-i386/mach-bigsmp/mach_apic.h 1.14 -> 1.15 # arch/ppc/kernel/setup.c 1.43 -> 1.44 # security/selinux/hooks.c 1.1 -> 1.2 # include/linux/netdevice.h 1.47 -> 1.50 # arch/ppc/kernel/smp.c 1.34 -> 1.35 # drivers/net/wan/pc300_drv.c 1.12 -> 1.13 # include/linux/node.h 1.4 -> 1.5 # drivers/acpi/Makefile 1.34 -> 1.35 # drivers/video/cg14.c 1.6 -> 1.8 # drivers/usb/misc/usbtest.c 1.19 -> 1.20 # arch/mips/sgi-ip27/ip27-init.c 1.8 -> 1.9 # include/linux/kernel_stat.h 1.12 -> 1.13 # drivers/net/sungem.c 1.41 -> 1.42 # drivers/scsi/scsi_ioctl.c 1.21 -> 1.22 # arch/i386/mach-generic/summit.c 1.2 -> 1.3 # crypto/Makefile 1.17 -> 1.19 # drivers/block/cciss.c 1.85 -> 1.86 # fs/xfs/xfs_buf.h 1.13 -> 1.14 # arch/s390/kernel/Makefile 1.19 -> 1.20 # drivers/scsi/dc395x.h 1.2 -> 1.3 # drivers/usb/serial/io_ti.c 1.19 -> 1.20 # fs/xfs/xfs_inode.c 1.30 -> 1.31 # drivers/net/wan/comx-hw-mixcom.c 1.10 -> 1.11 # arch/alpha/kernel/sys_alcor.c 1.8 -> 1.9 # sound/oss/emu10k1/main.c 1.18 -> 1.19 # drivers/pci/setup-bus.c 1.20 -> 1.21 # drivers/mtd/maps/Kconfig 1.7 -> 1.8 # drivers/ide/pci/pdc202xx_old.c 1.16 -> 1.17 # include/asm-sparc64/mmu_context.h 1.13 -> 1.14 # arch/ppc64/kernel/Makefile 1.27 -> 1.28 # arch/alpha/lib/stxncpy.S 1.6 -> 1.7 # drivers/usb/serial/empeg.c 1.39 -> 1.40 # drivers/char/ipmi/ipmi_watchdog.c 1.3 -> 1.4 # arch/x86_64/mm/k8topology.c 1.4 -> 1.5 # crypto/des.c 1.12 -> 1.13 # drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 1.2 -> 1.3 # include/linux/pnp.h 1.24 -> 1.25 # drivers/net/tokenring/3c359.c 1.12 -> 1.13 # drivers/scsi/esp.c 1.32 -> 1.33 # drivers/scsi/pcmcia/nsp_cs.c 1.25 -> 1.27 # arch/parisc/kernel/smp.c 1.6 -> 1.7 # arch/sparc64/Makefile 1.28 -> 1.29 # kernel/workqueue.c 1.9 -> 1.10 # include/asm-s390/tlbflush.h 1.6 -> 1.7 # net/netrom/nr_route.c 1.5 -> 1.8 # drivers/parport/parport_cs.c 1.8 -> 1.9 # include/scsi/scsi.h 1.11 -> 1.13 # fs/inode.c 1.101 -> 1.102 # include/asm-i386/hw_irq.h 1.23 -> 1.24 # drivers/serial/sunzilog.c 1.33 -> 1.34 # arch/ia64/kernel/smp.c 1.26 -> 1.27 # drivers/bluetooth/btuart_cs.c 1.7 -> 1.8 # sound/pci/rme32.c 1.18 -> 1.19 # drivers/base/class.c 1.38 -> 1.40 # net/ipv4/route.c 1.65 -> 1.67 # drivers/bluetooth/bt3c_cs.c 1.12 -> 1.13 # sound/oss/gus_midi.c 1.6 -> 1.7 # sound/oss/es1370.c 1.28 -> 1.30 # arch/ia64/kernel/Makefile 1.24 -> 1.25 # drivers/scsi/qla1280.h 1.18 -> 1.21 # scripts/kconfig/Makefile 1.6 -> 1.7 # drivers/acpi/Kconfig 1.13 -> 1.16 # drivers/scsi/sym53c8xx_2/sym_glue.h 1.10 -> 1.11 # drivers/ide/pci/amd74xx.c 1.19 -> 1.20 # drivers/usb/core/file.c 1.11 -> 1.12 # drivers/scsi/qla1280.c 1.40 -> 1.44 # arch/ppc64/kernel/ioctl32.c 1.35 -> 1.36 # crypto/twofish.c 1.2 -> 1.3 # arch/i386/kernel/apic.c 1.43 -> 1.46 # include/asm-i386/mach-default/mach_apic.h 1.26 -> 1.27 # drivers/char/riscom8.h 1.3 -> 1.4 # drivers/net/3c505.c 1.23 -> 1.24 # arch/v850/kernel/Makefile 1.8 -> 1.9 # drivers/usb/media/usbvideo.c 1.35 -> 1.36 # arch/x86_64/kernel/smpboot.c 1.19 -> 1.20 # kernel/ptrace.c 1.30 -> 1.31 # drivers/char/agp/amd-k7-agp.c 1.32 -> 1.34 # fs/xfs/xfs_vnodeops.c 1.33 -> 1.35 # drivers/net/slip.c 1.18 -> 1.19 # sound/oss/pss.c 1.10 -> 1.11 # include/linux/reboot.h 1.4 -> 1.5 # net/xfrm/Makefile 1.2 -> 1.3 # Documentation/kernel-parameters.txt 1.23.1.1 -> 1.26 # net/netrom/nr_subr.c 1.8 -> 1.9 # drivers/scsi/sym53c8xx_2/sym_glue.c 1.27 -> 1.32 # include/net/irda/irda_device.h 1.6 -> 1.8 # arch/ppc/vmlinux.lds.S 1.22 -> 1.23 arch/ppc/kernel/vmlinux.lds.S (moved) # drivers/usb/serial/usb-serial.h 1.32 -> 1.33 # drivers/mca/mca-legacy.c 1.4 -> 1.5 # drivers/video/ffb.c 1.6 -> 1.7 # include/asm-x86_64/siginfo.h 1.3 -> 1.4 # (new) -> 1.2 drivers/base/power/sysfs.c # (new) -> 1.4 drivers/base/power/power.h # (new) -> 1.1 include/asm-generic/cpumask_const_value.h # (new) -> 1.1 include/asm-generic/cpumask_const_reference.h # (new) -> 1.5 drivers/base/power/Makefile # (new) -> 1.2 crypto/cast6.c # (new) -> 1.1 kernel/power/main.c # (new) -> 1.2 net/core/ethtool.c # (new) -> 1.1 include/asm-generic/cpumask_up.h # (new) -> 1.2 drivers/macintosh/macio_asic.c # (new) -> 1.1 include/linux/cpumask.h # (new) -> 1.1 include/asm-generic/cpumask_array.h # (new) -> 1.2 kernel/power/poweroff.c # (new) -> 1.1 net/xfrm/xfrm_export.c # (new) -> 1.2 crypto/cast5.c # (new) -> 1.4 fs/sysfs/group.c # (new) -> 1.1 include/asm-ppc/of_device.h # (new) -> 1.1 drivers/block/noop-iosched.c # (new) -> 1.1 include/asm-generic/cpumask_arith.h # (new) -> 1.6 drivers/char/agp/ati-agp.c # (new) -> 1.1 drivers/base/power/runtime.c # (new) -> 1.6 drivers/base/power/main.c # (new) -> 1.5 drivers/base/power/resume.c # (new) -> 1.5 drivers/base/power/suspend.c # (new) -> 1.2 arch/ppc/syslib/of_device.c # (new) -> 1.1 include/linux/bitmap.h # (new) -> 1.4 drivers/net/sis190.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/08/08 torvalds@home.osdl.org 1.1123.3.12 # Linux 2.6.0-test3 # -------------------------------------------- # 03/08/08 davem@nuts.ninka.net 1.1123.6.1 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/08/08 davem@nuts.ninka.net 1.1123.3.13 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/08/09 davem@nuts.ninka.net 1.1123.3.14 # [IPV4]: Fix setting net.ipv4.conf.all.forwarding via sysctl() system call. # -------------------------------------------- # 03/08/09 yoshfuji@linux-ipv6.org 1.1123.3.15 # [IPV6]: Fix typo in linux/ipv6.h # -------------------------------------------- # 03/08/09 shemminger@osdl.org 1.1123.3.16 # [NET]: Fix tun driver to use private linked lists. # -------------------------------------------- # 03/08/09 rob@osinvestor.com 1.1123.7.1 # [SPARC64]: Delete fop->read stub in riowatchdog driver. # -------------------------------------------- # 03/08/09 ak@muc.de 1.1123.3.17 # [NET]: Allow XFRM subsystem to be optional. # -------------------------------------------- # 03/08/09 yoshfuji@linux-ipv6.org 1.1123.3.18 # [IPV4]: Fix IPVS build with IP_VS_PROTO_TCP disabled. # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.1 # [WATCHDOG] sbc60xxwdt.c patch # # general cleanup of trailing spaces and comments # fix possible wdt_is_open race # add KERN_* to printk's # changed watchdog_info to correctly reflect what the driver offers # added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls # made timeout (the emulated heartbeat) a module_param # made the keepalive ping an internal subroutine # added MODULE_AUTHOR and MODULE_DESCRIPTION info # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.2 # [WATCHDOG] sbc60xxwdt patch2 # # report default timeout as a number # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.3 # [WATCHDOG] sbc60xxwdt patch3 # # make wdt_stop and wdt_start module params # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.4 # [WATCHDOG] sbc60xxwdt patch4 # # added extra printk's to report what problem occured # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.5 # [WATCHDOG] sbc60xxwdt.c patch5 # # some last clean-ups # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.6 # [WATCHDOG] advantechwdt.c patch2 # # some small clean-ups (use PFX + report default timeout as it's value in the MODULE_PARM_DESC) # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.7 # [WATCHDOG] w83877f_wdt patch # # cleanup comments and trailing spaces # eliminate extra spin_unlock # add KERN_* tags to printks # added extra printk's to report what problem occured # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.8 # [WATCHDOG] w83877f_wdt.c patch2 # # add CONFIG_WATCHDOG_NOWAYOUT support # changed watchdog_info to correctly reflect what the driver offers # added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls # use module_param # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.9 # [WATCHDOG] w83877f_wdt.c patch3 (add timeout features) # # added WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT ioctls # made timeout (the emulated heartbeat) a module_param # made the keepalive ping an internal subroutine # -------------------------------------------- # 03/08/09 wim@iguana.be 1.1123.8.10 # [WATCHDOG] sbc60xxwdt.c patch6 # # some small clean-ups: do correct errorhandling # -------------------------------------------- # 03/08/09 herbert@gondor.apana.org.au 1.1123.8.11 # [PATCH] Fix usb interface change in hisax st5481_* # # This makes the HISAX ST5481 driver build again with 2.6.0-test3 where # the usb_host_config structure has changed. # -------------------------------------------- # 03/08/09 jgarzik@pobox.com 1.1123.8.12 # [PATCH] PATCH 2.6: fix X86_VENDOR_ID offset in head.S # # While reviewing my 2.4 backport of the 2.6 cpu capabilities (including # the Via RNG support), Mikael Pettersson noticed a bug in both my # backport, and 2.6: when NCAPINTS (x86_capability array size) is # increased, one must adjust the offset in arch/i386/kernel/head.S also. # # Contributed by Mikael Pettersson. # -------------------------------------------- # 03/08/09 benh@kernel.crashing.org 1.1123.8.13 # [PATCH] PowerMac: Ground work for new driver model # # This provides the necessary infrastructure for PowerMac specific drivers # (and actually some Open Firmware platform drivers on non-PowerMacs as # well provided somebody port them) to be properly probed & referenced via # the new driver model and be part of sysfs. # # As-is, this patch doesn't break anything nor change any driver. I'll # send you individual driver patches as I clean them up & get them tested # on as many machines as possible, though I don't expect much problems. # -------------------------------------------- # 03/08/09 tmolina@cablespeed.com 1.1123.8.14 # [PATCH] Re: Linux 2.6.0-test3: logo patch # # The following patch has been floating around forever. It is required # for several ARM framebuffer drivers, and several other drivers. James # has indicated that this is the correct fix back in May. # -------------------------------------------- # 03/08/09 mochel@osdl.org 1.1123.8.15 # Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/08/09 davem@kernel.bkbits.net 1.1123.7.2 # Merge davem@nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # into kernel.bkbits.net:/home/davem/sparc-2.5 # -------------------------------------------- # 03/08/09 wensong@linux-vs.org 1.1123.3.19 # [IPV4] IPVS: fix the dependence of IP_VS_FTP in Kconfig # -------------------------------------------- # 03/08/09 yoshfuji@linux-ipv6.org 1.1123.3.20 # [IPV6]: strategy handler for net.ipv6.conf.* forwarding. # -------------------------------------------- # 03/08/09 bunk@fs.tum.de 1.1123.3.21 # [NET]: Kill EXPORT_NO_SYMBOLS from meth.c # -------------------------------------------- # 03/08/09 davem@kernel.bkbits.net 1.1123.3.22 # Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5 # into kernel.bkbits.net:/home/davem/net-2.5 # -------------------------------------------- # 03/08/09 mochel@osdl.org 1.1123.1.3 # Merge bk://kernel.bkbits.net//home/mochel/linux-2.5-power # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/08/09 len.brown@intel.com 1.1046.1.426 # ACPI from 2.4: # build: add ACPI_HT, delete ACPI_HT_ONLY # boot: add acpi={force, off, ht}; delete "noht", "acpismp=" # add DMI blacklist from UnitedLinux # -------------------------------------------- # 03/08/09 jan.oravec@6com.sk 1.1123.9.1 # [NET]: Set NLM_F_MULTI in answer of RTM_GETADDR dump answer. # -------------------------------------------- # 03/08/10 len.brown@intel.com 1.1046.1.427 # ACPI: this delta should have been included in previous cset # -------------------------------------------- # 03/08/10 len.brown@intel.com 1.1046.1.428 # ACPI -- CONFIG_ACPI_HT # -------------------------------------------- # 03/08/10 len.brown@intel.com 1.1046.1.429 # ACPI -- CONFIG_ACPI_HT -- this delta should have been in previous cset # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.10.1 # [WATCHDOG] sc520_wdt.c patch # # cleanup comments and trailing spaces # add KERN_* tags to printks # added extra printk's to report what problem occured # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.10.2 # [WATCHDOG] sc520_wdt.c patch2 # # changed watchdog_info to correctly reflect what the driver offers # added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.10.3 # [WATCHDOG] sc520_wdt.c patch3 # # added WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT ioctls # made timeout (the emulated heartbeat) a module_param # made the keepalive ping an internal subroutine # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.11.1 # Merge http://linux-watchdog.bkbits.net/linux-2.5-watchdog # into iguana.be:/home/wim/BitKeeper/projects/linux-2.5-watchdog # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.11.2 # [WATCHDOG] alim7101_wdt.c patch # # cleanup comments and trailing spaces # added extra printk's to report what problem occured # added MODULE_DESCRIPTION # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.11.3 # [WATCHDOG] alim7101_wdt.c patch2 # # changed watchdog_info to correctly reflect what the driver offers # added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls # -------------------------------------------- # 03/08/10 wim@iguana.be 1.1123.11.4 # [WATCHDOG] alim7101_wdt.c patch3 # # added WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT ioctls # made timeout (the emulated heartbeat) a module_param # made the keepalive ping an internal subroutine # -------------------------------------------- # 03/08/10 davem@nuts.ninka.net 1.1123.12.1 # [SPARC]: Handle switches out of graphics mode properly in sbusfb drivers. # -------------------------------------------- # 03/08/10 davem@nuts.ninka.net 1.1123.12.2 # [SPARC]: Fix typos in leo/cg14 fixes. # -------------------------------------------- # 03/08/10 davej@tetrachloride.(none) 1.1123.13.1 # Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/trees/bk-linus # into tetrachloride.(none):/mnt/raid/src/kernel/2.5/trees/agpgart # -------------------------------------------- # 03/08/10 hch@lst.de 1.1046.591.7 # [PATCH] make sym2 scan devices again # # It needs a call to scsi_scan_host to find devices. Also remove the # superflous scsi_set_device call - scsi_add_host does that for us. # -------------------------------------------- # 03/08/10 mochel@osdl.org 1.1123.1.4 # [power] Add PM usage counting # # - Add ->pm_users and ->pm_parent fields to struct dev_pm_info. # - Add function device_pm_set_parent() # # The default power parent for a device is the device's physical parent, but # a driver may change it to represent a tranversal power dependency. # # Though it's not incorporated into the suspend/resume sequences yet, the # core will respect the power tree, rather than the physical/electrical one. # # Also added is a power usage count for devices, which indicates how many # devices are dependent on that one for power (how many children it has in # the power tree). The core will use this count to determine whether or not # a device can be put into a low power state or not. # -------------------------------------------- # 03/08/10 mochel@osdl.org 1.1123.14.1 # Merge bk://kernel.bkbits.net//home/mochel/linux-2.5-core # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core # -------------------------------------------- # 03/08/10 mochel@osdl.org 1.1123.14.2 # [sysfs] Convert struct attribute_group to take array of pointers. # # From Stephen Hemminger. Needed to use attribute groups effectively. # # -------------------------------------------- # 03/08/11 paulus@samba.org 1.1123.15.1 # PPC32: Fix compile error on SMP - asm-ppc/smp.h needs linux/threads.h. # -------------------------------------------- # 03/08/10 agrover@groveronline.com 1.1125 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/08/11 jejb@raven.il.steeleye.com 1.1123.16.1 # Merge ssh://mulgrave-w/BK/scsi-misc-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.6 # -------------------------------------------- # 03/08/11 jgarzik@redhat.com 1.1123.17.1 # Merge redhat.com:/garz/repo/linus-2.6 # into redhat.com:/garz/repo/misc-2.6 # -------------------------------------------- # 03/08/11 lord@jen.americas.sgi.com 1.1123.18.1 # Merge ssh://lord@kernel.bkbits.net/xfs-2.5 # into jen.americas.sgi.com:/src/lord/bitkeeper/xfs-2.5 # -------------------------------------------- # 03/08/11 lord@sgi.com 1.1123.18.2 # [XFS] remove an impossible code path from mkdir and link paths, # spotted by Al Viro. # # SGI Modid: 2.5.x-xfs:slinx:155518a # -------------------------------------------- # 03/08/11 trini@kernel.crashing.org 1.1123.19.1 # [PATCH] I2C: Fix for i2c-piix4 with on some boards # # Hello all. On some boards with an Intel PIIX4 the BIOS (such as the one # found on a Force CPCI-735) will incorrectly configure the chipset, and # leaves a register in an undefined state causing i2c to behave strangley. # The following patches (first vs lm_sensors-2.8.0 and then vs # 2.6.0-test3) fixes the issue. # -------------------------------------------- # 03/08/11 khali@linux-fr.org 1.1123.19.2 # [PATCH] i2c: user/kernel bug and memory leak in i2c-dev # -------------------------------------------- # 03/08/11 greg@kroah.com 1.1123.19.3 # [PATCH] i2c: fix up "raw" printk() call. # -------------------------------------------- # 03/08/11 oliver@neukum.org 1.1123.20.1 # [PATCH] USB: ttusb_dec.c: another case of GFP_KERNEL in interrupt # # - in interrupt usb_submit_urb must use GFP_ATOMIC # -------------------------------------------- # 03/08/11 oliver@neukum.org 1.1123.20.2 # [PATCH] USB: return to old timeout handling # # it seems that I've broken usblp. This reverts to the old # behaviour. Please apply. # # - revert to old timeout handling # -------------------------------------------- # 03/08/11 oliver@neukum.org 1.1123.20.3 # [PATCH] USB: correct error handling in usb_driver_claim_interface() # # this function races with itself, doesn't return errors and races with # releasing interfaces. This patch fixes it by changing the function # prototype, introducing locking and having a correct order in # releasing interfaces. # # - API change to check errors in usb_driver_claim_interface and # fix a race condition between releasing and reclaiming an interface # -------------------------------------------- # 03/08/11 oliver@neukum.org 1.1123.20.4 # [PATCH] USB: correct error handling in usb_driver_claim_interface() - comment # # - update commentary # -------------------------------------------- # 03/08/11 oliver@neukum.org 1.1123.20.5 # [PATCH] USB: error check for claiming second interface in usbnet # # - fail if second interface is already claimed # -------------------------------------------- # 03/08/11 oliver@neukum.org 1.1123.20.6 # [PATCH] USB: genelink_tx_fixup fails to check for memory allocation failure # # this can oops. # # - check for mem alloc failure # -------------------------------------------- # 03/08/11 greg@kroah.com 1.1123.19.4 # i2c: move w83481d to top of link order due to chip address takeover ability. # # Fixes http://bugme.osdl.org/show_bug.cgi?id=1066 # -------------------------------------------- # 03/08/11 david-b@pacbell.net 1.1123.20.7 # [PATCH] USB: dabusb doesn't claim every ez-usb an21xx device # # This resolves the annoyance that dabusb claims devices # it shouldn't (and hotplugs for them), because of wrongly # including the device IDs used by an21xx devices that don't # have an ID prom. Mostly affects developers. # # Deti OK'd such a patch ages ago. # -------------------------------------------- # 03/08/11 david-b@pacbell.net 1.1123.20.8 # [PATCH] add usb_reset_configuration() # # Unfortunately, usb_set_configuration() is widely mis-used as a # lightweight device reset. That's trouble because setting a # configuration must sometimes involve things that don't relate # at all to a light reset, and can't be done in contexts like # driver probe() calls. # # This patch updates most usb_set_configuration() users to use a call # that provides more appropriate functionality: # # - Adds a new usb_reset_configuration() call, which never needs # to change very much usbcore state. # # - Uses it to replace most usb_set_configuration() calls, in # many serial drivers, hisax, dvb, irda, and so on. # # - Modifies usb_reset_device() so it issues the control request # directly. It's both more of a reset (hides a USB reset) and # less of one (altsettings are unchanged). # # - Makes usbfs return the error code instead of discarding it. # # Once this goes in, then usb_set_configuration() can be made to # work properly (including from sysfs). # -------------------------------------------- # 03/08/11 kartik_me@hotmail.com 1.1123.9.2 # [CRYPTO]: Add cast5, integration by jmorris@intercode.com.au # -------------------------------------------- # 03/08/11 davej@redhat.com 1.1123.9.3 # [IPV6]: Missing break in switch statement of rawv6_getsockopt(). # -------------------------------------------- # 03/08/11 davej@redhat.com 1.1123.9.4 # [IPV4]: /proc/net/pnp dumps items marked initdata. # -------------------------------------------- # 03/08/11 davej@redhat.com 1.1123.9.5 # [SUNRPC]: Remove duplicate access_ok(). # -------------------------------------------- # 03/08/11 rusty@rustcorp.com.au 1.1123.9.6 # [NETFILTER]: Fix masquerade routing check. # # Alexey says: # Unrelated: giving out->ifindex is a bug, by the way. It can screw up # the things a lot. In this context, if you want to be sure that packet # will go out expected interface you do plain lookup and drop packet # if it gave you some strange route. # -------------------------------------------- # 03/08/11 shemminger@osdl.org 1.1123.9.7 # [NET]: Update bpqether for 2.6 # # This patch fixes several issues with drivers/net/hamradio/bpqether.c in 2.6.0-test3. # # 1. Fix encapsulation of net_device structure relative to private data (bpqdev) # 2. Convert from single-linked list to the list macros. # 3. Convert to using seq_file for the /proc interface # 4. Fix up locking by switching to RCU and the rtnl semaphore supplied # by the network layer. # 5. Fix removal cases of ethernet device and bpqether device to work # without deadlock. # 6. Get rid of MOD_INC/MOD_DEC # 7. Get rid of bogus check_devices method of cleanup, just cleanup correctly # when device changes state. # -------------------------------------------- # 03/08/12 nathans@sgi.com 1.1123.18.3 # [XFS] Use xfs_dev_t size rather than dev_t size in xfs_attr_fork initialization # # SGI Modid: 2.5.x-xfs:slinx:155551a # -------------------------------------------- # 03/08/12 nathans@sgi.com 1.1123.18.4 # [XFS] Fix up the default ACL inherit case, in the presence of failure during applying the default ACL (eg. from ENOSPC). # # SGI Modid: 2.5.x-xfs:slinx:155553a # -------------------------------------------- # 03/08/12 mochel@osdl.org 1.1123.14.3 # [sysfs] Mark some arguments const. # # From Stephen Hemminger # -------------------------------------------- # 03/08/12 mochel@osdl.org 1.1123.14.4 # [driver model] Change class functions to const arguments. # # From Stephen Hemminger: # # Several of the class_device functions don't modify their arguments and can # take const pointers. # -------------------------------------------- # 03/08/12 mochel@osdl.org 1.1123.14.5 # [driver model] Check for probing errors in drivers/base/bus.c # # From Janice Girouard. # # Currently if an error is detected when probing a device, # this error is not reported. Generally, an error value from # errno.h will be returned when the driver->probe function # fails. However, these errors are not logged, and the device # fails silently. # # -------------------------------------------- # 03/08/12 mochel@osdl.org 1.1123.1.5 # [power] Add hooks for runtime device power control. # # dpm_runtime_{suspend,resume} control the power state of a single device # while the system is running. # # dpm_runtime_suspend() will save state of the device, then attempt to power # it down. This happens with interrupts enabled, so if the device does not # support that, the device's state is restored, and we continue on our merry # way. # # dpm_runtime_resume() powers the device back on, then restores state of the # device. # # dpm_set_power_state() simply notifies the core of the power state the # device is in. Drivers can use this, since they are the only ones that can # really tell. # -------------------------------------------- # 03/08/12 mochel@osdl.org 1.1123.1.6 # Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/08/12 len.brown@intel.com 1.1126 # ACPI: merge andy-2.6 into lenb-2.6 # -------------------------------------------- # 03/08/12 len.brown@intel.com 1.1127 # ACPI: merge andy-2.6 into lenb-2.6 # -------------------------------------------- # 03/08/12 mochel@osdl.org 1.1123.1.7 # [power] Begin to add sysfs files for controlling device power states. # # - Moves sysfs controls to drivers/base/power/sysfs.c # - Creates dpm_sysfs_{add,remove} to add/remove sysfs attribute group. # - Creates 'state' file in 'pm' directory that properly controls device # power state at runtime. # -------------------------------------------- # 03/08/12 trini@kernel.crashing.org 1.1123.15.2 # PPC32: Restrict when we enable IBM405_ERR{77,51}. # Newer IBM40x cores have these problems fixed. # -------------------------------------------- # 03/08/12 len.brown@intel.com 1.1128 # ACPI # dmi_scan.c: delete some incomplete code that broke !SMP + APIC build; add ACPI blacklist comment, # move __i386__ out of do_mounts.c and into create mount_root_failed_msg() # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.13.2 # [AGPGART] Disable calibration cycle when not in AGP3 mode of operation on AGP3 chipset. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.13.3 # [AGPGART] VIA AGP3 fixups. # From folks at VIA. # -------------------------------------------- # 03/08/13 klassert@mathematik.ru-chemnitz.de 1.1123.9.8 # [BRIDGE]: Fix kfree(skb). # -------------------------------------------- # 03/08/13 chas@cmf.nrl.navy.mil 1.1123.9.9 # [ATM]: Fix printk() warnings in LANAI driver (from mitch@sfgoth.com). # -------------------------------------------- # 03/08/13 chas@cmf.nrl.navy.mil 1.1123.9.10 # [ATM]: Use likely()/unlikely() in many potential hot-paths of LANAI driver (from mitch@sfgoth.com). # -------------------------------------------- # 03/08/13 chas@cmf.nrl.navy.mil 1.1123.9.11 # [ATM]: Cleanup/minor fixes to interrupt handler of LANAI driver (from mitch@sfgoth.com). # -------------------------------------------- # 03/08/13 shemminger@osdl.org 1.1123.9.12 # [NET]: Add missing rcu_read_lock to bpqether. # -------------------------------------------- # 03/08/13 shemminger@osdl.org 1.1123.9.13 # [NET]: Make lapbether work on 2.6.0-test3. # - unneeded include (no proc here) # - redundant fields in local device structure # + convert to dynamic network device allocation # - refcounts on local data are redundant, it is really part of network_device # - excessive __inline__ # + correctly manage references to underlying network device # + cascade unregister # + use RCU and RTNL to avoid deadlock # + account for bytes as well as packets # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.1.8 # [power] Check device_suspend() return value in swsusp. # # From Pavel Machek. # -------------------------------------------- # 03/08/13 agrover@groveronline.com 1.1129 # ACPI: Fix ACPI for IA64 on Big Sur machines (HJ Lu) # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.1.9 # [power] Minor cleanups. # # From Pavel Machek. # -------------------------------------------- # 03/08/13 greg@kroah.com 1.1123.20.9 # [PATCH] USB: fix usb serial port release problem by untieing it from the usb_serial structure. # # This fixes the kobject messages when disconnecting a usb serial device that # people have been complaining about. # -------------------------------------------- # 03/08/13 greg@kroah.com 1.1123.20.10 # [PATCH] USB: fix up usb-serial drivers now that port[] is an array of pointers. # -------------------------------------------- # 03/08/13 agrover@groveronline.com 1.1130 # ACPI: Update version so we can keep bugreports straight # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.13.4 # [AGPGART] Fix overflow on machines with >4GB # From Marcelo E Magallon. # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.1.10 # [swsusp] Remove two panic()s. # # - Make software_suspend() return an int, so caller can tell what happened. # - Do check for HIGHMEM and DISCONTIGMEM early in software_suspend() and # fail gracefully, instead of checking far down the call chain and having # to call panic(). # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.1.11 # [power] Various swsusp cleanups. # # - Move SMP check to software_suspend() (from software_resume()), so we will # not even attempt to sleep with it enabled. # - Make software_resume() a late initcall, removing the explicit call from # prepare_namespace(). # - Initialize software_suspend_enabled to 1, instead of doing it manually in # software_resume(). # - Don't explicitly initialzie resume_file. # - Remove resume_status variable, as we can simply check for (non-) NULL # resume_file string. # - "noresume" setup function changed to simply zero first byte of resume_file # string, simplifying logic. # - Don't attempt to reset swap signature if noresume is specified. # - Downstream function (bdev_write_page() wasn't implemented anyway, so we # can just remove that also). # # If noresume is specified, there will still be a suspend image left on the # swap partition. It may behoove us to never reset the swap signature, and # always leave the image intact on the disk, since it is a valid snapshot # that we can resume from at anytime. # # This unconditional behavior would force the user to add 'mkswap ' to # their init scripts to reset the partition to swap use. IMO, this is better # anyway. # -------------------------------------------- # 03/08/13 greg@kroah.com 1.1123.20.11 # [PATCH] USB: fix usb class device sysfs representation. # # Again, I messed up the usage, now we are safe from devices being removed. # This fixes a number of error reports from users. # -------------------------------------------- # 03/08/13 mark@alpha.dyndns.org 1.1123.20.12 # [PATCH] USB: ov511 sysfs conversion (1/3) # # This is the first in a series of three patches to convert the ov511 # driver's /proc/video interface to sysfs. All V4L drivers must undergo # this conversion now that /proc/video has been removed from the core. # # This patch removes ov511's /proc/video support, which allows it to # compile again. # -------------------------------------------- # 03/08/13 mark@alpha.dyndns.org 1.1123.20.13 # [PATCH] USB: ov511 sysfs conversion (2/3) # # This patch converts ov511 to dynamically allocate struct video_device, # using the new interfaces in videodev.[ch]. This is required to safely # support sysfs without races. # -------------------------------------------- # 03/08/13 mark@alpha.dyndns.org 1.1123.20.14 # [PATCH] USB: ov511 sysfs conversion (3/3) # # This patch adds some read-only files to ov511's sysfs directory. The # read/write attributes will be added in a future patch. For now, the # read/write-related code is #if'd out to prevent warnings. # -------------------------------------------- # 03/08/13 david-b@pacbell.net 1.1123.20.15 # [PATCH] USB: usb hcd-pci suspend/resume updates # # This patch has some updates to the hcd pci power management glue: # # - removes now-obsolete comments (driver model now exists) # # - better state transitions: # * suspending "dead" controllers needn't oops # * multi-resume case (pm bug) simplified # * multi-suspend case likewise (not always a bug) # * should handle transitions other than D0->D3{hot,cold} # # - prepares for usb remote wake up support, which will be # wanting the driver model suspend/resume code to be ready. # -------------------------------------------- # 03/08/13 david-b@pacbell.net 1.1123.20.16 # [PATCH] usb hc cleanup-after-death, oops fix # # Recently we've seen some oopses reported in code that cleaned # up HCs after they died ... like pci-pm not letting ohci-hcd # suspend until after the hardware was partly disabled, or users # removing a Cardbus adapter with ehci-hcd. One root cause was # that the cleanup called hcd->stop() too many times. # # This patch just does the cleanup that's reasonable to do # before the (dead) root hub is cleaned up: it disconnects # the other devices. And based on a suggestion from Pavel, # a diagnostic always appears -- avoiding mystery. # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.21.1 # Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.2.2 # Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.1.12 # Merge kernel.bkbits.net:linux-2.5-power # into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-power # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.2.3 # [sysfs] Don't add ->d_fsdata until dentrys are created. # # - For both files and directories, we were leaving ->d_fsdata set even when # file and directory creation failed. This patch sets the field only after # we've successfully created the dentry. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.20.17 # [PATCH] USB: Add Minolta Dimage F300 to unusual_devs # -------------------------------------------- # 03/08/13 kevino@asti-usa.com 1.1123.20.18 # [PATCH] USB: bug in EHCI device reset through transaction # # This supports another special case: devices can revert to the "default" # (address zero) state temporarily in usb_reset_device(). # # This is the quick fix; 2.6 could get rid of these special cases in ep0 # hcd logic by disabling ep0, but 2.4 can't. # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.2.4 # Merge bk://kernel.bkbits.net//home/mochel/linux-2.5-core # into osdl.org:/home/mochel/src/kernel/linux-2.5-core # -------------------------------------------- # 03/08/13 mochel@osdl.org 1.1123.1.13 # [power] Make sure CONFIG_ACPI_SLEEP depends on CONFIG_PM # -------------------------------------------- # 03/08/13 jbarnes@sgi.com 1.1046.567.20 # [PATCH] ia64: is_headless_node fix # # Fix is_headless_node() macro to use node_to_cpumask(). # -------------------------------------------- # 03/08/13 davidm@tiger.hpl.hp.com 1.1046.567.21 # ia64: Patch by Peter Chubb: Kill _syscallX macros that generate lots of # warnings, in favour of inline syscalls for clone() and execve(), and direct # calling of kernel functions for other system calls. # -------------------------------------------- # 03/08/13 peterc@gelato.unsw.edu.au 1.1046.567.22 # [PATCH] ia64: Kill warnings in sys_ia32.c # # This patch kills compilation warnings in sys_ia32.c. # -------------------------------------------- # 03/08/13 bjorn.helgaas@hp.com 1.1046.567.23 # [PATCH] ia64: Trivial 2.5 efivars.c whitespace cleanup # # Convert leading spaces to tabs. # -------------------------------------------- # 03/08/13 bjorn.helgaas@hp.com 1.1046.567.24 # [PATCH] ia64: export EFI systab # # I know this probably needs to get exported somewhere other than # /proc, but the rest of efivars is still in /proc and if somebody does # convert efivars, they might as well do this systab bit at the same # time. # -------------------------------------------- # 03/08/13 torvalds@home.osdl.org 1.1123.3.23 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/13 torvalds@home.osdl.org 1.1123.3.24 # Merge bk://linux-dj.bkbits.net/agpgart # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.25 # [PATCH] Enable OOSTORE on Geode. # # From Hiroshi Miura # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.26 # [PATCH] Don't refer to devel kernel in Kconfig option # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.27 # [PATCH] winchip3d can use same -march as winchip2 # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.28 # [PATCH] Fix x87 FPU exception status check # # From Dave Richards (drichards@mahinetworks.com) # # "While diagnosing an MMX/FPU problem I found a minor problem in the # code which diagnoses and generates signals for FPU exceptions. On # x86 Stack Fault Exception are a subclass of Invalid Operation. Thus, # the FPU status register will have both the SF and IF bits set when a # stack fault occurs. The code which turns FPU exceptions into signals # was assuming IF would be clear". # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.29 # [PATCH] microcode driver sparse __user annotations. # # Plus with a little codeshuffling, we can do away with the # prototypes. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.30 # [PATCH] document easier bitkeeper option. # # Achieves the same result. From Lenz Grimmer at Mysql AG # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.31 # [PATCH] Remove duplicate ; at end of macro definitions # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.32 # [PATCH] DAC960 64bit fixup # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.33 # [PATCH] CCISS 64bit fixup. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.34 # [PATCH] cpu_relax whilst in busy-wait loops. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.35 # [PATCH] c99 initialisers for random.c # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.36 # [PATCH] Remove unneeded ; from macros in i8042 # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.37 # [PATCH] remove version.h from bttv # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.38 # [PATCH] misc 3c505 bits # # - Remove unneeded breaks # - Fix double spin_unlock_irqrestore problem # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.39 # [PATCH] c99 initialisers for bttv # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.40 # [PATCH] FusionMPT 64bit fixup # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.41 # [PATCH] arcnet indentation fixup # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.42 # [PATCH] c99 struct initialisers for AMD8111e driver. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.43 # [PATCH] boolean logic error in fpu emulation. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.44 # [PATCH] CodingStyle fixes for drm_agpsupport # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.45 # [PATCH] c99 initiliasers for bttv (2) # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.46 # [PATCH] c99 for blkmtd # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.47 # [PATCH] sparse annotations for MSR driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.48 # [PATCH] PCMCIA copy_*_user fixes. # # These copies already did a verify_area above. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.49 # [PATCH] missing copy_to_user check in tun driver. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.50 # [PATCH] Missing copy_from_user check in comx driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.51 # [PATCH] missing copy_from_user check in comx_proto_lapb driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.52 # [PATCH] missing copy_to_user check in pc300 wan driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.53 # [PATCH] missing copy_from_user check in comx-proto-fr driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.54 # [PATCH] missing copy_*_user checks in sbni wan driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.55 # [PATCH] Missing spin_unlock_irqrestore from rrunner driver. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.56 # [PATCH] missing copy_from_user check in munich driver # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.57 # [PATCH] missing copy_from_user check in mixcom driver. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.58 # [PATCH] sync iocb wakeup # # if ki_users = 1, we don't do the wakeup, which seems wrong. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.59 # [PATCH] BEFS 64bit fixup # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.60 # [PATCH] EFI 64bit fixup # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.61 # [PATCH] sparse annotations for page-writeback # # More to do, but its a beginning. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.62 # [PATCH] LDM 64bit fixup # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.63 # [PATCH] correct tlb_remove_page comment. # # Remove prototype. It was wrong anyway. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.64 # [PATCH] Remove useless assertions from reiserfs # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.65 # [PATCH] AD1848 claims a card it shouldn't. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.66 # [PATCH] sparse annotations for page_alloc # # Again, more work to do here.. # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.67 # [PATCH] sparse annotations for ipc/sem # -------------------------------------------- # 03/08/13 davej@redhat.com 1.1123.3.68 # [PATCH] logic error in gus_wave driver # -------------------------------------------- # 03/08/13 mikpe@csd.uu.se 1.1123.3.69 # [PATCH] Disable APIC on reboot # # This disables the local APIC before reboot. This fixes BIOS reboot # problems reported by a few people. # # disable_local_APIC() now checks if detect_init_APIC() enabled the # local APIC via the APIC_BASE MSR, and if so it now disables APIC_BASE. # Previously we would leave APIC_BASE enabled, and that made some # BIOSen unhappy. # # The SMP reboot code calls disable_local_APIC(). On SMP HW there is # no change since detect_init_APIC() isn't called and APIC_BASE isn't # enabled by us. An SMP kernel on UP HW behaves just like an UP_APIC # kernel, so it disables APIC_BASE if we enabled it at boot. # # The UP_APIC disable-before-suspend code is simplified since the existing # code to disable APIC_BASE is moved into disable_local_APIC(). # # (Felix Kühling originally reported the BIOS reboot problem. This is a # fixed-up version of his preliminary patch.) # -------------------------------------------- # 03/08/13 romieu@fr.zoreil.com 1.1123.3.70 # [PATCH] Clean up missing spin_unlock_irqrestore from rrunner driver # # This is a cleaner fix that avoids having two separate unlock # operations. # -------------------------------------------- # 03/08/13 torvalds@home.osdl.org 1.1123.3.71 # Merge http://linux-watchdog.bkbits.net/linux-2.5-watchdog # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/13 torvalds@home.osdl.org 1.1123.3.72 # Merge bk://ppc.bkbits.net/for-linus-ppc # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/13 torvalds@home.osdl.org 1.1123.3.73 # Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/13 msw@redhat.com 1.1123.3.74 # [PATCH] zap_other_threads() detaches thread group leader # # The change to detach the threads in zap_other_threads() broke the case # where the non-thread-group-leader is the cause of de_thread(). # # In this case the group leader will be detached and freed before # switch_exec_pids() is complete and invalid data will be used. This is a # patch that makes sure that the group leader does not get detached and # reaped. # -------------------------------------------- # 03/08/13 jamie@shareable.org 1.1123.3.75 # [PATCH] Fix protocol bugs with NFS and nanoseconds # # NFS with 2.5.75 as both client and server is broken with GNU Make. # # The nanosecond field of timestamps of newly touched files is often # negative on the client, which is probably why Make fails. The value # also bears no relation to the file's nanosecond field on the server. # # The culprit is htons() used where htonl() should be: # # - *p++ = htonl((u32) time->tv_sec); *p++ = htons(time->tv_nsec); # + *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); # # The rest of this patch corrects nfsd to use microseconds in NFSv2, not # nanoseconds. (The client already gets this right, but I have # optimised it slightly to avoid division when possible). # -------------------------------------------- # 03/08/13 mulix@mulix.org 1.1123.3.76 # [PATCH] fix trident.c lockup on module load 2.6.0-test2 # # This patch fixes a kernel lockup with 2.6.0-test2 when the trident.c # OSS driver is loaded and the driver attempts to initialize the # card. The problem is that in ali_ac97_get() we lock the card->lock # spinlock, but never release it on the good path, only on the error # path. This patch adds the missing spin_unlock_irqrestore(). # # This bug snuck in in a 2.4 sync from Alan, and 2.4 appears to suffer # from the same problem. A patch for that will be send to Marcelo # momentarily. # -------------------------------------------- # 03/08/13 geert@linux-m68k.org 1.1123.3.77 # [PATCH] Make SELinux security module compile on m68k # -------------------------------------------- # 03/08/13 ak@suse.de 1.1123.3.78 # [PATCH] x86-64 merge for 2.6.0test3 # # Without these changes an x86-64 NUMA kernel won't boot in many # configurations. # # The main change is the improved IOMMU code which supports merging of # mappings and has various bugfixes. # # - Update defconfig # - Use argument ptregs in 32bit elf_core_copy_task_fpregs # - Harden aperture fixup code: read aperture from the AGP bridge if needed, # better error checking. # - Support nmi_watchdog=panic to panic on watchdog trigger # - IOMMU: Support panic on IOMMU overflow (iommu=panic) # - IOMMU: Force SAC for mappings >40bits when iommu=force is active # (this can potentially give better performance) # - IOMMU: Cache northbridges for faster TLB flush # - IOMMU: Fix SMP race in TLB flush # - IOMMU: Merge pci_alloc_consistent and pci_map_single # - IOMMU: Clean up leak tracing # - IOMMU: Rewrite pci_map_sg, support merging of mappings # On overflow fall back to piece-by-piece mapping. # - IOMMU: Tell block layer to assume merging when iommu force is active # (this gives better performance with MTP fusion, drawback is that the # overflow/fragmentation handling of the IOMMU area is still a big # dubious with that) # - Fix/clean up per cpu data # - Add 64bit clean time(2) # - Export cpu_callout_map for IPv6 # - Handle nodes with no own memory in NUMA discovery. # This fixes boot on various newer Opteron motherboards where the memory # is only connected to a single CPU. # - Fix fallback path for failed NUMA discovery. numnodes has to be reset. # - Check for enabled nodes in NUMA discovery (Eric Biederman) # - Remove NUMA emunodes support. Has badly bitrotted. # - Add __clear_bit_string for IOMMU code # - Add new 32bit system calls to ia32_unistd.h # - Remove duplicate default_do_nmi prototype # - Make PCI_DMA_BUS_IS_PHYS dependent on no_iommu # - Fix padding length of siginfo_t to match glibc # - More pci direct access functions. # -------------------------------------------- # 03/08/13 neilb@cse.unsw.edu.au 1.1123.3.79 # [PATCH] Disable buggy raid5 handling of read-ahead # # raid5 tries to honour RWA_MASK, but messes it up and can return bad data. # Just ignore RAW_MASK for now. # -------------------------------------------- # 03/08/13 neilb@cse.unsw.edu.au 1.1123.3.80 # [PATCH] Fix bug in sunrpc/server code. # # When a socket has a request ready it notifies a server thread. # When the thread has 'received' the request it calls svc_sock_received # to confirm the fact. # # In some cases, svc_sock_received would be called an extra time and # this could lead to linked-list corruption and bad problems. # -------------------------------------------- # 03/08/13 Andries.Brouwer@cwi.nl 1.1123.3.81 # [PATCH] hpt366 fix # # The HPT366 code is broken - it tries to set the interface to too high a # speed, which leads to error messages at boot time and/or to data # corruption. # # The typical effect at boot time is # # hde: set_drive_speed_status: status=0x51 { DriveReady SeekComplete Error } # hde: set_drive_speed_status: error=0x04 { DriveStatusError } # # Fixed thus. # -------------------------------------------- # 03/08/13 cminyard@mvista.com 1.1123.3.82 # [PATCH] IPMI updates for 2.6.0-test3 # # Here are some minor updates to the IPMI driver. They fix the following: # # * A missing check for copy_to_user() in the watchdog driver. # * Removal of unnecessary check_region() calls. # * Fixes for the ACPI configuration. The previous one would only work # with memory addresses, this will work with memory addresses, # ports, and hadle checking that the type is correct. # -------------------------------------------- # 03/08/13 levon@movementarian.org 1.1123.3.83 # [PATCH] Document mounting of binfmt_misc # # Patch by Ivan Gyurdiev. # -------------------------------------------- # 03/08/13 Kai.Makisara@kolumbus.fi 1.1123.3.84 # [PATCH] SCSI tape fix for oops in read with wrong block size # # This corrects the following problem: # # - release user buffer mapping early in read path (prevent oops in some # HBA drivers) # -------------------------------------------- # 03/08/13 Kai.Makisara@kolumbus.fi 1.1123.3.85 # [PATCH] Email address update # # This updates my email address. # -------------------------------------------- # 03/08/13 viro@parcelfarce.linux.theplanet.co.uk 1.1123.3.86 # [PATCH] Fix pd.c for new queue allocation # # From A1tmblwd@netscape.net # -------------------------------------------- # 03/08/14 lord@kernel.bkbits.net 1.1123.3.87 # Merge kernel.bkbits.net:/home/repos/linux-2.5 # into kernel.bkbits.net:/home/lord/xfs-2.5 # -------------------------------------------- # 03/08/14 nathans@sgi.com 1.1123.18.5 # [XFS] Fix a race condition in async pagebuf IO completion, # by moving blk queue manipulation down into pagebuf. # Fix some busted comments in page_buf.h, use a more # descriptive name for __pagebuf_iorequest. # # SGI Modid: 2.5.x-xfs:slinx:155788a # -------------------------------------------- # 03/08/14 lord@jen.americas.sgi.com 1.1123.3.88 # Merge ssh://lord@kernel.bkbits.net/xfs-2.5 # into jen.americas.sgi.com:/src/lord/bitkeeper/xfs-2.5 # -------------------------------------------- # 03/08/14 torvalds@home.osdl.org 1.1131 # Merge http://linux-acpi.bkbits.net/linux-acpi # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/14 lkml@mathfillsmewithgreatjoy.com 1.1132 # [PATCH] Correct DEVPTS config help # # The help for CONFIG_DEVPTS_FS claims that devfs "is a more general # facility". But that apparently hasn't been true since 2.5.68. This patch # removes that claim, and adds a warning to the DEVFS_FS help. # -------------------------------------------- # 03/08/14 torvalds@home.osdl.org 1.1133 # Merge bk://kernel.bkbits.net/lord/xfs-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1134 # [PATCH] kill HDIO_GETGEO_BIG_RAW ioctl # # HDIO_GETGEO_BIG_RAW is an ide specific hack introduced in 2.3.99-pre3. # There are no known programs using this ioctl. # # Its aim was to provide current CHS translation to the user-space, # but very often it provides what driver thinks is a current translation # (drive with LBA have to support only one physical translation, also # drive may not support chosen translation and there is no return value check). # # hdparm -I can be used instead, it provides correct information # (and bogus data is still accessible through /proc/ide/hdX/geometry). # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1135 # [PATCH] ide: disk geometry/capacity cleanups # # From Andries.Brouwer@cwi.nl. # # - kill redundant, never executed code in lba_capacity_is_ok() # - add idedisk_supports_{hpa,lba48}() helpers # - don't recalculate drive->cyl for drives using LBA addressing, # we never fall-back to CHS, so its useless and confusing # - remove wrong drive->head and drive->sect assignments for LBA-48 # - don't overwrite id->lba_capacity and id->lba_capacity_2 # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1136 # [PATCH] ide: always store disk capacity in u64 # # From Andries.Brouwer@cwi.nl. # # - always use drive->capacity48 and kill drive->capacity # # I've changed drive->capacity48 to drive->capacity64 to avoid confusion. # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1137 # [PATCH] ide: limit drive capacity to 137GB if host doesn't support LBA48 # # Noticed by Andries.Brouwer@cwi.nl. # # Also: # - kill probe_lba_addressing() wrapper # - rename hwif->addressing to hwif->no_lba48 # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1138 # [PATCH] ide: more ide_unregister() fixes # # - more locking fixes # - preserve gendev.parent of the old hwif in the new one # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1139 # [PATCH] ide: build fixes for ide-tape.c # # also add missing Kconfig help entry from 2.4.x # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1140 # [PATCH] ide: remove bogus bh->bio conversion from ide-tape.c # # and add stripped down buffer_head variant (struct idetape_bh). # # ide-tape is accessed by a char device (not a block one!), # it uses block layer only to queue requests. # -------------------------------------------- # 03/08/14 B.Zolnierkiewicz@elka.pw.edu.pl 1.1141 # [PATCH] ide: some CodingStyle fixes from 2.4.x for ide-tape.c # # makes 2.4->2.6 diff noticeable smaller # -------------------------------------------- # 03/08/14 rmk@arm.linux.org.uk 1.1142 # [PATCH] Make modules work on ARM # # This patch allows modules to work for ARM, and is the one thing which # prevents the standard tree from building for any ARM machine. # # After reviewing the /proc/kcore and kclist issues, I've decided that I'm # no longer prepared to even _think_ about supporting /proc/kcore on ARM - # it just gets too ugly, and adds too much code to make it worth the effort, # the time or the energy to implement a solution to that problem. # # /proc/kcore should probably go away, but in the meantime this just allows # ARM to ignore the issues. # -------------------------------------------- # 03/08/14 ak@suse.de 1.1143 # [PATCH] add compat_statfs64 # # Add compat_* functions for statfs64. The 32bit layout unfortunately # does not match x86-64. # -------------------------------------------- # 03/08/14 ak@suse.de 1.1144 # [PATCH] add compat_utimes # # Add compat_sys_utimes for 32bit->64bit utimes conversion # -------------------------------------------- # 03/08/14 ak@suse.de 1.1145 # [PATCH] add posix timer compat functions # # Add 32bit->64bit conversion functions for POSIX timers. # # I kept timer_create architecture specific, because it does signal specific # stuff which is not portable enough for generic compat. # -------------------------------------------- # 03/08/14 ak@suse.de 1.1146 # [PATCH] Make x86-64 use new compat support code # # Just call them from the x86-64 entry code. # # Also implement the x86-64 specific sys32_timer_create. # -------------------------------------------- # 03/08/14 mochel@osdl.org 1.1123.22.1 # Merge osdl.org:/home/mochel/src/kernel/linux-2.5-virgin # into osdl.org:/home/mochel/src/kernel/linux-2.5-power # -------------------------------------------- # 03/08/14 mochel@osdl.org 1.1123.1.14 # Merge bk://kernel.bkbits.net//home/mochel/linux-2.5-power # into osdl.org:/home/mochel/src/kernel/linux-2.5-power # -------------------------------------------- # 03/08/14 clemens-dated-1061728015.bf63@endorphin.org 1.1147 # [PATCH] Fix cryptoloop ECB mode # # cryptoloop won't oops anymore if ECB mode is requested. # -------------------------------------------- # 03/08/14 clemens-dated-1061728015.bf63@endorphin.org 1.1148 # [PATCH] Fix cryptoloop disk corruption under CBC mode # # It was caused by improper IV calculation in loop.c # -------------------------------------------- # 03/08/14 christophe@saout.de 1.1149 # [PATCH] Fix /sys///dev format: %04x -> %u:%u # # A part of the 64 bit kdev_t patch already got merged, and it changes the # format of /sys/block//dev from %02x%02x to %u:%u. The partition # could must also be changed. # # e.g. cat /sys/block/hda/hda5/dev should return 3:5 instead of 0305 # -------------------------------------------- # 03/08/14 torvalds@home.osdl.org 1.1150 # Mark CLONE_DETACHED as being irrelevant: it must match CLONE_THREAD. # # CLONE_THREAD without CLONE_DETACHED will now return -EINVAL, and # for a while we will warn about anything that uses it (there are no # known users, but this will help pinpoint any problems if somebody # used to care about the invalid combination). # -------------------------------------------- # 03/08/14 mochel@osdl.org 1.1123.1.15 # [driver model] Allow per-device shutdown or suspend on driver detach. # # - Add struct device::detach_state, which tells the core what state to put # the device in when it's detached from its driver (on module removal). # # This is a value in the range of 0-4, with 0 being On and meaning 'Do # Nothing', 4 being Off, meaing calling ->shutdown() for the device, and # 1-3 being low-power states, meaning call ->suspend() for the device. # # - Add per-device sysfs file 'detach_state' to control the value of the # field. # # - Add device_device_shutdown() function, and call it from bus.c:: # device_detach_driver(). # -------------------------------------------- # 03/08/14 mochel@osdl.org 1.1123.1.16 # [driver model] Remove 'power' file in favor of 'power' directory. # # - Only present when CONFIG_PM=y. # - Contains 'state' file for controlling power state with new PM # infrastructure. # -------------------------------------------- # 03/08/14 torvalds@home.osdl.org 1.1151 # DRI CVS update: document r128 and radeon version numbers # -------------------------------------------- # 03/08/14 torvalds@home.osdl.org 1.1152 # DRI CVS update: bump i810 driver to 1.4. # # This fixes the DMA interface to be backwards compatible with older # XFree86 versions, by looking at the I810_INIT_DMA parameters and # figuring out old version semantics. # -------------------------------------------- # 03/08/14 mochel@kernel.bkbits.net 1.1153 # Merge kernel.bkbits.net:/home/repos/linux-2.5 # into kernel.bkbits.net:/home/mochel/linux-2.5-core # -------------------------------------------- # 03/08/14 mhoffman@lightlink.com 1.1123.19.5 # [PATCH] I2C: i2c nforce2.c fixes # # This patch restores a line that was wrongly removed. There are also some # trivial cleanups. It applies & compiles vs. 2.6.0-test3. It's untested # (no hardware here). # -------------------------------------------- # 03/08/14 rusty@linux.co.intel.com 1.1123.19.6 # [PATCH] I2C: bugfix for initialization bug in adm1021 driver # # While initializing the adm1021 device, the driver is performing a conversion # from fixed point to Celcius on values that were declaired as Celcius. On # my Dell Precision 220 this results in a shutdown after a couple of minutes # running. # # This is a very simple patch against the 2.6.0-test3 tree that just removes the # conversion. # -------------------------------------------- # 03/08/14 mochel@osdl.org 1.1152.1.1 # Hand Merge # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1123.19.7 # [PATCH] I2C: fix up the wording for the pii4x bugfix. # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1123.20.19 # USB: handle overloading of usb-serial functions in a much cleaner manner. # -------------------------------------------- # 03/08/14 jejb@fuzzy.(none) 1.1150.1.1 # Qla1280 update to 3.23.24 # # From: Jes Sorensen # with minor compile and rejection fixes # # This patch might make the qla1280 driver build again in Linus' bk # tree. I don't have those sources here so I made the changes relative to # 2.6.0-test2 and I am out of space on my laptop # # Only compile tested, but if it works it works ;-) # -------------------------------------------- # 03/08/14 bellucda@tiscali.it 1.1123.20.20 # [PATCH] USB: usbvideo cleanup on error # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1152.2.1 # Driver Core: remove struct device.name as it is not needed # # If a specific driver subsystem needs a name field, they should implement it # for just that subsystem. # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1152.2.2 # Remove .name usage from floppy driver. # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1152.2.3 # Remove usage of struct device.name from ide core # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1152.2.4 # Remove usage of struct device.name from pcmcia layer # -------------------------------------------- # 03/08/14 greg@kroah.com 1.1152.2.5 # Remove usage of struct device.name from bttv driver # # I missed this on the i2c series of patches. # -------------------------------------------- # 03/08/14 hch@lst.de 1.1150.1.2 # [PATCH] fix dc395x compile # # The recent update made it check the scsi_remove_host retval which # is void now. # -------------------------------------------- # 03/08/14 hch@lst.de 1.1150.1.3 # [PATCH] nuke some junk from the pcmcia scsi drivers # # DEV_STALE_* is used for some crude hacks in pcmcia netdrivers and it # seems people copied it blindly over to the scsi ones also it couldn't # ever be triggered (dev_link_t.open is never incremented e.g.) # -------------------------------------------- # 03/08/14 hch@lst.de 1.1150.1.4 # [PATCH] place host-related LDM code directly in hosts.c # # This was in scsi_sysfs.c previously but given that it's not # sysfs-related and the whole scsi code is built around the driver # model now it's better to have it where it belongs. Also allows # us to reduce the scsi_mod-wide globals. # -------------------------------------------- # 03/08/14 patmans@us.ibm.com 1.1150.1.5 # [PATCH] add sysfs attributes to scan and delete scsi_devices # # This patch against scsi-misc-2.5 adds a sysfs attribute to allow scanning # (or rescanning) and deletion of scsi_devices. # # It also allows scanning of entire hosts, channels, or targets. # # It adds a per-host scan attribute, and a per scsi_device delete attribute. # -------------------------------------------- # 03/08/14 mochel@osdl.org 1.1152.1.2 # [power] Register PM subsystem, and create power/ directory in sysfs. # # - Add file 'state' which provides single point of entry for all PM # transitions. # File accepts a string specifying what state to enter, which is one of: # "standby": Power-on Suspend (aka S1) # "suspend": Suspend-to-RAM (aka S3) # "hibernate": Suspend-to-disk (aka S4) # # The names do suck, because they are lifted from the ACPI spec. Better # naming suggestions are welcome, though these names are relatively well- # known. # # - Handler for file does little now, but will validate the passed string and # call the appropriate functions. # # - Needs to be integrated with swsusp and ACPI S3 code. # -------------------------------------------- # 03/08/14 davem@nuts.ninka.net 1.1152.3.1 # Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5 # into nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # -------------------------------------------- # 03/08/14 davem@nuts.ninka.net 1.1152.4.1 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/08/14 rddunlap@osdl.org 1.1152.4.2 # [NET]: Fixing kfree() in SLIP driver. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.3 # [NETROM]: Fix sysctl initializers. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.4 # [NETROM]: Expire sockets faster on close. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.5 # [NETROM]: Free buffers in write queue on socket destroy. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.6 # [NETROM]: Reserve space in socket header for AX25 header. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.7 # [NETROM]: Lock sockets while doing protocol processing. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.8 # [NETROM]: Better control over the AX25 devices. # -------------------------------------------- # 03/08/14 pe1rxq@amsat.org 1.1152.4.9 # [NETROM]: Use hlist for the routing table information. # # Note: there is a call to ax25_cb_put commented out, that # can be added back when ax25 refcount patches go in. # -------------------------------------------- # 03/08/14 shemminger@osdl.org 1.1152.4.10 # [NETROM]: Make lists and locks static since they are only used in one file. # -------------------------------------------- # 03/08/14 shemminger@osdl.org 1.1152.4.11 # [NETROM]: Convert to alloc_netdev(). # # Convert net_device's from array of structures to an array # of pointers, so they can be freed individually on module # exit. The net_device_stats are stored at dev->priv. # -------------------------------------------- # 03/08/14 shemminger@osdl.org 1.1152.4.12 # [NETROM]: Convert /proc interface to seq_file. # -------------------------------------------- # 03/08/14 shemminger@osdl.org 1.1152.4.13 # [NETROM]: Fix use after free in socket close. # # netrom would oops if one did: # modprobe netrom # ifconfig -a # # because the code in destroy was freeing the socket then release_sock was # called. # -------------------------------------------- # 03/08/14 shemminger@osdl.org 1.1152.4.14 # [NET]: Convert YAM driver to dynamic net_device. # -------------------------------------------- # 03/08/14 shemminger@osdl.org 1.1152.4.15 # [NET]: Convert YAM driver to seq_file. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.1 # [PATCH] fadvise(POSIX_FADV_DONTNEED) fix # # invalidate_mapping_pages() takes start/end, but fadvise is currently passing # it start/len. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.2 # [PATCH] sys_fadvise64_64 # # Alas, both POSIX and I got the fadvise() interface wrong. It needs to take a # 64-bit length, not a 32-bit one. Because fadvise(POSIX_FADV_DONTNEED) on a # 4TB file will require 1000 syscalls. Silly. # # There are glibc's in the wild which use the existing syscall, so we must # make a new one. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.3 # [PATCH] Fix raid "bio too big" failures # # From: Neil Brown # # Fix "bio too big" problem with md # # Whenever a device is attached to an md device, we make sure the sector # limits of the md device do not exceed those of the added device. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.4 # [PATCH] missing #if for 1000 HZ # # From: Albert Cahalan # # This should improve timekeeping a bit @ 1000 HZ. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.5 # [PATCH] timer race fixes # # From: Ingo Molnar # # It unifies the functionality of add_timer() and mod_timer(), and makes any # combination of the timer API calls completely SMP-safe. del_timer() is still # not using the timer lock. # # this patch fixes the only timer bug in 2.6 i'm aware of: the del_timer_sync() # + add_timer() combination in kernel/itimer.c is buggy. This was correct code # in 2.4, because there it was safe to do an add_timer() from the timer handler # itself, parallel to a del_timer_sync(). # # If we want to make this safe in 2.6 too (which i think we want to) then we # have to make add_timer() almost equivalent to mod_timer(), locking-wise. And # once we are at this point i think it's much cleaner to actually make # add_timer() a variant of mod_timer(). (There's no locking cost for # add_timer(), only the cost of an extra branch. And we've removed another # commonly used function from the icache.) # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.6 # [PATCH] AS: remove hash valid stuff # # From: Nick Piggin # # The crazy HASH_VALID stuff now makes no difference now. It was there to # try to enforce no merging over a barrier, but it turned out that requests # can just be reordered. Jens picked this up a a while ago and fixed # deadline (and I AS) by simply dispatching all reqs on the queue on # encountering a barrier. The hash valid stuff didn't get cleaned up. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.7 # [PATCH] AS: no trinary states # # From: Nick Piggin # # Gets rid of the silly (and undocumented) trinary stateness of # ad->changed_batch. # # Kernel style flags field could now save 20 bytes per asd (request queue) and # 4 per arq. But I figure that change can wait until I do autotuning... # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.8 # [PATCH] AS requeue implementation # # From: Mark Haverkamp # # Properly implement elevator_t..elevator_requeue_req_fn for the anticipatory # scheduler. # # This fixes some rarely-occurring oops in the IO scheduler. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.9 # [PATCH] standalone elevator noop # # From: Nick Piggin # # Following patch seperates elevator noop, and allows it to be treated # like the other schedulers. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.10 # [PATCH] pipe.c: don't write to readonly filesystems # # The pipe code's mtime and ctime updates are causing writes to read-only # mounted filesystems. # # Fix that up by teaching inode_update_time() to honour readonly mounts, and # call it from the pipe code. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.11 # [PATCH] reiserfs: remove unneeded kunmap # # From: Oleg Drokin # # There is a leftover kunmap in reiserfs_unprepare_pages() which was not # deleted after conversion to kmap_atomic. This path is virtually never # executed, that's why it was not caught earlier. Please apply. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.12 # [PATCH] reiserfs: Fix handling of some extended inode # # From: Oleg Drokin # # This patch fixes a problem in reiserfs' handling of immutable attribute, # where every user (not just root) can unset it. Also it adds "append-only" # attribute "support" (all the support is in VFS anyway, we only recognise the # bit now). Also misleading comment in reiserfs_fs.h is removed. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.13 # [PATCH] Set up P4 thermal interrupt vector on UP # # From: Zwane Mwaikambo # # The P4 thermal interrupt vector was only getting set on SMP builds. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.14 # [PATCH] nbd: fix send/receive/shutdown/disconnect races # # From: Paul Clements # # Here's the updated patch to fix several race conditions in nbd. It # requires reverting the already included (but incomplete) # nbd-race-fix.patch that's in -mm5. # # This patch fixes the following race conditions: # # 1) adds an increment of req->ref_count to eliminate races between # do_nbd_request and nbd_end_request, which resulted in the freeing of # in-use requests -- there were races between send/receive, send/shutdown # (killall -9 nbd-client), and send/disconnect (nbd-client -d), which are # now all fixed # # 2) adds locking and properly orders the code in NBD_CLEAR_SOCK to # eliminate races with other code # # 3) adds an lo->sock check to nbd_clear_que to eliminate races between # do_nbd_request and nbd_clear_que, which resulted in the dequeuing of # active requests # # 4) adds an lo->sock check to NBD_DO_IT to eliminate races with # NBD_CLEAR_SOCK, which caused an Oops when "nbd-client -d" was called # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.15 # [PATCH] /proc/net/pnp oops fix # # ic_servaddr is accessible after boot via /proc/net/pnp. So it cannot be # __initdata. # # davej says that other varibles there are treated the same way, so move them # all into the regular data section. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.16 # [PATCH] vt_ioctl warning fixes # # Several comparisons which can never be true because they're comparing u8's # with numbers which are greater than 255. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.17 # [PATCH] fix task struct refcount bug # # From: Manfred Spraul # # (We think this might be the mystery bug which has been hanging about for # months) # # # We found a [the?] task struct refcount error: A task that dies sets # tsk->state to TASK_ZOMBIE. The next scheduled task checks prev->state, and # if it's ZOMBIE, then it decrements the reference count of prev. The # prev->state & _ZOMBIE test is not atomic with schedule, thus if prev is # scheduled again and dies between dropping the runqueue lock and checking # prev->state, then the reference it dropped twice. # # This is possible with either preemption [schedule_tail is called by # ret_from_fork with preemption count 1, finish_arch_switch drops it to 0] or # profiling [profile_exit_mmap can sleep on profile_rwsem, called by # mmdrop()] enabled. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.18 # [PATCH] probe UDF after reiserfs # # Bug 1065 (http://bugme.osdl.org/show_bug.cgi?id=1065) points out that there # is a risk that UDF will accidentally mount a reiserfs partition, which would # prevent a successful boot. # # Andries points out that probing is unreliable and that users/admins should # always specify the root filesystem type on the kernel boot command line with # "rootfstype=resierfs". # # But nobody does that, so we should be trying reiserfs before UDF. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.19 # [PATCH] fix ide-scsi for ide_drive_t->queue change # # From: Mikael Pettersson # # This patch fixes ide-scsi.c for the ide_drive_t->queue type change # in 2.6.0-test3. # # Without the patch you'll get these new warnings in -test3: # # drivers/scsi/ide-scsi.c: In function `idescsi_abort': # drivers/scsi/ide-scsi.c:875: warning: passing arg 1 of `elv_queue_empty' from incompatible pointer type # drivers/scsi/ide-scsi.c: In function `idescsi_reset': # drivers/scsi/ide-scsi.c:902: warning: passing arg 1 of `elv_next_request' from incompatible pointer type # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.20 # [PATCH] BUG fix for drivers/bluetooth/hci_usb.c # # From: Vinay K Nallamothu # # The patch below fixes two pointer reference bugs (shows up as compile # time warnings given below) which wrongly take the address of "struct # usb_interface*". # # drivers/bluetooth/hci_usb.c: In function `hci_usb_probe': # drivers/bluetooth/hci_usb.c:786: warning: assignment from incompatible pointer type # drivers/bluetooth/hci_usb.c:810: warning: assignment from incompatible pointer type # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.21 # [PATCH] handle old-style "root=" arguments # # When we changed try_name() to handle new-style printable dev_t formatting we # broke lots of people's setups. Lilo, grub, etc. # # Fix that by trying new-style formatting first, then fall back to old-style. # # People should generally use new-style %u:%u major:minor formatting in the # future. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.22 # [PATCH] firmware loader requires hotplug # # From: Ramn Rey Vicente # # Fix the config issue with the hotplug firmware loader. The firmware loader # use hotplug, so this must be included as a dependency. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.23 # [PATCH] devfs_mk_dir fix # # From: Andrey Borzenkov # # devfs_mk_dir freed wrong de and incorrectly passed to devfsd already freed # de. Besides it did not even check if entry found was actually directory. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.24 # [PATCH] _devfs_walk_path fix # # From: Andrey Borzenkov # # _devfs_walk_path does not check if de it is about to scan is a directory. # Next step is spinlock on non-spinlock memory. It requires either artificial # setup or really broken driver but fairly easy to reproduce once you know how. # # It is likely to exist in 2.4 as well. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.25 # [PATCH] floppy_init fix # # From: Andrey Borzenkov # # The floppy driver doesn't remove /dev/floppy when floppy_init fails. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.26 # [PATCH] Make MTRR init conform with recommended procedure # # From: Zwane Mwaikambo # # This is a patch to make the MTRR initialisation more conformant with what # is stated in volume 3 of (10-36 Memory Cache Control). The most notable # change is entering the no-fill cache mode before clearing the PGE bit in # cr4. Intel also states that we should do the cache flush via the cr3 # register shuffle. If there is a problem with the patch please don't # hesitate to beat me vigorously with a clue-by-four. # # It has been tested on a 3x Pentium 133, 8x PIII Xeon 700, 1x Celeron 550 and 32x # PIII 500 NUMAQ (hardware courtesy of OSDL) # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.27 # [PATCH] fix typo in hd.c # # From: Adrian Bunk # # hd.c contains a typo # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.28 # [PATCH] fix hugetlbfs slab corruption on umount # # From: Zwane Mwaikambo # # hugetlbfs was accessing super_block->s_fs_info after free'ing it. This was # because it was being free'd prematurely. I have deferred free until # ->put_super(). I have also removed hugetlbfs_kill_super since it now is # simply a kill_litter_super. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.29 # [PATCH] Kill warning in minix filesystem on 64-bit archs # # From: Peter Chubb # # On 64-bit architectures, ino_t is int, not long, so the attached patch # is needed to prevent a warning. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.30 # [PATCH] loop oops fix # # loop-on-file oopses during unmount. This is because lo_queue is now freed # during lo_ioctl(LOOP_CLR_FD). I think the scenario is: # # 1: umount(8) opens /dev/loop0 # # 2: umount(8) runs lo_ioctl(LOOP_CLR_FD) (this frees the queue) # # 3: umount(8) closes the /dev/loop0 handle. The blockdev layer syncs the # blockdev, but its mapping->backing_dev_info now points into la-la-land. # # We shouldn't be freeing the queue until all refs to it have gone away. This # patch gives the queue the same lifetime as the controlling loop_device # itself. It also makes the loop driver's queue appear in sysfs again. # # It would be better to free the queue when the device is not in use, but I'm # not sure how we can hook into the blockdev layer to do that. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.31 # [PATCH] request_firmware fix # # From: Manuel Estrada Sainz # # - undo recent change, made in the believe that "buffer" was the size of # the whole file, it is just PAGE_SIZE in size. This was causing kernel # memory corruption. # # - Since files are allowed to have unknown sizes, by setting their # size to 0, we can't preallocate a buffer of their size on open. # # - Adapt request_firmware() to the sysfs change. # # - Adapt drivers/pci/pci-sysfs.c to the sysfs change. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.32 # [PATCH] Kill warning in drivers/input/misc/uinput.c on IA64 # # From: Peter Chubb # # Attached patch kills a warning when compiling on a 64-bit architecture # (ssize_t is long, not int) # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.33 # [PATCH] kill warning in jbd/revoke.c # # From: Peter Chubb # # If you need a long long format, then cast to long long, not u64. u64 is # long on 64-bit architectures. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.34 # [PATCH] keyboard.c warning fix # # drivers/char/keyboard.c: In function `k_fn': # drivers/char/keyboard.c:665: warning: comparison is always true due # to limited range of data type # # I didn't want to just delete the code because one day the size of func_table # may get smaller, or the type of `value' may get larger. When that happens, # the test becomes valid again. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.35 # [PATCH] fix [un]likely(), add ptr support # # From: Albert Cahalan # # 1. allows likely() and unlikely() to work for pointers # # 2. fixes likely() (in C, any non-zero value is true) # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.36 # [PATCH] ipmi_kcs_intf.c compile warning # # From: Zwane Mwaikambo # # drivers/char/ipmi/ipmi_kcs_intf.c: In function `acpi_find_bmc': # drivers/char/ipmi/ipmi_kcs_intf.c:1088: warning: long unsigned int format, different type arg (arg 2) # drivers/char/ipmi/ipmi_kcs_intf.c:1088: warning: long unsigned int format, different type arg (arg 2) # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.37 # [PATCH] hugetlbfs - 'recovering' too many blocks on failure # # From: Zwane Mwaikambo # # The code appears to be able to add too many blocks back to # sbinfo->free_blocks in the failure path. We first do; # # len = vma->vm_end - vma->vm_start; # sbinfo->free_blocks -= len; # # but then later do; # len = (vma->vm_end - vma->vma_start) + (vma->vm_pgoff << HPAGE_SHIFT) # # error: # sbinfo->free_blocks += len; # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.38 # [PATCH] more documentation for request_firmware() # # From: Manuel Estrada Sainz # # Add some higher level docs to Documentation/firmware_class/README. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.39 # [PATCH] state request_firmware() maintainership. # # From: Manuel Estrada Sainz # # Add Manuel to MAINTAINERS for request_firmware(). # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.40 # [PATCH] jffs statfs fix # # From: Josh Boyer # # jffs was missed in the statfs64 conversions. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.41 # [PATCH] Make 16-way x440's boot # # From: Matthew Dobson # # 16 proc x440 boxen aren't booting mainline kernels right now for many valid # configs. This patch makes sure NUMA codepaths aren't executed for SMP # configs. It also adds some sane error messages to the code, and cleans up # some #ifdefs. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.42 # [PATCH] Fix strncpy off-by-one error # # From: Yoshinori Sato # # It writes one too many zeroes when nulling out the destination. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.43 # [PATCH] nls Makefile fix # # From: Todor Todorov # # A missig line fs/nls/Makefile prevents codepage 1250 from compiling and # installing whatever the .config value. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.44 # [PATCH] Fix DAC960 oops # # From: Dave Olien # # The dynamic queue allocation appears to have exposed a long-standing bug. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.45 # [PATCH] Better argument size tracking in fs/exec.c # # From: Matthew Wilcox # # Introduce a new variable "arg_size" and set it appropriately in each arm of # the CONFIG_STACK_GROWSUP. This patch fixes a bug for PA-RISC and makes the # code cleaner for everyone. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.46 # [PATCH] bugfix for initialization bug in adm1021 driver # # From: Rusty Lynch # # While initializing the adm1021 device, the driver is performing a conversion # from fixed point to Celcius on values that were declaired as Celcius. On my # Dell Precision 220 this results in a shutdown after a couple of minutes # running. # # The latch simply removes the conversion. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.47 # [PATCH] dnotify documentation update # # From: Stephen Rothwell # # Fix the dnotify documentation and code example to reflect reality. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.48 # [PATCH] access_process_vm() needs to dirty the page # # If POKETEXT modifies the page it needs to tell the VM about it. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.49 # [PATCH] Use mark_page_accessed() in follow_page() # # Touching a page via follow_page() counts as a reference so we should be # either setting the referenced bit in the pte or running mark_page_accessed(). # # Altering the pte is tricky because we haven't implemented an atomic # pte_mkyoung(). And mark_page_accessed() is better anyway because it has more # aging state: it can move the page onto the active list. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.50 # [PATCH] uinput oops and panic fix # # From: Aristeu Sergio Rozanski Filho # # verify maximum number of bits before using set_bit # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.51 # [PATCH] Docbook: Make mandocs output more terse # # From: Michael Still # # This patch takes into account requests from various LKML members for the # mandocs output to be more terse. Information about the copyright, and # formatting of the man page is moved into a comment at the start of the # groff output. # # Sample output can be found at: # http://www.stillhq.com/linux/mandocs/2.6.0-test3-bk1/ # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.52 # [PATCH] opl3 use-after-free fix # # From: Shawn Starr # # opl3 use-after-free fix # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.53 # [PATCH] SELinux inode security init # # From: Stephen Smalley # # This patch reworks the SELinux module code that handles inodes initialized # before the policy is initially loaded to also cover the case where a pseudo # filesystem such as selinuxfs or nfsd directly populate themselves. # # The list of inode security structures is split into per-superblock lists # associated with each superblock security structure, and the initialization # is performed by superblock_doinit. # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1152.5.54 # [PATCH] Add SELinux entry to MAINTAINERS # # From: Stephen Smalley # # This patch adds a SELINUX entry to the MAINTAINERS file. # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1152.3.2 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1152.3.3 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1154 # Merge bk://kernel.bkbits.net//home/mochel/linux-2.5-core # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1155 # Merge bk://kernel.bkbits.net//home/mochel/linux-2.5-power # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1156 # Don't add noisy "deprecated" things to PM. # -------------------------------------------- # 03/08/15 mingo@elte.hu 1.1157 # [PATCH] More timer race fixes # # Patch from Julie DeWandel. # # This patch has solved the crashes observed during TPC-C runs on the # 16-way box. (I'm confident it will fix the other reported cases as # well.) # # The race is the setting of timer->base to NULL, by del_timer() or # __run_timers(). If new_base == old_base in __mod_timer() then we do not # re-check timer->base after getting the lock. (the only case where we do # not have to re-check the base is in the !old_base case, but the else # branch also includes the old_base==new_base case.) # # The __run_timers() case made the lock_timer() patch not work fully - we # cannot use lock_timer() in __run_timers() due to lock ordering. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1158 # [PATCH] janitor: scsi/gdth error handling # # From: Daniele Bellucci # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1159 # [PATCH] janitor: scsi/qlogicfc error handling # # From: Leann Ogasawara # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1160 # [PATCH] janitor: scsi ioctl error handling # # From: Daniele Bellucci # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1161 # [PATCH] janitor: use -Evalues in cpufreq/speedstep # # From: Maximilian Attems # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1162 # [PATCH] janitor: [sound] don't init statics to 0 # # From: Leann Ogasawara # # Uninitialize static variables initialized to 0 # so they are pushed to the .bss instead of .data. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1163 # [PATCH] janitor: remove bogus locking # # From: Domen Puncer # # Matthew Wilcox wrote: # > # > This routine looks to be bogus to begin with. i'd just remove the # > save_flags, cli and restore_flags calls entirely. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1164 # [PATCH] janitor: ad1816: don't init statics to 0 # # From: Eugene Teo # # Removed initialisation to zero on static variables in # sound/oss/ad1816.c. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1165 # [PATCH] janitor: ite8172: don't init statics to 0 # # From: Eugene Teo # # Removed initialisation to zero on static variables. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1166 # [PATCH] janitor: use pci_name in emu10k1 # # From: Eugene Teo # # Converted code to use pci_name instead of accessing slot_name directly. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1167 # [PATCH] janitor: i810_audio: balance pci_alloc/free_consistent # # From: Leann Ogasawara # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1168 # [PATCH] janitor: es1370: pci_alloc_consistent error handling # # From: Leann Ogasawara # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1169 # [PATCH] janitor: input cleanups # # From: Daniele Bellucci # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1170 # [PATCH] janitor: input/evdev fix copy_user fault # # From: Daniele Bellucci # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1171 # [PATCH] janitor: handle locking in joydump same as in tmdc # # From: Domen Puncer # # Did it the way it is in drivers/input/joystick/tmdc.c # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1172 # [PATCH] janitor: add static/exit to some modules # # From: Domen Puncer # # (2 statics added by rddunlap) # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1173 # [PATCH] janitor: audit RTC # # From: Daniele Bellucci # # Audit create_proc_read_entry in rtc_init # and fix coding style too. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1174 # [PATCH] janitor: dvb: return register_chrdev value # # From: Daniele Bellucci # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1175 # [PATCH] janitor: floppy: use register_blkdev return value # # From: Daniele Bellucci # # On failure register_blkdev doesn't necessarly return -ENODEV .. it can return -ENOMEM too. # This patch add a little better audit of register_blkdev. # -------------------------------------------- # 03/08/15 rddunlap@osdl.org 1.1176 # [PATCH] janitor: use request_module() # # From: Domen Puncer # -------------------------------------------- # 03/08/15 akpm@osdl.org 1.1177 # [PATCH] AS: update as_requeue_request() # # - Ensure that arq->state is always set (ie. even if io context # allocation failed). # # - Call as_antic_stop() unconditionally - which checks for the same # condition. There are other callers which make the same check and should # be changed too... # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1178 # [AGPGART] Merge ATI IGP GART driver. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1179 # [AGPGART] Move ATI PCI IDs to pci_ids.h # - sort some of the ATI entries. (note, there are dupes in there # that could be fixed up at some point). # - Rename PCI_DEVICE_ID_RADEON_IGP to ATI_RS100. # RadeonIGP is the family, not the specific chip. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1180 # [AGPGART] Kill off agp_try_unsupported for ATI. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1181 # [AGPGART] Masks cleanup for ATI GART # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1182 # [AGPGART] Plug memory leak in failure path of ATI GATT allocator. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1183 # [AGPGART] Kill compiler warnings for ATI GART driver. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1184 # [AGPGART] Fix compiler warning. # Need cacheflush.h for change_page_attr() # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1185 # [AGPGART] Check ioremap for failure in Serverworks GART driver. # Based on patch from Randy Dunlap. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1186 # [AGPGART] Remove duplicate agpgart: from printk's. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1187 # [AGPGART] Another missing ioremap() failure check. # Again, from Randy Dunlap # -------------------------------------------- # 03/08/15 hirofumi@mail.parknet.co.jp 1.1177.1.1 # [PATCH] thread coredump oops fix # # If ->group_leader of current thread already was exiting, # group_leader's ->mm is NULL in fill_psinfo(). Then I got Oops. # # This uses current->mm instead of ->group_leader->mm to dump args. # -------------------------------------------- # 03/08/15 davej@redhat.com 1.1188 # [AGPGART] Kconfig updates for the ATI GART # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1189 # Merge bk://linux-dj.bkbits.net/agpgart # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 david-b@pacbell.net 1.1123.20.21 # [PATCH] USB: usb_start_wait_urb() rewrite # # The code that manges the synchronous control/bulk calls has # been a mess for ages. This patch rewrites it using: # # - "struct completion" instead of a usb-internal clone therof, # - prepare_to_wait()/finish_wait() instead of the tangled # mess it now uses (or a new wait_event_timeout call, as in # previous versions of this patch). # # It's a net code shrink and simplification. # -------------------------------------------- # 03/08/15 dhollis@davehollis.com 1.1123.20.22 # [PATCH] USB: usbnet.c - trailing 'else' that probably breaks net1080 # # A trailing else in the #ifdef CONFIG_USB_NET1080 block that would # prevent it from properly filling the bulk URB. # -------------------------------------------- # 03/08/15 greg@kroah.com 1.1152.2.6 # Remove usage of struct device.name from scsi core # -------------------------------------------- # 03/08/15 greg@kroah.com 1.1152.2.7 # Driver Core: add warnings if .release functions are not set for objects. # # This has been in the -mm tree for a while and has helped a lot in finding # lots of improper users of the driver core. It also moves the driver core # code up quite a few levels on the "Rusty's guide to kernel APIs". # -------------------------------------------- # 03/08/15 greg@kroah.com 1.1190 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.6 # -------------------------------------------- # 03/08/15 greg@kroah.com 1.1189.1.1 # merge # -------------------------------------------- # 03/08/15 greg@kroah.com 1.1123.19.8 # I2C: add adapter and client name files as the driver core no longer provides them. # -------------------------------------------- # 03/08/15 greg@kroah.com 1.1189.2.1 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/i2c-2.6 # -------------------------------------------- # 03/08/15 davidm@tiger.hpl.hp.com 1.1123.23.1 # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.6.0-test3 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # -------------------------------------------- # 03/08/15 jejb@fuzzy.(none) 1.1150.1.6 # oops in sd_shutdown # # From: Andries Brouwer # # I see an Oops in the SCSI code, caused by the fact that sdkp is NULL # in sd_shutdown. "How can that be?", you will ask - dev->driver_data was set # in sd_probe. But in my case sd_probe never finished. An insmod usb-storage # hangs forever, or at least for more than six hours, giving ample opportunity # to observe this race between sd_probe and sd_shutdown. # (Of course sd_probe hangs in sd_revalidate disk.) # # Perhaps the obvious test is a good idea. # Locking seems meaningless - sd_probe will never finish. # -------------------------------------------- # 03/08/15 davidm@tiger.hpl.hp.com 1.1123.23.2 # entry.S: # ia64: Fix prologue directives for sys_clone() and sys_clone2() # -------------------------------------------- # 03/08/15 davidm@tiger.hpl.hp.com 1.1123.23.3 # ia64: Make things compile with gcc-pre3.4 and work on the simulator. # -------------------------------------------- # 03/08/15 davidm@tiger.hpl.hp.com 1.1123.23.4 # Move patch from linux-ia64-2.5 to to-linus-2.5 repository. # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1191 # Merge bk://kernel.bkbits.net/gregkh/linux/driver-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1192 # Merge bk://kernel.bkbits.net/gregkh/linux/i2c-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/15 torvalds@home.osdl.org 1.1193 # Merge http://lia64.bkbits.net/to-linus-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1194 # [IDE]: Fix alim15x3 build after ATI PCI ID changes. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1195 # [IDE]: Use pci_name() in amd74xx driver. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1196 # [INPUT]: Use pci_name() in pcips2 driver. # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1150.1.7 # Add fastfail to SCSI # # This is the preliminary version with no error indications or # control over the types of failures. # -------------------------------------------- # 03/08/16 anton@samba.org 1.1150.1.8 # [PATCH] minor fix to sym2 hotplug conversion # # One problem we found when we hit a bad adapter, we need to use scsi_host_put. # -------------------------------------------- # 03/08/16 anton@samba.org 1.1150.1.9 # [PATCH] another fix to sym2 hotplug conversion # # In sym_attach we call sym_hcb_attach. If it fails we call # sym_free_resources which will call sym_hcb_free. Unfortunately # sym_hcb_attach also calls sym_hcb_free on failure. # # This results in a bunch of things being freed twice and it looks like # the sym2 memory allocator adds them to the freelist twice. Sometime later # on we allocate the memory twice, with weird consequences. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1197 # [SCSI]: Use pci_name() in eata_pio.c # -------------------------------------------- # 03/08/16 davej@redhat.com 1.1123.24.1 # [CPUFREQ] Fix up dumb thinko in powernow-k7 # From John Clemens # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1198 # [SPARC64]: Use pci_name() in sparc64 PCI layer. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1199 # [SPARC]: Add sys_fadvise64{,_64} syscall entries. # -------------------------------------------- # 03/08/16 davej@tetrachloride.(none) 1.1193.1.1 # Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/trees/bk-linus # into tetrachloride.(none):/mnt/raid/src/kernel/2.5/trees/cpufreq # -------------------------------------------- # 03/08/16 kyle@debian.org 1.1193.2.1 # [IPSEC]: Add support for Twofish and Serpent. # # This patch adds support for the use of twofish and serpent as # ESP algorithms. The ESP index numbers given are in accordance # with RFC2407, draft-ietf-ipsec-ciph-aes-cbc-00 (before Rijndael # was selected), and KAME which assigns 253 to twofishcbc. # # Support for using twofish was requested on linux-kernel, and # since I noticed serpent was missing too, included that as well. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.2 # [NET]: ibmtr - get rid of MOD_INC/DEC. # # With the new module system MOD_INC/MOD_DEC are no longer necessary. # Also changed to new module init/exit macros for function setup. # # The module exit code can sleep, so calling schedule_timeout is better # than spinning. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.3 # [NET]: Network device renaming sysfs fix. # -------------------------------------------- # 03/08/16 kartik_me@hotmail.com 1.1193.2.4 # [CRYPTO]: Add CAST6 (CAST-256) algorithm. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.5 # [IPV6]: Set owner on /proc/net/rt6_stats. # -------------------------------------------- # 03/08/16 yoshfuji@linux-ipv6.org 1.1193.2.6 # [SCTP]: Fix typo in Kconfig. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.7 # [IPV6]: Fix build with CONFIG_XFRM disabled. # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1150.1.10 # ips 1/4: lindent ips.c # # From: David Jeffery # (with fix ups for rejections on CONFIG_HIGHIO) # # This patch has no code changes. It is only the result of running # scripts/Lindent on drivers/scsi/ips.c in test3. Rather than use this # patch, it may be advisable to just run # # sh scripts/Lindent drivers/scsi/ips.c # # The nasty 3-4 space indenting in ips.c has always made it a pain to # read. The remaining patches in this patch set all assume ips.c has been # lindented. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.8 # [NET]: net-sysfs misc fixes. # # - define format strings once rather than N times # - add GNU license that I forgot in original code # - move read_lock out from format_address to show_address so # device is alive test is inside of lock. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.9 # [NET]: net-sysfs - use attribute group instead of kobject for statistics. # # Net statistics were in a kobject only because there was no better way # to create a directory. Latest 2.6.0-test3 bk tree, has merged in # Pat's change to provide 'attribute groups'. # # This patch converts netdevice's from a statistic's kobject to attribute # group. This is cleaner and fixes some shutdown unload issues as well. # # Ps. it gets rid of of the object # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1150.1.11 # ips 2/4: 2.4 resync # # From: David Jeffery # (with minor fixes for rejects) # # This patch is a resync with the 6.10 driver for 2.4 and updates the 2.4 # compatability code. It adds a new wrapper function for differences # between the 2.4 and 2.6 scsi proc interface, forces pci posting in 3 # places, corrects using a meaningless constant of 0x80 to 0, and syncs # comments that had changed. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.10 # [NET]: Move code inline if short and used once. # # Now that unregister_sysfs got smaller, just eliminate it and call # class_device_unregister directly. netdev_finish_unregister is called # one place, therefore it is easier to understand if we just put those # few lines into wait_allrefs state machine. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.11 # [NET]: Add wireless statistics to sysfs. # # Add wireless statistics to /net/class/ethXX/wireless. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.12 # [IRDA]: Get rid of useless hashbin in irtty. # # Working on converting IRDA to new netdevice semantics, this is the first # of some of the small things I found. # # The irtty hashbin is created, maintained and never used. # Motivation for removing is that the hashbin locking has problems with # the locking assumptions in on network device removal. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.13 # [IRDA]: Fix irtty line disc and module semantics. # # The irda tty line discipline does not handle the new module # paradigm well. This patch fixes that: # - initialize line discipline as data, not with code # - set module owner # - make prototype for irtty_ioctl match expected # arguments from tty discipline # - get rid of explicit MOD_INC/MOD_DEC # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.14 # [IRDA]: irda_device_setup should match ether_setup. # # irda_device_setup signature should match ether_setup so it can # be used with alloc_netdev. No caller was checking the return # value anyway. # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1150.1.12 # ips 3/4: use pci_dma APIs and remove GFP abuse # # From: David Jeffery # (with minor reject fixes) # # This patch removes several places where we were using kmalloc flag # tricks to always get memory <4GB instead of using the proper # dma_alloc_consistent() API. It also no longer #errors on when compiled # for x86-64 kernels. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.15 # [IRDA]: irlap_open should take const string. # # irlap_open should take a constant string because it copies # its argument. Therefore, irtty_net_open doesn't have to make # a copy! # -------------------------------------------- # 03/08/16 david_jeffery@adaptec.com 1.1150.1.13 # [PATCH] ips 4/4: version resync # # This patch has no code changes. It is just a resync of all the version # numbers with the 6.10 driver and bumping up the driver version number. # -------------------------------------------- # 03/08/16 shemminger@osdl.org 1.1193.2.16 # [IRDA]: irlap hashbin can be private # # irlap hashbin is only used in one file, so make it private not global. # -------------------------------------------- # 03/08/16 rddunlap@osdl.org 1.1150.1.14 # [PATCH] ppa needs to scsi_unregister(host) # # When umounting a ppa device, I see (2.6.0-test3): # # Releasing ppa0 # Iomega VPI0 (ppa) interface did not call scsi_unregister # Call Trace: # [] exit_this_scsi_driver+0xb6/0xfa [ppa] # [] sys_delete_module+0x18d/0x1e0 # [] do_munmap+0x136/0x1b0 # [] sys_munmap+0x43/0x70 # [] syscall_call+0x7/0xb # # so ppa needs to call scsi_unregister(). # Is this all that's needed? # # -- # ~Randy # # # patch_name: scsi_ppa_unreg.patch # patch_version: 2003-08-15.09:46:30 # author: Randy.Dunlap # description: ppa driver needs to call scsi_unregister(host); # product: Linux # product_versions: 260-815 # maintainer: campbell@torque.net # diffstat: = # drivers/scsi/ppa.c | 1 + # 1 files changed, 1 insertion(+) # -------------------------------------------- # 03/08/16 hch@infradead.org 1.1150.1.15 # [PATCH] Re: scsi proc_info called unconditionally # # On Sat, Aug 16, 2003 at 10:44:09AM +0200, Olaf Hering wrote: # > # > Why is ->proc_info() called when the function pointer is NULL? # # Looks like the check for it's presence got lost in # # [PATCH] Correct removal of procfs host enteries [1/2] # # Here's a trivial patch to get it back: # -------------------------------------------- # 03/08/16 stern@rowland.harvard.edu 1.1150.1.16 # [PATCH] PATCH: (as70b) Update request_bufflen to match this_count # # This patch addresses a problem in both sd.c and sr.c. When a read/write # command is initialized, the routines may reduce this_count (the number of # sectors to transfer) if it exceeds the maximum allowed value (i.e., 0xffff # for READ(10)). However, the code does not similarly alter # scmd->request_bufflen and scmd->bufflen to match the change in the CDB # value. # # scmd->request_bufflen is important for the usb-storage driver, which # requires that it be exactly equal to the number of bytes transferred. # scmd->bufflen is used in the rw_intr() routines, where it is passed to # scsi_io_completion() as the number of sectors transferred if no errors # occur. # # Another small change in the patch concerns the code in sr.c that checks # whether the total of the scatter-gather area lengths matches # scmd->request_bufflen. If they don't match, the patch bumps the kernel # log message level up to KERN_ERR, and it takes the more conservative # approach of adjusting scmd->request_bufflen only if the s-g length is # smaller than the request length. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1200 # [SPARC]: Fix TLS and thread ID handling. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1201 # [SPARC64]: Fix typo in clone changes. # -------------------------------------------- # 03/08/16 rth@kanga.twiddle.home 1.1193.3.1 # [ALPHA] Disable some printks in bootp. # From Jay Estabrook . # -------------------------------------------- # 03/08/16 rth@kanga.twiddle.home 1.1193.3.2 # [ALPHA] Make sure the bridge COMMAND register is correctly set # after assigning resources. # From Jay Estabrook . # -------------------------------------------- # 03/08/16 rth@kanga.twiddle.home 1.1193.3.3 # [ALPHA] Fix whitespace. # -------------------------------------------- # 03/08/16 rth@kanga.twiddle.home 1.1193.3.4 # [ALPHA] Tidy debugging of pci resources. # -------------------------------------------- # 03/08/16 kuznet@ms2.inr.ac.ru 1.1193.2.17 # [IPV4]: Fix rt_score() and usage when purging rtcache hash chains. # -------------------------------------------- # 03/08/16 greg@kroah.com 1.1193.4.1 # [PATCH] Fix Driver Core fixes Firewire # # Damm, I keep forgetting about firewire, sorry. # # This should fix the ieee1394 code for the device.name removal, and for # the i2c structure changes that happened in 2.6.0-test3. # -------------------------------------------- # 03/08/16 davem@kernel.bkbits.net 1.1193.4.2 # [MM]: Add and use offset_in_page() convenience macro. # # Based upon patches from Yoshfuji Hideaki # -------------------------------------------- # 03/08/16 benh@kernel.crashing.org 1.1193.5.1 # [PATCH] Fix ide-scsi build with driver model change # # This fixes build of ide-scsi after removal of struct device.name # -------------------------------------------- # 03/08/16 benh@kernel.crashing.org 1.1193.5.2 # [PATCH] PowerMac: Update for removal of device->name # # This fixes the build of PowerMac driver core with the removal # of struct device "name" field. # -------------------------------------------- # 03/08/16 benh@kernel.crashing.org 1.1193.5.3 # [PATCH] Fix incorrect pci_ids.h for Radeon # # A recent patch from James had incorrect PCI IDs for a few Radeon # chips (the Radeon M9 chips Ld,Le,Lf and Lg, he used the IDs of the # Id,Ie,If and Ig instead). # # This fixes that and group the properly by family (those got a bit # shuffled around lately). # -------------------------------------------- # 03/08/16 torvalds@home.osdl.org 1.1193.1.2 # Merge bk://linux-dj.bkbits.net/cpufreq # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/16 torvalds@home.osdl.org 1.1193.1.3 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/16 torvalds@home.osdl.org 1.1199.1.1 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1202 # [SPARC]: Add missing sys_tgkill syscall entries. # -------------------------------------------- # 03/08/16 hch@de.rmk.(none) 1.1123.25.1 # [PCMCIA] kill remaining pcmcia release timers # # The scsi ones are already gone in jejb's tree, I'll post a patch # to kill the struct fields once the scsi tree and this patch end # up merged in mainline. # -------------------------------------------- # 03/08/16 torvalds@home.osdl.org 1.1199.1.2 # Merge bk://kernel.bkbits.net/davem/offset_in_page-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1203 # [SPARC]: Add more missing system calls. # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1204 # [SPARC64]: Fix syscall table alignments. # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1193.6.1 # Merge # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1193.6.2 # merge hch/gregkh scsi changes # -------------------------------------------- # 03/08/16 ambx1@neo.rr.com 1.1199.1.3 # [PATCH] Remove remaining usage of device.name in PnP # # This removes three remaining instances of device.name. # 1.) the isapnp driver # 2.) the protocol management code # 3.) the pnp serial driver # # A name field has been introduced to pnp_dev and pnp_card to # store human readable names reported by pnp. # -------------------------------------------- # 03/08/16 torvalds@home.osdl.org 1.1199.1.4 # Merge bk://bk.arm.linux.org.uk/linux-2.5-pcmcia # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1199.1.5 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/08/16 davem@nuts.ninka.net 1.1205 # Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5 # into nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # -------------------------------------------- # 03/08/16 torvalds@home.osdl.org 1.1199.2.1 # Fix "no_idt" usage in reboot code, noticed by better asm # typechecking in gcc-3.3.1. # -------------------------------------------- # 03/08/16 jejb@raven.il.steeleye.com 1.1193.6.3 # remove generic device name field from parisc SCSI devices # # zalon and lasi700 still use this; replace it with bus_id. # -------------------------------------------- # 03/08/16 mitch@sfgoth.com 1.1199.1.6 # [NET]: Small loopback.c cleanups. # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1193.3.5 # [ALPHA] Corrected testing for peer PCI bus root. # From Jay Estabrook . # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1193.3.6 # [ALPHA] Forward port SRM restore code from 2.4. # From Jay Estabrook . # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1193.3.7 # [ALPHA] Convert DEBUG_MCHECK define to runtime variable. # From Jay Estabrook . # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1199.2.2 # Merge kanga.twiddle.home:/home/rth/work/linux/linus-2.5 # into kanga.twiddle.home:/home/rth/work/linux/axp-2.5 # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1199.2.3 # [ALPHA] Fix stxncpy zapping bytes outside the string. # From Ivan Kokshaysky . # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.3.1 # Merge redhat.com:/garz/repo/linus-2.6 # into redhat.com:/garz/repo/ethtool-2.6 # -------------------------------------------- # 03/08/17 andrea@suse.de 1.1199.4.1 # [PATCH] address update # -------------------------------------------- # 03/08/17 dmo@osdl.org 1.1199.4.2 # [PATCH] DAC960 fix for NULL dereference in open() # # This fixes a problem that's been hidden for a while. # # DAC960_open() will try to dereference a NULL pointer if an application # opens (for example) /dev/rd/c0d12 when there has never been a logical # device created for that file. # -------------------------------------------- # 03/08/17 albert@users.sourceforge.net 1.1199.4.3 # [PATCH] fast AND correct strncpy # # This is Erik Andersen's excellent strncpy. # It works like magic. That "if" isn't a jump; # gcc uses a few integer instructions to wipe # out all jumps except for the loop itself and # the function call/return. # # This has been exhaustively tested against glibc. # # The existing code has 5 extra branches and # is over twice as large. (my gcc, etc.) # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.1 # [netdrvr] clean up driver object name removal breakage # # Affected drivers: atmel_cs, olympic, 3c359 # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.2 # [arcnet com20020] check_region removal, ->name removal breakage fix # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.3 # [arcnet com20020] misc fixes # # * com20020_close expects two arguments (and actually uses the # second argument), but the arcnet layer only passes one arg. # Fun ensues. # * Remove __devinit markers, this is a library module. # * Move request_region up in com20020_found, to make the call # occur before the first I/O access in the function. # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.4 # [arcnet com90io] replace check_region with temporary request_region, # in probe phase. # -------------------------------------------- # 03/08/17 achirica@telefonica.net 1.1199.5.5 # [wireless airo] Turns on spy code in wireless extensions v16 # -------------------------------------------- # 03/08/17 achirica@telefonica.net 1.1199.5.6 # [wireless airo] Fix PCI unregister code # -------------------------------------------- # 03/08/17 rddunlap@osdl.org 1.1199.5.7 # [netdrvr hydra] janitor cleanups # -------------------------------------------- # 03/08/17 shemminger@osdl.org 1.1199.5.8 # [PATCH] Make z8530.c build on 2.6 # # Either we need to mark this driver (and the parts that use them) as BROKEN, # or at least get it building again. # # With this it builds, but of course, I don't have the real hardware. # -------------------------------------------- # 03/08/17 lenehan@twibble.org 1.1193.6.4 # [PATCH] dc395x - list handling cleanups # # Here's another patch in the "try and make the driver readable" # cleanup series. This one cleans up all of the list handling. # # Description: Replaced the various hand crafted scsi req lists # (waiting and going in the dcb and free in the acb) and the dcb list # (in the acb) with the generic linux lists. This makes all of the list # related code a *lot* more readable then it was previously. # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.9 # [netdrvr] add sis190 gigabit ethernet driver (note: needs work) # -------------------------------------------- # 03/08/17 jejb@raven.il.steeleye.com 1.1193.6.5 # scsi.h uses "u8" which isn't defined. # # From: Muli Ben-Yehuda # # IMO, it's more correct to include in scsi.h, which # will bring in u8 and make scsi.h compilable on its own (provided # __KERNEL__ is defined, as it should be). # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.10 # [netdrvr sis190] Lindent sis190. zero code changes. # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.11 # [netdrvr sis190] manually clean up formatting a bit more # # Also, two trivial code changes: # * add unlikely() to assert() definition # * fix MODULE_AUTHOR email address brackets # -------------------------------------------- # 03/08/17 dledford@compaq.xsintricity.com 1.1189.3.1 # Add irq and softirq time accounting to the kernel # -------------------------------------------- # 03/08/17 dledford@compaq.xsintricity.com 1.1189.3.2 # Reserve the sys_prctl() numbers for and add the stub for allowing # programs to select whether they use statistical time accounting # or accurate timestamp based accounting. # -------------------------------------------- # 03/08/17 dledford@compaq.xsintricity.com 1.1199.4.4 # Merge bk://linux.bkbits.net/linux-2.5 # into compaq.xsintricity.com:/home/dledford/bk/linux-2.5-wo-timeval # -------------------------------------------- # 03/08/17 ionut@badula.org 1.1199.5.12 # [netdrvr tulip] add pci id for 3com 3CSOHO100B-TX # -------------------------------------------- # 03/08/17 jgarzik@redhat.com 1.1199.5.13 # [netdrvr sis190] allocate RX/TX descriptors using PCI DMA API # # The RX buffers themselves still need to be converted. The three # places that need fixing are marked with #warning. # -------------------------------------------- # 03/08/17 hch@de.rmk.(none) 1.1123.25.2 # [PCMCIA] kill off last remains of the release timer # # update the previously missed atmel_cs driver and kill the struct # member. # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1199.6.1 # [EISA] Update for moving "name" out of struct device. # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.4.5 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.4.6 # Merge bk://bk.arm.linux.org.uk/linux-2.5-pcmcia # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.3.2 # Merge http://gkernel.bkbits.net/ethtool-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.3.3 # Merge bk://are.twiddle.net/eisa # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.3.4 # Make include the right headers and use the right types. # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.3.5 # Fix incomplete EISA device "name" conversion # -------------------------------------------- # 03/08/17 vandrove@vc.cvut.cz 1.1199.3.6 # [PATCH] Recent i2c changes broke matroxfb # # The 'name' member of i2c clients & adapters moved again back to the # i2c_* from generic device. # # Thanks to Petri Koistinen for bringing this to my attention. # -------------------------------------------- # 03/08/17 sam@ravnborg.org 1.1199.3.7 # [PATCH] Move config tasks to kconfig/Makefile # # This fixes a bug with multiple targets. # # Olaf Hering reported that the build failed for PowerPc if used like # this: make oldconfig zImage # # The reason for this was that .config was not present for any targets # specified in arch/$(ARCH)/Makefile and below. # # That's because .config would not be included when oldconfig is present # in the list of targets. The fix is to move handling of *config task to # the kconfig/Makefile. Furthermore the logic in top-level makefile has # changed a bit, creating a more logial structure. When building a fresh # kernel, the user is now told that .config is missing, not an anonymous # report that .config did not exist. # # The error has survided this long because the targets used in i386/boot # in general does not use CONFIG_ symbols. # # Olaf Hering has tested this patch with success. # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1199.2.4 # Merge kanga.twiddle.home:/home/rth/work/linux/linus-2.5 # into kanga.twiddle.home:/home/rth/work/linux/axp-2.5 # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.3.8 # Fix "make clean" in scripts/genksyms # # Don't prepend $(obj) to "targets", since the generic rules will # do that for us, and doing it twice just makes things not work. # -------------------------------------------- # 03/08/17 ambx1@neo.rr.com 1.1199.3.9 # [PATCH] Fix sb_card.c for "name" removal # # This will correct the sb_card compile error from removing "name" from # "struct device". # # I also decided to read the name from the card structure instead of the # device structure because, for isapnp devices, the card structure is more # likely to contain an appropriate name. # -------------------------------------------- # 03/08/17 jgarzik@pobox.com 1.1199.3.10 # [PATCH] add missing export-symbol lines for ethtool_ops # # ethtool helpers need exporting. # -------------------------------------------- # 03/08/17 jamie@shareable.org 1.1199.3.11 # [PATCH] use simple_strtoul for unsigned kernel parameters # # The largest "unsigned int" value doesn't fit in a "long", on many machines. # So we should use simple_strtoul, not simple_strtol, to decode these values. # -------------------------------------------- # 03/08/17 jamie@shareable.org 1.1199.3.12 # [PATCH] make NFS lockd port numbers assignable at run time # # When writing firewall rules, and you are serving NFS, it's really # useful to know the port numbers of the various NFS services. nfsd has # a standard value; mountd and statd are userspace daemons, and those # ports are settable on the command line. # # The fiddly one is lockd. nlm_udpport and nlm_tcpport can be set on # the kernel command line or at module load time, but after that it's a # bit awkward (particularly as the lockd module can't be unloaded safely # - "rmmod -f lockd" sometimes panics). # # This patch allows the port numbers and the other lockd parameters to # be set through files in /proc/sys/fs/nfs/nlm_*. The port numbers take # effect when lockd is next started or restarted. # # In order to install the sysctl table even when compiled into the # kernel, it was necessary to update the initialisation code to the # current methods, using module_init() et al. This patch does that and # in so doing updates the module/kernel parameters to use the 2.6 # module_param() method, as well as making the numeric range changes # consistent between the two. # -------------------------------------------- # 03/08/17 jgarzik@pobox.com 1.1199.3.13 # [PATCH] another ethtool_ops quickie # # Let not my fingers type in haste. # # net/netsyms.c must include linux/ethtool.h, when exporting its symbols. # -------------------------------------------- # 03/08/17 James.Bottomley@SteelEye.com 1.1199.3.14 # [PATCH] Fix MCA for driver core update # # This should fix the MCA problems. # # I moved the name field to the struct mca_device because it was in such # extensive use, and this approach caused the least impact. # -------------------------------------------- # 03/08/17 acme@conectiva.com.br 1.1199.7.1 # o atm/eni: use skb_queue_walk, not open coded equivalent # -------------------------------------------- # 03/08/17 torvalds@home.osdl.org 1.1199.3.15 # More EISA/MCA fixups for removal of 'name' member in device struct. # -------------------------------------------- # 03/08/17 jejb@raven.il.steeleye.com 1.1199.8.1 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.6 # -------------------------------------------- # 03/08/17 rth@kanga.twiddle.home 1.1199.2.5 # [ALPHA] Update for "name" out of struct device. # -------------------------------------------- # 03/08/17 davem@nuts.ninka.net 1.1206 # Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5 # into nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # -------------------------------------------- # 03/08/17 davem@nuts.ninka.net 1.1199.1.7 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/08/17 davem@nuts.ninka.net 1.1199.1.8 # Merge bk://kernel.bkbits.net/acme/sk_buff-2.6 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/08/17 davem@nuts.ninka.net 1.1207 # [SCSI]: In dc395x.c, scsi_release_host() does not return a value. # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1199.1.9 # [TCP]: When socket route changes, do not forget to update ext2_header_len and sk_route_caps. # # Based upon a patch from Herbert Xu (herbert@gondor.apana.org.au). # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1208 # [SPARC64]: Fix syscall table base loading assembler. # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1209 # [SCSI]: Fix bugs in sym2 hotplug conversion. # # 1) Make sym2_template.module get setup properly. It was # the scsi_module.c code taking care of this for us previously. # 2) Zero out on-stack structures, in particular sym_dev not being # zeroed out was causing sometimes-boots-sometimes-doesnt problems # for me on sparc64 with sym2 non-modular. # -------------------------------------------- # 03/08/18 vnourval@tcs.hut.fi 1.1199.1.10 # [IPV6]: Fix ip6_dst_lookup() route corruption. # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1199.1.11 # [IPV6]: Fix some dst cache leaks. # 1) icmpv6_send() and icmpv6_echo_reply() never release dst. # 2) ip6_{push,flush}_pending_frames() leak np->cork.rt. # -------------------------------------------- # 03/08/18 vnourval@tcs.hut.fi 1.1199.1.12 # [IPV6]: Fix leaks of rt6_cow()d routes in route.c # -------------------------------------------- # 03/08/18 jmorris@intercode.com.au 1.1199.1.13 # [CRYPTO]: Documentation bugfix. # -------------------------------------------- # 03/08/18 my@post.utfors.se 1.1199.1.14 # [IPSEC]: Fix oops using null ciper in CBC mode. # -------------------------------------------- # 03/08/18 herbert@gondor.apana.org.au 1.1199.1.15 # [IPSEC]: Fix oops when destroying stillborn states. # -------------------------------------------- # 03/08/18 vnourval@tcs.hut.fi 1.1199.1.16 # [IPV6]: Fix tunnel encap limit handling as per RFC2473. # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1199.1.17 # [CRYPTO]: Fix cast{5,6} build after cia_ivsize removal. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1210 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1211 # Merge SCSI update # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1212 # Merge bk://are.twiddle.net/axp-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/18 rmk@arm.linux.org.uk 1.1213 # [PATCH] Fix Acorn Eesox partition handling build # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1214 # Fix compile warning in AFS by passing around "const" types properly. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1215 # Fix up ad1848 OSS driver for PnP 'name' move. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1216 # Update scx200 i2c driver for 'name' move. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1217 # Fix up riscom8 driver to use work queues instead of task queueing. # # This gets it potentially closer to working, if somebody could # just test it... # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1218 # Fix up esp driver for task_queue -> work abstraction. # # This might bring the driver to a state where people who # have hardware can try to fix the locking problems. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1219 # Switch specialix driver from task-queues to work queues. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1220 # Fix AGP device ID's - make them static, and fix bad ATI name confusion. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1221 # Update isicom driver to work queue abstraction. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1222 # Fix more drivers that broke due to losing the 'name' entry. # -------------------------------------------- # 03/08/18 solt@dns.toxicfilms.tv 1.1223 # [PATCH] C99 initialisers for sound/oss # # Here is a batch of C99 initialisers for sound/oss. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1224 # Merge bk://linux-isdn.bkbits.net/linux-2.5.make # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1225 # Add proper header file for fewer warnings in blkmtd.c # # It's still broken, but now the silly warnings no longer hide # the _real_ problems in this file. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1226 # Add CONFIG_BROKEN (default 'n') to hide known-broken drivers. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1227 # Make BLKMTD and MTD_PCMCIA broken. They are. Maybe somebody # will stand up and un-break them. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1228 # Fix broken x86_64 ioport code # -------------------------------------------- # 03/08/18 albert.cahalan@ccur.com 1.1229 # [PATCH] reduce diff between x86-64 & i386 # # This cleans up ioport.c to use BITS_PER_LONG, sizeof, and so on. This # makes it easier to spot the differences that matter, and thus easier to # find bugs. # -------------------------------------------- # 03/08/18 hollisb@us.ibm.com 1.1230 # [PATCH] spelling fix # # Kernul proggrammers cant spel. # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1231 # [SPARC]: Kill bogus SHELL= lines in Makefiles. # -------------------------------------------- # 03/08/18 davem@nuts.ninka.net 1.1232 # [SPARC64]: Update defconfig. # -------------------------------------------- # 03/08/18 javier@tudela.mad.ttd.net 1.1233 # [wireless airo] Replaces task queues by simpler kernel_thread # -------------------------------------------- # 03/08/18 matthewn@snapgear.com 1.1234 # [netdrvr 8139cp] fix h/w vlan offload # # It wants big endian vlan tags. IEEE, or just weird? # -------------------------------------------- # 03/08/18 jgarzik@redhat.com 1.1232.1.1 # Merge redhat.com:/garz/repo/linus-2.6 # into redhat.com:/garz/repo/misc-2.6 # -------------------------------------------- # 03/08/18 akpm@osdl.org 1.1232.2.1 # [PATCH] cpumask_t: allow more than BITS_PER_LONG CPUs # # From: William Lee Irwin III # # Contributions from: # Jan Dittmer # Arnd Bergmann # "Bryan O'Sullivan" # "David S. Miller" # Badari Pulavarty # "Martin J. Bligh" # Zwane Mwaikambo # # It has ben tested on x86, sparc64, x86_64, ia64 (I think), ppc and ppc64. # # cpumask_t enables systems with NR_CPUS > BITS_PER_LONG to utilize all their # cpus by creating an abstract data type dedicated to representing cpu # bitmasks, similar to fd sets from userspace, and sweeping the appropriate # code to update callers to the access API. The fd set-like structure is # according to Linus' own suggestion; the macro calling convention to ambiguate # representations with minimal code impact is my own invention. # # Specifically, a new set of inline functions for manipulating arbitrary-width # bitmaps is introduced with a relatively simple implementation, in tandem with # a new data type representing bitmaps of width NR_CPUS, cpumask_t, whose # accessor functions are defined in terms of the bitmap manipulation inlines. # This bitmap ADT found an additional use in i386 arch code handling sparse # physical APIC ID's, which was convenient to use in this case as the # accounting structure was required to be wider to accommodate the physids # consumed by larger numbers of cpus. # # For the sake of simplicity and low code impact, these cpu bitmasks are passed # primarily by value; however, an additional set of accessors along with an # auxiliary data type with const call-by-reference semantics is provided to # address performance concerns raised in connection with very large systems, # such as SGI's larger models, where copying and call-by-value overhead would # be prohibitive. Few (if any) users of the call-by-reference API are # immediately introduced. # # Also, in order to avoid calling convention overhead on architectures where # structures are required to be passed by value, NR_CPUS <= BITS_PER_LONG is # special-cased so that cpumask_t falls back to an unsigned long and the # accessors perform the usual bit twiddling on unsigned longs as opposed to # arrays thereof. Audits were done with the structure overhead in-place, # restoring this special-casing only afterward so as to ensure a more complete # API conversion while undergoing the majority of its end-user exposure in -mm. # More -mm's were shipped after its restoration to be sure that was tested, # too. # # The immediate users of this functionality are Sun sparc64 systems, SGI mips64 # and ia64 systems, and IBM ia32, ppc64, and s390 systems. Of these, only the # ppc64 machines needing the functionality have yet to be released; all others # have had systems requiring it for full functionality for at least 6 months, # and in some cases, since the initial Linux port to the affected architecture. # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1232.2.2 # Update x86 defconfig # -------------------------------------------- # 03/08/18 rob@landley.net 1.1232.1.2 # [docbook] Fix kernel-api reference to kernel/power/pm.c. # -------------------------------------------- # 03/08/18 sziwan@hell.org.pl 1.1235 # [netdrvr 8139too] fix resume behavior # -------------------------------------------- # 03/08/18 jgarzik@redhat.com 1.1232.1.3 # [ia32] Note that X86_VENDOR_ID offset in head.S is dependent # on NCAPINTS value found in include/asm-i386/cpufeature.h. # -------------------------------------------- # 03/08/19 akropel1@rochester.rr.com 1.1236 # [netdrvr] fix seeq8005 entry help text in Kconfig # -------------------------------------------- # 03/08/19 jgarzik@redhat.com 1.1237 # [netdrvr 8139too] add adapter to supported list, in docs # -------------------------------------------- # 03/08/19 srk@thekelleys.org.uk 1.1238 # [wireless atmel] minor updates # # 1) Add another card to the PCMCIA card database. # 2) Fix a bug in wireless extensions. # 3) Remove extra code for compilation without the firmware loader # 4) force-enable CRC32 and FW_LOADER in Kconfig. # # -------------------------------------------- # 03/08/19 jgarzik@redhat.com 1.1239 # [netdrvr de2104x] fix Kconfig help text to reflect reality # -------------------------------------------- # 03/08/19 alan@lxorguk.ukuu.org.uk 1.1240 # [netdrvr eexpress] fix buglet in skb_padto conversion # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1232.1.4 # Merge bk://kernel.bkbits.net/jgarzik/misc-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/18 torvalds@home.osdl.org 1.1241 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # diff -Nru a/CREDITS b/CREDITS --- a/CREDITS Mon Aug 18 22:21:04 2003 +++ b/CREDITS Mon Aug 18 22:21:04 2003 @@ -110,16 +110,18 @@ S: USA N: Andrea Arcangeli -E: andrea@e-mind.com -W: http://e-mind.com/~andrea/ -P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 +E: andrea@suse.de +W: http://www.kernel.org/pub/linux/kernel/people/andrea/ +P: 1024D/68B9CB43 13D9 8355 295F 4823 7C49 C012 DFA1 686E 68B9 CB43 +P: 1024R/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 D: Parport hacker D: Implemented a workaround for some interrupt buggy printers -D: Author of pscan that helps to fix lp/parport bug +D: Author of pscan that helps to fix lp/parport bugs D: Author of lil (Linux Interrupt Latency benchmark) D: Fixed the shm swap deallocation at swapoff time (try_to_unuse message) +D: VM hacker D: Various other kernel hacks -S: Via Ciaclini 26 +S: Via Cicalini 26 S: Imola 40026 S: Italy @@ -1988,7 +1990,7 @@ S: Canada B3J 3C8 N: Kai Mäkisara -E: Kai.Makisara@metla.fi +E: Kai.Makisara@kolumbus.fi D: SCSI Tape Driver N: Asit Mallick diff -Nru a/Documentation/BK-usage/bk-kernel-howto.txt b/Documentation/BK-usage/bk-kernel-howto.txt --- a/Documentation/BK-usage/bk-kernel-howto.txt Mon Aug 18 22:21:03 2003 +++ b/Documentation/BK-usage/bk-kernel-howto.txt Mon Aug 18 22:21:03 2003 @@ -216,7 +216,7 @@ 3) Include a summary and "diffstat -p1" of each changeset that will be downloaded, when Linus issues a "bk pull". The author auto-generates -these summaries using "bk push -nl 2>&1", to obtain a listing +these summaries using "bk changes -L ", to obtain a listing of all the pending-to-send changesets, and their commit messages. It is important to show Linus what he will be downloading when he issues diff -Nru a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt --- a/Documentation/DMA-mapping.txt Mon Aug 18 22:21:03 2003 +++ b/Documentation/DMA-mapping.txt Mon Aug 18 22:21:03 2003 @@ -689,7 +689,7 @@ and offset using something like this: struct page *page = virt_to_page(ptr); - unsigned long offset = ((unsigned long)ptr & ~PAGE_MASK); + unsigned long offset = offset_in_page(ptr); Here are the interfaces: diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl --- a/Documentation/DocBook/kernel-api.tmpl Mon Aug 18 22:21:00 2003 +++ b/Documentation/DocBook/kernel-api.tmpl Mon Aug 18 22:21:00 2003 @@ -206,7 +206,7 @@ Power Management -!Ekernel/pm.c +!Ekernel/power/pm.c diff -Nru a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt --- a/Documentation/binfmt_misc.txt Mon Aug 18 22:21:03 2003 +++ b/Documentation/binfmt_misc.txt Mon Aug 18 22:21:03 2003 @@ -11,6 +11,9 @@ bits) you have supplied. Binfmt_misc can also recognise a filename extension aka '.com' or '.exe'. +First you must mount binfmt_misc: + mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc + To actually register a new binary type, you have to set up a string looking like :name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon your needs) and echo it to /proc/sys/fs/binfmt_misc/register. diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt --- a/Documentation/crypto/api-intro.txt Mon Aug 18 22:21:04 2003 +++ b/Documentation/crypto/api-intro.txt Mon Aug 18 22:21:04 2003 @@ -185,7 +185,7 @@ Matthew Skala (Twofish) Dag Arne Osvik (Serpent) Brian Gladman (AES) - + Kartikey Mahendra Bhatt (CAST6) SHA1 algorithm contributors: Jean-Francois Dive @@ -213,6 +213,9 @@ Herbert Valerio Riedel Kyle McMartin Adam J. Richter + +CAST5 algorithm contributors: + Kartikey Mahendra Bhatt (original developers unknown, FSF copyright). Generic scatterwalk code by Adam J. Richter diff -Nru a/Documentation/dnotify.txt b/Documentation/dnotify.txt --- a/Documentation/dnotify.txt Mon Aug 18 22:21:04 2003 +++ b/Documentation/dnotify.txt Mon Aug 18 22:21:04 2003 @@ -32,7 +32,8 @@ Preferably the application will choose one of the real time signals (SIGRTMIN + ) so that the notifications may be queued. This is -especially important if DN_MULTISHOT is specified. +especially important if DN_MULTISHOT is specified. Note that SIGRTMIN +is often blocked, so it is better to use (at least) SIGRTMIN + 1. Implementation expectations (features and bugs :-)) --------------------------- @@ -78,10 +79,10 @@ act.sa_sigaction = handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; - sigaction(SIGRTMIN, &act, NULL); + sigaction(SIGRTMIN + 1, &act, NULL); fd = open(".", O_RDONLY); - fcntl(fd, F_SETSIG, SIGRTMIN); + fcntl(fd, F_SETSIG, SIGRTMIN + 1); fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT); /* we will now be notified if any of the files in "." is modified or new files are created */ diff -Nru a/Documentation/firmware_class/README b/Documentation/firmware_class/README --- a/Documentation/firmware_class/README Mon Aug 18 22:21:04 2003 +++ b/Documentation/firmware_class/README Mon Aug 18 22:21:04 2003 @@ -15,6 +15,71 @@ 3) Some people, like the Debian crowd, don't consider some firmware free enough and remove entire drivers (e.g.: keyspan). + High level behavior (mixed): + ============================ + + kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device) + + userspace: + - /sys/class/firmware/xxx/{loading,data} appear. + - hotplug gets called with a firmware identifier in $FIRMWARE + and the usual hotplug environment. + - hotplug: echo 1 > /sys/class/firmware/xxx/loading + + kernel: Discard any previous partial load. + + userspace: + - hotplug: cat appropriate_firmware_image > \ + /sys/class/firmware/xxx/data + + kernel: grows a buffer in PAGE_SIZE increments to hold the image as it + comes in. + + userspace: + - hotplug: echo 0 > /sys/class/firmware/xxx/loading + + kernel: request_firmware() returns and the driver has the firmware + image in fw_entry->{data,size}. If something went wrong + request_firmware() returns non-zero and fw_entry is set to + NULL. + + kernel(driver): Driver code calls release_firmware(fw_entry) releasing + the firmware image and any related resource. + + High level behavior (driver code): + ================================== + + if(request_firmware(&fw_entry, $FIRMWARE, device) == 0) + copy_fw_to_device(fw_entry->data, fw_entry->size); + release(fw_entry); + + Sample/simple hotplug script: + ============================ + + # Both $DEVPATH and $FIRMWARE are already provided in the environment. + + HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/ + + echo 1 > /sysfs/$DEVPATH/loading + cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data + echo 0 > /sysfs/$DEVPATH/loading + + Random notes: + ============ + + - "echo -1 > /sys/class/firmware/xxx/loading" will cancel the load at + once and make request_firmware() return with error. + + - firmware_data_read() and firmware_loading_show() are just provided + for testing and completeness, they are not called in normal use. + + - There is also /sys/class/firmware/timeout which holds a timeout in + seconds for the whole load operation. + + - request_firmware_nowait() is also provided for convenience in + non-user contexts. + + about in-kernel persistence: --------------------------- Under some circumstances, as explained below, it would be interesting to keep @@ -56,3 +121,4 @@ Note: If persistence is implemented on top of initramfs, register_firmware() may not be appropriate. + diff -Nru a/Documentation/hw_random.txt b/Documentation/hw_random.txt --- a/Documentation/hw_random.txt Mon Aug 18 22:21:04 2003 +++ b/Documentation/hw_random.txt Mon Aug 18 22:21:04 2003 @@ -1,17 +1,17 @@ - Hardware driver for Intel i810 Random Number Generator (RNG) + Hardware driver for Intel/AMD/VIA Random Number Generators (RNG) Copyright 2000,2001 Jeff Garzik Copyright 2000,2001 Philipp Rumpf Introduction: - The i810_rng device driver is software that makes use of a - special hardware feature on the Intel i8xx-based chipsets, + The hw_random device driver is software that makes use of a + special hardware feature on your CPU or motherboard, a Random Number Generator (RNG). In order to make effective use of this device driver, you should download the support software as well. Download the - latest version of the "intel-rng-tools" package from the - i810_rng driver's official Web site: + latest version of the "rng-tools" package from the + hw_random driver's official Web site: http://sourceforge.net/projects/gkernel/ @@ -29,14 +29,14 @@ Character driver. Using the standard open() and read() system calls, you can read random data from - the i810 RNG device. This data is NOT CHECKED by any + the hardware RNG device. This data is NOT CHECKED by any fitness tests, and could potentially be bogus (if the hardware is faulty or has been tampered with). Data is only output if the hardware "has-data" flag is set, but nevertheless a security-conscious person would run fitness tests on the data before assuming it is truly random. - /dev/intel_rng is char device major 10, minor 183. + /dev/hwrandom is char device major 10, minor 183. Driver notes: @@ -69,6 +69,10 @@ did the "brains" and all the testing. Change history: + + Version 1.0.0: + * Merge Intel, AMD, VIA RNG drivers into one. + Further changelog in BitKeeper. Version 0.9.8: * Support other i8xx chipsets by adding 82801E detection diff -Nru a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt --- a/Documentation/kbuild/kconfig-language.txt Mon Aug 18 22:21:02 2003 +++ b/Documentation/kbuild/kconfig-language.txt Mon Aug 18 22:21:02 2003 @@ -124,8 +124,8 @@ '!=' (3) '(' ')' (4) '!' (5) - '||' (6) - '&&' (7) + '&&' (6) + '||' (7) Expressions are listed in decreasing order of precedence. diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Mon Aug 18 22:21:06 2003 +++ b/Documentation/kernel-parameters.txt Mon Aug 18 22:21:06 2003 @@ -85,7 +85,10 @@ See also Documentation/scsi/ncr53c7xx.txt. acpi= [HW,ACPI] Advanced Configuration and Power Interface - Format: off[,<...>] + Format: { force | off | ht } + force -- enables ACPI for systems with default off + off -- disabled ACPI for systems with default on + ht -- run only enough ACPI to enable Hyper Threading See also Documentation/pm.txt. ad1816= [HW,OSS] @@ -612,8 +615,6 @@ no-hlt [BUGS=IA-32] Tells the kernel that the hlt instruction doesn't work correctly and not to use it. - - noht [SMP,IA-32] Disables P4 Xeon(tm) HyperThreading. noirqdebug [IA-32] Disables the code which attempts to detect and disable unhandled interrupt sources. diff -Nru a/Documentation/networking/8139too.txt b/Documentation/networking/8139too.txt --- a/Documentation/networking/8139too.txt Mon Aug 18 22:21:04 2003 +++ b/Documentation/networking/8139too.txt Mon Aug 18 22:21:04 2003 @@ -93,6 +93,7 @@ --------------- AOpen ALN-325C AT-2500TX 10/100 PCI Fast Ethernet Network Adapter Card +D-Link DFE-530TX Cnet CNF401 'SinglePoint' 10/100 Base-TX Genius GF 100TXR4 Fast Ethernet 10/100M PCI Network Card KTI KF-230TX diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Mon Aug 18 22:21:04 2003 +++ b/MAINTAINERS Mon Aug 18 22:21:04 2003 @@ -717,6 +717,12 @@ M: viro@math.psu.edu S: Maintained +FIRMWARE LOADER (request_firmware) +P: Manuel Estrada Sainz +M: ranty@debian.org +L: linux-kernel@vger.kernel.org +S: Maintained + FPU EMULATOR P: Bill Metzenthen M: billm@suburbia.net @@ -1636,13 +1642,13 @@ SCSI SUBSYSTEM P: James E.J. Bottomley -M: James.Bottomley@HansenPartnership.com +M: James.Bottomley@SteelEye.com L: linux-scsi@vger.kernel.org S: Maintained SCSI TAPE DRIVER P: Kai Mäkisara -M: Kai.Makisara@metla.fi +M: Kai.Makisara@kolumbus.fi L: linux-scsi@vger.kernel.org S: Maintained @@ -1656,6 +1662,16 @@ P: Christer Weinigel M: christer@weinigel.se W: http://www.weinigel.se +S: Supported + +SELINUX SECURITY MODULE +P: Stephen Smalley +M: sds@epoch.ncsc.mil +P: James Morris +M: jmorris@redhat.com +L: linux-kernel@vger.kernel.org (kernel issues) +L: selinux@tycho.nsa.gov (general discussion) +W: http://www.nsa.gov/selinux S: Supported SGI VISUAL WORKSTATION 320 AND 540 diff -Nru a/Makefile b/Makefile --- a/Makefile Mon Aug 18 22:21:04 2003 +++ b/Makefile Mon Aug 18 22:21:04 2003 @@ -243,17 +243,15 @@ comma := , depfile = $(subst $(comma),_,$(@D)/.$(@F).d) -noconfig_targets := xconfig gconfig menuconfig config oldconfig randconfig \ - defconfig allyesconfig allnoconfig allmodconfig \ - clean mrproper distclean rpm \ - help tags TAGS cscope %docs \ - checkconfig checkhelp checkincludes +# Files to ignore in find ... statements RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS +# =========================================================================== +# Rules shared between *config targets and build targets + # Helpers built in scripts/ -# --------------------------------------------------------------------------- scripts/docproc scripts/fixdep scripts/split-include : scripts ; @@ -261,9 +259,49 @@ scripts: $(Q)$(MAKE) $(build)=scripts -# Objects we will link into vmlinux / subdirs we need to visit -# --------------------------------------------------------------------------- +# To make sure we do not include .config for any of the *config targets +# catch them early, and hand them over to scripts/kconfig/Makefile +# It is allowed to specify more targets when calling make, including +# mixing *config targets and build targets. +# For example 'make oldconfig all'. +# Detect when mixed targets is specified, and make a second invocation +# of make so .config is not included in this case either (for *config). + +config-targets := 0 +mixed-targets := 0 +ifneq ($(filter config %config,$(MAKECMDGOALS)),) + config-targets := 1 + ifneq ($(filter-out config %config,$(MAKECMDGOALS)),) + mixed-targets := 1 + endif +endif + +ifeq ($(mixed-targets),1) +# =========================================================================== +# We're called with mixed targets (*config and build targets). +# Handle them one by one. + +%:: FORCE + $(Q)$(MAKE) $@ + +else +ifeq ($(config-targets),1) +# =========================================================================== +# *config targets only - make sure prerequisites are updated, and descend +# in scripts/kconfig to make the *config target + +%config: scripts/fixdep FORCE + $(Q)$(MAKE) $(build)=scripts/kconfig $@ +config : scripts/fixdep FORCE + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + +else +# =========================================================================== +# Build targets only - this includes vmlinux, arch specific targets, clean +# targets and others. In general all targets except *config targets. + +# Objects we will link into vmlinux / subdirs we need to visit init-y := init/ drivers-y := drivers/ sound/ net-y := net/ @@ -271,14 +309,8 @@ core-y := usr/ SUBDIRS := -ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),) - -export include_config := 1 - -include .config -endif - include arch/$(ARCH)/Makefile # Let architecture Makefiles change CPPFLAGS if needed @@ -304,10 +336,8 @@ libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) libs-y := $(libs-y1) $(libs-y2) -ifdef include_config - # Here goes the main Makefile -# =========================================================================== +# --------------------------------------------------------------------------- # # If the user gave a *config target, it'll be handled in another # section below, since in this case we cannot include .config @@ -388,7 +418,7 @@ $(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map endef -LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s +LDFLAGS_vmlinux += -T arch/$(ARCH)/kernel/vmlinux.lds.s # Generate section listing all symbols and add it into vmlinux # It's a three stage process: @@ -414,23 +444,23 @@ .tmp_kallsyms%.S: .tmp_vmlinux% $(call cmd,kallsyms) -.tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE +.tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/kernel/vmlinux.lds.s FORCE +$(call if_changed_rule,vmlinux__) -.tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/vmlinux.lds.s FORCE +.tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/kernel/vmlinux.lds.s FORCE $(call if_changed_rule,vmlinux__) endif # Finally the vmlinux rule -vmlinux: $(vmlinux-objs) $(kallsyms.o) arch/$(ARCH)/vmlinux.lds.s FORCE +vmlinux: $(vmlinux-objs) $(kallsyms.o) arch/$(ARCH)/kernel/vmlinux.lds.s FORCE $(call if_changed_rule,vmlinux) # The actual objects are generated when descending, # make sure no implicit rule kicks in -$(sort $(vmlinux-objs)): $(SUBDIRS) ; +$(sort $(vmlinux-objs)) arch/$(ARCH)/kernel/vmlinux.lds.s: $(SUBDIRS) ; # Handle descending into subdirectories listed in $(SUBDIRS) @@ -453,15 +483,10 @@ endif $(if $(CONFIG_MODULES),$(Q)mkdir -p $(MODVERDIR)) -# This can be used by arch/$ARCH/Makefile to preprocess -# their vmlinux.lds.S file - -AFLAGS_vmlinux.lds.o += -P -C -U$(ARCH) +# Leave this as default for preprocessing vmlinux.lds.S, which is now +# done in arch/$(ARCH)/kernel/Makefile -arch/$(ARCH)/vmlinux.lds.s: %.s: %.S scripts FORCE - $(call if_changed_dep,as_s_S) - -targets += arch/$(ARCH)/vmlinux.lds.s +export AFLAGS_vmlinux.lds.o += -P -C -U$(ARCH) # Single targets # --------------------------------------------------------------------------- @@ -608,72 +633,6 @@ echo "#endif" ) endef -else # ifdef include_config - -ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),) - -# Targets which don't need .config -# =========================================================================== -# -# These targets basically have their own Makefile - not quite, but at -# least its own exclusive section in the same Makefile. The reason for -# this is the following: -# To know the configuration, the main Makefile has to include -# .config. That's a obviously a problem when .config doesn't exist -# yet, but that could be kludged around with only including it if it -# exists. -# However, the larger problem is: If you run make *config, make will -# include the old .config, then execute your *config. It will then -# notice that a piece it included (.config) did change and restart from -# scratch. Which will cause execution of *config again. You get the -# picture. -# If we don't explicitly let the Makefile know that .config is changed -# by *config (the old way), it won't reread .config after *config, -# thus working with possibly stale values - we don't that either. -# -# So we divide things: This part here is for making *config targets, -# and other targets which should work when no .config exists yet. -# The main part above takes care of the rest after a .config exists. - -# Kernel configuration -# --------------------------------------------------------------------------- - -.PHONY: oldconfig xconfig gconfig menuconfig config \ - make_with_config rpm - -scripts/kconfig/conf scripts/kconfig/mconf scripts/kconfig/qconf scripts/kconfig/gconf: scripts/fixdep FORCE - $(Q)$(MAKE) $(build)=scripts/kconfig $@ - -xconfig: scripts/kconfig/qconf - ./scripts/kconfig/qconf arch/$(ARCH)/Kconfig - -gconfig: scripts/kconfig/gconf - ./scripts/kconfig/gconf arch/$(ARCH)/Kconfig - -menuconfig: scripts/kconfig/mconf - $(Q)$(MAKE) $(build)=scripts/lxdialog - ./scripts/kconfig/mconf arch/$(ARCH)/Kconfig - -config: scripts/kconfig/conf - ./scripts/kconfig/conf arch/$(ARCH)/Kconfig - -oldconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -o arch/$(ARCH)/Kconfig - -randconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -r arch/$(ARCH)/Kconfig - -allyesconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -y arch/$(ARCH)/Kconfig - -allnoconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -n arch/$(ARCH)/Kconfig - -allmodconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -m arch/$(ARCH)/Kconfig - -defconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -d arch/$(ARCH)/Kconfig ### # Cleaning is done on three levels. @@ -778,6 +737,8 @@ # RPM target # --------------------------------------------------------------------------- +.PHONY: rpm + # If you do a make spec before packing the tarball you can rpm -ta it spec: @@ -813,14 +774,7 @@ @echo ' mrproper - remove all generated files + config + various backup files' @echo '' @echo 'Configuration targets:' - @echo ' oldconfig - Update current config utilising a line-oriented program' - @echo ' menuconfig - Update current config utilising a menu based program' - @echo ' xconfig - Update current config utilising a QT based front-end' - @echo ' gconfig - Update current config utilising a GTK based front-end' - @echo ' defconfig - New config with default answer to all options' - @echo ' allmodconfig - New config selecting modules when possible' - @echo ' allyesconfig - New config where all options are accepted with yes' - @echo ' allnoconfig - New minimal config' + @$(MAKE) -f scripts/kconfig/Makefile help @echo '' @echo 'Other generic targets:' @echo ' all - Build all targets marked with [*]' @@ -833,7 +787,7 @@ @echo ' tags/TAGS - Generate tags file for editors' @echo '' @echo 'Documentation targets:' - @$(MAKE) --no-print-directory -f Documentation/DocBook/Makefile dochelp + @$(MAKE) -f Documentation/DocBook/Makefile dochelp @echo '' @echo 'Architecture specific targets ($(ARCH)):' @$(if $(archhelp),$(archhelp),\ @@ -864,17 +818,8 @@ -name '*.[hcS]' -type f -print | sort \ | xargs $(PERL) -w scripts/checkincludes.pl -else # ifneq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),) - -# We're called with both targets which do and do not need -# .config included. Handle them one after the other. -# =========================================================================== - -%:: FORCE - $(Q)$(MAKE) $@ - -endif # ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),) -endif # ifdef include_config +endif #ifeq ($(config-targets),1) +endif #ifeq ($(mixed-targets),1) # FIXME Should go into a make.lib or something # =========================================================================== @@ -882,9 +827,6 @@ a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) $(NOSTDINC_FLAGS) \ $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) -quiet_cmd_as_s_S = CPP $@ -cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< - quiet_cmd_as_o_S = AS $@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< @@ -894,6 +836,7 @@ cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) + $(cmd_files): ; # Do not try to update included dependency files include $(cmd_files) endif diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig --- a/arch/alpha/Kconfig Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/Kconfig Mon Aug 18 22:21:05 2003 @@ -556,6 +556,24 @@ config VERBOSE_MCHECK bool "Verbose Machine Checks" +config VERBOSE_MCHECK_ON + int "Verbose Printing Mode (0=off, 1=on, 2=all)" + depends on VERBOSE_MCHECK + default 1 + ---help--- + This option allows the default printing mode to be set, and then + possibly overridden by a boot command argument. + + For example, if one wanted the option of printing verbose + machine checks, but wanted the default to be as if verbose + machine check printing was turned off, then one would choose + the printing mode to be 0. Then, upon reboot, one could add + the boot command line "verbose_mcheck=1" to get the normal + verbose machine check printing, or "verbose_mcheck=2" to get + the maximum information available. + + Take the default (1) unless you want more control or more info. + source "drivers/pci/Kconfig" source "drivers/eisa/Kconfig" diff -Nru a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c --- a/arch/alpha/boot/bootpz.c Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/boot/bootpz.c Mon Aug 18 22:21:01 2003 @@ -29,8 +29,17 @@ /* FIXME FIXME FIXME */ +/* + WARNING NOTE + + It is very possible that turning on additional messages may cause + kernel image corruption due to stack usage to do the printing. + +*/ + #undef DEBUG_CHECK_RANGE -#define DEBUG_ADDRESSES +#undef DEBUG_ADDRESSES +#undef DEBUG_LAST_STEPS #define DEBUG_SP(x) \ {register long sp asm("30"); srm_printk("%s (sp=%lx)\n", x, sp);} @@ -433,15 +442,25 @@ } /* Clear the zero page, then move the argument list in. */ +#ifdef DEBUG_LAST_STEPS + srm_printk("Preparing ZERO_PGE...\n"); +#endif memset((char*)ZERO_PGE, 0, PAGE_SIZE); strcpy((char*)ZERO_PGE, envval); #ifdef INITRD_IMAGE_SIZE + +#ifdef DEBUG_LAST_STEPS + srm_printk("Preparing INITRD info...\n"); +#endif /* Finally, set the INITRD paramenters for the kernel. */ ((long *)(ZERO_PGE+256))[0] = initrd_image_start; ((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE; #endif /* INITRD_IMAGE_SIZE */ +#ifdef DEBUG_LAST_STEPS + srm_printk("Doing 'runkernel()'...\n"); +#endif runkernel(); } diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile --- a/arch/alpha/kernel/Makefile Mon Aug 18 22:21:03 2003 +++ b/arch/alpha/kernel/Makefile Mon Aug 18 22:21:03 2003 @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -extra-y := head.o +extra-y := head.o vmlinux.lds.s EXTRA_AFLAGS := $(CFLAGS) EXTRA_CFLAGS := -Werror -Wno-sign-compare diff -Nru a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c --- a/arch/alpha/kernel/core_cia.c Mon Aug 18 22:21:04 2003 +++ b/arch/alpha/kernel/core_cia.c Mon Aug 18 22:21:04 2003 @@ -47,15 +47,6 @@ #define vip volatile int * -/* Save CIA configuration data as the console had it set up. */ - -struct -{ - unsigned int w_base; - unsigned int w_mask; - unsigned int t_base; -} saved_config[4] __attribute((common)); - /* * Given a bus, device, and function number, compute resulting * configuration space address. It is therefore not safe to have @@ -567,6 +558,77 @@ goto exit; } +#if defined(ALPHA_RESTORE_SRM_SETUP) +/* Save CIA configuration data as the console had it set up. */ +struct +{ + unsigned int hae_mem; + unsigned int hae_io; + unsigned int pci_dac_offset; + unsigned int err_mask; + unsigned int cia_ctrl; + unsigned int cia_cnfg; + struct { + unsigned int w_base; + unsigned int w_mask; + unsigned int t_base; + } window[4]; +} saved_config __attribute((common)); + +void +cia_save_srm_settings(int is_pyxis) +{ + int i; + + /* Save some important registers. */ + saved_config.err_mask = *(vip)CIA_IOC_ERR_MASK; + saved_config.cia_ctrl = *(vip)CIA_IOC_CIA_CTRL; + saved_config.hae_mem = *(vip)CIA_IOC_HAE_MEM; + saved_config.hae_io = *(vip)CIA_IOC_HAE_IO; + saved_config.pci_dac_offset = *(vip)CIA_IOC_PCI_W_DAC; + + if (is_pyxis) + saved_config.cia_cnfg = *(vip)CIA_IOC_CIA_CNFG; + else + saved_config.cia_cnfg = 0; + + /* Save DMA windows configuration. */ + for (i = 0; i < 4; i++) { + saved_config.window[i].w_base = *(vip)CIA_IOC_PCI_Wn_BASE(i); + saved_config.window[i].w_mask = *(vip)CIA_IOC_PCI_Wn_MASK(i); + saved_config.window[i].t_base = *(vip)CIA_IOC_PCI_Tn_BASE(i); + } + mb(); +} + +void +cia_restore_srm_settings(void) +{ + int i; + + for (i = 0; i < 4; i++) { + *(vip)CIA_IOC_PCI_Wn_BASE(i) = saved_config.window[i].w_base; + *(vip)CIA_IOC_PCI_Wn_MASK(i) = saved_config.window[i].w_mask; + *(vip)CIA_IOC_PCI_Tn_BASE(i) = saved_config.window[i].t_base; + } + + *(vip)CIA_IOC_HAE_MEM = saved_config.hae_mem; + *(vip)CIA_IOC_HAE_IO = saved_config.hae_io; + *(vip)CIA_IOC_PCI_W_DAC = saved_config.pci_dac_offset; + *(vip)CIA_IOC_ERR_MASK = saved_config.err_mask; + *(vip)CIA_IOC_CIA_CTRL = saved_config.cia_ctrl; + + if (saved_config.cia_cnfg) /* Must be pyxis. */ + *(vip)CIA_IOC_CIA_CNFG = saved_config.cia_cnfg; + + mb(); +} +#else /* ALPHA_RESTORE_SRM_SETUP */ +#define cia_save_srm_settings(p) do {} while (0) +#define cia_restore_srm_settings() do {} while (0) +#endif /* ALPHA_RESTORE_SRM_SETUP */ + + static void __init do_init_arch(int is_pyxis) { @@ -577,6 +639,9 @@ printk("pci: cia revision %d%s\n", cia_rev, is_pyxis ? " (pyxis)" : ""); + if (alpha_using_srm) + cia_save_srm_settings(is_pyxis); + /* Set up error reporting. */ temp = *(vip)CIA_IOC_ERR_MASK; temp &= ~(CIA_ERR_CPU_PE | CIA_ERR_MEM_NEM | CIA_ERR_PA_PTE_INV @@ -646,24 +711,6 @@ hose->dense_io_base = CIA_BW_IO - IDENT_ADDR; } - /* Save CIA configuration data as the console had it set up. */ - - saved_config[0].w_base = *(vip)CIA_IOC_PCI_W0_BASE; - saved_config[0].w_mask = *(vip)CIA_IOC_PCI_W0_MASK; - saved_config[0].t_base = *(vip)CIA_IOC_PCI_T0_BASE; - - saved_config[1].w_base = *(vip)CIA_IOC_PCI_W1_BASE; - saved_config[1].w_mask = *(vip)CIA_IOC_PCI_W1_MASK; - saved_config[1].t_base = *(vip)CIA_IOC_PCI_T1_BASE; - - saved_config[2].w_base = *(vip)CIA_IOC_PCI_W2_BASE; - saved_config[2].w_mask = *(vip)CIA_IOC_PCI_W2_MASK; - saved_config[2].t_base = *(vip)CIA_IOC_PCI_T2_BASE; - - saved_config[3].w_base = *(vip)CIA_IOC_PCI_W3_BASE; - saved_config[3].w_mask = *(vip)CIA_IOC_PCI_W3_MASK; - saved_config[3].t_base = *(vip)CIA_IOC_PCI_T3_BASE; - /* * Set up the PCI to main memory translation windows. * @@ -761,21 +808,8 @@ void cia_kill_arch(int mode) { - *(vip)CIA_IOC_PCI_W0_BASE = saved_config[0].w_base; - *(vip)CIA_IOC_PCI_W0_MASK = saved_config[0].w_mask; - *(vip)CIA_IOC_PCI_T0_BASE = saved_config[0].t_base; - - *(vip)CIA_IOC_PCI_W1_BASE = saved_config[1].w_base; - *(vip)CIA_IOC_PCI_W1_MASK = saved_config[1].w_mask; - *(vip)CIA_IOC_PCI_T1_BASE = saved_config[1].t_base; - - *(vip)CIA_IOC_PCI_W2_BASE = saved_config[2].w_base; - *(vip)CIA_IOC_PCI_W2_MASK = saved_config[2].w_mask; - *(vip)CIA_IOC_PCI_T2_BASE = saved_config[2].t_base; - - *(vip)CIA_IOC_PCI_W3_BASE = saved_config[3].w_base; - *(vip)CIA_IOC_PCI_W3_MASK = saved_config[3].w_mask; - *(vip)CIA_IOC_PCI_T3_BASE = saved_config[3].t_base; + if (alpha_using_srm) + cia_restore_srm_settings(); } void __init @@ -1065,7 +1099,8 @@ printk(KERN_CRIT " Command: %s, Parity bit: %d\n", cmd, par); printk(KERN_CRIT " Address: %#010lx, Mask: %#lx\n", addr, mask); } -#endif +#endif /* CONFIG_VERBOSE_MCHECK */ + static int cia_decode_mchk(unsigned long la_ptr) @@ -1080,6 +1115,9 @@ return 0; #ifdef CONFIG_VERBOSE_MCHECK + if (!alpha_verbose_mcheck) + return 1; + switch (ffs(cia->cia_err & 0xfff) - 1) { case 0: /* CIA_ERR_COR_ERR */ cia_decode_ecc_error(cia, "Corrected ECC error"); @@ -1152,7 +1190,7 @@ if (cia->cia_err & CIA_ERR_LOST_IOA_TIMEOUT) printk(KERN_CRIT "CIA lost machine check: " "I/O timeout\n"); -#endif +#endif /* CONFIG_VERBOSE_MCHECK */ return 1; } diff -Nru a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c --- a/arch/alpha/kernel/core_lca.c Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/kernel/core_lca.c Mon Aug 18 22:21:05 2003 @@ -242,7 +242,7 @@ lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); - *(vip)LCA_IOC_TBIA = 0; + *(vulp)LCA_IOC_TBIA = 0; mb(); } @@ -268,21 +268,25 @@ /* * Set up the PCI to main memory translation windows. * - * Window 0 is direct access 1GB at 1GB - * Window 1 is scatter-gather 8MB at 8MB (for isa) + * Mimic the SRM settings for the direct-map window. + * Window 0 is scatter-gather 8MB at 8MB (for isa). + * Window 1 is direct access 1GB at 1GB. + * + * Note that we do not try to save any of the DMA window CSRs + * before setting them, since we cannot read those CSRs on LCA. */ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); hose->sg_pci = NULL; __direct_map_base = 0x40000000; __direct_map_size = 0x40000000; - *(vulp)LCA_IOC_W_BASE0 = __direct_map_base | (2UL << 32); - *(vulp)LCA_IOC_W_MASK0 = (__direct_map_size - 1) & 0xfff00000; - *(vulp)LCA_IOC_T_BASE0 = 0; - - *(vulp)LCA_IOC_W_BASE1 = hose->sg_isa->dma_base | (3UL << 32); - *(vulp)LCA_IOC_W_MASK1 = (hose->sg_isa->size - 1) & 0xfff00000; - *(vulp)LCA_IOC_T_BASE1 = virt_to_phys(hose->sg_isa->ptes); + *(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32); + *(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000; + *(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes); + + *(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32); + *(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000; + *(vulp)LCA_IOC_T_BASE1 = 0; *(vulp)LCA_IOC_TB_ENA = 0x80; @@ -294,6 +298,15 @@ * data parity errors. */ *(vulp)LCA_IOC_PAR_DIS = 1UL<<5; + + /* + * Finally, set up for restoring the correct HAE if using SRM. + * Again, since we cannot read many of the CSRs on the LCA, + * one of which happens to be the HAE, we save the value that + * the SRM will expect... + */ + if (alpha_using_srm) + srm_hae = 0x80000000UL; } /* @@ -447,8 +460,8 @@ } /* Dump the logout area to give all info. */ -#if DEBUG_MCHECK > 1 - { +#ifdef CONFIG_VERBOSE_MCHECK + if (alpha_verbose_mcheck > 1) { unsigned long * ptr = (unsigned long *) la_ptr; long i; for (i = 0; i < el.c->size / sizeof(long); i += 2) { @@ -456,7 +469,7 @@ i*sizeof(long), ptr[i], ptr[i+1]); } } -#endif +#endif /* CONFIG_VERBOSE_MCHECK */ } /* diff -Nru a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c --- a/arch/alpha/kernel/core_marvel.c Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/kernel/core_marvel.c Mon Aug 18 22:21:01 2003 @@ -524,7 +524,7 @@ if (!io7_port->enabled) return addr; - if (hose->bus == pbus) { + if (!pbus->parent) { /* No parent means peer PCI bus. */ /* Don't support idsel > 20 on primary bus. */ if (devfn >= PCI_DEVFN(21, 0)) return addr; diff -Nru a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c --- a/arch/alpha/kernel/core_mcpcia.c Mon Aug 18 22:21:04 2003 +++ b/arch/alpha/kernel/core_mcpcia.c Mon Aug 18 22:21:04 2003 @@ -185,7 +185,7 @@ /* Type 1 configuration cycle for *ALL* busses. */ *type1 = 1; - if (hose->bus == pbus) + if (!pbus->parent) /* No parent means peer PCI bus. */ bus = 0; addr = (bus << 16) | (devfn << 8) | (where); addr <<= 5; /* swizzle for SPARSE */ diff -Nru a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c --- a/arch/alpha/kernel/core_t2.c Mon Aug 18 22:21:00 2003 +++ b/arch/alpha/kernel/core_t2.c Mon Aug 18 22:21:00 2003 @@ -557,9 +557,9 @@ struct pt_regs * regs) { int cpu = smp_processor_id(); -#if DEBUG_MCHECK > 0 +#ifdef CONFIG_VERBOSE_MCHECK struct el_common *mchk_header = (struct el_common *)la_ptr; -#endif /* DEBUG_MCHECK */ +#endif /* Clear the error before any reporting. */ mb(); @@ -580,39 +580,45 @@ * * Just dismiss it for now on this CPU... */ -#if DEBUG_MCHECK > 0 - printk("t2_machine_check(cpu%d): any_expected 0x%x -" - " (assumed) spurious -" - " code 0x%x\n", cpu, t2_mcheck_any_expected, - (unsigned int)mchk_header->code); -#endif /* DEBUG_MCHECK */ +#ifdef CONFIG_VERBOSE_MCHECK + if (alpha_verbose_mcheck > 1) { + printk("t2_machine_check(cpu%d): any_expected 0x%x -" + " (assumed) spurious -" + " code 0x%x\n", cpu, t2_mcheck_any_expected, + (unsigned int)mchk_header->code); + } +#endif return; } if (!mcheck_expected(cpu) && !t2_mcheck_any_expected) { if (t2_mcheck_last_taken & (1 << cpu)) { -#if DEBUG_MCHECK > 0 +#ifdef CONFIG_VERBOSE_MCHECK + if (alpha_verbose_mcheck > 1) { printk("t2_machine_check(cpu%d): last_taken 0x%x - " "unexpected mcheck - code 0x%x\n", cpu, t2_mcheck_last_taken, (unsigned int)mchk_header->code); -#endif /* DEBUG_MCHECK */ - t2_mcheck_last_taken = 0; - mb(); - return; + } +#endif + t2_mcheck_last_taken = 0; + mb(); + return; } else { t2_mcheck_last_taken = 0; mb(); } } -#if DEBUG_MCHECK > 0 - printk("%s t2_mcheck(cpu%d): last_taken 0x%x - " - "any_expected 0x%x - code 0x%x\n", - (mcheck_expected(cpu) ? "EX" : "UN"), cpu, - t2_mcheck_last_taken, t2_mcheck_any_expected, - (unsigned int)mchk_header->code); -#endif /* DEBUG_MCHECK */ +#ifdef CONFIG_VERBOSE_MCHECK + if (alpha_verbose_mcheck > 1) { + printk("%s t2_mcheck(cpu%d): last_taken 0x%x - " + "any_expected 0x%x - code 0x%x\n", + (mcheck_expected(cpu) ? "EX" : "UN"), cpu, + t2_mcheck_last_taken, t2_mcheck_any_expected, + (unsigned int)mchk_header->code); + } +#endif process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu)); } diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c --- a/arch/alpha/kernel/core_titan.c Mon Aug 18 22:21:02 2003 +++ b/arch/alpha/kernel/core_titan.c Mon Aug 18 22:21:02 2003 @@ -43,7 +43,6 @@ * BIOS32-style PCI interface: */ -#define DEBUG_MCHECK 0 /* 0 = minimum, 1 = debug, 2 = dump+dump */ #define DEBUG_CONFIG 0 #if DEBUG_CONFIG @@ -123,7 +122,7 @@ "pci_addr=0x%p, type1=0x%p)\n", bus, device_fn, where, pci_addr, type1)); - if (hose->bus == pbus) + if (!pbus->parent) /* No parent means peer PCI bus. */ bus = 0; *type1 = (bus != 0); diff -Nru a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c --- a/arch/alpha/kernel/core_tsunami.c Mon Aug 18 22:21:02 2003 +++ b/arch/alpha/kernel/core_tsunami.c Mon Aug 18 22:21:02 2003 @@ -45,7 +45,6 @@ * BIOS32-style PCI interface: */ -#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */ #define DEBUG_CONFIG 0 #if DEBUG_CONFIG @@ -100,8 +99,8 @@ DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, " "pci_addr=0x%p, type1=0x%p)\n", bus, device_fn, where, pci_addr, type1)); - - if (hose->bus == pbus) + + if (!pbus->parent) /* No parent means peer PCI bus. */ bus = 0; *type1 = (bus != 0); diff -Nru a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c --- a/arch/alpha/kernel/core_wildfire.c Mon Aug 18 22:21:00 2003 +++ b/arch/alpha/kernel/core_wildfire.c Mon Aug 18 22:21:00 2003 @@ -24,7 +24,6 @@ #include "proto.h" #include "pci_impl.h" -#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */ #define DEBUG_CONFIG 0 #define DEBUG_DUMP_REGS 0 #define DEBUG_DUMP_CONFIG 1 @@ -367,7 +366,7 @@ "pci_addr=0x%p, type1=0x%p)\n", bus, device_fn, where, pci_addr, type1)); - if (hose->bus == pbus) + if (!pbus->parent) /* No parent means peer PCI bus. */ bus = 0; *type1 = (bus != 0); diff -Nru a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c --- a/arch/alpha/kernel/err_titan.c Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/kernel/err_titan.c Mon Aug 18 22:21:05 2003 @@ -438,8 +438,9 @@ (unsigned int)vector, (int)smp_processor_id()); #ifdef CONFIG_VERBOSE_MCHECK - titan_process_logout_frame(mchk_header, 1); - dik_show_regs(regs, NULL); + titan_process_logout_frame(mchk_header, alpha_verbose_mcheck); + if (alpha_verbose_mcheck) + dik_show_regs(regs, NULL); #endif /* CONFIG_VERBOSE_MCHECK */ err_print_prefix = saved_err_prefix; diff -Nru a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c --- a/arch/alpha/kernel/irq_alpha.c Mon Aug 18 22:21:02 2003 +++ b/arch/alpha/kernel/irq_alpha.c Mon Aug 18 22:21:02 2003 @@ -130,9 +130,11 @@ * ignore it. */ -#if DEBUG_MCHECK > 0 - printk(KERN_CRIT "%s machine check %s\n", machine, - expected ? "expected." : "NOT expected!!!"); +#ifdef CONFIG_VERBOSE_MCHECK + if (alpha_verbose_mcheck > 1) { + printk(KERN_CRIT "%s machine check %s\n", machine, + expected ? "expected." : "NOT expected!!!"); + } #endif if (expected) { @@ -188,8 +190,8 @@ dik_show_regs(regs, NULL); -#if DEBUG_MCHECK > 1 - { +#ifdef CONFIG_VERBOSE_MCHECK + if (alpha_verbose_mcheck > 1) { /* Dump the logout area to give all info. */ unsigned long *ptr = (unsigned long *)la_ptr; long i; @@ -198,7 +200,7 @@ i*sizeof(long), ptr[i], ptr[i+1]); } } -#endif +#endif /* CONFIG_VERBOSE_MCHECK */ } /* diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c --- a/arch/alpha/kernel/pci.c Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/kernel/pci.c Mon Aug 18 22:21:01 2003 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "proto.h" @@ -44,7 +45,11 @@ const char pci_hae0_name[] = "HAE0"; /* Indicate whether we respect the PCI setup left by console. */ -int __initdata pci_probe_only; +/* + * Make this long-lived so that we know when shutting down + * whether we probed only or not. + */ +int pci_probe_only; /* * The PCI controller list. @@ -202,6 +207,52 @@ return str; } +#ifdef ALPHA_RESTORE_SRM_SETUP +static struct pdev_srm_saved_conf *srm_saved_configs; + +void __init +pdev_save_srm_config(struct pci_dev *dev) +{ + struct pdev_srm_saved_conf *tmp; + static int printed = 0; + + if (!alpha_using_srm || pci_probe_only) + return; + + if (!printed) { + printk(KERN_INFO "pci: enabling save/restore of SRM state\n"); + printed = 1; + } + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) { + printk(KERN_ERR "%s: kmalloc() failed!\n", __FUNCTION__); + return; + } + tmp->next = srm_saved_configs; + tmp->dev = dev; + + pci_save_state(dev, tmp->regs); + + srm_saved_configs = tmp; +} + +void +pci_restore_srm_config(void) +{ + struct pdev_srm_saved_conf *tmp; + + /* No need to restore if probed only. */ + if (pci_probe_only) + return; + + /* Restore SRM config. */ + for (tmp = srm_saved_configs; tmp; tmp = tmp->next) { + pci_restore_state(tmp->dev, tmp->regs); + } +} +#endif + void __init pcibios_fixup_resource(struct resource *res, struct resource *root) { @@ -260,6 +311,8 @@ for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { struct pci_dev *dev = pci_dev_b(ln); + + pdev_save_srm_config(dev); if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) pcibios_fixup_device_resources(dev, bus); } @@ -269,8 +322,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); - - /* ??? FIXME -- record old value for shutdown. */ } /* Most Alphas have straight-forward swizzling needs. */ @@ -278,20 +329,16 @@ u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) { - struct pci_controller *hose = dev->sysdata; - - if (dev->bus != hose->bus) { - u8 pin = *pinp; - do { - pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); - /* Move up the chain of bridges. */ - dev = dev->bus->self; - } while (dev->bus->parent); - *pinp = pin; + u8 pin = *pinp; - /* The slot is the slot of the last bridge. */ - } + while (dev->bus->parent) { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* Move up the chain of bridges. */ + dev = dev->bus->self; + } + *pinp = pin; + /* The slot is the slot of the last bridge. */ return PCI_SLOT(dev->devfn); } diff -Nru a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h --- a/arch/alpha/kernel/pci_impl.h Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/kernel/pci_impl.h Mon Aug 18 22:21:05 2003 @@ -147,6 +147,33 @@ unsigned int align_entry; }; +#if defined(CONFIG_ALPHA_SRM) && \ + (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA)) +# define NEED_SRM_SAVE_RESTORE +#else +# undef NEED_SRM_SAVE_RESTORE +#endif + +#if defined(CONFIG_ALPHA_GENERIC) || defined(NEED_SRM_SAVE_RESTORE) +# define ALPHA_RESTORE_SRM_SETUP +#else +# undef ALPHA_RESTORE_SRM_SETUP +#endif + +#ifdef ALPHA_RESTORE_SRM_SETUP +/* Store PCI device configuration left by SRM here. */ +struct pdev_srm_saved_conf +{ + struct pdev_srm_saved_conf *next; + struct pci_dev *dev; + u32 regs[16]; +}; + +extern void pci_restore_srm_config(void); +#else +#define pdev_save_srm_config(dev) do {} while (0) +#define pci_restore_srm_config() do {} while (0) +#endif /* The hose list. */ extern struct pci_controller *hose_head, **hose_tail; diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c --- a/arch/alpha/kernel/process.c Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/kernel/process.c Mon Aug 18 22:21:05 2003 @@ -129,7 +129,7 @@ /* This has the effect of resetting the VGA video origin. */ take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); #endif - /* reset_for_srm(); */ + pci_restore_srm_config(); set_hae(srm_hae); } diff -Nru a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h --- a/arch/alpha/kernel/proto.h Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/kernel/proto.h Mon Aug 18 22:21:01 2003 @@ -110,6 +110,9 @@ /* setup.c */ extern unsigned long srm_hae; extern int boot_cpuid; +#ifdef CONFIG_VERBOSE_MCHECK +extern unsigned long alpha_verbose_mcheck; +#endif /* srmcons.c */ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) @@ -204,8 +207,6 @@ #define mcheck_taken(cpu) ((void)(cpu), __mcheck_info.taken) #define mcheck_extra(cpu) ((void)(cpu), __mcheck_info.extra) #endif - -#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */ extern void process_mcheck_info(unsigned long vector, unsigned long la_ptr, struct pt_regs *regs, const char *machine, diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c --- a/arch/alpha/kernel/setup.c Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/kernel/setup.c Mon Aug 18 22:21:01 2003 @@ -63,6 +63,12 @@ struct hwrpb_struct *hwrpb; unsigned long srm_hae; +#ifdef CONFIG_VERBOSE_MCHECK +/* 0=minimum, 1=verbose, 2=all */ +/* These can be overridden via the command line, ie "verbose_mcheck=2") */ +unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON; +#endif + /* Which processor we booted from. */ int boot_cpuid; @@ -538,6 +544,12 @@ get_mem_size_limit(p+9) << PAGE_SHIFT; continue; } +#ifdef CONFIG_VERBOSE_MCHECK + if (strncmp(p, "verbose_mcheck=", 15) == 0) { + alpha_verbose_mcheck = simple_strtol(p+15, NULL, 0); + continue; + } +#endif } /* Replace the command line, now that we've killed it with strsep. */ @@ -596,6 +608,38 @@ type_name, (*var_name ? " variation " : ""), var_name, alpha_mv.vector_name, (alpha_using_srm ? "SRM" : "MILO")); + + printk("Major Options: " +#ifdef CONFIG_SMP + "SMP " +#endif +#ifdef CONFIG_ALPHA_EV56 + "EV56 " +#endif +#ifdef CONFIG_ALPHA_EV67 + "EV67 " +#endif +#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS + "LEGACY_START " +#endif +#ifdef CONFIG_VERBOSE_MCHECK + "VERBOSE_MCHECK " +#endif + +#ifdef CONFIG_DISCONTIGMEM + "DISCONTIGMEM " +#ifdef CONFIG_NUMA + "NUMA " +#endif +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + "DEBUG_SPINLOCK " +#endif +#ifdef CONFIG_MAGIC_SYSRQ + "MAGIC_SYSRQ " +#endif + "\n"); printk("Command line: %s\n", command_line); diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c --- a/arch/alpha/kernel/smp.c Mon Aug 18 22:21:02 2003 +++ b/arch/alpha/kernel/smp.c Mon Aug 18 22:21:02 2003 @@ -71,7 +71,7 @@ /* Which cpus ids came online. */ unsigned long cpu_present_mask; -volatile unsigned long cpu_online_map; +cpumask_t cpu_online_map; /* cpus reported in the hwrpb */ static unsigned long hwrpb_cpu_present_mask __initdata = 0; @@ -132,7 +132,7 @@ { int cpuid = hard_smp_processor_id(); - if (test_and_set_bit(cpuid, &cpu_online_map)) { + if (cpu_test_and_set(cpuid, cpu_online_map)) { printk("??, cpu 0x%x already present??\n", cpuid); BUG(); } @@ -575,8 +575,8 @@ /* * 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); + cpu_set(smp_processor_id(), cpu_present_mask); + cpu_set(smp_processor_id(), cpu_online_map); } int __devinit diff -Nru a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c --- a/arch/alpha/kernel/sys_alcor.c Mon Aug 18 22:21:06 2003 +++ b/arch/alpha/kernel/sys_alcor.c Mon Aug 18 22:21:06 2003 @@ -223,6 +223,7 @@ { cia_kill_arch(mode); +#ifndef ALPHA_RESTORE_SRM_SETUP switch(mode) { case LINUX_REBOOT_CMD_RESTART: /* Who said DEC engineer's have no sense of humor? ;-) */ @@ -238,6 +239,29 @@ } halt(); +#endif +} + +static void __init +alcor_init_pci(void) +{ + struct pci_dev *dev; + + cia_init_pci(); + + /* + * Now we can look to see if we are really running on an XLT-type + * motherboard, by looking for a 21040 TULIP in slot 6, which is + * built into XLT and BRET/MAVERICK, but not available on ALCOR. + */ + dev = pci_find_device(PCI_VENDOR_ID_DEC, + PCI_DEVICE_ID_DEC_TULIP, + NULL); + if (dev && dev->devfn == PCI_DEVFN(6,0)) { + alpha_mv.sys.cia.gru_int_req_bits = XLT_GRU_INT_REQ_BITS; + printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n", + __FUNCTION__); + } } @@ -262,7 +286,7 @@ .init_arch = cia_init_arch, .init_irq = alcor_init_irq, .init_rtc = common_init_rtc, - .init_pci = cia_init_pci, + .init_pci = alcor_init_pci, .kill_arch = alcor_kill_arch, .pci_map_irq = alcor_map_irq, .pci_swizzle = common_swizzle, @@ -290,7 +314,7 @@ .init_arch = cia_init_arch, .init_irq = alcor_init_irq, .init_rtc = common_init_rtc, - .init_pci = cia_init_pci, + .init_pci = alcor_init_pci, .kill_arch = alcor_kill_arch, .pci_map_irq = alcor_map_irq, .pci_swizzle = common_swizzle, diff -Nru a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c --- a/arch/alpha/kernel/sys_dp264.c Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/kernel/sys_dp264.c Mon Aug 18 22:21:01 2003 @@ -463,7 +463,7 @@ struct pci_controller *hose = dev->sysdata; int slot, pin = *pinp; - if (hose->bus == dev->bus) { + if (!dev->bus->parent) { slot = PCI_SLOT(dev->devfn); } /* Check for the built-in bridge on hose 1. */ diff -Nru a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c --- a/arch/alpha/kernel/sys_marvel.c Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/kernel/sys_marvel.c Mon Aug 18 22:21:05 2003 @@ -33,6 +33,13 @@ # error NR_IRQS < MARVEL_NR_IRQS !!! #endif +/* ??? Should probably be generic. */ +#ifdef CONFIG_PCI_NAMES +#define pci_pretty_name(x) ((x)->pretty_name) +#else +#define pci_pretty_name(x) "" +#endif + /* * Interrupt handling. @@ -378,7 +385,7 @@ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), hose->index, - dev->dev.name); + pci_pretty_name (dev)); printk(" %d message(s) from 0x%04x\n", 1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4), msg_dat); diff -Nru a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c --- a/arch/alpha/kernel/sys_miata.c Mon Aug 18 22:21:03 2003 +++ b/arch/alpha/kernel/sys_miata.c Mon Aug 18 22:21:03 2003 @@ -240,6 +240,7 @@ { cia_kill_arch(mode); +#ifndef ALPHA_RESTORE_SRM_SETUP switch(mode) { case LINUX_REBOOT_CMD_RESTART: /* Who said DEC engineers have no sense of humor? ;-) */ @@ -255,6 +256,7 @@ } halt(); +#endif } diff -Nru a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c --- a/arch/alpha/kernel/sys_noritake.c Mon Aug 18 22:21:01 2003 +++ b/arch/alpha/kernel/sys_noritake.c Mon Aug 18 22:21:01 2003 @@ -218,7 +218,7 @@ { 16+2, 16+2, 16+3, 32+2, 32+3}, /* IdSel 22, slot 0 */ { 16+4, 16+4, 16+5, 32+4, 32+5}, /* IdSel 23, slot 1 */ { 16+6, 16+6, 16+7, 32+6, 32+7}, /* IdSel 24, slot 2 */ - { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */ + { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */ /* The following 5 are actually on PCI bus 1, which is across the built-in bridge of the NORITAKE only. */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */ diff -Nru a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c --- a/arch/alpha/kernel/sys_sio.c Mon Aug 18 22:21:00 2003 +++ b/arch/alpha/kernel/sys_sio.c Mon Aug 18 22:21:00 2003 @@ -36,6 +36,14 @@ #include "pci_impl.h" #include "machvec_impl.h" +#if defined(ALPHA_RESTORE_SRM_SETUP) +/* Save LCA configuration data as the console had it set up. */ +struct +{ + unsigned int orig_route_tab; /* for SAVE/RESTORE */ +} saved_config __attribute((common)); +#endif + static void __init sio_init_irq(void) @@ -77,6 +85,15 @@ static void __init sio_pci_route(void) { +#if defined(ALPHA_RESTORE_SRM_SETUP) + /* First, read and save the original setting. */ + pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60, + &saved_config.orig_route_tab); + printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__, + saved_config.orig_route_tab, alpha_mv.sys.sio.route_tab); +#endif + + /* Now override with desired setting. */ pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60, alpha_mv.sys.sio.route_tab); } @@ -245,6 +262,21 @@ outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */ } +void +sio_kill_arch(int mode) +{ +#if defined(ALPHA_RESTORE_SRM_SETUP) + /* Since we cannot read the PCI DMA Window CSRs, we + * cannot restore them here. + * + * However, we CAN read the PIRQ route register, so restore it + * now... + */ + pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60, + saved_config.orig_route_tab); +#endif +} + /* * The System Vectors @@ -269,7 +301,7 @@ .init_irq = sio_init_irq, .init_rtc = common_init_rtc, .init_pci = alphabook1_init_pci, - .kill_arch = NULL, + .kill_arch = sio_kill_arch, .pci_map_irq = noname_map_irq, .pci_swizzle = common_swizzle, @@ -300,6 +332,7 @@ .init_irq = sio_init_irq, .init_rtc = common_init_rtc, .init_pci = noname_init_pci, + .kill_arch = sio_kill_arch, .pci_map_irq = noname_map_irq, .pci_swizzle = common_swizzle, @@ -329,6 +362,7 @@ .init_irq = sio_init_irq, .init_rtc = common_init_rtc, .init_pci = noname_init_pci, + .kill_arch = sio_kill_arch, .pci_map_irq = noname_map_irq, .pci_swizzle = common_swizzle, @@ -367,6 +401,7 @@ .init_irq = sio_init_irq, .init_rtc = common_init_rtc, .init_pci = noname_init_pci, + .kill_arch = sio_kill_arch, .pci_map_irq = p2k_map_irq, .pci_swizzle = common_swizzle, @@ -396,6 +431,7 @@ .init_irq = sio_init_irq, .init_rtc = common_init_rtc, .init_pci = noname_init_pci, + .kill_arch = sio_kill_arch, .pci_map_irq = noname_map_irq, .pci_swizzle = common_swizzle, diff -Nru a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/alpha/kernel/vmlinux.lds.S Mon Aug 18 22:21:03 2003 @@ -0,0 +1,152 @@ +#include +#include + +OUTPUT_FORMAT("elf64-alpha") +OUTPUT_ARCH(alpha) +ENTRY(__start) +PHDRS { kernel PT_LOAD ; } +jiffies = jiffies_64; +SECTIONS +{ +#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS + . = 0xfffffc0000310000; +#else + . = 0xfffffc0001010000; +#endif + + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } :kernel + _etext = .; /* End of text section */ + + . = ALIGN(16); + __start___ex_table = .; /* Exception table */ + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + + /* Will be freed after init */ + . = ALIGN(8192); /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + + . = ALIGN(8); + __start___param = .; + __param : { *(__param) } + __stop___param = .; + + . = ALIGN(8); + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + + . = ALIGN(8192); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + + . = ALIGN(8); + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + + . = ALIGN(8); + SECURITY_INIT + + . = ALIGN(64); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + + . = ALIGN(2*8192); + __init_end = .; + /* Freed after init ends here */ + + /* Note 2 page alignment above. */ + .data.init_thread : { *(.data.init_thread) } + + . = ALIGN(8192); + .data.page_aligned : { *(.data.page_aligned) } + + . = ALIGN(64); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _data = .; + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + .got : { *(.got) } + .sdata : { *(.sdata) } + + _edata = .; /* End of data section */ + + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : { *(.bss) *(COMMON) } + __bss_stop = .; + + _end = .; + + /* Sections to be discarded */ + /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } + + .mdebug 0 : { *(.mdebug) } + .note 0 : { *(.note) } + .comment 0 : { *(.comment) } + + /* 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) } + /* 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) } + .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/alpha/lib/ev6-stxncpy.S b/arch/alpha/lib/ev6-stxncpy.S --- a/arch/alpha/lib/ev6-stxncpy.S Mon Aug 18 22:21:05 2003 +++ b/arch/alpha/lib/ev6-stxncpy.S Mon Aug 18 22:21:05 2003 @@ -360,9 +360,9 @@ lda t2, -1 # E : for creating masks later beq t12, $u_head # U : (stall) - nop - cmpbge zero, t1, t8 # E : is there a zero? extql t2, a1, t2 # U : + cmpbge zero, t1, t8 # E : is there a zero? + andnot t2, t6, t12 # E : dest mask for a single word copy or t8, t10, t5 # E : test for end-of-count too cmpbge zero, t2, t3 # E : @@ -379,13 +379,13 @@ negq t8, t6 # E : build bitmask of bytes <= zero mskqh t1, t4, t1 # U : - and t6, t8, t12 # E : - subq t12, 1, t6 # E : (stall) - or t6, t12, t8 # E : (stall) - zapnot t2, t8, t2 # U : prepare source word; mirror changes (stall) + and t6, t8, t2 # E : + subq t2, 1, t6 # E : (stall) + or t6, t2, t8 # E : (stall) + zapnot t12, t8, t12 # U : prepare source word; mirror changes (stall) zapnot t1, t8, t1 # U : to source validity mask - andnot t0, t2, t0 # E : zero place for source to reside + andnot t0, t12, t0 # E : zero place for source to reside or t0, t1, t0 # E : and put it there (stall both t0, t1) stq_u t0, 0(a0) # L : (stall) diff -Nru a/arch/alpha/lib/stxncpy.S b/arch/alpha/lib/stxncpy.S --- a/arch/alpha/lib/stxncpy.S Mon Aug 18 22:21:06 2003 +++ b/arch/alpha/lib/stxncpy.S Mon Aug 18 22:21:06 2003 @@ -313,9 +313,9 @@ lda t2, -1 # e0 : for creating masks later beq t12, $u_head # .. e1 : - nop # e0 : - cmpbge zero, t1, t8 # .. e1 : is there a zero? extql t2, a1, t2 # e0 : + cmpbge zero, t1, t8 # .. e1 : is there a zero? + andnot t2, t6, t12 # e0 : dest mask for a single word copy or t8, t10, t5 # .. e1 : test for end-of-count too cmpbge zero, t2, t3 # e0 : cmoveq a2, t5, t8 # .. e1 : @@ -330,14 +330,14 @@ ldq_u t0, 0(a0) # e0 : negq t8, t6 # .. e1 : build bitmask of bytes <= zero mskqh t1, t4, t1 # e0 : - and t6, t8, t12 # .. e1 : - subq t12, 1, t6 # e0 : - or t6, t12, t8 # e1 : + and t6, t8, t2 # .. e1 : + subq t2, 1, t6 # e0 : + or t6, t2, t8 # e1 : - zapnot t2, t8, t2 # e0 : prepare source word; mirror changes + zapnot t12, t8, t12 # e0 : prepare source word; mirror changes zapnot t1, t8, t1 # .. e1 : to source validity mask - andnot t0, t2, t0 # e0 : zero place for source to reside + andnot t0, t12, t0 # e0 : zero place for source to reside or t0, t1, t0 # e1 : and put it there stq_u t0, 0(a0) # e0 : ret (t9) # .. e1 : diff -Nru a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S --- a/arch/alpha/vmlinux.lds.S Mon Aug 18 22:21:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,152 +0,0 @@ -#include -#include - -OUTPUT_FORMAT("elf64-alpha") -OUTPUT_ARCH(alpha) -ENTRY(__start) -PHDRS { kernel PT_LOAD ; } -jiffies = jiffies_64; -SECTIONS -{ -#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS - . = 0xfffffc0000310000; -#else - . = 0xfffffc0001010000; -#endif - - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } :kernel - _etext = .; /* End of text section */ - - . = ALIGN(16); - __start___ex_table = .; /* Exception table */ - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - RODATA - - /* Will be freed after init */ - . = ALIGN(8192); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - - . = ALIGN(8); - __start___param = .; - __param : { *(__param) } - __stop___param = .; - - . = ALIGN(8); - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - - . = ALIGN(8192); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - - . = ALIGN(8); - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - - . = ALIGN(8); - SECURITY_INIT - - . = ALIGN(64); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - - . = ALIGN(2*8192); - __init_end = .; - /* Freed after init ends here */ - - /* Note 2 page alignment above. */ - .data.init_thread : { *(.data.init_thread) } - - . = ALIGN(8192); - .data.page_aligned : { *(.data.page_aligned) } - - . = ALIGN(64); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _data = .; - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - .got : { *(.got) } - .sdata : { *(.sdata) } - - _edata = .; /* End of data section */ - - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : { *(.bss) *(COMMON) } - __bss_stop = .; - - _end = .; - - /* Sections to be discarded */ - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } - - .mdebug 0 : { *(.mdebug) } - .note 0 : { *(.note) } - .comment 0 : { *(.comment) } - - /* 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) } - /* 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) } - .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/arm/kernel/Makefile b/arch/arm/kernel/Makefile --- a/arch/arm/kernel/Makefile Mon Aug 18 22:21:05 2003 +++ b/arch/arm/kernel/Makefile Mon Aug 18 22:21:05 2003 @@ -30,7 +30,7 @@ head-y := head.o obj-$(CONFIG_DEBUG_LL) += debug.o -extra-y := $(head-y) init_task.o +extra-y := $(head-y) init_task.o vmlinux.lds.s # Spell out some dependencies that `make dep' doesn't spot $(obj)/entry-armv.o: $(obj)/entry-header.S include/asm-arm/constants.h diff -Nru a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/kernel/vmlinux.lds.S Mon Aug 18 22:21:00 2003 @@ -0,0 +1,21 @@ +#include + +#ifdef CONFIG_CPU_26 + +#ifdef CONFIG_ROM_KERNEL + +#include "vmlinux-armo-rom.lds.in" + +#else + +#include "vmlinux-armo.lds.in" + +#endif + +#endif + +#ifdef CONFIG_CPU_32 + +#include "vmlinux-armv.lds.in" + +#endif diff -Nru a/arch/arm/vmlinux.lds.S b/arch/arm/vmlinux.lds.S --- a/arch/arm/vmlinux.lds.S Mon Aug 18 22:21:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,21 +0,0 @@ -#include - -#ifdef CONFIG_CPU_26 - -#ifdef CONFIG_ROM_KERNEL - -#include "vmlinux-armo-rom.lds.in" - -#else - -#include "vmlinux-armo.lds.in" - -#endif - -#endif - -#ifdef CONFIG_CPU_32 - -#include "vmlinux-armv.lds.in" - -#endif diff -Nru a/arch/arm26/kernel/Makefile b/arch/arm26/kernel/Makefile --- a/arch/arm26/kernel/Makefile Mon Aug 18 22:21:03 2003 +++ b/arch/arm26/kernel/Makefile Mon Aug 18 22:21:03 2003 @@ -14,5 +14,5 @@ obj-$(CONFIG_FIQ) += fiq.o obj-$(CONFIG_MODULES) += armksyms.o -extra-y := init_task.o +extra-y := init_task.o vmlinux.lds.s diff -Nru a/arch/arm26/kernel/vmlinux.lds.S b/arch/arm26/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm26/kernel/vmlinux.lds.S Mon Aug 18 22:21:04 2003 @@ -0,0 +1,12 @@ +#include + +#ifdef CONFIG_ROM_KERNEL + +#include "vmlinux-armo-rom.lds.in" + +#else + +#include "vmlinux-armo.lds.in" + +#endif + diff -Nru a/arch/arm26/vmlinux.lds.S b/arch/arm26/vmlinux.lds.S --- a/arch/arm26/vmlinux.lds.S Mon Aug 18 22:21:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,12 +0,0 @@ -#include - -#ifdef CONFIG_ROM_KERNEL - -#include "vmlinux-armo-rom.lds.in" - -#else - -#include "vmlinux-armo.lds.in" - -#endif - diff -Nru a/arch/cris/Makefile b/arch/cris/Makefile --- a/arch/cris/Makefile Mon Aug 18 22:21:03 2003 +++ b/arch/cris/Makefile Mon Aug 18 22:21:03 2003 @@ -93,7 +93,7 @@ @ln -sfn $(SARCH)/drivers arch/$(ARCH)/drivers @ln -sfn $(SARCH)/boot arch/$(ARCH)/boot @ln -sfn $(SARCH)/lib arch/$(ARCH)/lib - @ln -sfn $(SARCH)/vmlinux.lds.S arch/$(ARCH)/vmlinux.lds.S + @ln -sfn $(SARCH)/vmlinux.lds.S arch/$(ARCH)/kernel/vmlinux.lds.S @touch $@ # Create link to sub arch includes diff -Nru a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile --- a/arch/cris/kernel/Makefile Mon Aug 18 22:21:04 2003 +++ b/arch/cris/kernel/Makefile Mon Aug 18 22:21:04 2003 @@ -3,6 +3,8 @@ # Makefile for the linux kernel. # +extra-y := vmlinux.lds.s + obj-y := process.o traps.o irq.o ptrace.o setup.o \ time.o sys_cris.o semaphore.o diff -Nru a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile --- a/arch/h8300/kernel/Makefile Mon Aug 18 22:21:04 2003 +++ b/arch/h8300/kernel/Makefile Mon Aug 18 22:21:04 2003 @@ -1,11 +1,8 @@ # # Makefile for the linux kernel. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... + +extra-y := vmlinux.lds.s obj-y := process.o traps.o ptrace.o \ sys_h8300.o time.o semaphore.o signal.o \ diff -Nru a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/h8300/kernel/vmlinux.lds.S Mon Aug 18 22:21:04 2003 @@ -0,0 +1,178 @@ +#include + +#ifdef CONFIG_H8300H_GENERIC +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/generic/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/generic/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8300H_AKI3068NET +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/aki3068net/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/aki3068net/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8300H_H8MAX +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/h8max/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/h8max/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8300H_SIM +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/generic/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/generic/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8S_SIM +#ifdef CONFIG_ROMKERNEL +#include "platform/h8s/generic/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8s/generic/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8S_EDOSK2674 +#ifdef CONFIG_ROMKERNEL +#include "platform/h8s/edosk2674/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8s/edosk2674/ram.ld" +#endif +#endif + +_jiffies = _jiffies_64 + 4; + +SECTIONS +{ +#if defined(CONFIG_ROMKERNEL) + .vectors : + { + __vector = . ; + *(.vectors*) + } > vector +#endif +#if defined(CONFIG_RAMKERNEL) + .bootvec : + { + *(.bootvec) + } > ram +#endif + .text : + { +#if defined(CONFIG_ROMKERNEL) + *(.int_redirect) +#endif + __stext = . ; + *(.text) + . = ALIGN(0x4) ; + *(.exit.text) + *(.text.*) + . = ALIGN(0x4) ; + *(.exitcall.exit) + . = ALIGN(0x4) ; + *(.kstrtab) + . = ALIGN(0x4) ; + *(.rodata*) + . = ALIGN(16); /* Exception table */ + ___start___ex_table = .; + *(__ex_table) + ___stop___ex_table = .; + + ___start___ksymtab = .; /* Kernel symbol table */ + *(__ksymtab) + ___stop___ksymtab = .; + + . = ALIGN(0x4) ; + __etext = . ; +#if defined(CONFIG_ROMKERNEL) + } > rom +#endif +#if defined(CONFIG_RAMKERNEL) + } > ram +#endif + .data : AT( ADDR(.text)+SIZEOF(.text)) + { + __sdata = . ; + ___data_start = . ; + + . = ALIGN(0x2000) ; + *(.data.init_task) + . = ALIGN(0x4) ; + *(.data) + . = ALIGN(0x4) ; + *(.data.*) + + . = ALIGN(0x4) ; + ___init_begin = .; + __sinittext = .; + *(.init.text) + __einittext = .; + *(.init.data) + . = ALIGN(0x4) ; + ___setup_start = .; + *(.init.setup) + . = ALIGN(0x4) ; + ___setup_end = .; + ___start___param = .; + *(__param) + ___stop___param = .; + ___initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + ___initcall_end = .; + ___con_initcall_start = .; + *(.con_initcall.init) + ___con_initcall_end = .; + . = ALIGN(4); + ___initramfs_start = .; + *(.init.ramfs) + ___initramfs_end = .; + . = ALIGN(0x4) ; + ___init_end = .; + __edata = . ; + } > ram + __begin_data = LOADADDR(.data) ; +#if defined(CONFIG_ROMKERNEL) + .erom : + { + __erom = . ; + } > erom +#endif + .bss : + { + . = ALIGN(0x4) ; + __sbss = . ; + *(.bss*) + . = ALIGN(0x4) ; + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __end = . ; + __ramstart = .; + } > ram + .dummy : + { + COMMAND_START = . - 0x200 ; + __ramend = . ; + } > eram +} + diff -Nru a/arch/h8300/vmlinux.lds.S b/arch/h8300/vmlinux.lds.S --- a/arch/h8300/vmlinux.lds.S Mon Aug 18 22:21:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,178 +0,0 @@ -#include - -#ifdef CONFIG_H8300H_GENERIC -#ifdef CONFIG_ROMKERNEL -#include "platform/h8300h/generic/rom.ld" -#endif -#ifdef CONFIG_RAMKERNEL -#include "platform/h8300h/generic/ram.ld" -#endif -#endif - -#ifdef CONFIG_H8300H_AKI3068NET -#ifdef CONFIG_ROMKERNEL -#include "platform/h8300h/aki3068net/rom.ld" -#endif -#ifdef CONFIG_RAMKERNEL -#include "platform/h8300h/aki3068net/ram.ld" -#endif -#endif - -#ifdef CONFIG_H8300H_H8MAX -#ifdef CONFIG_ROMKERNEL -#include "platform/h8300h/h8max/rom.ld" -#endif -#ifdef CONFIG_RAMKERNEL -#include "platform/h8300h/h8max/ram.ld" -#endif -#endif - -#ifdef CONFIG_H8300H_SIM -#ifdef CONFIG_ROMKERNEL -#include "platform/h8300h/generic/rom.ld" -#endif -#ifdef CONFIG_RAMKERNEL -#include "platform/h8300h/generic/ram.ld" -#endif -#endif - -#ifdef CONFIG_H8S_SIM -#ifdef CONFIG_ROMKERNEL -#include "platform/h8s/generic/rom.ld" -#endif -#ifdef CONFIG_RAMKERNEL -#include "platform/h8s/generic/ram.ld" -#endif -#endif - -#ifdef CONFIG_H8S_EDOSK2674 -#ifdef CONFIG_ROMKERNEL -#include "platform/h8s/edosk2674/rom.ld" -#endif -#ifdef CONFIG_RAMKERNEL -#include "platform/h8s/edosk2674/ram.ld" -#endif -#endif - -_jiffies = _jiffies_64 + 4; - -SECTIONS -{ -#if defined(CONFIG_ROMKERNEL) - .vectors : - { - __vector = . ; - *(.vectors*) - } > vector -#endif -#if defined(CONFIG_RAMKERNEL) - .bootvec : - { - *(.bootvec) - } > ram -#endif - .text : - { -#if defined(CONFIG_ROMKERNEL) - *(.int_redirect) -#endif - __stext = . ; - *(.text) - . = ALIGN(0x4) ; - *(.exit.text) - *(.text.*) - . = ALIGN(0x4) ; - *(.exitcall.exit) - . = ALIGN(0x4) ; - *(.kstrtab) - . = ALIGN(0x4) ; - *(.rodata*) - . = ALIGN(16); /* Exception table */ - ___start___ex_table = .; - *(__ex_table) - ___stop___ex_table = .; - - ___start___ksymtab = .; /* Kernel symbol table */ - *(__ksymtab) - ___stop___ksymtab = .; - - . = ALIGN(0x4) ; - __etext = . ; -#if defined(CONFIG_ROMKERNEL) - } > rom -#endif -#if defined(CONFIG_RAMKERNEL) - } > ram -#endif - .data : AT( ADDR(.text)+SIZEOF(.text)) - { - __sdata = . ; - ___data_start = . ; - - . = ALIGN(0x2000) ; - *(.data.init_task) - . = ALIGN(0x4) ; - *(.data) - . = ALIGN(0x4) ; - *(.data.*) - - . = ALIGN(0x4) ; - ___init_begin = .; - __sinittext = .; - *(.init.text) - __einittext = .; - *(.init.data) - . = ALIGN(0x4) ; - ___setup_start = .; - *(.init.setup) - . = ALIGN(0x4) ; - ___setup_end = .; - ___start___param = .; - *(__param) - ___stop___param = .; - ___initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - ___initcall_end = .; - ___con_initcall_start = .; - *(.con_initcall.init) - ___con_initcall_end = .; - . = ALIGN(4); - ___initramfs_start = .; - *(.init.ramfs) - ___initramfs_end = .; - . = ALIGN(0x4) ; - ___init_end = .; - __edata = . ; - } > ram - __begin_data = LOADADDR(.data) ; -#if defined(CONFIG_ROMKERNEL) - .erom : - { - __erom = . ; - } > erom -#endif - .bss : - { - . = ALIGN(0x4) ; - __sbss = . ; - *(.bss*) - . = ALIGN(0x4) ; - *(COMMON) - . = ALIGN(0x4) ; - __ebss = . ; - __end = . ; - __ramstart = .; - } > ram - .dummy : - { - COMMAND_START = . - 0x200 ; - __ramend = . ; - } > eram -} - diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Mon Aug 18 22:21:01 2003 +++ b/arch/i386/Kconfig Mon Aug 18 22:21:01 2003 @@ -276,9 +276,9 @@ help Select this for an IDT Winchip-2A or 3. Linux and GCC treat this chip as a 586TSC with some extended instructions - and alignment reqirements. Development kernels also enable - out of order memory stores for this CPU, which can increase - performance of some operations. + and alignment reqirements. Also enable out of order memory + stores for this CPU, which can increase performance of some + operations. config MCYRIXIII bool "CyrixIII/VIA-C3" @@ -438,9 +438,9 @@ If you don't know what to do here, say N. config NR_CPUS - int "Maximum number of CPUs (2-32)" + int "Maximum number of CPUs (2-255)" depends on SMP - default "32" + default "8" help This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 32 and the @@ -846,8 +846,11 @@ source "drivers/acpi/Kconfig" +menu "APM (Advanced Power Management) BIOS Support" +depends on PM + config APM - tristate "Advanced Power Management BIOS support" + tristate "APM (Advanced Power Management) BIOS support" depends on PM ---help--- APM is a BIOS specification for saving power using several different @@ -991,6 +994,8 @@ a work-around for a number of buggy BIOSes. Switch this option on if your computer crashes instead of powering off properly. +endmenu + source "arch/i386/kernel/cpu/cpufreq/Kconfig" endmenu @@ -1198,6 +1203,10 @@ source "drivers/pnp/Kconfig" source "drivers/block/Kconfig" + +config MOUNT_ROOT_FAILED_MSG + bool + default y source "drivers/ide/Kconfig" diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile --- a/arch/i386/Makefile Mon Aug 18 22:21:02 2003 +++ b/arch/i386/Makefile Mon Aug 18 22:21:02 2003 @@ -38,12 +38,14 @@ cflags-$(CONFIG_MPENTIUMIII) += $(call check_gcc,-march=pentium3,-march=i686) cflags-$(CONFIG_MPENTIUM4) += $(call check_gcc,-march=pentium4,-march=i686) cflags-$(CONFIG_MK6) += $(call check_gcc,-march=k6,-march=i586) +# Please note, that patches that add -march=athlon-xp and friends are pointless. +# They make zero difference whatsosever to performance at this time. cflags-$(CONFIG_MK7) += $(call check_gcc,-march=athlon,-march=i686 $(align)-functions=4) cflags-$(CONFIG_MK8) += $(call check_gcc,-march=k8,$(call check_gcc,-march=athlon,-march=i686 $(align)-functions=4)) cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MWINCHIPC6) += $(call check_gcc,-march=winchip-c6,-march=i586) cflags-$(CONFIG_MWINCHIP2) += $(call check_gcc,-march=winchip2,-march=i586) -cflags-$(CONFIG_MWINCHIP3D) += -march=i586 +cflags-$(CONFIG_MWINCHIP3D) += $(call check_gcc,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call check_gcc,-march=c3-2,-march=i686) diff -Nru a/arch/i386/defconfig b/arch/i386/defconfig --- a/arch/i386/defconfig Mon Aug 18 22:21:04 2003 +++ b/arch/i386/defconfig Mon Aug 18 22:21:04 2003 @@ -3,7 +3,6 @@ # CONFIG_X86=y CONFIG_MMU=y -CONFIG_SWAP=y CONFIG_UID16=y CONFIG_GENERIC_ISA_DMA=y @@ -11,24 +10,31 @@ # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_BROKEN is not set # # General setup # -CONFIG_NET=y +CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_IKCONFIG=n -CONFIG_IKCONFIG_PROC=n +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y # # Loadable module support # CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set CONFIG_KMOD=y # @@ -38,12 +44,17 @@ # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set # CONFIG_X86_SUMMIT is not set +# CONFIG_X86_BIGSMP is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_GENERICARCH is not set +# CONFIG_X86_ES7000 is not set # CONFIG_M386 is not set # CONFIG_M486 is not set # CONFIG_M586 is not set # CONFIG_M586TSC is not set # CONFIG_M586MMX is not set # CONFIG_M686 is not set +# CONFIG_MPENTIUMII is not set # CONFIG_MPENTIUMIII is not set CONFIG_MPENTIUM4=y # CONFIG_MK6 is not set @@ -55,6 +66,8 @@ # CONFIG_MWINCHIP2 is not set # CONFIG_MWINCHIP3D is not set # CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y CONFIG_X86_L1_CACHE_SHIFT=7 @@ -63,26 +76,25 @@ CONFIG_X86_INVLPG=y CONFIG_X86_BSWAP=y CONFIG_X86_POPAD_OK=y -CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_SSE2=y # CONFIG_HUGETLB_PAGE is not set CONFIG_SMP=y -# CONFIG_PREEMPT is not set +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y -CONFIG_NR_CPUS=32 +CONFIG_X86_TSC=y CONFIG_X86_MCE=y -# CONFIG_X86_MCE_NONFATAL is not set +CONFIG_X86_MCE_NONFATAL=y CONFIG_X86_MCE_P4THERMAL=y # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set # CONFIG_X86_CPUID is not set -CONFIG_EDD=y +# CONFIG_EDD is not set CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set @@ -97,26 +109,37 @@ # CONFIG_SOFTWARE_SUSPEND is not set # -# ACPI Support +# ACPI (Advanced Configuration and Power Interface) Support # +CONFIG_ACPI_HT=y CONFIG_ACPI=y -# CONFIG_ACPI_HT_ONLY is not set CONFIG_ACPI_BOOT=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SLEEP_PROC_FS=y CONFIG_ACPI_AC=y CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_ASUS is not set # CONFIG_ACPI_TOSHIBA is not set -CONFIG_ACPI_DEBUG=y +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_BUS=y CONFIG_ACPI_INTERPRETER=y CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y + +# +# APM (Advanced Power Management) BIOS Support +# # CONFIG_APM is not set + +# +# CPU Frequency scaling +# # CONFIG_CPU_FREQ is not set # @@ -128,21 +151,19 @@ CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y -# CONFIG_SCx200 is not set +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y CONFIG_ISA=y # CONFIG_EISA is not set # CONFIG_MCA is not set +# CONFIG_SCx200 is not set CONFIG_HOTPLUG=y # # PCMCIA/CardBus support # -CONFIG_PCMCIA=y -CONFIG_CARDBUS=y -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -# CONFIG_TCIC is not set +# CONFIG_PCMCIA is not set +CONFIG_PCMCIA_PROBE=y # # PCI Hotplug Support @@ -154,11 +175,16 @@ # CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_MISC=y # +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Memory Technology Devices (MTD) # # CONFIG_MTD is not set @@ -172,21 +198,19 @@ # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_PC_PCMCIA is not set # CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y +# CONFIG_PARPORT_1284 is not set # # Plug and Play support # CONFIG_PNP=y -CONFIG_PNP_NAMES=y -# CONFIG_PNP_CARD is not set # CONFIG_PNP_DEBUG is not set # # Protocols # +# CONFIG_ISAPNP is not set # CONFIG_PNPBIOS is not set # @@ -202,64 +226,64 @@ # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set CONFIG_LBD=y +CONFIG_MOUNT_ROOT_FAILED_MSG=y # -# ATA/ATAPI/MFM/RLL device support +# ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y # CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE 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_IDE_TASKFILE_IO=y # # IDE chipset support/bugfixes # CONFIG_BLK_DEV_CMD640=y # CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_GENERIC=y CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDE_TCQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set -CONFIG_BLK_DEV_RZ1000=y # CONFIG_BLK_DEV_SVWKS is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set @@ -267,8 +291,11 @@ # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support @@ -281,16 +308,15 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y +# CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=y # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_REPORT_LUNS=y -CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # @@ -302,13 +328,7 @@ # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=64 -CONFIG_AIC7XXX_RESET_DELAY_MS=2000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set @@ -321,7 +341,6 @@ # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set @@ -333,9 +352,7 @@ # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set @@ -344,10 +361,10 @@ # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set -CONFIG_SCSI_QLOGIC_1280=y +# CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_SEAGATE is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -356,11 +373,6 @@ # CONFIG_SCSI_DEBUG is not set # -# PCMCIA SCSI adapter support -# -# CONFIG_SCSI_PCMCIA is not set - -# # Old CD-ROM drivers (not SCSI, not IDE) # # CONFIG_CD_NO_IDESCSI is not set @@ -378,7 +390,32 @@ # # IEEE 1394 (FireWire) support (EXPERIMENTAL) # -# CONFIG_IEEE1394 is not set +CONFIG_IEEE1394=y + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_OUI_DB is not set + +# +# Device Drivers +# + +# +# Texas Instruments PCILynx requires I2C bit-banging +# +CONFIG_IEEE1394_OHCI1394=y + +# +# Protocol Drivers +# +# CONFIG_IEEE1394_VIDEO1394 is not set +# CONFIG_IEEE1394_SBP2 is not set +# CONFIG_IEEE1394_ETH1394 is not set +# CONFIG_IEEE1394_DV1394 is not set +# CONFIG_IEEE1394_RAWIO is not set +# CONFIG_IEEE1394_CMP is not set # # I2O device support @@ -386,13 +423,16 @@ # CONFIG_I2O is not set # +# Networking support +# +CONFIG_NET=y + +# # 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 @@ -407,8 +447,11 @@ # 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_INET_IPCOMP is not set # CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -418,8 +461,6 @@ # 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 @@ -437,10 +478,6 @@ # Network testing # # CONFIG_NET_PKTGEN is not set - -# -# Network device support -# CONFIG_NETDEVICES=y # @@ -452,11 +489,13 @@ # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set @@ -474,6 +513,7 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_AC3200 is not set # CONFIG_APRICOT is not set @@ -481,12 +521,16 @@ # CONFIG_CS89x0 is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set -CONFIG_E100=y +# CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139CP is not set -# CONFIG_8139TOO is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -504,8 +548,14 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -530,21 +580,6 @@ # 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=y -# 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_NET_PCMCIA_RADIO=y -CONFIG_PCMCIA_RAYCS=y - -# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -591,6 +626,7 @@ # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set # # Input Device Drivers @@ -623,7 +659,7 @@ # CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_CONSOLE is not set -# CONFIG_SERIAL_8250_CS is not set +# CONFIG_SERIAL_8250_ACPI is not set # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -649,6 +685,7 @@ # # I2C Hardware Sensors Chip support # +# CONFIG_I2C_SENSOR is not set # # Mice @@ -657,11 +694,15 @@ # CONFIG_QIC02_TAPE is not set # +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_INTEL_RNG=y -# CONFIG_AMD_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set @@ -675,28 +716,26 @@ # # CONFIG_FTAPE is not set CONFIG_AGP=y -# CONFIG_AGP3 is not set -CONFIG_AGP_INTEL=y -CONFIG_AGP_VIA=y -CONFIG_AGP_AMD=y -CONFIG_AGP_SIS=y -CONFIG_AGP_ALI=y -CONFIG_AGP_SWORKS=y +# CONFIG_AGP_ALI is not set +# CONFIG_AGP_ATI is not set +# CONFIG_AGP_AMD is not set # CONFIG_AGP_AMD_8151 is not set +CONFIG_AGP_INTEL=y +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_VIA is not set CONFIG_DRM=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set # CONFIG_DRM_R128 is not set -CONFIG_DRM_RADEON=y +# CONFIG_DRM_RADEON is not set # CONFIG_DRM_I810 is not set -# CONFIG_DRM_I830 is not set +CONFIG_DRM_I830=y # CONFIG_DRM_MGA is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set # CONFIG_MWAVE is not set # CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -704,72 +743,92 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # 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=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS 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=y -# CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_SYSV_FS is not set -CONFIG_UDF_FS=y # 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=y # CONFIG_NFS_V3 is not set # CONFIG_NFS_V4 is not set CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set # CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_EXPORTFS=y -# CONFIG_CIFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y # # Partition Types @@ -884,11 +943,13 @@ # CONFIG_SND_CMI8330 is not set # CONFIG_SND_OPL3SA2 is not set # CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set # # PCI devices # # CONFIG_SND_ALI5451 is not set +# CONFIG_SND_AZT3328 is not set # CONFIG_SND_CS46XX is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set @@ -909,9 +970,11 @@ # CONFIG_SND_MAESTRO3 is not set # CONFIG_SND_FM801 is not set # CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set CONFIG_SND_INTEL8X0=y # CONFIG_SND_SONICVIBES is not set # CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set # # ALSA USB devices @@ -933,7 +996,7 @@ # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -CONFIG_USB_BANDWIDTH=y +# CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # @@ -950,7 +1013,7 @@ # CONFIG_USB_BLUETOOTH_TTY is not set # CONFIG_USB_MIDI is not set # CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +CONFIG_USB_PRINTER=y CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set @@ -965,15 +1028,13 @@ # # USB Human Interface Devices (HID) # -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_XPAD is not set @@ -997,8 +1058,8 @@ # # USB Network adaptors # +# CONFIG_USB_AX8817X is not set # CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set @@ -1023,6 +1084,7 @@ # CONFIG_USB_BRLVGER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_TEST is not set +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -1038,7 +1100,6 @@ # Kernel hacking # # CONFIG_DEBUG_KERNEL is not set -CONFIG_KALLSYMS=y CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_FRAME_POINTER=y CONFIG_X86_EXTRA_IRQS=y diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Mon Aug 18 22:21:01 2003 +++ b/arch/i386/kernel/Makefile Mon Aug 18 22:21:01 2003 @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s 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 \ @@ -11,7 +11,7 @@ obj-y += cpu/ obj-y += timers/ -obj-$(CONFIG_ACPI) += acpi/ +obj-$(CONFIG_ACPI_BOOT) += acpi/ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o obj-$(CONFIG_MCA) += mca.o obj-$(CONFIG_X86_MSR) += msr.o diff -Nru a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile --- a/arch/i386/kernel/acpi/Makefile Mon Aug 18 22:21:03 2003 +++ b/arch/i386/kernel/acpi/Makefile Mon Aug 18 22:21:03 2003 @@ -1,4 +1,3 @@ -obj-$(CONFIG_ACPI_HT_ONLY) := acpitable.o obj-$(CONFIG_ACPI_BOOT) := boot.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o diff -Nru a/arch/i386/kernel/acpi/acpitable.c b/arch/i386/kernel/acpi/acpitable.c --- a/arch/i386/kernel/acpi/acpitable.c Mon Aug 18 22:21:02 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,553 +0,0 @@ -/* - * acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1) - * - * Copyright (C) 1999 Andrew Henroid - * Copyright (C) 2001 Richard Schaal - * Copyright (C) 2001 Paul Diefenbaugh - * Copyright (C) 2001 Jun Nakajima - * Copyright (C) 2001 Arjan van de Ven - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * 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 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "acpitable.h" - -static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT]; - -int acpi_lapic; - -static unsigned char __init -acpi_checksum(void *buffer, int length) -{ - int i; - unsigned char *bytebuffer; - unsigned char sum = 0; - - if (!buffer || length <= 0) - return 0; - - bytebuffer = (unsigned char *) buffer; - - for (i = 0; i < length; i++) - sum += *(bytebuffer++); - - return sum; -} - -static void __init -acpi_print_table_header(acpi_table_header * header) -{ - if (!header) - return; - - printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n", - header->signature, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision >> 16, - header->oem_revision & 0xffff); - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_tb_scan_memory_for_rsdp - * - * PARAMETERS: address - Starting pointer for search - * length - Maximum length to search - * - * RETURN: Pointer to the RSDP if found and valid, otherwise NULL. - * - * DESCRIPTION: Search a block of memory for the RSDP signature - * - ******************************************************************************/ - -static void *__init -acpi_tb_scan_memory_for_rsdp(void *address, int length) -{ - u32 offset; - - if (length <= 0) - return NULL; - - /* Search from given start addr for the requested length */ - - offset = 0; - - while (offset < length) { - /* The signature must match and the checksum must be correct */ - if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 && - acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) { - /* If so, we have found the RSDP */ - printk(KERN_INFO "ACPI: RSDP located at physical address %p\n", - address); - return address; - } - offset += RSDP_SCAN_STEP; - address += RSDP_SCAN_STEP; - } - - /* Searched entire block, no RSDP was found */ - printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n"); - return NULL; -} - -/******************************************************************************* - * - * FUNCTION: acpi_find_root_pointer - * - * PARAMETERS: none - * - * RETURN: physical address of the RSDP - * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. - * - * NOTE: The RSDP must be either in the first 1_k of the Extended - * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section - * 5.2.2; assertion #421). - * - ******************************************************************************/ - -static struct acpi_table_rsdp * __init -acpi_find_root_pointer(void) -{ - struct acpi_table_rsdp * rsdp; - - /* - * Physical address is given - */ - /* - * Region 1) Search EBDA (low memory) paragraphs - */ - rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE), - LO_RSDP_WINDOW_SIZE); - - if (rsdp) - return rsdp; - - /* - * Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h - */ - rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE), - HI_RSDP_WINDOW_SIZE); - - - - if (rsdp) - return rsdp; - - printk(KERN_ERR "ACPI: System description tables not found\n"); - return NULL; -} - - -/* - * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, - * to map the target physical address. The problem is that set_fixmap() - * provides a single page, and it is possible that the page is not - * sufficient. - * By using this area, we can map up to MAX_IO_APICS pages temporarily, - * i.e. until the next __va_range() call. - * - * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* - * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and - * count idx down while incrementing the phys address. - */ -static __init char * -__va_range(unsigned long phys, unsigned long size) -{ - unsigned long base, offset, mapped_size; - int idx; - - offset = phys & (PAGE_SIZE - 1); - mapped_size = PAGE_SIZE - offset; - set_fixmap(FIX_IO_APIC_BASE_END, phys); - base = fix_to_virt(FIX_IO_APIC_BASE_END); - dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size, - FIX_IO_APIC_BASE_END, base); - - /* - * Most cases can be covered by the below. - */ - idx = FIX_IO_APIC_BASE_END; - while (mapped_size < size) { - if (--idx < FIX_IO_APIC_BASE_0) - return 0; /* cannot handle this */ - phys += PAGE_SIZE; - set_fixmap(idx, phys); - mapped_size += PAGE_SIZE; - } - - return ((unsigned char *) base + offset); -} - -static int __init acpi_tables_init(void) -{ - int result = -ENODEV; - acpi_table_header *header = NULL; - struct acpi_table_rsdp *rsdp = NULL; - struct acpi_table_rsdt *rsdt = NULL; - struct acpi_table_rsdt saved_rsdt; - int tables = 0; - int type = 0; - int i = 0; - - - rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer(); - - if (!rsdp) - return -ENODEV; - - printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision, - rsdp->oem_id); - - if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) { - printk(KERN_WARNING "RSDP table signature incorrect\n"); - return -EINVAL; - } - - rsdt = (struct acpi_table_rsdt *) - __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt)); - - if (!rsdt) { - printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n"); - return -ENODEV; - } - - header = & rsdt->header; - acpi_print_table_header(header); - - if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) { - printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); - return -ENODEV; - } - - /* - * The number of tables is computed by taking the - * size of all entries (header size minus total - * size of RSDT) divided by the size of each entry - * (4-byte table pointers). - */ - tables = (header->length - sizeof(acpi_table_header)) / 4; - - memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); - - if (saved_rsdt.header.length > sizeof(saved_rsdt)) { - printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length); - return -ENODEV; - } - - for (i = 0; i < tables; i++) { - /* Map in header, then map in full table length. */ - header = (acpi_table_header *) - __va_range(saved_rsdt.entry[i], - sizeof(acpi_table_header)); - if (!header) - break; - header = (acpi_table_header *) - __va_range(saved_rsdt.entry[i], header->length); - if (!header) - break; - - acpi_print_table_header(header); - - if (acpi_checksum(header,header->length)) { - printk(KERN_WARNING "ACPI %s has invalid checksum\n", - acpi_table_signatures[i]); - continue; - } - - for (type = 0; type < ACPI_TABLE_COUNT; type++) - if (!strncmp((char *) &header->signature, - acpi_table_signatures[type],strlen(acpi_table_signatures[type]))) - break; - - if (type >= ACPI_TABLE_COUNT) { - printk(KERN_WARNING "ACPI: Unsupported table %.4s\n", - header->signature); - continue; - } - - - if (!acpi_boot_ops[type]) - continue; - - result = acpi_boot_ops[type] (header, - (unsigned long) saved_rsdt. - entry[i]); - } - - return result; -} - -static int total_cpus __initdata = 0; -int have_acpi_tables; - -extern void __init MP_processor_info(struct mpc_config_processor *); - -static void __init -acpi_parse_lapic(struct acpi_table_lapic *local_apic) -{ - struct mpc_config_processor proc_entry; - int ix = 0; - - if (!local_apic) - return; - - printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n", - local_apic->acpi_id, local_apic->id, local_apic->flags.enabled); - - printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id); - - if (local_apic->flags.enabled) { - printk(" enabled"); - ix = local_apic->id; - if (ix >= MAX_APICS) { - printk(KERN_WARNING - "Processor #%d INVALID - (Max ID: %d).\n", ix, - MAX_APICS); - return; - } - /* - * Fill in the info we want to save. Not concerned about - * the processor ID. Processor features aren't present in - * the table. - */ - proc_entry.mpc_type = MP_PROCESSOR; - proc_entry.mpc_apicid = local_apic->id; - proc_entry.mpc_cpuflag = CPU_ENABLED; - if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) { - printk(" (BSP)"); - proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR; - } - proc_entry.mpc_cpufeature = - (boot_cpu_data.x86 << 8) | - (boot_cpu_data.x86_model << 4) | - boot_cpu_data.x86_mask; - proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0]; - proc_entry.mpc_reserved[0] = 0; - proc_entry.mpc_reserved[1] = 0; - proc_entry.mpc_apicver = 0x10; /* integrated APIC */ - MP_processor_info(&proc_entry); - } else { - printk(" disabled"); - } - printk("\n"); - - total_cpus++; - return; -} - -static void __init -acpi_parse_ioapic(struct acpi_table_ioapic *ioapic) -{ - - if (!ioapic) - return; - - printk(KERN_INFO - "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n", - ioapic->id, ioapic->address, ioapic->global_irq_base); - - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_WARNING - "Max # of I/O APICs (%d) exceeded (found %d).\n", - MAX_IO_APICS, nr_ioapics); -/* panic("Recompile kernel with bigger MAX_IO_APICS!\n"); */ - } -} - - -/* Interrupt source overrides inform the machine about exceptions - to the normal "PIC" mode interrupt routing */ - -static void __init -acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc) -{ - if (!intsrc) - return; - - printk(KERN_INFO - "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n", - intsrc->bus, intsrc->bus_irq, intsrc->global_irq, - intsrc->flags.polarity, intsrc->flags.trigger); -} - -/* - * At this point, we look at the interrupt assignment entries in the MPS - * table. - */ - -static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc) -{ - if (!nmisrc) - return; - - printk(KERN_INFO - "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n", - nmisrc->flags.polarity, nmisrc->flags.trigger, - nmisrc->global_irq); - -} -static void __init -acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi) -{ - if (!localnmi) - return; - - printk(KERN_INFO - "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n", - localnmi->acpi_id, localnmi->flags.polarity, - localnmi->flags.trigger, localnmi->lint); -} -static void __init -acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr) -{ - if (!lapic_addr_ovr) - return; - - printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n", - (unsigned long) lapic_addr_ovr->address); - -} - -static void __init -acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc) -{ - if (!plintsrc) - return; - - printk(KERN_INFO - "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", - plintsrc->flags.polarity, plintsrc->flags.trigger, - plintsrc->type, plintsrc->id, plintsrc->eid, - plintsrc->iosapic_vector, plintsrc->global_irq); -} -static int __init -acpi_parse_madt(acpi_table_header * header, unsigned long phys) -{ - - struct acpi_table_madt *madt; - acpi_madt_entry_header *entry_header; - int table_size; - - madt = (struct acpi_table_madt *) __va_range(phys, header->length); - - if (!madt) - return -EINVAL; - - table_size = (int) (header->length - sizeof(*madt)); - entry_header = - (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt)); - - while (entry_header && (table_size > 0)) { - switch (entry_header->type) { - case ACPI_MADT_LAPIC: - acpi_parse_lapic((struct acpi_table_lapic *) - entry_header); - break; - case ACPI_MADT_IOAPIC: - acpi_parse_ioapic((struct acpi_table_ioapic *) - entry_header); - break; - case ACPI_MADT_INT_SRC_OVR: - acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *) - entry_header); - break; - case ACPI_MADT_NMI_SRC: - acpi_parse_nmi_src((struct acpi_table_nmi_src *) - entry_header); - break; - case ACPI_MADT_LAPIC_NMI: - acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *) - entry_header); - break; - case ACPI_MADT_LAPIC_ADDR_OVR: - acpi_parse_lapic_addr_ovr((struct - acpi_table_lapic_addr_ovr *) - entry_header); - break; - case ACPI_MADT_PLAT_INT_SRC: - acpi_parse_plat_int_src((struct acpi_table_plat_int_src - *) entry_header); - break; - default: - printk(KERN_WARNING - "Unsupported MADT entry type 0x%x\n", - entry_header->type); - break; - } - table_size -= entry_header->length; - entry_header = - (acpi_madt_entry_header *) ((void *) entry_header + - entry_header->length); - } - - if (!total_cpus) { - printk("ACPI: No Processors found in the APCI table.\n"); - return -EINVAL; - } - - printk(KERN_INFO "%d CPUs total\n", total_cpus); - - if (madt->lapic_address) - mp_lapic_addr = madt->lapic_address; - else - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - - printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address); - - return 0; -} - - -/* - * Configure the processor info using MADT in the ACPI tables. If we fail to - * configure that, then we use the MPS tables. - */ -void __init -acpi_boot_init(void) -{ - - memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops)); - acpi_boot_ops[ACPI_APIC] = acpi_parse_madt; - - /* - * Only do this when requested, either because of CPU/Bios type or from the command line - */ - - if (!acpi_tables_init()) - acpi_lapic = 1; -} - diff -Nru a/arch/i386/kernel/acpi/acpitable.h b/arch/i386/kernel/acpi/acpitable.h --- a/arch/i386/kernel/acpi/acpitable.h Mon Aug 18 22:21:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,260 +0,0 @@ -/* - * acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1) - * - * Copyright (C) 1999 Andrew Henroid - * Copyright (C) 2001 Richard Schaal - * Copyright (C) 2001 Paul Diefenbaugh - * Copyright (C) 2001 Jun Nakajima - * Copyright (C) 2001 Arjan van de Ven - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * 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 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * $Id: acpitable.h,v 1.3 2001/11/03 22:41:34 fenrus Exp $ - */ - -/* - * The following codes are cut&pasted from drivers/acpi. Part of the code - * there can be not updated or delivered yet. - * To avoid conflicts when CONFIG_ACPI is defined, the following codes are - * modified so that they are self-contained in this file. - * -- jun - */ - -#ifndef _HEADER_ACPITABLE_H_ -#define _HEADER_ACPITABLE_H_ - -#define dprintk printk -typedef unsigned int ACPI_TBLPTR; - -typedef struct { /* ACPI common table header */ - char signature[4]; /* identifies type of table */ - u32 length; /* length of table, - in bytes, * including header */ - u8 revision; /* 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 */ -} acpi_table_header __attribute__ ((packed));; - -enum { - ACPI_APIC = 0, - ACPI_BOOT, - ACPI_DBGP, - ACPI_DSDT, - ACPI_ECDT, - ACPI_ETDT, - ACPI_FACP, - ACPI_FACS, - ACPI_OEMX, - ACPI_PSDT, - ACPI_SBST, - ACPI_SLIT, - ACPI_SPCR, - ACPI_SRAT, - ACPI_SSDT, - ACPI_SPMI, - ACPI_XSDT, - ACPI_TABLE_COUNT -}; - -static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { - "APIC", - "BOOT", - "DBGP", - "DSDT", - "ECDT", - "ETDT", - "FACP", - "FACS", - "OEM", - "PSDT", - "SBST", - "SLIT", - "SPCR", - "SRAT", - "SSDT", - "SPMI", - "XSDT" -}; - -struct acpi_table_madt { - acpi_table_header header; - u32 lapic_address; - struct { - u32 pcat_compat:1; - u32 reserved:31; - } flags __attribute__ ((packed)); -} __attribute__ ((packed));; - -enum { - ACPI_MADT_LAPIC = 0, - ACPI_MADT_IOAPIC, - ACPI_MADT_INT_SRC_OVR, - ACPI_MADT_NMI_SRC, - ACPI_MADT_LAPIC_NMI, - ACPI_MADT_LAPIC_ADDR_OVR, - ACPI_MADT_IOSAPIC, - ACPI_MADT_LSAPIC, - ACPI_MADT_PLAT_INT_SRC, - ACPI_MADT_ENTRY_COUNT -}; - -#define RSDP_SIG "RSD PTR " -#define RSDT_SIG "RSDT" - -#define ACPI_DEBUG_PRINT(pl) - -#define ACPI_MEMORY_MODE 0x01 -#define ACPI_LOGICAL_ADDRESSING 0x00 -#define ACPI_PHYSICAL_ADDRESSING 0x01 - -#define LO_RSDP_WINDOW_BASE 0 /* Physical Address */ -#define HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ -#define LO_RSDP_WINDOW_SIZE 0x400 -#define HI_RSDP_WINDOW_SIZE 0x20000 -#define RSDP_SCAN_STEP 16 -#define RSDP_CHECKSUM_LENGTH 20 - -typedef int (*acpi_table_handler) (acpi_table_header * header, unsigned long); - -struct acpi_table_rsdp { - char signature[8]; - u8 checksum; - char oem_id[6]; - u8 revision; - u32 rsdt_address; -} __attribute__ ((packed)); - -struct acpi_table_rsdt { - acpi_table_header header; - u32 entry[ACPI_TABLE_COUNT]; -} __attribute__ ((packed)); - -typedef struct { - u8 type; - u8 length; -} acpi_madt_entry_header __attribute__ ((packed)); - -typedef struct { - u16 polarity:2; - u16 trigger:2; - u16 reserved:12; -} acpi_madt_int_flags __attribute__ ((packed)); - -struct acpi_table_lapic { - acpi_madt_entry_header header; - u8 acpi_id; - u8 id; - struct { - u32 enabled:1; - u32 reserved:31; - } flags __attribute__ ((packed)); -} __attribute__ ((packed)); - -struct acpi_table_ioapic { - acpi_madt_entry_header header; - u8 id; - u8 reserved; - u32 address; - u32 global_irq_base; -} __attribute__ ((packed)); - -struct acpi_table_int_src_ovr { - acpi_madt_entry_header header; - u8 bus; - u8 bus_irq; - u32 global_irq; - acpi_madt_int_flags flags; -} __attribute__ ((packed)); - -struct acpi_table_nmi_src { - acpi_madt_entry_header header; - acpi_madt_int_flags flags; - u32 global_irq; -} __attribute__ ((packed)); - -struct acpi_table_lapic_nmi { - acpi_madt_entry_header header; - u8 acpi_id; - acpi_madt_int_flags flags; - u8 lint; -} __attribute__ ((packed)); - -struct acpi_table_lapic_addr_ovr { - acpi_madt_entry_header header; - u8 reserved[2]; - u64 address; -} __attribute__ ((packed)); - -struct acpi_table_iosapic { - acpi_madt_entry_header header; - u8 id; - u8 reserved; - u32 global_irq_base; - u64 address; -} __attribute__ ((packed)); - -struct acpi_table_lsapic { - acpi_madt_entry_header header; - u8 acpi_id; - u8 id; - u8 eid; - u8 reserved[3]; - struct { - u32 enabled:1; - u32 reserved:31; - } flags; -} __attribute__ ((packed)); - -struct acpi_table_plat_int_src { - acpi_madt_entry_header header; - acpi_madt_int_flags flags; - u8 type; - u8 id; - u8 eid; - u8 iosapic_vector; - u32 global_irq; - u32 reserved; -} __attribute__ ((packed)); - -/* - * ACPI Table Descriptor. One per ACPI table - */ -typedef struct acpi_table_desc { - struct acpi_table_desc *prev; - struct acpi_table_desc *next; - struct acpi_table_desc *installed_desc; - acpi_table_header *pointer; - void *base_pointer; - u8 *aml_pointer; - u64 physical_address; - u32 aml_length; - u32 length; - u32 count; - u16 table_id; - u8 type; - u8 allocation; - u8 loaded_into_namespace; - -} acpi_table_desc __attribute__ ((packed));; - -#endif diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c Mon Aug 18 22:21:05 2003 +++ b/arch/i386/kernel/acpi/boot.c Mon Aug 18 22:21:05 2003 @@ -39,6 +39,7 @@ #define PREFIX "ACPI: " extern int acpi_disabled; +extern int acpi_ht; /* -------------------------------------------------------------------------- Boot-time Configuration @@ -157,7 +158,7 @@ return 0; } -#ifndef CONFIG_ACPI_HT_ONLY +#ifdef CONFIG_ACPI static int __init acpi_parse_lapic_nmi ( @@ -177,7 +178,7 @@ return 0; } -#endif /*CONFIG_ACPI_HT_ONLY*/ +#endif /*CONFIG_ACPI*/ #endif /*CONFIG_X86_LOCAL_APIC*/ @@ -185,7 +186,7 @@ int acpi_ioapic; -#ifndef CONFIG_ACPI_HT_ONLY +#ifdef CONFIG_ACPI static int __init acpi_parse_ioapic ( @@ -247,7 +248,7 @@ return 0; } -#endif /*!CONFIG_ACPI_HT_ONLY*/ +#endif /*CONFIG_ACPI*/ #endif /*CONFIG_X86_IO_APIC*/ @@ -289,12 +290,34 @@ return rsdp_phys; } +/* + * acpi_boot_init() + * called from setup_arch(), always. + * 1. maps ACPI tables for later use + * 2. enumerates lapics + * 3. enumerates io-apics + * + * side effects: + * acpi_lapic = 1 if LAPIC found + * acpi_ioapic = 1 if IOAPIC found + * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; + * if acpi_blacklisted() acpi_disabled = 1; + * acpi_irq_model=... + * ... + * + * return value: (currently ignored) + * 0: success + * !0: failure + */ int __init acpi_boot_init (void) { int result = 0; + if (acpi_disabled && !acpi_ht) + return 1; + /* * The default interrupt routing model is PIC (8259). This gets * overriden if IOAPICs are enumerated (below). @@ -308,13 +331,14 @@ if (result) return result; +#ifdef CONFIG_ACPI result = acpi_blacklisted(); if (result) { + printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); acpi_disabled = 1; return result; } - else - printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n"); +#endif #ifdef CONFIG_X86_LOCAL_APIC @@ -365,27 +389,37 @@ return result; } -#ifndef CONFIG_ACPI_HT_ONLY +#ifdef CONFIG_ACPI result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); if (result < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ return result; } -#endif /*!CONFIG_ACPI_HT_ONLY*/ +#endif /*CONFIG_ACPI*/ acpi_lapic = 1; #endif /*CONFIG_X86_LOCAL_APIC*/ #ifdef CONFIG_X86_IO_APIC -#ifndef CONFIG_ACPI_HT_ONLY +#ifdef CONFIG_ACPI /* * I/O APIC * -------- */ + /* + * ACPI interpreter is required to complete interrupt setup, + * so if it is off, don't enumerate the io-apics with ACPI. + * If MPS is present, it will handle them, + * otherwise the system will stay in PIC mode + */ + if (acpi_disabled) { + return 1; + } + result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); if (!result) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); @@ -417,7 +451,7 @@ acpi_ioapic = 1; -#endif /*!CONFIG_ACPI_HT_ONLY*/ +#endif /*CONFIG_ACPI*/ #endif /*CONFIG_X86_IO_APIC*/ #ifdef CONFIG_X86_LOCAL_APIC diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c --- a/arch/i386/kernel/apic.c Mon Aug 18 22:21:06 2003 +++ b/arch/i386/kernel/apic.c Mon Aug 18 22:21:06 2003 @@ -52,6 +52,11 @@ /* IPI vectors for APIC spurious and error interrupts */ set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); + + /* thermal monitor LVT interrupt */ +#ifdef CONFIG_X86_MCE_P4THERMAL + set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); +#endif } /* Using APIC to generate smp_local_timer_interrupt? */ @@ -61,6 +66,8 @@ static DEFINE_PER_CPU(int, prof_old_multiplier) = 1; static DEFINE_PER_CPU(int, prof_counter) = 1; +static int enabled_via_apicbase; + void enable_NMI_through_LVT0 (void * dummy) { unsigned int v, ver; @@ -190,6 +197,13 @@ value = apic_read(APIC_SPIV); value &= ~APIC_SPIV_APIC_ENABLED; apic_write_around(APIC_SPIV, value); + + if (enabled_via_apicbase) { + unsigned int l, h; + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_ENABLE; + wrmsr(MSR_IA32_APICBASE, l, h); + } } /* @@ -485,7 +499,6 @@ static int lapic_suspend(struct sys_device *dev, u32 state) { - unsigned int l, h; unsigned long flags; if (!apic_pm_state.active) @@ -507,9 +520,6 @@ local_irq_save(flags); disable_local_APIC(); - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_ENABLE; - wrmsr(MSR_IA32_APICBASE, l, h); local_irq_restore(flags); return 0; } @@ -636,6 +646,7 @@ l &= ~MSR_IA32_APICBASE_BASE; l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; wrmsr(MSR_IA32_APICBASE, l, h); + enabled_via_apicbase = 1; } } /* @@ -1137,7 +1148,7 @@ connect_bsp_APIC(); - phys_cpu_present_map = 1 << boot_cpu_physical_apicid; + phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); setup_local_APIC(); diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c --- a/arch/i386/kernel/apm.c Mon Aug 18 22:21:01 2003 +++ b/arch/i386/kernel/apm.c Mon Aug 18 22:21:01 2003 @@ -508,16 +508,16 @@ #ifdef CONFIG_SMP -static unsigned long apm_save_cpus(void) +static cpumask_t apm_save_cpus(void) { - unsigned long x = current->cpus_allowed; + cpumask_t x = current->cpus_allowed; /* Some bioses don't like being called from CPU != 0 */ - set_cpus_allowed(current, 1UL << 0); + set_cpus_allowed(current, cpumask_of_cpu(0)); BUG_ON(smp_processor_id() != 0); return x; } -static inline void apm_restore_cpus(unsigned long mask) +static inline void apm_restore_cpus(cpumask_t mask) { set_cpus_allowed(current, mask); } @@ -528,7 +528,7 @@ * No CPU lockdown needed on a uniprocessor */ -#define apm_save_cpus() 0 +#define apm_save_cpus() (current->cpus_allowed) #define apm_restore_cpus(x) (void)(x) #endif @@ -593,7 +593,7 @@ { APM_DECL_SEGS unsigned long flags; - unsigned long cpus; + cpumask_t cpus; int cpu; struct desc_struct save_desc_40; @@ -635,7 +635,7 @@ u8 error; APM_DECL_SEGS unsigned long flags; - unsigned long cpus; + cpumask_t cpus; int cpu; struct desc_struct save_desc_40; @@ -913,7 +913,7 @@ */ #ifdef CONFIG_SMP /* Some bioses don't like being called from CPU != 0 */ - set_cpus_allowed(current, 1UL << 0); + set_cpus_allowed(current, cpumask_of_cpu(0)); BUG_ON(smp_processor_id() != 0); #endif if (apm_info.realmode_power_off) @@ -1704,7 +1704,7 @@ * Some bioses don't like being called from CPU != 0. * Method suggested by Ingo Molnar. */ - set_cpus_allowed(current, 1UL << 0); + set_cpus_allowed(current, cpumask_of_cpu(0)); BUG_ON(smp_processor_id() != 0); #endif diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Mon Aug 18 22:21:05 2003 +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Mon Aug 18 22:21:05 2003 @@ -53,10 +53,9 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) { u32 l, h; - unsigned long cpus_allowed; + cpumask_t cpus_allowed, affected_cpu_map; struct cpufreq_freqs freqs; int hyperthreading = 0; - int affected_cpu_map = 0; int sibling = 0; if (!cpu_online(cpu) || (newstate > DC_DISABLE) || @@ -67,16 +66,16 @@ cpus_allowed = current->cpus_allowed; /* only run on CPU to be set, or on its sibling */ - affected_cpu_map = 1 << cpu; + affected_cpu_map = cpumask_of_cpu(cpu); #ifdef CONFIG_X86_HT hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2)); if (hyperthreading) { sibling = cpu_sibling_map[cpu]; - affected_cpu_map |= (1 << sibling); + cpu_set(sibling, affected_cpu_map); } #endif set_cpus_allowed(current, affected_cpu_map); - BUG_ON(!(affected_cpu_map & (1 << smp_processor_id()))); + BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map)); /* get current state */ rdmsr(MSR_IA32_THERM_CONTROL, l, h); diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c Mon Aug 18 22:21:00 2003 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c Mon Aug 18 22:21:00 2003 @@ -230,8 +230,8 @@ freqs.cpu = 0; - cfid = fidvidstatus.bits.CFID; rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); + cfid = fidvidstatus.bits.CFID; freqs.old = fsb * fid_codes[cfid] * 100; freqs.new = powernow_table[index].frequency; diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c Mon Aug 18 22:21:05 2003 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c Mon Aug 18 22:21:05 2003 @@ -230,12 +230,12 @@ unsigned long flags; if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) - return EINVAL; + return -EINVAL; /* get current speed */ prev_speed = speedstep_get_processor_frequency(processor); if (!prev_speed) - return EIO; + return -EIO; local_irq_save(flags); @@ -243,7 +243,7 @@ set_state(SPEEDSTEP_LOW, 0); *low_speed = speedstep_get_processor_frequency(processor); if (!*low_speed) { - ret = EIO; + ret = -EIO; goto out; } @@ -251,12 +251,12 @@ set_state(SPEEDSTEP_HIGH, 0); *high_speed = speedstep_get_processor_frequency(processor); if (!*high_speed) { - ret = EIO; + ret = -EIO; goto out; } if (*low_speed == *high_speed) { - ret = ENODEV; + ret = -ENODEV; goto out; } diff -Nru a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c --- a/arch/i386/kernel/cpu/cyrix.c Mon Aug 18 22:21:01 2003 +++ b/arch/i386/kernel/cpu/cyrix.c Mon Aug 18 22:21:01 2003 @@ -109,7 +109,6 @@ static void __init set_cx86_reorder(void) { -#ifdef CONFIG_OOSTORE u8 ccr3; printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n"); @@ -118,12 +117,9 @@ /* Load/Store Serialize to mem access disable (=reorder it)  */ setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80); -#ifdef CONFIG_NOHIGHMEM /* set load/store serialize from 1GB to 4GB */ ccr3 |= 0xe0; -#endif setCx86(CX86_CCR3, ccr3); -#endif } static void __init set_cx86_memwb(void) diff -Nru a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c --- a/arch/i386/kernel/cpu/intel.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/cpu/intel.c Mon Aug 18 22:21:02 2003 @@ -11,7 +11,6 @@ #include "cpu.h" -static int disable_P4_HT __initdata = 0; extern int trap_init_f00f_bug(void); #ifdef CONFIG_X86_INTEL_USERCOPY @@ -68,13 +67,6 @@ return 0; } -static int __init P4_disable_ht(char *s) -{ - disable_P4_HT = 1; - return 1; -} -__setup("noht", P4_disable_ht); - #define LVL_1_INST 1 #define LVL_1_DATA 2 #define LVL_2 3 @@ -281,7 +273,7 @@ strcpy(c->x86_model_id, p); #ifdef CONFIG_X86_HT - if (cpu_has(c, X86_FEATURE_HT) && !disable_P4_HT) { + if (cpu_has(c, X86_FEATURE_HT)) { extern int phys_proc_id[NR_CPUS]; u32 eax, ebx, ecx, edx; @@ -329,8 +321,6 @@ } too_many_siblings: - if (disable_P4_HT) - clear_bit(X86_FEATURE_HT, c->x86_capability); #endif /* Work around errata */ diff -Nru a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c --- a/arch/i386/kernel/cpu/mtrr/generic.c Mon Aug 18 22:21:04 2003 +++ b/arch/i386/kernel/cpu/mtrr/generic.c Mon Aug 18 22:21:04 2003 @@ -8,6 +8,7 @@ #include #include #include +#include #include "mtrr.h" struct mtrr_state { @@ -241,18 +242,20 @@ more invasive changes to the way the kernel boots */ spin_lock(&set_atomicity_lock); + /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ + cr0 = read_cr0() | 0x40000000; /* set CD flag */ + wbinvd(); + write_cr0(cr0); + wbinvd(); + /* Save value of CR4 and clear Page Global Enable (bit 7) */ if ( cpu_has_pge ) { cr4 = read_cr4(); write_cr4(cr4 & (unsigned char) ~(1 << 7)); } - /* Disable and flush caches. Note that wbinvd flushes the TLBs as - a side-effect */ - cr0 = read_cr0() | 0x40000000; - wbinvd(); - write_cr0(cr0); - wbinvd(); + /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ + __flush_tlb(); /* Save MTRR state */ rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); @@ -265,6 +268,7 @@ { /* Flush caches and TLBs */ wbinvd(); + __flush_tlb(); /* Intel (P6) standard MTRRs */ wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); diff -Nru a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c --- a/arch/i386/kernel/cpu/proc.c Mon Aug 18 22:21:05 2003 +++ b/arch/i386/kernel/cpu/proc.c Mon Aug 18 22:21:05 2003 @@ -60,7 +60,7 @@ int fpu_exception; #ifdef CONFIG_SMP - if (!(cpu_online_map & (1<f_dentry->d_inode->i_rdev); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; - if ( !(cpu_online_map & (1UL << cpu)) ) + if (!cpu_online(cpu)) return -ENXIO; /* No such CPU */ if ( c->cpuid_level < 0 ) return -EIO; /* CPUID not supported */ diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c --- a/arch/i386/kernel/dmi_scan.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/dmi_scan.c Mon Aug 18 22:21:02 2003 @@ -129,10 +129,10 @@ * the SMBIOS version, which we don't know at this point. */ if(buf[14]!=0) - dmi_printk((KERN_INFO "DMI %d.%d present.\n", - buf[14]>>4, buf[14]&0x0F)); + printk(KERN_INFO "DMI %d.%d present.\n", + buf[14]>>4, buf[14]&0x0F); else - dmi_printk((KERN_INFO "DMI present.\n")); + printk(KERN_INFO "DMI present.\n"); dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", num, len)); dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", @@ -162,6 +162,20 @@ static char *dmi_ident[DMI_STRING_MAX]; +/* print some information suitable for a blacklist entry. */ +static void dmi_dump_system(void) +{ + printk("DMI: BIOS: %.40s, %.40s, %.40s\n", + dmi_ident[DMI_BIOS_VENDOR], dmi_ident[DMI_BIOS_VERSION], + dmi_ident[DMI_BIOS_DATE]); + printk("DMI: System: %.40s, %.40s, %.40s\n", + dmi_ident[DMI_SYS_VENDOR], dmi_ident[DMI_PRODUCT_NAME], + dmi_ident[DMI_PRODUCT_VERSION]); + printk("DMI: Board: %.40s, %.40s, %.40s\n", + dmi_ident[DMI_BOARD_VENDOR], dmi_ident[DMI_BOARD_NAME], + dmi_ident[DMI_BOARD_VERSION]); +} + /* * Save a DMI string */ @@ -416,6 +430,17 @@ } /* + * 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. */ @@ -489,6 +514,54 @@ return 0; } + +extern int acpi_disabled, acpi_force; +extern int skip_ioapic_setup; + +static __init __attribute__((unused)) int acpi_disable(struct dmi_blacklist *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); + acpi_disabled = 1; + } else { + printk(KERN_NOTICE + "Warning: DMI blacklist says broken, but acpi forced\n"); + } + return 0; +} + + +#ifdef CONFIG_ACPI_BOOT +extern int acpi_ht; + +/* + * Limit ACPI to CPU enumeration for HT + */ +static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d) +{ + if (!acpi_force) { + printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); + acpi_disabled = 1; + acpi_ht = 1; + } else { + printk(KERN_NOTICE + "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); + } + return 0; +} +#endif + +#ifdef CONFIG_ACPI_PCI +static __init int disable_acpi_pci(struct dmi_blacklist *d) +{ + extern __init void pci_disable_acpi(void) ; + + printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident); + pci_disable_acpi(); + return 0; +} +#endif + /* * Process the DMI blacklists */ @@ -551,6 +624,11 @@ MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), NO_MATCH, NO_MATCH } }, + { apm_is_horked, "ABIT KX7-333[R]", { /* APM blows on shutdown */ + MATCH(DMI_BOARD_VENDOR, "ABIT"), + MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), + NO_MATCH, NO_MATCH, + } }, { apm_is_horked, "Trigem Delhi3", { /* APM crashes */ MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"), MATCH(DMI_PRODUCT_NAME, "Delhi3"), @@ -734,6 +812,12 @@ 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 */ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), NO_MATCH, NO_MATCH, NO_MATCH @@ -792,6 +876,117 @@ NO_MATCH, NO_MATCH, } }, +#ifdef CONFIG_ACPI_BOOT + /* + * If your system is blacklisted here, but you find that acpi=force + * works for you, please contact acpi-devel@sourceforge.net + */ + + /* + * Boxes that need ACPI disabled + */ + + { acpi_disable, "IBM Thinkpad", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "2629H1G"), + NO_MATCH, NO_MATCH }}, + + /* + * Boxes that need acpi=ht + */ + + { force_acpi_ht, "FSC Primergy T850", { + MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "DELL GX240", { + MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "HP VISUALIZE NT Workstation", { + MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq ProLiant DL380 G2", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "ProLiant DL380 G2"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq ProLiant ML530 G2", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "ProLiant ML530 G2"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq ProLiant ML350 G3", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "ProLiant ML350 G3"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "Compaq Workstation W8000", { + MATCH(DMI_SYS_VENDOR, "Compaq"), + MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS P4B266", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "P4B266"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS P2B-DS", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "P2B-DS"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS CUR-DLS", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "CUR-DLS"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "ASUS A7V", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), + MATCH(DMI_BOARD_NAME, ""), + MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }}, + + { force_acpi_ht, "ABIT i440BX-W83977", { + MATCH(DMI_BOARD_VENDOR, "ABIT "), + MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM Bladecenter", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM eServer xSeries 360", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM eserver xSeries 330", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), + NO_MATCH, NO_MATCH }}, + + { force_acpi_ht, "IBM eserver xSeries 440", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), + NO_MATCH, NO_MATCH }}, +#endif // CONFIG_ACPI_BOOT + +#ifdef CONFIG_ACPI_PCI + /* + * Boxes that need ACPI PCI IRQ routing disabled + */ + + { disable_acpi_pci, "ASUS A7V", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), + MATCH(DMI_BOARD_NAME, ""), + MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }}, +#endif + { NULL, } }; @@ -801,11 +996,31 @@ * returns 1 or we hit the end. */ +#define ACPI_BLACKLIST_CUTOFF_YEAR 2001 + static __init void dmi_check_blacklist(void) { struct dmi_blacklist *d; int i; + if (dmi_ident[DMI_BIOS_DATE]) { + char *s = strrchr(dmi_ident[DMI_BIOS_DATE], '/'); + if (s) { + int year, disable = 0; + s++; + year = simple_strtoul(s,NULL,0); + if (year >= 1000) + disable = year < ACPI_BLACKLIST_CUTOFF_YEAR; + else if (year < 1 || (year > 90 && year <= 99)) + disable = 1; + if (disable && !acpi_force) { + printk(KERN_NOTICE "ACPI disabled because your bios is from %s and too old\n", s); + printk(KERN_NOTICE "You can enable it with acpi=force\n"); + acpi_disabled = 1; + } + } + } + d=&dmi_blacklist[0]; while(d->callback) { @@ -885,6 +1100,32 @@ int err = dmi_iterate(dmi_decode); if(err == 0) dmi_check_blacklist(); + else + printk(KERN_INFO "DMI not present.\n"); } EXPORT_SYMBOL(is_unsafe_smbus); + +#ifdef CONFIG_MOUNT_ROOT_FAILED_MSG +/* + * mount_root_failed_msg() + * + * Called from mount_block_root() upon failure to mount root. + * architecture dependent to give different platforms + * the opportunity to print different handy messages + * On x86 this lives here b/c it dumps out some DMI info. + */ + +void +mount_root_failed_msg(void) +{ +#ifdef CONFIG_ACPI_BOOT + printk ("Try booting with pci=noacpi, acpi=ht, " + "or acpi=off on the command line.\n"); + printk ("If one helps, please report the following lines:\n"); + + dmi_dump_system(); +#endif +} +#endif /* CONFIG_MOUNT_ROOT_FAILED_MSG */ + diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S --- a/arch/i386/kernel/entry.S Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/entry.S Mon Aug 18 22:21:02 2003 @@ -878,5 +878,6 @@ .long sys_fstatfs64 .long sys_tgkill /* 270 */ .long sys_utimes - + .long sys_fadvise64_64 + nr_syscalls=(.-sys_call_table)/4 diff -Nru a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S --- a/arch/i386/kernel/head.S Mon Aug 18 22:21:01 2003 +++ b/arch/i386/kernel/head.S Mon Aug 18 22:21:01 2003 @@ -35,7 +35,7 @@ #define X86_HARD_MATH CPU_PARAMS+6 #define X86_CPUID CPU_PARAMS+8 #define X86_CAPABILITY CPU_PARAMS+12 -#define X86_VENDOR_ID CPU_PARAMS+28 +#define X86_VENDOR_ID CPU_PARAMS+36 /* offset dependent on NCAPINTS */ /* * Initialize page tables diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/io_apic.c Mon Aug 18 22:21:02 2003 @@ -249,14 +249,14 @@ clear_IO_APIC_pin(apic, pin); } -static void set_ioapic_affinity (unsigned int irq, unsigned long cpu_mask) +static void set_ioapic_affinity(unsigned int irq, cpumask_t cpumask) { unsigned long flags; int pin; struct irq_pin_list *entry = irq_2_pin + irq; unsigned int apicid_value; - apicid_value = cpu_mask_to_apicid(cpu_mask); + apicid_value = cpu_mask_to_apicid(mk_cpumask_const(cpumask)); /* Prepare to do the io_apic_write */ apicid_value = apicid_value << 24; spin_lock_irqsave(&ioapic_lock, flags); @@ -286,9 +286,9 @@ # define Dprintk(x...) # endif -extern unsigned long irq_affinity[NR_IRQS]; +extern cpumask_t irq_affinity[NR_IRQS]; -static int __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; +static cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; #define IRQBALANCE_CHECK_ARCH -999 static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; @@ -307,8 +307,7 @@ #define IDLE_ENOUGH(cpu,now) \ (idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1)) -#define IRQ_ALLOWED(cpu,allowed_mask) \ - ((1 << cpu) & (allowed_mask)) +#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask) #define CPU_TO_PACKAGEINDEX(i) \ ((physical_balance && i > cpu_sibling_map[i]) ? cpu_sibling_map[i] : i) @@ -320,7 +319,7 @@ long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; -static unsigned long move(int curr_cpu, unsigned long allowed_mask, +static unsigned long move(int curr_cpu, cpumask_t allowed_mask, unsigned long now, int direction) { int search_idle = 1; @@ -350,20 +349,20 @@ static inline void balance_irq(int cpu, int irq) { unsigned long now = jiffies; - unsigned long allowed_mask; + cpumask_t allowed_mask; unsigned int new_cpu; if (irqbalance_disabled) return; - allowed_mask = cpu_online_map & irq_affinity[irq]; + cpus_and(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; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); - pending_irq_balance_cpumask[irq] = 1 << new_cpu; + pending_irq_balance_cpumask[irq] = cpumask_of_cpu(new_cpu); spin_unlock_irqrestore(&desc->lock, flags); } } @@ -399,8 +398,7 @@ int tmp_loaded, first_attempt = 1; unsigned long tmp_cpu_irq; unsigned long imbalance = 0; - unsigned long allowed_mask; - unsigned long target_cpu_mask; + cpumask_t allowed_mask, target_cpu_mask, tmp; for (i = 0; i < NR_CPUS; i++) { int package_index; @@ -549,10 +547,11 @@ 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; + cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); + target_cpu_mask = cpumask_of_cpu(min_loaded); + cpus_and(tmp, target_cpu_mask, allowed_mask); - if (target_cpu_mask & allowed_mask) { + if (!cpus_empty(tmp)) { irq_desc_t *desc = irq_desc + selected_irq; unsigned long flags; @@ -560,7 +559,8 @@ selected_irq, min_loaded); /* mark for change destination */ spin_lock_irqsave(&desc->lock, flags); - pending_irq_balance_cpumask[selected_irq] = 1 << min_loaded; + pending_irq_balance_cpumask[selected_irq] = + cpumask_of_cpu(min_loaded); spin_unlock_irqrestore(&desc->lock, flags); /* Since we made a change, come back sooner to * check for more variation. @@ -591,8 +591,9 @@ daemonize("kirqd"); /* push everything to CPU 0 to give us a starting point. */ - for (i = 0 ; i < NR_IRQS ; i++) - pending_irq_balance_cpumask[i] = 1; + for (i = 0 ; i < NR_IRQS ; i++) { + pending_irq_balance_cpumask[i] = cpumask_of_cpu(0); + } repeat: set_current_state(TASK_INTERRUPTIBLE); @@ -611,7 +612,9 @@ { int i; struct cpuinfo_x86 *c; + cpumask_t tmp; + cpus_shift_right(tmp, cpu_online_map, 2); c = &boot_cpu_data; /* When not overwritten by the command line ask subarchitecture. */ if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) @@ -628,7 +631,7 @@ * Enable physical balance only if more than 1 physical processor * is present */ - if (smp_num_siblings > 1 && cpu_online_map >> 2) + if (smp_num_siblings > 1 && !cpus_empty(tmp)) physical_balance = 1; for (i = 0; i < NR_CPUS; i++) { @@ -667,14 +670,14 @@ __setup("noirqbalance", irqbalance_disable); -static void set_ioapic_affinity (unsigned int irq, unsigned long mask); +static void set_ioapic_affinity(unsigned int irq, cpumask_t mask); static inline void move_irq(int irq) { /* note - we hold the desc->lock */ - if (unlikely(pending_irq_balance_cpumask[irq])) { + if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) { set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]); - pending_irq_balance_cpumask[irq] = 0; + cpus_clear(pending_irq_balance_cpumask[irq]); } } @@ -837,7 +840,7 @@ * we need to reprogram the ioredtbls to cater for the cpus which have come online * so mask in all cases should simply be TARGET_CPUS */ -void __init setup_ioapic_dest (unsigned long mask) +void __init setup_ioapic_dest(cpumask_t mask) { int pin, ioapic, irq, irq_entry; @@ -1613,7 +1616,7 @@ static void __init setup_ioapic_ids_from_mpc(void) { union IO_APIC_reg_00 reg_00; - unsigned long phys_id_present_map; + physid_mask_t phys_id_present_map; int apic; int i; unsigned char old_id; @@ -1623,6 +1626,10 @@ /* This gets done during IOAPIC enumeration for ACPI. */ return; + /* + * This is broken; anything with a real cpu count has to + * circumvent this idiocy regardless. + */ phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map); /* @@ -1654,18 +1661,20 @@ mp_ioapics[apic].mpc_apicid)) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", apic, mp_ioapics[apic].mpc_apicid); - for (i = 0; i < 0xf; i++) - if (!(phys_id_present_map & (1 << i))) + for (i = 0; i < APIC_BROADCAST_ID; i++) + if (!physid_isset(i, phys_id_present_map)) break; - if (i >= 0xf) + if (i >= APIC_BROADCAST_ID) panic("Max APIC ID exceeded!\n"); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", i); - phys_id_present_map |= 1 << i; + physid_set(i, phys_id_present_map); mp_ioapics[apic].mpc_apicid = i; } else { + physid_mask_t tmp; + tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid); printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid); - phys_id_present_map |= apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid); + physids_or(phys_id_present_map, phys_id_present_map, tmp); } @@ -2235,7 +2244,8 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; - static unsigned long apic_id_map = 0; + static physid_mask_t apic_id_map = PHYSID_MASK_NONE; + physid_mask_t tmp; unsigned long flags; int i = 0; @@ -2248,8 +2258,8 @@ * advantage of new APIC bus architecture. */ - if (!apic_id_map) - apic_id_map = phys_cpu_present_map; + if (physids_empty(apic_id_map)) + apic_id_map = ioapic_phys_id_map(phys_cpu_present_map); spin_lock_irqsave(&ioapic_lock, flags); reg_00.raw = io_apic_read(ioapic, 0); @@ -2281,7 +2291,8 @@ apic_id = i; } - apic_id_map |= apicid_to_cpu_present(apic_id); + tmp = apicid_to_cpu_present(apic_id); + physids_or(apic_id_map, apic_id_map, tmp); if (reg_00.bits.ID != apic_id) { reg_00.bits.ID = apic_id; @@ -2328,7 +2339,7 @@ } -int io_apic_set_pci_routing (int ioapic, int pin, int irq) +int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) { struct IO_APIC_route_entry entry; unsigned long flags; @@ -2350,19 +2361,23 @@ entry.delivery_mode = INT_DELIVERY_MODE; entry.dest_mode = INT_DEST_MODE; entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - entry.mask = 1; /* Disabled (masked) */ - entry.trigger = 1; /* Level sensitive */ - entry.polarity = 1; /* Low active */ + entry.trigger = edge_level; + entry.polarity = active_high_low; + entry.mask = 1; add_pin_to_irq(irq, ioapic, pin); entry.vector = assign_irq_vector(irq); printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " - "IRQ %d)\n", ioapic, - mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq); + "IRQ %d Mode:%i Active:%i)\n", ioapic, + mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low); + if (edge_level) { irq_desc[irq].handler = &ioapic_level_irq_type; + } else { + irq_desc[irq].handler = &ioapic_edge_irq_type; + } set_intr_gate(entry.vector, interrupt[irq]); diff -Nru a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c --- a/arch/i386/kernel/ioport.c Mon Aug 18 22:21:03 2003 +++ b/arch/i386/kernel/ioport.c Mon Aug 18 22:21:03 2003 @@ -17,32 +17,32 @@ #include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ -static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) +static void set_bitmap(unsigned long *bitmap, unsigned long base, unsigned long extent, int new_value) { - int mask; - unsigned long *bitmap_base = bitmap + (base >> 5); - unsigned short low_index = base & 0x1f; + unsigned long mask; + unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG); + unsigned long low_index = base & (BITS_PER_LONG-1); int length = low_index + extent; if (low_index != 0) { - mask = (~0 << low_index); - if (length < 32) - mask &= ~(~0 << length); + mask = (~0UL << low_index); + if (length < BITS_PER_LONG) + mask &= ~(~0UL << length); if (new_value) *bitmap_base++ |= mask; else *bitmap_base++ &= ~mask; - length -= 32; + length -= BITS_PER_LONG; } - mask = (new_value ? ~0 : 0); - while (length >= 32) { + mask = (new_value ? ~0UL : 0UL); + while (length >= BITS_PER_LONG) { *bitmap_base++ = mask; - length -= 32; + length -= BITS_PER_LONG; } if (length > 0) { - mask = ~(~0 << length); + mask = ~(~0UL << length); if (new_value) *bitmap_base++ |= mask; else @@ -53,7 +53,7 @@ /* * this changes the io permissions bitmap in the current task. */ -asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) +asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) { struct thread_struct * t = ¤t->thread; struct tss_struct * tss; @@ -111,7 +111,7 @@ * code. */ -asmlinkage int sys_iopl(unsigned long unused) +asmlinkage long sys_iopl(unsigned long unused) { volatile struct pt_regs * regs = (struct pt_regs *) &unused; unsigned int level = regs->ebx; @@ -124,7 +124,7 @@ if (!capable(CAP_SYS_RAWIO)) return -EPERM; } - regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12); + regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12); /* Make sure we return the long way (not sysenter) */ set_thread_flag(TIF_IRET); return 0; diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c --- a/arch/i386/kernel/irq.c Mon Aug 18 22:21:01 2003 +++ b/arch/i386/kernel/irq.c Mon Aug 18 22:21:01 2003 @@ -45,8 +45,6 @@ #include #include - - /* * Linux has a controller-independent x86 interrupt architecture. * every controller has a 'controller-template', that is used @@ -889,13 +887,13 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; -#define HEX_DIGITS 8 +#define HEX_DIGITS (2*sizeof(cpumask_t)) -static unsigned int parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) +static unsigned int parse_hex_value(const char __user *buffer, + unsigned long count, cpumask_t *ret) { - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; + unsigned char hexnum[HEX_DIGITS]; + cpumask_t value = CPU_MASK_NONE; int i; if (!count) @@ -909,10 +907,10 @@ * Parse the first 8 characters as a hex string, any non-hex char * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ - value = 0; for (i = 0; i < count; i++) { unsigned int c = hexnum[i]; + int k; switch (c) { case '0' ... '9': c -= '0'; break; @@ -921,7 +919,10 @@ default: goto out; } - value = (value << 4) | c; + cpus_shift_left(value, value, 4); + for (k = 0; k < 4; ++k) + if (test_bit(k, (unsigned long *)&c)) + cpu_set(k, value); } out: *ret = value; @@ -930,22 +931,35 @@ #ifdef CONFIG_SMP -static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; +static struct proc_dir_entry *smp_affinity_entry[NR_IRQS]; + +cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; -unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; -static int irq_affinity_read_proc (char *page, char **start, off_t off, +static int irq_affinity_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + int k, len; + cpumask_t tmp = irq_affinity[(long)data]; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", irq_affinity[(long)data]); + + len = 0; + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } -static int irq_affinity_write_proc (struct file *file, const char __user *buffer, +static int irq_affinity_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { - int irq = (long) data, full_count = count, err; - unsigned long new_value; + int irq = (long)data, full_count = count, err; + cpumask_t new_value, tmp; if (!irq_desc[irq].handler->set_affinity) return -EIO; @@ -957,11 +971,13 @@ * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - if (!(new_value & cpu_online_map)) + cpus_and(tmp, new_value, cpu_online_map); + if (cpus_empty(tmp)) return -EINVAL; irq_affinity[irq] = new_value; - irq_desc[irq].handler->set_affinity(irq, new_value); + irq_desc[irq].handler->set_affinity(irq, + cpumask_of_cpu(first_cpu(new_value))); return full_count; } @@ -980,8 +996,9 @@ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + cpumask_t *mask = (cpumask_t *)data; + unsigned long full_count = count, err; + cpumask_t new_value; err = parse_hex_value(buffer, count, &new_value); if (err) diff -Nru a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c --- a/arch/i386/kernel/ldt.c Mon Aug 18 22:21:04 2003 +++ b/arch/i386/kernel/ldt.c Mon Aug 18 22:21:04 2003 @@ -56,9 +56,11 @@ if (reload) { #ifdef CONFIG_SMP + cpumask_t mask; preempt_disable(); load_LDT(pc); - if (current->mm->cpu_vm_mask != (1 << smp_processor_id())) + mask = cpumask_of_cpu(smp_processor_id()); + if (!cpus_equal(current->mm->cpu_vm_mask, mask)) smp_call_function(flush_ldt, 0, 1, 1); preempt_enable(); #else diff -Nru a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c --- a/arch/i386/kernel/mca.c Mon Aug 18 22:21:05 2003 +++ b/arch/i386/kernel/mca.c Mon Aug 18 22:21:05 2003 @@ -295,7 +295,7 @@ mca_dev->pos_register = 0x7f; outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); - mca_dev->dev.name[0] = 0; + mca_dev->name[0] = 0; mca_read_and_store_pos(mca_dev->pos); mca_configure_adapter_status(mca_dev); /* fake POS and slot for a motherboard */ @@ -315,7 +315,7 @@ mca_dev->pos_register = 0xdf; outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); - mca_dev->dev.name[0] = 0; + mca_dev->name[0] = 0; mca_read_and_store_pos(mca_dev->pos); mca_configure_adapter_status(mca_dev); /* fake POS and slot for the integrated video */ @@ -414,13 +414,13 @@ if(slot == MCA_INTEGSCSI) { printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n", - mca_dev->dev.name); + mca_dev->name); } else if(slot == MCA_INTEGVIDEO) { printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n", - mca_dev->dev.name); + mca_dev->name); } else if(slot == MCA_MOTHERBOARD) { printk(KERN_CRIT "NMI: caused by motherboard (%s)\n", - mca_dev->dev.name); + mca_dev->name); } /* More info available in POS 6 and 7? */ diff -Nru a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c --- a/arch/i386/kernel/microcode.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/microcode.c Mon Aug 18 22:21:02 2003 @@ -89,15 +89,6 @@ #define printf(x...) #endif -/* VFS interface */ -static int microcode_open(struct inode *, struct file *); -static ssize_t microcode_read(struct file *, char *, size_t, loff_t *); -static ssize_t microcode_write(struct file *, const char *, size_t, loff_t *); -static int microcode_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - -static int do_microcode_update(void); -static void do_update_one(void *); - /* read()/write()/ioctl() are serialized on this */ static DECLARE_RWSEM(microcode_rwsem); @@ -106,46 +97,6 @@ static char *mc_applied; /* array of applied microcode blocks */ static unsigned int mc_fsize; /* file size of /dev/cpu/microcode */ -static struct file_operations microcode_fops = { - .owner = THIS_MODULE, - .read = microcode_read, - .write = microcode_write, - .ioctl = microcode_ioctl, - .open = microcode_open, -}; - -static struct miscdevice microcode_dev = { - .minor = MICROCODE_MINOR, - .name = "microcode", - .devfs_name = "cpu/microcode", - .fops = µcode_fops, -}; - -static int __init microcode_init(void) -{ - int error; - - error = misc_register(µcode_dev); - if (error) - return error; - - printk(KERN_INFO - "IA-32 Microcode Update Driver: v%s \n", - MICROCODE_VERSION); - return 0; -} - -static void __exit microcode_exit(void) -{ - misc_deregister(µcode_dev); - kfree(mc_applied); - printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", - MICROCODE_VERSION); -} - -module_init(microcode_init) -module_exit(microcode_exit) - static int microcode_open(struct inode *unused1, struct file *unused2) { return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; @@ -160,27 +111,6 @@ int slot; } update_req[NR_CPUS]; -static int do_microcode_update(void) -{ - int i, error = 0, err; - struct microcode *m; - - if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) { - printk(KERN_ERR "microcode: IPI timeout, giving up\n"); - return -EIO; - } - - for (i=0; i\n", + MICROCODE_VERSION); + return 0; +} + +static void __exit microcode_exit(void) +{ + misc_deregister(µcode_dev); + kfree(mc_applied); + printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", + MICROCODE_VERSION); +} + +module_init(microcode_init) +module_exit(microcode_exit) + diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/mpparse.c Mon Aug 18 22:21:02 2003 @@ -71,7 +71,7 @@ static unsigned int __initdata num_processors; /* Bitmask of physically existing CPUs */ -unsigned long phys_cpu_present_map; +physid_mask_t phys_cpu_present_map; u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; @@ -106,6 +106,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) { int ver, apicid; + physid_mask_t tmp; if (!(m->mpc_cpuflag & CPU_ENABLED)) return; @@ -176,7 +177,8 @@ } ver = m->mpc_apicver; - phys_cpu_present_map |= apicid_to_cpu_present(apicid); + tmp = apicid_to_cpu_present(apicid); + physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp); /* * Validate version @@ -620,7 +622,7 @@ /* * ACPI may be used to obtain the entire SMP configuration or just to - * enumerate/configure processors (CONFIG_ACPI_HT_ONLY). Note that + * enumerate/configure processors (CONFIG_ACPI_HT). Note that * ACPI supports both logical (e.g. Hyper-Threading) and physical * processors, where MPS only supports physical. */ @@ -1011,8 +1013,9 @@ panic("Max # of irq sources exceeded!\n"); } } +#endif /* CONFIG_X86_IO_APIC */ -#ifndef CONFIG_ACPI_HT_ONLY +#ifdef CONFIG_ACPI /* Ensure the ACPI SCI interrupt level is active low, edge-triggered */ @@ -1065,10 +1068,9 @@ ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; - io_apic_set_pci_routing(ioapic, ioapic_pin, irq); + io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered } - -#endif /*CONFIG_ACPI_HT_ONLY*/ +#endif /* CONFIG_ACPI */ #ifdef CONFIG_ACPI_PCI @@ -1080,6 +1082,8 @@ int ioapic_pin = 0; int irq = 0; int idx, bit = 0; + int edge_level = 0; + int active_high_low = 0; /* * Parsing through the PCI Interrupt Routing Table (PRT) and program @@ -1090,12 +1094,16 @@ /* Need to get irq for dynamic entry */ if (entry->link.handle) { - irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index); + irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); if (!irq) continue; } - else + else { + /* Hardwired IRQ. Assume PCI standard settings */ irq = entry->link.index; + edge_level = 1; + active_high_low = 1; + } /* Don't set up the ACPI SCI because it's already set up */ if (acpi_fadt.sci_int == irq) @@ -1130,7 +1138,7 @@ mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = irq; printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", @@ -1139,12 +1147,8 @@ mp_ioapic_routing[ioapic].apic_id, ioapic_pin, entry->irq); } - - return; } #endif /*CONFIG_ACPI_PCI*/ - -#endif /*CONFIG_X86_IO_APIC*/ #endif /*CONFIG_ACPI_BOOT*/ diff -Nru a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c --- a/arch/i386/kernel/msr.c Mon Aug 18 22:21:03 2003 +++ b/arch/i386/kernel/msr.c Mon Aug 18 22:21:03 2003 @@ -187,7 +187,7 @@ return ret; } -static ssize_t msr_read(struct file * file, char * buf, +static ssize_t msr_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { u32 *tmp = (u32 *)buf; @@ -212,7 +212,7 @@ return ((char *)tmp) - buf; } -static ssize_t msr_write(struct file * file, const char * buf, +static ssize_t msr_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { const u32 *tmp = (const u32 *)buf; @@ -242,7 +242,7 @@ int cpu = minor(file->f_dentry->d_inode->i_rdev); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; - if ( !(cpu_online_map & (1UL << cpu)) ) + if (!cpu_online(cpu)) return -ENXIO; /* No such CPU */ if ( !cpu_has(c, X86_FEATURE_MSR) ) return -EIO; /* MSR not supported */ diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c --- a/arch/i386/kernel/reboot.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/kernel/reboot.c Mon Aug 18 22:21:02 2003 @@ -8,6 +8,7 @@ #include #include #include +#include #include "mach_reboot.h" /* @@ -15,7 +16,6 @@ */ void (*pm_power_off)(void); -static long no_idt[2]; static int reboot_mode; int reboot_thru_bios; @@ -86,7 +86,9 @@ unsigned long long * base __attribute__ ((packed)); } real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries }, -real_mode_idt = { 0x3ff, 0 }; +real_mode_idt = { 0x3ff, 0 }, +no_idt = { 0, 0 }; + /* This is 16-bit protected mode code to disable paging and the cache, switch to real mode and jump to the BIOS reset code. @@ -226,7 +228,7 @@ if its not, default to the BSP */ if ((reboot_cpu == -1) || (reboot_cpu > (NR_CPUS -1)) || - !(phys_cpu_present_map & (1< */ -static volatile unsigned long flush_cpumask; +static cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED; @@ -255,7 +258,7 @@ { if (cpu_tlbstate[cpu].state == TLBSTATE_OK) BUG(); - clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask); + cpu_clear(cpu, cpu_tlbstate[cpu].active_mm->cpu_vm_mask); load_cr3(swapper_pg_dir); } @@ -265,7 +268,7 @@ * [cpu0: the cpu that switches] * 1) switch_mm() either 1a) or 1b) * 1a) thread switch to a different mm - * 1a1) clear_bit(cpu, &old_mm->cpu_vm_mask); + * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); * Stop ipi delivery for the old mm. This is not synchronized with * the other cpus, but smp_invalidate_interrupt ignore flush ipis * for the wrong mm, and in the worst case we perform a superflous @@ -275,7 +278,7 @@ * was in lazy tlb mode. * 1a3) update cpu_tlbstate[].active_mm * Now cpu0 accepts tlb flushes for the new mm. - * 1a4) set_bit(cpu, &new_mm->cpu_vm_mask); + * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); * Now the other cpus will send tlb flush ipis. * 1a4) change cr3. * 1b) thread switch without mm change @@ -311,7 +314,7 @@ cpu = get_cpu(); - if (!test_bit(cpu, &flush_cpumask)) + if (!cpu_isset(cpu, flush_cpumask)) goto out; /* * This was a BUG() but until someone can quote me the @@ -332,15 +335,17 @@ leave_mm(cpu); } ack_APIC_irq(); - clear_bit(cpu, &flush_cpumask); - + smp_mb__before_clear_bit(); + cpu_clear(cpu, flush_cpumask); + smp_mb__after_clear_bit(); out: put_cpu_no_resched(); } -static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, +static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, unsigned long va) { + cpumask_t tmp; /* * A couple of (to be removed) sanity checks: * @@ -348,14 +353,12 @@ * - current CPU must not be in mask * - mask must exist :) */ - if (!cpumask) - BUG(); - if ((cpumask & cpu_online_map) != cpumask) - BUG(); - if (cpumask & (1 << smp_processor_id())) - BUG(); - if (!mm) - BUG(); + BUG_ON(cpus_empty(cpumask)); + + cpus_and(tmp, cpumask, cpu_online_map); + BUG_ON(!cpus_equal(cpumask, tmp)); + BUG_ON(cpu_isset(smp_processor_id(), cpumask)); + BUG_ON(!mm); /* * i'm not happy about this global shared spinlock in the @@ -367,15 +370,26 @@ flush_mm = mm; flush_va = va; +#if NR_CPUS <= BITS_PER_LONG atomic_set_mask(cpumask, &flush_cpumask); +#else + { + int k; + unsigned long *flush_mask = (unsigned long *)&flush_cpumask; + unsigned long *cpu_mask = (unsigned long *)&cpumask; + for (k = 0; k < BITS_TO_LONGS(NR_CPUS); ++k) + atomic_set_mask(cpu_mask[k], &flush_mask[k]); + } +#endif /* * We have to send the IPI only to * CPUs affected. */ send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR); - while (flush_cpumask) - /* nothing. lockup detection does not belong here */; + while (!cpus_empty(flush_cpumask)) + /* nothing. lockup detection does not belong here */ + mb(); flush_mm = NULL; flush_va = 0; @@ -385,23 +399,25 @@ void flush_tlb_current_task(void) { struct mm_struct *mm = current->mm; - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); local_flush_tlb(); - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } void flush_tlb_mm (struct mm_struct * mm) { - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); if (current->active_mm == mm) { if (current->mm) @@ -409,7 +425,7 @@ else leave_mm(smp_processor_id()); } - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); @@ -418,10 +434,11 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) { struct mm_struct *mm = vma->vm_mm; - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); if (current->active_mm == mm) { if(current->mm) @@ -430,7 +447,7 @@ leave_mm(smp_processor_id()); } - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, va); preempt_enable(); @@ -457,7 +474,7 @@ */ void smp_send_reschedule(int cpu) { - send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); + send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); } /* @@ -533,7 +550,7 @@ /* * Remove this CPU: */ - clear_bit(smp_processor_id(), &cpu_online_map); + cpu_clear(smp_processor_id(), cpu_online_map); local_irq_disable(); disable_local_APIC(); if (cpu_data[smp_processor_id()].hlt_works_ok) diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c --- a/arch/i386/kernel/smpboot.c Mon Aug 18 22:21:03 2003 +++ b/arch/i386/kernel/smpboot.c Mon Aug 18 22:21:03 2003 @@ -61,12 +61,12 @@ int smp_num_siblings = 1; int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ -/* Bitmask of currently online CPUs */ -unsigned long cpu_online_map; +/* bitmap of online cpus */ +cpumask_t cpu_online_map; -static volatile unsigned long cpu_callin_map; -volatile unsigned long cpu_callout_map; -static unsigned long smp_commenced_mask; +static cpumask_t cpu_callin_map; +cpumask_t cpu_callout_map; +static cpumask_t smp_commenced_mask; /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; @@ -268,7 +268,7 @@ sum = 0; for (i = 0; i < NR_CPUS; i++) { - if (test_bit(i, &cpu_callout_map)) { + if (cpu_isset(i, cpu_callout_map)) { t0 = tsc_values[i]; sum += t0; } @@ -277,7 +277,7 @@ sum = 0; for (i = 0; i < NR_CPUS; i++) { - if (!test_bit(i, &cpu_callout_map)) + if (!cpu_isset(i, cpu_callout_map)) continue; delta = tsc_values[i] - avg; if (delta < 0) @@ -353,7 +353,7 @@ */ phys_id = GET_APIC_ID(apic_read(APIC_ID)); cpuid = smp_processor_id(); - if (test_bit(cpuid, &cpu_callin_map)) { + if (cpu_isset(cpuid, cpu_callin_map)) { printk("huh, phys CPU#%d, CPU#%d already present??\n", phys_id, cpuid); BUG(); @@ -376,7 +376,7 @@ /* * Has the boot CPU finished it's STARTUP sequence? */ - if (test_bit(cpuid, &cpu_callout_map)) + if (cpu_isset(cpuid, cpu_callout_map)) break; rep_nop(); } @@ -417,7 +417,7 @@ /* * Allow the master to continue. */ - set_bit(cpuid, &cpu_callin_map); + cpu_set(cpuid, cpu_callin_map); /* * Synchronize the TSC with the BP @@ -442,7 +442,7 @@ */ cpu_init(); smp_callin(); - while (!test_bit(smp_processor_id(), &smp_commenced_mask)) + while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); setup_secondary_APIC_clock(); if (nmi_watchdog == NMI_IO_APIC) { @@ -456,7 +456,7 @@ * the local TLBs too. */ local_flush_tlb(); - set_bit(smp_processor_id(), &cpu_online_map); + cpu_set(smp_processor_id(), cpu_online_map); wmb(); return cpu_idle(); } @@ -499,16 +499,16 @@ #ifdef CONFIG_NUMA /* which logical CPUs are on which nodes */ -volatile unsigned long node_2_cpu_mask[MAX_NR_NODES] = - { [0 ... MAX_NR_NODES-1] = 0 }; +cpumask_t node_2_cpu_mask[MAX_NR_NODES] = + { [0 ... MAX_NR_NODES-1] = CPU_MASK_NONE }; /* which node each logical CPU is on */ -volatile int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 }; +int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 }; /* set up a mapping between cpu and node. */ static inline void map_cpu_to_node(int cpu, int node) { printk("Mapping cpu %d to node %d\n", cpu, node); - node_2_cpu_mask[node] |= (1 << cpu); + cpu_set(cpu, node_2_cpu_mask[node]); cpu_2_node[cpu] = node; } @@ -519,7 +519,7 @@ printk("Unmapping cpu %d from all nodes\n", cpu); for (node = 0; node < MAX_NR_NODES; node ++) - node_2_cpu_mask[node] &= ~(1 << cpu); + cpu_clear(cpu, node_2_cpu_mask[node]); cpu_2_node[cpu] = -1; } #else /* !CONFIG_NUMA */ @@ -529,7 +529,7 @@ #endif /* CONFIG_NUMA */ -volatile u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; void map_cpu_to_logical_apicid(void) { @@ -770,7 +770,7 @@ } #endif /* WAKE_SECONDARY_VIA_INIT */ -extern unsigned long cpu_initialized; +extern cpumask_t cpu_initialized; static int __init do_boot_cpu(int apicid) /* @@ -836,19 +836,19 @@ * allow APs to start initializing. */ Dprintk("Before Callout %d.\n", cpu); - set_bit(cpu, &cpu_callout_map); + cpu_set(cpu, cpu_callout_map); Dprintk("After Callout %d.\n", cpu); /* * Wait 5s total for a response */ for (timeout = 0; timeout < 50000; timeout++) { - if (test_bit(cpu, &cpu_callin_map)) + if (cpu_isset(cpu, cpu_callin_map)) break; /* It has booted */ udelay(100); } - if (test_bit(cpu, &cpu_callin_map)) { + if (cpu_isset(cpu, cpu_callin_map)) { /* number CPUs logically, starting from 1 (BSP is 0) */ Dprintk("OK.\n"); printk("CPU%d: ", cpu); @@ -869,8 +869,8 @@ if (boot_error) { /* Try to put things back the way they were before ... */ unmap_cpu_to_logical_apicid(cpu); - clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */ - clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ + cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ + cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ cpucount--; } @@ -954,10 +954,10 @@ * If we couldn't find an SMP configuration at boot time, * get out of here now! */ - if (!smp_found_config) { + if (!smp_found_config && !acpi_lapic) { printk(KERN_NOTICE "SMP motherboard not detected.\n"); smpboot_clear_io_apic_irqs(); - phys_cpu_present_map = 1; + phys_cpu_present_map = physid_mask_of_physid(0); if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); @@ -973,7 +973,7 @@ if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", boot_cpu_physical_apicid); - phys_cpu_present_map |= (1 << hard_smp_processor_id()); + physid_set(hard_smp_processor_id(), phys_cpu_present_map); } /* @@ -984,7 +984,7 @@ boot_cpu_physical_apicid); printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); smpboot_clear_io_apic_irqs(); - phys_cpu_present_map = 1; + phys_cpu_present_map = physid_mask_of_physid(0); return; } @@ -997,7 +997,7 @@ smp_found_config = 0; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); smpboot_clear_io_apic_irqs(); - phys_cpu_present_map = 1; + phys_cpu_present_map = physid_mask_of_physid(0); return; } @@ -1017,10 +1017,10 @@ * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the * clustered apic ID. */ - Dprintk("CPU present map: %lx\n", phys_cpu_present_map); + Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); kicked = 1; - for (bit = 0; kicked < NR_CPUS && bit < BITS_PER_LONG; bit++) { + for (bit = 0; kicked < NR_CPUS && bit < MAX_APICS; bit++) { apicid = cpu_present_to_apicid(bit); /* * Don't even attempt to start the boot CPU! @@ -1055,7 +1055,7 @@ } else { unsigned long bogosum = 0; for (cpu = 0; cpu < NR_CPUS; cpu++) - if (cpu_callout_map & (1< #include +#ifdef CONFIG_NUMA static void __init setup_pci_node_map_for_wpeg(int wpeg_num, struct rio_table_hdr *rth, struct scal_detail **scal_nodes, struct rio_detail **rio_nodes){ int twst_num = 0, node = 0, first_bus = 0; @@ -93,15 +94,21 @@ mp_bus_id_to_node[bus] = node; } -static void __init build_detail_arrays(struct rio_table_hdr *rth, +static int __init build_detail_arrays(struct rio_table_hdr *rth, struct scal_detail **sd, struct rio_detail **rd){ unsigned long ptr; int i, scal_detail_size, rio_detail_size; + if ((rth->num_scal_dev > MAX_NUMNODES) || + (rth->num_rio_dev > MAX_NUMNODES * 2)){ + printk("%s: MAX_NUMNODES too low! Defined as %d, but system has %d nodes.\n", __FUNCTION__, MAX_NUMNODES, rth->num_scal_dev); + return 1; + } + switch (rth->version){ default: printk("%s: Bad Rio Grande Table Version: %d\n", __FUNCTION__, rth->version); - /* Fall through to default to version 2 spec */ + return 1; case 2: scal_detail_size = 11; rio_detail_size = 13; @@ -119,6 +126,8 @@ ptr += scal_detail_size * rth->num_scal_dev; for(i = 0; i < rth->num_rio_dev; i++) rd[i] = (struct rio_detail *)(ptr + (rio_detail_size * i)); + + return 0; } void __init setup_summit(void) @@ -152,11 +161,12 @@ return; } - /* Deal with the ugly version 2/3 pointer arithmetic */ - build_detail_arrays(rio_table_hdr, scal_devs, rio_devs); + if (build_detail_arrays(rio_table_hdr, scal_devs, rio_devs)) + return; for(i = 0; i < rio_table_hdr->num_rio_dev; i++) if (is_WPEG(rio_devs[i]->type)) /* It's a Winnipeg, it's got PCI Busses */ setup_pci_node_map_for_wpeg(i, rio_table_hdr, scal_devs, rio_devs); } +#endif /* CONFIG_NUMA */ diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c --- a/arch/i386/kernel/timers/timer_tsc.c Mon Aug 18 22:21:04 2003 +++ b/arch/i386/kernel/timers/timer_tsc.c Mon Aug 18 22:21:04 2003 @@ -182,9 +182,9 @@ if (lost >= 2) { jiffies += lost-1; - /* sanity check to ensure we're not always loosing ticks */ + /* sanity check to ensure we're not always losing ticks */ if (lost_count++ > 100) { - printk(KERN_WARNING "Loosing too many ticks!\n"); + printk(KERN_WARNING "Losing too many ticks!\n"); printk(KERN_WARNING "TSC cannot be used as a timesource." " (Are you running with SpeedStep?)\n"); printk(KERN_WARNING "Falling back to a sane timesource.\n"); diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c Mon Aug 18 22:21:01 2003 +++ b/arch/i386/kernel/traps.c Mon Aug 18 22:21:01 2003 @@ -629,9 +629,10 @@ default: break; case 0x001: /* Invalid Op */ - case 0x040: /* Stack Fault */ - case 0x240: /* Stack Fault | Direction */ + case 0x041: /* Stack Fault */ + case 0x241: /* Stack Fault | Direction */ info.si_code = FPE_FLTINV; + /* Should we clear the SF or let user space do it ???? */ break; case 0x002: /* Denormalize */ case 0x010: /* Underflow */ diff -Nru a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/vmlinux.lds.S Mon Aug 18 22:21:01 2003 @@ -0,0 +1,125 @@ +/* ld script to make i386 Linux kernel + * Written by Martin Mares ; + */ + +#include + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(startup_32) +jiffies = jiffies_64; +SECTIONS +{ + . = 0xC0000000 + 0x100000; + /* read-only */ + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x9090 + + _etext = .; /* End of text section */ + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + + /* writeable */ + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + + . = ALIGN(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + + /* will be freed after init */ + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(4); + __alt_instructions = .; + .altinstructions : { *(.altinstructions) } + __alt_instructions_end = .; + .altinstr_replacement : { *(.altinstr_replacement) } + /* .exit.text is discard at runtime, not link time, to deal with references + from .altinstructions and .eh_frame */ + .exit.text : { *(.exit.text) } + .exit.data : { *(.exit.data) } + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + /* freed after init ends here */ + + __bss_start = .; /* BSS */ + .bss : { *(.bss) } + __bss_stop = .; + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exitcall.exit) + } + + /* 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) } +} diff -Nru a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c --- a/arch/i386/mach-generic/bigsmp.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/mach-generic/bigsmp.c Mon Aug 18 22:21:02 2003 @@ -3,6 +3,10 @@ * Drives the local APIC in "clustered mode". */ #define APIC_DEFINITION 1 +#include +#include +#include +#include #include #include #include diff -Nru a/arch/i386/mach-generic/default.c b/arch/i386/mach-generic/default.c --- a/arch/i386/mach-generic/default.c Mon Aug 18 22:21:01 2003 +++ b/arch/i386/mach-generic/default.c Mon Aug 18 22:21:01 2003 @@ -2,6 +2,10 @@ * Default generic APIC driver. This handles upto 8 CPUs. */ #define APIC_DEFINITION 1 +#include +#include +#include +#include #include #include #include diff -Nru a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c --- a/arch/i386/mach-generic/probe.c Mon Aug 18 22:21:01 2003 +++ b/arch/i386/mach-generic/probe.c Mon Aug 18 22:21:01 2003 @@ -3,11 +3,15 @@ * * Generic x86 APIC driver probe layer. */ +#include +#include +#include #include #include #include #include #include +#include #include #include diff -Nru a/arch/i386/mach-generic/summit.c b/arch/i386/mach-generic/summit.c --- a/arch/i386/mach-generic/summit.c Mon Aug 18 22:21:06 2003 +++ b/arch/i386/mach-generic/summit.c Mon Aug 18 22:21:06 2003 @@ -2,6 +2,10 @@ * APIC driver for the IBM "Summit" chipset. */ #define APIC_DEFINITION 1 +#include +#include +#include +#include #include #include #include diff -Nru a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c --- a/arch/i386/mach-visws/mpparse.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/mach-visws/mpparse.c Mon Aug 18 22:21:02 2003 @@ -26,7 +26,7 @@ unsigned int boot_cpu_logical_apicid = -1U; /* Bitmask of physically existing CPUs */ -unsigned long phys_cpu_present_map; +physid_mask_t phys_cpu_present_map; /* @@ -38,6 +38,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) { int ver, logical_apicid; + cpumask_t apic_cpus; if (!(m->mpc_cpuflag & CPU_ENABLED)) return; @@ -62,7 +63,8 @@ } ver = m->mpc_apicver; - phys_cpu_present_map |= apicid_to_cpu_present(m->mpc_apicid); + apic_cpus = apicid_to_cpu_present(m->mpc_apicid); + physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); /* * Validate version */ diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c --- a/arch/i386/mach-voyager/voyager_smp.c Mon Aug 18 22:21:02 2003 +++ b/arch/i386/mach-voyager/voyager_smp.c Mon Aug 18 22:21:02 2003 @@ -75,15 +75,15 @@ int smp_found_config = 0; /* Used for the invalidate map that's also checked in the spinlock */ -volatile unsigned long smp_invalidate_needed; +static volatile unsigned long smp_invalidate_needed; /* Bitmask of currently online CPUs - used by setup.c for /proc/cpuinfo, visible externally but still physical */ -unsigned long cpu_online_map = 0; +cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmask of CPUs present in the system - exported by i386_syms.c, used * by scheduler but indexed physically */ -unsigned long phys_cpu_present_map = 0; +cpumask_t phys_cpu_present_map = CPU_MASK_NONE; /* estimate of time used to flush the SMP-local cache - used in * processor affinity calculations */ @@ -108,7 +108,7 @@ static void disable_local_vic_irq(unsigned int irq); static void before_handle_vic_irq(unsigned int irq); static void after_handle_vic_irq(unsigned int irq); -static void set_vic_irq_affinity(unsigned int irq, unsigned long mask); +static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask); static void ack_vic_irq(unsigned int irq); static void vic_enable_cpi(void); static void do_boot_cpu(__u8 cpuid); @@ -128,13 +128,12 @@ static inline void send_QIC_CPI(__u32 cpuset, __u8 cpi) { - int mask; - __u8 cpu; + int cpu; - for_each_cpu(cpu, mask) { + for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) { if(cpuset & (1<cpu_vm_mask); + cpu_clear(cpu, cpu_tlbstate[cpu].active_mm->cpu_vm_mask); load_cr3(swapper_pg_dir); } @@ -878,7 +876,7 @@ { __u8 cpu = get_cpu(); - if(!test_bit(cpu, &smp_invalidate_needed)) + if (!(smp_invalidate_needed & (1UL << cpu))) goto out; /* This will flood messages. Don't uncomment unless you see * Problems with cross cpu invalidation @@ -895,7 +893,7 @@ } else leave_mm(cpu); } - clear_bit(cpu, &smp_invalidate_needed); + smp_invalidate_needed |= 1UL << cpu; out: put_cpu_no_resched(); } @@ -912,7 +910,7 @@ if (!cpumask) BUG(); - if ((cpumask & cpu_online_map) != cpumask) + if ((cpumask & cpus_coerce(cpu_online_map)) != cpumask) BUG(); if (cpumask & (1 << smp_processor_id())) BUG(); @@ -954,7 +952,7 @@ preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id()); + cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); local_flush_tlb(); if (cpu_mask) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); @@ -970,7 +968,7 @@ preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id()); + cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if (current->mm) @@ -991,7 +989,7 @@ preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id()); + cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if(current->mm) __flush_tlb_one(va); @@ -1033,7 +1031,7 @@ smp_stop_cpu_function(void *dummy) { VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id())); - clear_bit(smp_processor_id(), &cpu_online_map); + cpu_clear(smp_processor_id(), cpu_online_map); local_irq_disable(); for(;;) __asm__("hlt"); @@ -1100,7 +1098,7 @@ int wait) { struct call_data_struct data; - __u32 mask = cpu_online_map; + __u32 mask = cpus_coerce(cpu_online_map); mask &= ~(1<bindings[(i)].escr_address, (escr), (high));} while (0); -#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0); +#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0) +#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0) #define CCCR_RESERVED_BITS 0x38030FFF #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) @@ -366,13 +366,13 @@ #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) -#define CCCR_READ(low, high, i) do {rdmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0); -#define CCCR_WRITE(low, high, i) do {wrmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0); +#define CCCR_READ(low, high, i) do {rdmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0) +#define CCCR_WRITE(low, high, i) do {wrmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0) #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) -#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0); -#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0); +#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0) +#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0) #define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) diff -Nru a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c --- a/arch/i386/pci/acpi.c Mon Aug 18 22:21:04 2003 +++ b/arch/i386/pci/acpi.c Mon Aug 18 22:21:04 2003 @@ -32,4 +32,14 @@ return 0; } +/* + * pci_disable_acpi() + * act like pci=noacpi seen on command line + * called by DMI blacklist code + */ +__init void pci_disable_acpi(void) +{ + pci_probe |= PCI_NO_ACPI_ROUTING; +} + subsys_initcall(pci_acpi_init); diff -Nru a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S --- a/arch/i386/vmlinux.lds.S Mon Aug 18 22:21:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,125 +0,0 @@ -/* ld script to make i386 Linux kernel - * Written by Martin Mares ; - */ - -#include - -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(startup_32) -jiffies = jiffies_64; -SECTIONS -{ - . = 0xC0000000 + 0x100000; - /* read-only */ - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - - _etext = .; /* End of text section */ - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - RODATA - - /* writeable */ - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(4); - __alt_instructions = .; - .altinstructions : { *(.altinstructions) } - __alt_instructions_end = .; - .altinstr_replacement : { *(.altinstr_replacement) } - /* .exit.text is discard at runtime, not link time, to deal with references - from .altinstructions and .eh_frame */ - .exit.text : { *(.exit.text) } - .exit.data : { *(.exit.data) } - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; - /* freed after init ends here */ - - __bss_start = .; /* BSS */ - .bss : { *(.bss) } - __bss_stop = .; - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exitcall.exit) - } - - /* 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) } -} diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c Mon Aug 18 22:21:04 2003 +++ b/arch/ia64/ia32/sys_ia32.c Mon Aug 18 22:21:04 2003 @@ -1374,7 +1374,7 @@ break; old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_msgctl(first, second, &m64); + err = sys_msgctl(first, second, (struct msqid_ds *)&m64); set_fs(old_fs); break; @@ -1382,7 +1382,7 @@ case MSG_STAT: old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_msgctl(first, second, (void *) &m64); + err = sys_msgctl(first, second, (struct msqid_ds *)&m64); set_fs(old_fs); if (version == IPC_64) { @@ -1518,7 +1518,7 @@ break; old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_shmctl(first, second, &s64); + err = sys_shmctl(first, second, (struct shmid_ds *)&s64); set_fs(old_fs); break; @@ -1526,7 +1526,7 @@ case SHM_STAT: old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_shmctl(first, second, (void *) &s64); + err = sys_shmctl(first, second, (struct shmid_ds *)&s64); set_fs(old_fs); if (err < 0) break; @@ -1693,6 +1693,10 @@ } return i; } + +asmlinkage long +compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options, + struct compat_rusage *ru); asmlinkage long sys32_waitpid (int pid, unsigned int *stat_addr, int options) diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile --- a/arch/ia64/kernel/Makefile Mon Aug 18 22:21:06 2003 +++ b/arch/ia64/kernel/Makefile Mon Aug 18 22:21:06 2003 @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ diff -Nru a/arch/ia64/kernel/efivars.c b/arch/ia64/kernel/efivars.c --- a/arch/ia64/kernel/efivars.c Mon Aug 18 22:21:03 2003 +++ b/arch/ia64/kernel/efivars.c Mon Aug 18 22:21:03 2003 @@ -168,13 +168,12 @@ efi_char16_t *variable_name, efi_guid_t *vendor_guid) { - int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; char *short_name; efivar_entry_t *new_efivar; - short_name = kmalloc(short_name_size+1, GFP_KERNEL); - new_efivar = kmalloc(sizeof(efivar_entry_t), GFP_KERNEL); + short_name = kmalloc(short_name_size+1, GFP_KERNEL); + new_efivar = kmalloc(sizeof(efivar_entry_t), GFP_KERNEL); if (!short_name || !new_efivar) { if (short_name) kfree(short_name); @@ -210,9 +209,9 @@ new_efivar->entry->read_proc = efivar_read; new_efivar->entry->write_proc = efivar_write; - spin_lock(&efivars_lock); - list_add(&new_efivar->list, &efivar_list); - spin_unlock(&efivars_lock); + spin_lock(&efivars_lock); + list_add(&new_efivar->list, &efivar_list); + spin_unlock(&efivars_lock); return 0; } @@ -283,7 +282,7 @@ if (!var_data) return -ENOMEM; if (copy_from_user(var_data, buffer, size)) { - kfree(var_data); + kfree(var_data); return -EFAULT; } @@ -344,12 +343,73 @@ return size; } +/* + * The EFI system table contains pointers to the SAL system table, + * HCDP, ACPI, SMBIOS, etc, that may be useful to applications. + */ +static ssize_t +efi_systab_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + void *data; + u8 *proc_buffer; + ssize_t size, length; + int ret; + const int max_nr_entries = 7; /* num ptrs to tables we could expose */ + const int max_line_len = 80; + + if (!efi.systab) + return 0; + proc_buffer = kmalloc(max_nr_entries * max_line_len, GFP_KERNEL); + if (!proc_buffer) + return -ENOMEM; + + length = 0; + if (efi.mps) + length += sprintf(proc_buffer + length, "MPS=0x%lx\n", __pa(efi.mps)); + if (efi.acpi20) + length += sprintf(proc_buffer + length, "ACPI20=0x%lx\n", __pa(efi.acpi20)); + if (efi.acpi) + length += sprintf(proc_buffer + length, "ACPI=0x%lx\n", __pa(efi.acpi)); + if (efi.smbios) + length += sprintf(proc_buffer + length, "SMBIOS=0x%lx\n", __pa(efi.smbios)); + if (efi.sal_systab) + length += sprintf(proc_buffer + length, "SAL=0x%lx\n", __pa(efi.sal_systab)); + if (efi.hcdp) + length += sprintf(proc_buffer + length, "HCDP=0x%lx\n", __pa(efi.hcdp)); + if (efi.boot_info) + length += sprintf(proc_buffer + length, "BOOTINFO=0x%lx\n", __pa(efi.boot_info)); + + if (*ppos >= length) { + ret = 0; + goto out; + } + + data = proc_buffer + file->f_pos; + size = length - file->f_pos; + if (size > count) + size = count; + if (copy_to_user(buffer, data, size)) { + ret = -EFAULT; + goto out; + } + + *ppos += size; + ret = size; + +out: + kfree(proc_buffer); + return ret; +} + +static struct proc_dir_entry *efi_systab_entry; +static struct file_operations efi_systab_fops = { + .read = efi_systab_read, +}; static int __init efivars_init(void) { - efi_status_t status; efi_guid_t vendor_guid; efi_char16_t *variable_name = kmalloc(1024, GFP_KERNEL); @@ -357,13 +417,17 @@ printk(KERN_INFO "EFI Variables Facility v%s\n", EFIVARS_VERSION); - /* Since efi.c happens before procfs is available, - we create the directory here if it doesn't - already exist. There's probably a better way - to do this. - */ - if (!efi_dir) - efi_dir = proc_mkdir("efi", NULL); + /* Since efi.c happens before procfs is available, + we create the directory here if it doesn't + already exist. There's probably a better way + to do this. + */ + if (!efi_dir) + efi_dir = proc_mkdir("efi", NULL); + + efi_systab_entry = create_proc_entry("systab", S_IRUSR | S_IRGRP, efi_dir); + if (efi_systab_entry) + efi_systab_entry->proc_fops = &efi_systab_fops; efi_vars_dir = proc_mkdir("vars", efi_dir); @@ -407,7 +471,9 @@ struct list_head *pos, *n; efivar_entry_t *efivar; - spin_lock(&efivars_lock); + spin_lock(&efivars_lock); + if (efi_systab_entry) + remove_proc_entry(efi_systab_entry->name, efi_dir); list_for_each_safe(pos, n, &efivar_list) { efivar = efivar_entry(pos); remove_proc_entry(efivar->entry->name, efi_vars_dir); diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S --- a/arch/ia64/kernel/entry.S Mon Aug 18 22:21:02 2003 +++ b/arch/ia64/kernel/entry.S Mon Aug 18 22:21:02 2003 @@ -113,7 +113,7 @@ * u64 tls) */ GLOBAL_ENTRY(sys_clone2) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6) alloc r16=ar.pfs,6,2,6,0 DO_SAVE_SWITCH_STACK adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp @@ -142,7 +142,7 @@ * Deprecated. Use sys_clone2() instead. */ GLOBAL_ENTRY(sys_clone) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) alloc r16=ar.pfs,5,2,6,0 DO_SAVE_SWITCH_STACK adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c Mon Aug 18 22:21:03 2003 +++ b/arch/ia64/kernel/iosapic.c Mon Aug 18 22:21:03 2003 @@ -274,7 +274,7 @@ static void -iosapic_set_affinity (unsigned int irq, unsigned long mask) +iosapic_set_affinity (unsigned int irq, cpumask_t mask) { #ifdef CONFIG_SMP unsigned long flags; @@ -287,12 +287,10 @@ irq &= (~IA64_IRQ_REDIRECTED); vec = irq_to_vector(irq); - mask &= cpu_online_map; - - if (!mask || vec >= IA64_NUM_VECTORS) + if (cpus_empty(mask) || vec >= IA64_NUM_VECTORS) return; - dest = cpu_physical_id(ffz(~mask)); + dest = cpu_physical_id(first_cpu(mask)); rte_index = iosapic_intr_info[vec].rte_index; addr = iosapic_intr_info[vec].addr; diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c --- a/arch/ia64/kernel/irq.c Mon Aug 18 22:21:05 2003 +++ b/arch/ia64/kernel/irq.c Mon Aug 18 22:21:05 2003 @@ -898,13 +898,14 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; -#define HEX_DIGITS 8 +#define HEX_DIGITS (2*sizeof(cpumask_t)) -static unsigned int parse_hex_value (const char *buffer, - unsigned long count, unsigned long *ret) +static unsigned int parse_hex_value(const char *buffer, + unsigned long count, cpumask_t *ret) { - unsigned char hexnum [HEX_DIGITS]; - unsigned long value, i; + unsigned char hexnum[HEX_DIGITS]; + cpumask_t value = CPU_MASK_NONE; + unsigned long i; if (!count) return -EINVAL; @@ -917,10 +918,9 @@ * Parse the first 8 characters as a hex string, any non-hex char * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ - value = 0; - for (i = 0; i < count; i++) { unsigned int c = hexnum[i]; + int k; switch (c) { case '0' ... '9': c -= '0'; break; @@ -929,7 +929,10 @@ default: goto out; } - value = (value << 4) | c; + cpus_shift_left(value, value, 4); + for (k = 0; k < 4; ++k) + if (test_bit(k, (unsigned long *)&c)) + cpu_set(k, value); } out: *ret = value; @@ -940,12 +943,15 @@ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; + static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 }; void set_irq_affinity_info (unsigned int irq, int hwid, int redir) { - unsigned long mask = 1UL<handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value); @@ -1003,18 +1021,28 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; + cpumask_t *mask = (cpumask_t *)data; + int k, len = 0; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", *mask); + + for (k = 0; k < sizeof(cpumask_t)/sizeof(unsigned long); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(*mask)); + len += j; + page += j; + cpus_shift_right(*mask, *mask, 16); + } + len += sprintf(page, "\n"); + return len; } static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data; - int full_count = count, err; - unsigned long new_value; + cpumask_t *mask = (cpumask_t *)data; + unsigned long full_count = count, err; + cpumask_t new_value; err = parse_hex_value(buffer, count, &new_value); if (err) @@ -1058,7 +1086,7 @@ #endif } -unsigned long prof_cpu_mask = -1; +cpumask_t prof_cpu_mask = CPU_MASK_ALL; void init_irq_proc (void) { diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c --- a/arch/ia64/kernel/mca.c Mon Aug 18 22:21:03 2003 +++ b/arch/ia64/kernel/mca.c Mon Aug 18 22:21:03 2003 @@ -115,6 +115,7 @@ .name = "mca_wkup" }; +#ifdef CONFIG_ACPI static struct irqaction mca_cpe_irqaction = { .handler = ia64_mca_cpe_int_handler, .flags = SA_INTERRUPT, @@ -126,6 +127,7 @@ .flags = SA_INTERRUPT, .name = "cpe_poll" }; +#endif /* CONFIG_ACPI */ #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */ #define MIN_CPE_POLL_INTERVAL (2*60*HZ) /* 2 minutes */ @@ -434,6 +436,7 @@ device_initcall(ia64_mca_check_errors); +#ifdef CONFIG_ACPI /* * ia64_mca_register_cpev * @@ -458,6 +461,7 @@ IA64_MCA_DEBUG("ia64_mca_platform_init: corrected platform error " "vector %#x setup and enabled\n", cpev); } +#endif /* CONFIG_ACPI */ #endif /* PLATFORM_MCA_HANDLERS */ @@ -750,6 +754,7 @@ /* Setup the MCA wakeup interrupt vector */ register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); +#ifdef CONFIG_ACPI /* Setup the CPE interrupt vector */ { irq_desc_t *desc; @@ -767,6 +772,7 @@ ia64_mca_register_cpev(cpev); } } +#endif /* Initialize the areas set aside by the OS to buffer the * platform/processor error states for MCA/INIT/CMC @@ -1279,11 +1285,13 @@ init_timer(&cpe_poll_timer); cpe_poll_timer.function = ia64_mca_cpe_poll; +#ifdef CONFIG_ACPI /* If platform doesn't support CPEI, get the timer going. */ if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0 && cpe_poll_enabled) { register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); ia64_mca_cpe_poll(0UL); } +#endif return 0; } @@ -1398,6 +1406,9 @@ // SAL will tell us the maximum size of any error record of this type max_size = ia64_sal_get_state_info_size(sal_info_type); + if (!max_size) + /* alloc_bootmem() doesn't like zero-sized allocations! */ + return; // set up OS data structures to hold error info IA64_LOG_ALLOCATE(sal_info_type, max_size); diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c Mon Aug 18 22:21:06 2003 +++ b/arch/ia64/kernel/perfmon.c Mon Aug 18 22:21:06 2003 @@ -221,14 +221,6 @@ #define PFM_REG_RETFLAG_SET(flags, val) do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0) -#ifdef CONFIG_SMP -#define PFM_CPU_ONLINE_MAP cpu_online_map -#define cpu_is_online(i) (PFM_CPU_ONLINE_MAP & (1UL << i)) -#else -#define PFM_CPU_ONLINE_MAP 1UL -#define cpu_is_online(i) (i==0) -#endif - /* * cmp0 must be the value of pmc0 */ @@ -5354,7 +5346,7 @@ 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; + if (cpu_online(i) == 0) continue; p += sprintf(p, "CPU%-2d overflow intrs : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count); p += sprintf(p, "CPU%-2d overflow cycles : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles); p += sprintf(p, "CPU%-2d overflow min : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_min); @@ -5372,7 +5364,7 @@ p += sprintf(p, "CPU%-2d activations : %lu\n", i, pfm_get_cpu_data(pmu_activation_number,i)); } - if (hweight64(PFM_CPU_ONLINE_MAP) == 1) + if (num_online_cpus() == 1) { psr = pfm_get_psr(); ia64_srlz_d(); diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c Mon Aug 18 22:21:03 2003 +++ b/arch/ia64/kernel/process.c Mon Aug 18 22:21:03 2003 @@ -45,7 +45,7 @@ ia64_do_show_stack (struct unw_frame_info *info, void *arg) { unsigned long ip, sp, bsp; - char buf[80]; /* don't make it so big that it overflows the stack! */ + char buf[128]; /* don't make it so big that it overflows the stack! */ printk("\nCall Trace:\n"); do { @@ -55,7 +55,9 @@ unw_get_sp(info, &sp); unw_get_bsp(info, &bsp); - snprintf(buf, sizeof(buf), " [<%016lx>] %%s\n\t\t\t\tsp=%016lx bsp=%016lx\n", + snprintf(buf, sizeof(buf), + " [<%016lx>] %%s\n" + " sp=%016lx bsp=%016lx\n", ip, sp, bsp); print_symbol(buf, ip); } while (unw_unwind(info) >= 0); diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Mon Aug 18 22:21:01 2003 +++ b/arch/ia64/kernel/setup.c Mon Aug 18 22:21:01 2003 @@ -542,7 +542,7 @@ c_start (struct seq_file *m, loff_t *pos) { #ifdef CONFIG_SMP - while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos))) + while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map)) ++*pos; #endif return *pos < NR_CPUS ? cpu_data(*pos) : NULL; diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c --- a/arch/ia64/kernel/smp.c Mon Aug 18 22:21:06 2003 +++ b/arch/ia64/kernel/smp.c Mon Aug 18 22:21:06 2003 @@ -81,7 +81,7 @@ /* * Remove this CPU: */ - clear_bit(smp_processor_id(), &cpu_online_map); + cpu_clear(smp_processor_id(), cpu_online_map); max_xtp(); local_irq_disable(); cpu_halt(); diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c --- a/arch/ia64/kernel/smpboot.c Mon Aug 18 22:21:02 2003 +++ b/arch/ia64/kernel/smpboot.c Mon Aug 18 22:21:02 2003 @@ -79,13 +79,13 @@ task_t *task_for_booting_cpu; /* Bitmask of currently online CPUs */ -volatile unsigned long cpu_online_map; -unsigned long phys_cpu_present_map; +cpumask_t cpu_online_map; +cpumask_t phys_cpu_present_map; /* which logical CPU number maps to which CPU (physical APIC ID) */ volatile int ia64_cpu_to_sapicid[NR_CPUS]; -static volatile unsigned long cpu_callin_map; +static volatile cpumask_t cpu_callin_map; struct smp_boot_data smp_boot_data __initdata; @@ -282,7 +282,7 @@ cpuid = smp_processor_id(); phys_id = hard_smp_processor_id(); - if (test_and_set_bit(cpuid, &cpu_online_map)) { + if (cpu_test_and_set(cpuid, cpu_online_map)) { printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n", phys_id, cpuid); BUG(); @@ -327,7 +327,7 @@ /* * Allow the master to continue. */ - set_bit(cpuid, &cpu_callin_map); + cpu_set(cpuid, cpu_callin_map); Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid); } @@ -391,19 +391,19 @@ */ Dprintk("Waiting on callin_map ..."); for (timeout = 0; timeout < 100000; timeout++) { - if (test_bit(cpu, &cpu_callin_map)) + if (cpu_isset(cpu, cpu_callin_map)) break; /* It has booted */ udelay(100); } Dprintk("\n"); - if (test_bit(cpu, &cpu_callin_map)) { + if (cpu_isset(cpu, cpu_callin_map)) { /* number CPUs logically, starting from 1 (BSP is 0) */ 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; - clear_bit(cpu, &cpu_online_map); /* was set in smp_callin() */ + cpu_clear(cpu, cpu_online_map); /* was set in smp_callin() */ return -EINVAL; } return 0; @@ -446,13 +446,14 @@ ia64_cpu_to_sapicid[cpu] = -1; ia64_cpu_to_sapicid[0] = boot_cpu_id; - phys_cpu_present_map = 1; + cpus_clear(phys_cpu_present_map); + cpu_set(0, phys_cpu_present_map); for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) { sapicid = smp_boot_data.cpu_phys_id[i]; if (sapicid == boot_cpu_id) continue; - phys_cpu_present_map |= (1UL << cpu); + cpu_set(cpu, phys_cpu_present_map); ia64_cpu_to_sapicid[cpu] = sapicid; cpu++; } @@ -463,7 +464,7 @@ /* on which node is each logical CPU (one cacheline even for 64 CPUs) */ volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned; /* which logical CPUs are on which nodes */ -volatile unsigned long node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; +volatile cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; /* * Build cpu to node mapping and initialize the per node cpu masks. @@ -474,7 +475,7 @@ int cpu, i, node; for(node=0; node= 0) - node_to_cpu_mask[node] |= (1UL << cpu); + cpu_set(cpu, node_to_cpu_mask[node]); } } @@ -515,8 +516,8 @@ /* * We have the boot CPU online for sure. */ - set_bit(0, &cpu_online_map); - set_bit(0, &cpu_callin_map); + cpu_set(0, cpu_online_map); + cpu_set(0, cpu_callin_map); local_cpu_data->loops_per_jiffy = loops_per_jiffy; ia64_cpu_to_sapicid[0] = boot_cpu_id; @@ -531,15 +532,18 @@ */ if (!max_cpus) { printk(KERN_INFO "SMP mode deactivated.\n"); - cpu_online_map = phys_cpu_present_map = 1; + cpus_clear(cpu_online_map); + cpus_clear(phys_cpu_present_map); + cpu_set(1, cpu_online_map); + cpu_set(1, phys_cpu_present_map); return; } } void __devinit smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); - set_bit(smp_processor_id(), &cpu_callin_map); + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), cpu_callin_map); } void diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c --- a/arch/ia64/kernel/time.c Mon Aug 18 22:21:01 2003 +++ b/arch/ia64/kernel/time.c Mon Aug 18 22:21:01 2003 @@ -41,12 +41,12 @@ static void do_profile (unsigned long ip) { - extern unsigned long prof_cpu_mask; + extern cpumask_t prof_cpu_mask; if (!prof_buffer) return; - if (!((1UL << smp_processor_id()) & prof_cpu_mask)) + if (!cpu_isset(smp_processor_id(), prof_cpu_mask)) return; ip -= (unsigned long) _stext; diff -Nru a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/kernel/vmlinux.lds.S Mon Aug 18 22:21:05 2003 @@ -0,0 +1,246 @@ +#include + +#include +#include +#include +#include + +#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE) +#include + +OUTPUT_FORMAT("elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(phys_start) +jiffies = jiffies_64; +SECTIONS +{ + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + *(.IA_64.unwind.exit.text) + *(.IA_64.unwind_info.exit.text) + } + + v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */ + phys_start = _start - LOAD_OFFSET; + + . = KERNEL_START; + + _text = .; + _stext = .; + + .text : AT(ADDR(.text) - LOAD_OFFSET) + { + *(.text.ivt) + *(.text) + } + .text2 : AT(ADDR(.text2) - LOAD_OFFSET) + { *(.text2) } +#ifdef CONFIG_SMP + .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) + { *(.text.lock) } +#endif + _etext = .; + + /* Read-only data */ + + /* Exception table */ + . = ALIGN(16); + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) + { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) + { + __start___vtop_patchlist = .; + *(.data.patch.vtop) + __end___vtop_patchlist = .; + } + + .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET) + { + __start___mckinley_e9_bundles = .; + *(.data.patch.mckinley_e9) + __end___mckinley_e9_bundles = .; + } + + /* Global data */ + _data = .; + +#if defined(CONFIG_IA64_GENERIC) + /* Machine Vector */ + . = ALIGN(16); + .machvec : AT(ADDR(.machvec) - LOAD_OFFSET) + { + machvec_start = .; + *(.machvec) + machvec_end = .; + } +#endif + + /* Unwind info & table: */ + . = ALIGN(8); + .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET) + { *(.IA_64.unwind_info*) } + .IA_64.unwind : AT(ADDR(.IA_64.unwind) - LOAD_OFFSET) + { + __start_unwind = .; + *(.IA_64.unwind*) + __end_unwind = .; + } + + RODATA + + .opd : AT(ADDR(.opd) - LOAD_OFFSET) + { *(.opd) } + + /* Initialization code and data: */ + + . = ALIGN(PAGE_SIZE); + __init_begin = .; + .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) + { + _sinittext = .; + *(.init.text) + _einittext = .; + } + + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) + { *(.init.data) } + + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) + { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } + + . = ALIGN(16); + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) + { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + __param : AT(ADDR(__param) - LOAD_OFFSET) + { + __start___param = .; + *(__param) + __stop___param = .; + } + .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) + { + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + } + __con_initcall_start = .; + .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) + { *(.con_initcall.init) } + __con_initcall_end = .; + __security_initcall_start = .; + .security_initcall.init : AT(ADDR(.security_initcall.init) - PAGE_OFFSET) + { *(.security_initcall.init) } + __security_initcall_end = .; + . = ALIGN(PAGE_SIZE); + __init_end = .; + + /* The initial task and kernel stack */ + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) + { *(.data.init_task) } + + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) + { *(__special_page_section) + __start_gate_section = .; + *(.data.gate) + __stop_gate_section = .; + } + . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ + + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) + { *(.data.cacheline_aligned) } + + /* Per-cpu data: */ + . = ALIGN(PERCPU_PAGE_SIZE); + __phys_per_cpu_start = .; + .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET) + { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } + . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits into percpu page size */ + + .data : AT(ADDR(.data) - LOAD_OFFSET) + { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS } + + . = ALIGN(16); + __gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */ + + .got : AT(ADDR(.got) - LOAD_OFFSET) + { *(.got.plt) *(.got) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) + { *(.sdata) } + _edata = .; + _bss = .; + .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) + { *(.sbss) *(.scommon) } + .bss : AT(ADDR(.bss) - LOAD_OFFSET) + { *(.bss) *(COMMON) } + + _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) } + /* 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) } + .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) } + /* These must appear regardless of . */ + /* Discard them for now since Intel SoftSDV cannot handle them. + .comment 0 : { *(.comment) } + .note 0 : { *(.note) } + */ + /DISCARD/ : { *(.comment) } + /DISCARD/ : { *(.note) } +} diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S --- a/arch/ia64/vmlinux.lds.S Mon Aug 18 22:21:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,246 +0,0 @@ -#include - -#include -#include -#include -#include - -#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE) -#include - -OUTPUT_FORMAT("elf64-ia64-little") -OUTPUT_ARCH(ia64) -ENTRY(phys_start) -jiffies = jiffies_64; -SECTIONS -{ - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - *(.IA_64.unwind.exit.text) - *(.IA_64.unwind_info.exit.text) - } - - v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */ - phys_start = _start - LOAD_OFFSET; - - . = KERNEL_START; - - _text = .; - _stext = .; - - .text : AT(ADDR(.text) - LOAD_OFFSET) - { - *(.text.ivt) - *(.text) - } - .text2 : AT(ADDR(.text2) - LOAD_OFFSET) - { *(.text2) } -#ifdef CONFIG_SMP - .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) - { *(.text.lock) } -#endif - _etext = .; - - /* Read-only data */ - - /* Exception table */ - . = ALIGN(16); - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) - { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - - .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) - { - __start___vtop_patchlist = .; - *(.data.patch.vtop) - __end___vtop_patchlist = .; - } - - .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET) - { - __start___mckinley_e9_bundles = .; - *(.data.patch.mckinley_e9) - __end___mckinley_e9_bundles = .; - } - - /* Global data */ - _data = .; - -#if defined(CONFIG_IA64_GENERIC) - /* Machine Vector */ - . = ALIGN(16); - .machvec : AT(ADDR(.machvec) - LOAD_OFFSET) - { - machvec_start = .; - *(.machvec) - machvec_end = .; - } -#endif - - /* Unwind info & table: */ - . = ALIGN(8); - .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET) - { *(.IA_64.unwind_info*) } - .IA_64.unwind : AT(ADDR(.IA_64.unwind) - LOAD_OFFSET) - { - __start_unwind = .; - *(.IA_64.unwind*) - __end_unwind = .; - } - - RODATA - - .opd : AT(ADDR(.opd) - LOAD_OFFSET) - { *(.opd) } - - /* Initialization code and data: */ - - . = ALIGN(PAGE_SIZE); - __init_begin = .; - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) - { - _sinittext = .; - *(.init.text) - _einittext = .; - } - - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) - { *(.init.data) } - - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) - { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } - - . = ALIGN(16); - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) - { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } - __param : AT(ADDR(__param) - LOAD_OFFSET) - { - __start___param = .; - *(__param) - __stop___param = .; - } - .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) - { - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - } - __con_initcall_start = .; - .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) - { *(.con_initcall.init) } - __con_initcall_end = .; - __security_initcall_start = .; - .security_initcall.init : AT(ADDR(.security_initcall.init) - PAGE_OFFSET) - { *(.security_initcall.init) } - __security_initcall_end = .; - . = ALIGN(PAGE_SIZE); - __init_end = .; - - /* The initial task and kernel stack */ - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) - { *(.data.init_task) } - - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) - { *(__special_page_section) - __start_gate_section = .; - *(.data.gate) - __stop_gate_section = .; - } - . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ - - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) - { *(.data.cacheline_aligned) } - - /* Per-cpu data: */ - . = ALIGN(PERCPU_PAGE_SIZE); - __phys_per_cpu_start = .; - .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET) - { - __per_cpu_start = .; - *(.data.percpu) - __per_cpu_end = .; - } - . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits into percpu page size */ - - .data : AT(ADDR(.data) - LOAD_OFFSET) - { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS } - - . = ALIGN(16); - __gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */ - - .got : AT(ADDR(.got) - LOAD_OFFSET) - { *(.got.plt) *(.got) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) - { *(.sdata) } - _edata = .; - _bss = .; - .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) - { *(.sbss) *(.scommon) } - .bss : AT(ADDR(.bss) - LOAD_OFFSET) - { *(.bss) *(COMMON) } - - _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) } - /* 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) } - .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) } - /* These must appear regardless of . */ - /* Discard them for now since Intel SoftSDV cannot handle them. - .comment 0 : { *(.comment) } - .note 0 : { *(.note) } - */ - /DISCARD/ : { *(.comment) } - /DISCARD/ : { *(.note) } -} diff -Nru a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile --- a/arch/m68k/kernel/Makefile Mon Aug 18 22:21:05 2003 +++ b/arch/m68k/kernel/Makefile Mon Aug 18 22:21:05 2003 @@ -6,7 +6,8 @@ extra-y := head.o else extra-y := sun3-head.o -endif +endif +extra-y += vmlinux.lds.s 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/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/m68k/kernel/vmlinux.lds.S Mon Aug 18 22:21:02 2003 @@ -0,0 +1,7 @@ +#include + +#ifdef CONFIG_SUN3 +#include "vmlinux-sun3.lds" +#else +#include "vmlinux-std.lds" +#endif diff -Nru a/arch/m68k/vmlinux.lds.S b/arch/m68k/vmlinux.lds.S --- a/arch/m68k/vmlinux.lds.S Mon Aug 18 22:21:02 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,7 +0,0 @@ -#include - -#ifdef CONFIG_SUN3 -#include "vmlinux-sun3.lds" -#else -#include "vmlinux-std.lds" -#endif diff -Nru a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile --- a/arch/m68knommu/kernel/Makefile Mon Aug 18 22:21:02 2003 +++ b/arch/m68knommu/kernel/Makefile Mon Aug 18 22:21:02 2003 @@ -2,6 +2,8 @@ # Makefile for arch/m68knommu/kernel. # +extra-y := vmlinux.lds.s + obj-y += entry.o init_task.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/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/m68knommu/kernel/vmlinux.lds.S Mon Aug 18 22:21:03 2003 @@ -0,0 +1,314 @@ +/* + * vmlinux.lds.S -- master linker script for m68knommu arch + * + * (C) Copyright 2002-2003, Greg Ungerer + * + * This ends up looking compilcated, because of the number of + * address variations for ram and rom/flash layouts. The real + * work of the linker script is all at the end, and reasonably + * strait forward. + */ + +#include +#include + +/* + * Original Palm pilot (same for Xcopilot). + * There is really only a rom target for this. + */ +#ifdef CONFIG_PILOT3 +#define ROMVEC_START 0x10c00000 +#define ROMVEC_LENGTH 0x10400 +#define ROM_START 0x10c10400 +#define ROM_LENGTH 0xfec00 +#define ROM_END 0x10d00000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x10000400 +#define RAM_LENGTH 0xffc00 +#define RAM_END 0x10100000 +#define _ramend _ram_end_notused +#define DATA_ADDR RAM_START +#endif + +/* + * Same setup on both the uCsimm and uCdimm. + */ +#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) +#ifdef CONFIG_RAMKERNEL +#define ROMVEC_START 0x10c10000 +#define ROMVEC_LENGTH 0x400 +#define ROM_START 0x10c10400 +#define ROM_LENGTH 0x1efc00 +#define ROM_END 0x10e00000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x00020400 +#define RAM_LENGTH 0x7dfc00 +#define RAM_END 0x00800000 +#endif +#ifdef CONFIG_ROMKERNEL +#define ROMVEC_START 0x10c10000 +#define ROMVEC_LENGTH 0x400 +#define ROM_START 0x10c10400 +#define ROM_LENGTH 0x1efc00 +#define ROM_END 0x10e00000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x00020000 +#define RAM_LENGTH 0x600000 +#define RAM_END 0x00800000 +#endif +#ifdef CONFIG_HIMEMKERNEL +#define ROMVEC_START 0x00600000 +#define ROMVEC_LENGTH 0x400 +#define ROM_START 0x00600400 +#define ROM_LENGTH 0x1efc00 +#define ROM_END 0x007f0000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x00020000 +#define RAM_LENGTH 0x5e0000 +#define RAM_END 0x00600000 +#endif +#endif + +#ifdef CONFIG_DRAGEN2 +#define RAM_START 0x10000 +#define RAM_LENGTH 0x7f0000 +#endif + +#ifdef CONFIG_UCQUICC +#define ROMVEC_START 0x00000000 +#define ROMVEC_LENGTH 0x404 +#define ROM_START 0x00000404 +#define ROM_LENGTH 0x1ff6fc +#define ROM_END 0x00200000 +#define RAMVEC_START 0x00200000 +#define RAMVEC_LENGTH 0x404 +#define RAM_START 0x00200404 +#define RAM_LENGTH 0x1ff6fc +#define RAM_END 0x00400000 +#endif + +/* + * The standard Arnewsh 5206 board only has 1MiB of ram. Not normally + * enough to be useful. Assume the user has fitted something larger, + * at least 4MiB in size. No point in not letting the kernel completely + * link, it will be obvious if it is too big when they go to load it. + */ +#if defined(CONFIG_ARN5206) +#define RAM_START 0x10000 +#define RAM_LENGTH 0x3f0000 +#endif + +/* + * The Motorola 5206eLITE board only has 1MiB of static RAM. + */ +#if defined(CONFIG_ELITE) +#define RAM_START 0x30020000 +#define RAM_END 0xe0000 +#endif + +/* + * All the Motorola eval boards have the same basic arrangement. + * The end of RAM will vary depending on how much ram is fitted, + * but this isn't important here, we assume at least 4MiB. + */ +#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \ + defined(CONFIG_M5272C3) || defined(CONFIG_M5307C3) || \ + defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3) +#define RAM_START 0x20000 +#define RAM_LENGTH 0x3e0000 +#endif + +#if defined(CONFIG_M5282C3) +#define RAM_START 0x10000 +#define RAM_LENGTH 0x3f0000 +#endif + +/* + * These flash boot boards use all of ram for operation. Again the + * actual memory size is not important here, assume at least 4MiB. + * They currently have no support for running in flash. + */ +#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ + defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ + defined(CONFIG_CLEOPATRA) +#define RAM_START 0x400 +#define RAM_LENGTH 0x3ffc00 +#endif + +#if defined(CONFIG_RAMKERNEL) +#define TEXT ram +#define DATA ram +#define INIT ram +#define BSS ram +#endif +#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) +#define TEXT rom +#define DATA ram +#define INIT ram +#define BSS ram +#endif + +#ifndef DATA_ADDR +#define DATA_ADDR +#endif + + +OUTPUT_ARCH(m68k) +ENTRY(_start) + +MEMORY { +#ifdef RAMVEC_START + ramvec : ORIGIN = RAMVEC_START, LENGTH = RAMVEC_LENGTH +#endif + ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH +#ifdef RAM_END + eram : ORIGIN = RAM_END, LENGTH = 0 +#endif +#ifdef ROM_START + romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH + rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH + erom : ORIGIN = ROM_END, LENGTH = 0 +#endif +} + +jiffies = jiffies_64 + 4; + +SECTIONS { + +#ifdef ROMVEC_START + . = ROMVEC_START ; + .romvec : { + __rom_start = . ; + _romvec = .; + *(.data.initvect) + } > romvec +#endif + + .text : { + _stext = . ; + *(.text) + *(.text.lock) + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + + *(.rodata) *(.rodata.*) + *(__vermagic) /* Kernel version magic */ + *(.rodata1) + + /* Kernel symbol table: Normal symbols */ + __start___ksymtab = .; + *(__ksymtab) + __stop___ksymtab = .; + + /* Kernel symbol table: GPL-only symbols */ + __start___ksymtab_gpl = .; + *(__ksymtab_gpl) + __stop___ksymtab_gpl = .; + + /* Kernel symbol table: Normal symbols */ + __start___kcrctab = .; + *(__kcrctab) + __stop___kcrctab = .; + + /* Kernel symbol table: GPL-only symbols */ + __start___kcrctab_gpl = .; + *(__kcrctab_gpl) + __stop___kcrctab_gpl = .; + + /* Kernel symbol table: strings */ + *(__ksymtab_strings) + + . = ALIGN(4) ; + _etext = . ; + } > TEXT + +#ifdef ROM_END + . = ROM_END ; + .erom : { + __rom_end = . ; + } > erom +#endif +#ifdef RAMVEC_START + . = RAMVEC_START ; + .ramvec : { + __ramvec = .; + } > ramvec +#endif + + .data DATA_ADDR : { + . = ALIGN(4); + _sdata = . ; + *(.data) + . = ALIGN(8192) ; + *(.data.init_task) + _edata = . ; + } > DATA + + .init : { + . = ALIGN(4096); + __init_begin = .; + _sinittext = .; + *(.init.text) + _einittext = .; + *(.init.data) + . = ALIGN(16); + __setup_start = .; + *(.init.setup) + __setup_end = .; + __start___param = .; + *(__param) + __stop___param = .; + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + __security_initcall_start = .; + *(.security_initcall.init) + __security_initcall_end = .; + . = ALIGN(4); + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + . = ALIGN(4); + __init_end = .; + } > INIT + + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + .bss : { + . = ALIGN(4); + _sbss = . ; + *(.bss) + *(COMMON) + . = ALIGN(4) ; + _ebss = . ; + } > BSS + +#ifdef RAM_END + . = RAM_END ; + .eram : { + __ramend = . ; + _ramend = . ; + } > eram +#endif +} + diff -Nru a/arch/m68knommu/vmlinux.lds.S b/arch/m68knommu/vmlinux.lds.S --- a/arch/m68knommu/vmlinux.lds.S Mon Aug 18 22:21:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,314 +0,0 @@ -/* - * vmlinux.lds.S -- master linker script for m68knommu arch - * - * (C) Copyright 2002-2003, Greg Ungerer - * - * This ends up looking compilcated, because of the number of - * address variations for ram and rom/flash layouts. The real - * work of the linker script is all at the end, and reasonably - * strait forward. - */ - -#include -#include - -/* - * Original Palm pilot (same for Xcopilot). - * There is really only a rom target for this. - */ -#ifdef CONFIG_PILOT3 -#define ROMVEC_START 0x10c00000 -#define ROMVEC_LENGTH 0x10400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0xfec00 -#define ROM_END 0x10d00000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x10000400 -#define RAM_LENGTH 0xffc00 -#define RAM_END 0x10100000 -#define _ramend _ram_end_notused -#define DATA_ADDR RAM_START -#endif - -/* - * Same setup on both the uCsimm and uCdimm. - */ -#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) -#ifdef CONFIG_RAMKERNEL -#define ROMVEC_START 0x10c10000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x10e00000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x00020400 -#define RAM_LENGTH 0x7dfc00 -#define RAM_END 0x00800000 -#endif -#ifdef CONFIG_ROMKERNEL -#define ROMVEC_START 0x10c10000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x10e00000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x00020000 -#define RAM_LENGTH 0x600000 -#define RAM_END 0x00800000 -#endif -#ifdef CONFIG_HIMEMKERNEL -#define ROMVEC_START 0x00600000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x00600400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x007f0000 -#define RAMVEC_START 0x00000000 -#define RAMVEC_LENGTH 0x400 -#define RAM_START 0x00020000 -#define RAM_LENGTH 0x5e0000 -#define RAM_END 0x00600000 -#endif -#endif - -#ifdef CONFIG_DRAGEN2 -#define RAM_START 0x10000 -#define RAM_LENGTH 0x7f0000 -#endif - -#ifdef CONFIG_UCQUICC -#define ROMVEC_START 0x00000000 -#define ROMVEC_LENGTH 0x404 -#define ROM_START 0x00000404 -#define ROM_LENGTH 0x1ff6fc -#define ROM_END 0x00200000 -#define RAMVEC_START 0x00200000 -#define RAMVEC_LENGTH 0x404 -#define RAM_START 0x00200404 -#define RAM_LENGTH 0x1ff6fc -#define RAM_END 0x00400000 -#endif - -/* - * The standard Arnewsh 5206 board only has 1MiB of ram. Not normally - * enough to be useful. Assume the user has fitted something larger, - * at least 4MiB in size. No point in not letting the kernel completely - * link, it will be obvious if it is too big when they go to load it. - */ -#if defined(CONFIG_ARN5206) -#define RAM_START 0x10000 -#define RAM_LENGTH 0x3f0000 -#endif - -/* - * The Motorola 5206eLITE board only has 1MiB of static RAM. - */ -#if defined(CONFIG_ELITE) -#define RAM_START 0x30020000 -#define RAM_END 0xe0000 -#endif - -/* - * All the Motorola eval boards have the same basic arrangement. - * The end of RAM will vary depending on how much ram is fitted, - * but this isn't important here, we assume at least 4MiB. - */ -#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \ - defined(CONFIG_M5272C3) || defined(CONFIG_M5307C3) || \ - defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3) -#define RAM_START 0x20000 -#define RAM_LENGTH 0x3e0000 -#endif - -#if defined(CONFIG_M5282C3) -#define RAM_START 0x10000 -#define RAM_LENGTH 0x3f0000 -#endif - -/* - * These flash boot boards use all of ram for operation. Again the - * actual memory size is not important here, assume at least 4MiB. - * They currently have no support for running in flash. - */ -#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ - defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ - defined(CONFIG_CLEOPATRA) -#define RAM_START 0x400 -#define RAM_LENGTH 0x3ffc00 -#endif - -#if defined(CONFIG_RAMKERNEL) -#define TEXT ram -#define DATA ram -#define INIT ram -#define BSS ram -#endif -#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) -#define TEXT rom -#define DATA ram -#define INIT ram -#define BSS ram -#endif - -#ifndef DATA_ADDR -#define DATA_ADDR -#endif - - -OUTPUT_ARCH(m68k) -ENTRY(_start) - -MEMORY { -#ifdef RAMVEC_START - ramvec : ORIGIN = RAMVEC_START, LENGTH = RAMVEC_LENGTH -#endif - ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH -#ifdef RAM_END - eram : ORIGIN = RAM_END, LENGTH = 0 -#endif -#ifdef ROM_START - romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH - rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH - erom : ORIGIN = ROM_END, LENGTH = 0 -#endif -} - -jiffies = jiffies_64 + 4; - -SECTIONS { - -#ifdef ROMVEC_START - . = ROMVEC_START ; - .romvec : { - __rom_start = . ; - _romvec = .; - *(.data.initvect) - } > romvec -#endif - - .text : { - _stext = . ; - *(.text) - *(.text.lock) - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - - *(.rodata) *(.rodata.*) - *(__vermagic) /* Kernel version magic */ - *(.rodata1) - - /* Kernel symbol table: Normal symbols */ - __start___ksymtab = .; - *(__ksymtab) - __stop___ksymtab = .; - - /* Kernel symbol table: GPL-only symbols */ - __start___ksymtab_gpl = .; - *(__ksymtab_gpl) - __stop___ksymtab_gpl = .; - - /* Kernel symbol table: Normal symbols */ - __start___kcrctab = .; - *(__kcrctab) - __stop___kcrctab = .; - - /* Kernel symbol table: GPL-only symbols */ - __start___kcrctab_gpl = .; - *(__kcrctab_gpl) - __stop___kcrctab_gpl = .; - - /* Kernel symbol table: strings */ - *(__ksymtab_strings) - - . = ALIGN(4) ; - _etext = . ; - } > TEXT - -#ifdef ROM_END - . = ROM_END ; - .erom : { - __rom_end = . ; - } > erom -#endif -#ifdef RAMVEC_START - . = RAMVEC_START ; - .ramvec : { - __ramvec = .; - } > ramvec -#endif - - .data DATA_ADDR : { - . = ALIGN(4); - _sdata = . ; - *(.data) - . = ALIGN(8192) ; - *(.data.init_task) - _edata = . ; - } > DATA - - .init : { - . = ALIGN(4096); - __init_begin = .; - _sinittext = .; - *(.init.text) - _einittext = .; - *(.init.data) - . = ALIGN(16); - __setup_start = .; - *(.init.setup) - __setup_end = .; - __start___param = .; - *(__param) - __stop___param = .; - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - __security_initcall_start = .; - *(.security_initcall.init) - __security_initcall_end = .; - . = ALIGN(4); - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - . = ALIGN(4); - __init_end = .; - } > INIT - - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - .bss : { - . = ALIGN(4); - _sbss = . ; - *(.bss) - *(COMMON) - . = ALIGN(4) ; - _ebss = . ; - } > BSS - -#ifdef RAM_END - . = RAM_END ; - .eram : { - __ramend = . ; - _ramend = . ; - } > eram -#endif -} - diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile --- a/arch/mips/kernel/Makefile Mon Aug 18 22:21:03 2003 +++ b/arch/mips/kernel/Makefile Mon Aug 18 22:21:03 2003 @@ -2,7 +2,7 @@ # Makefile for the Linux/MIPS kernel. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c --- a/arch/mips/kernel/irq.c Mon Aug 18 22:21:01 2003 +++ b/arch/mips/kernel/irq.c Mon Aug 18 22:21:01 2003 @@ -860,20 +860,30 @@ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + int len, k; + cpumask_t tmp = irq_affinity[(long)data]; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", irq_affinity[(long)data]); + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value, tmp; if (!irq_desc[irq].handler->set_affinity) return -EIO; @@ -885,7 +895,8 @@ * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - if (!(new_value & cpu_online_map)) + cpus_and(tmp, tmp, cpu_online_map); + if (cpus_empty(tmp)) return -EINVAL; irq_affinity[irq] = new_value; @@ -899,17 +910,28 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; + int len, k; + cpumask_t *mask = (cpumask_t *)data, tmp; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", *mask); + tmp = *mask; + + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + cpumask_t *mask = (cpumask_t *)data, new_value; + unsigned long full_count = count, err; err = parse_hex_value(buffer, count, &new_value); if (err) diff -Nru a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c --- a/arch/mips/kernel/proc.c Mon Aug 18 22:21:02 2003 +++ b/arch/mips/kernel/proc.c Mon Aug 18 22:21:02 2003 @@ -81,7 +81,7 @@ char fmt [64]; #ifdef CONFIG_SMP - if (!CPUMASK_TSTB(cpu_online_map, n)) + if (!cpu_isset(n, cpu_online_map)) return 0; #endif diff -Nru a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c --- a/arch/mips/kernel/smp.c Mon Aug 18 22:21:01 2003 +++ b/arch/mips/kernel/smp.c Mon Aug 18 22:21:01 2003 @@ -146,7 +146,7 @@ cpu_data[cpu].udelay_val = loops_per_jiffy; prom_smp_finish(); printk("Slave cpu booted successfully\n"); - CPUMASK_SETB(cpu_online_map, cpu); + cpu_set(cpu, cpu_online_map); atomic_inc(&cpus_booted); cpu_idle(); } @@ -249,7 +249,7 @@ /* * Remove this CPU: */ - clear_bit(smp_processor_id(), &cpu_online_map); + cpu_clear(smp_processor_id(), cpu_online_map); local_irq_enable(); /* May need to service _machine_restart IPI */ for (;;); /* Wait if available. */ } diff -Nru a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/kernel/vmlinux.lds.S Mon Aug 18 22:21:02 2003 @@ -0,0 +1,179 @@ +#include + +#undef mips /* CPP really sucks for this job */ +#define mips mips +OUTPUT_ARCH(mips) +ENTRY(kernel_entry) +jiffies = JIFFIES; +SECTIONS +{ +#ifdef CONFIG_BOOT_ELF64 + /* Read-only sections, merged into text segment: */ + /* . = 0xc000000000000000; */ + + /* This is the value for an Origin kernel, taken from an IRIX kernel. */ + /* . = 0xc00000000001c000; */ + + /* Set the vaddr for the text segment to a value + >= 0xa800 0000 0001 9000 if no symmon is going to configured + >= 0xa800 0000 0030 0000 otherwise */ + + /* . = 0xa800000000300000; */ + /* . = 0xa800000000300000; */ + . = 0xffffffff80300000; +#endif + . = LOADADDR; + /* read-only */ + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } =0 + + _etext = .; /* End of text section */ + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + RODATA + + . = ALIGN(64); + + /* writeable */ + .data : { /* Data */ + *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + + CONSTRUCTORS + } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + +#ifdef CONFIG_MIPS32 + . = ALIGN(8192); /* init_task */ +#endif +#ifdef CONFIG_MIPS64 + . = ALIGN(16384); /* init_task */ +#endif + . = . + MAPPED_OFFSET; /* for CONFIG_MAPPED_KERNEL */ + .data.init_task : { *(.data.init_task) } + + /* will be freed after init */ + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + /* /DISCARD/ doesn't work for .reginfo */ + .reginfo : { *(.reginfo) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + /* freed after init ends here */ + + __bss_start = .; /* BSS */ + .sbss : { + *(.sbss) + *(.scommon) + } + .bss : { + *(.bss) + *(COMMON) + } + __bss_stop = .; + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } +} diff -Nru a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c --- a/arch/mips/sgi-ip27/ip27-init.c Mon Aug 18 22:21:06 2003 +++ b/arch/mips/sgi-ip27/ip27-init.c Mon Aug 18 22:21:06 2003 @@ -480,7 +480,7 @@ */ __cpu_number_map[cpu] = num_cpus; __cpu_logical_map[num_cpus] = cpu; - CPUMASK_SETB(cpu_online_map, cpu); + cpu_set(cpu, cpu_online_map); /* * Wait this cpu to start up and initialize its hub, diff -Nru a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c --- a/arch/mips/sibyte/cfe/smp.c Mon Aug 18 22:21:05 2003 +++ b/arch/mips/sibyte/cfe/smp.c Mon Aug 18 22:21:05 2003 @@ -66,7 +66,7 @@ /* Use CFE to find out how many CPUs are available */ for (i=1; icpu = 0; cpu_data[0].udelay_val = loops_per_jiffy; cpu_data[0].asid_cache = ASID_FIRST_VERSION; - CPUMASK_CLRALL(cpu_online_map); - CPUMASK_SETB(cpu_online_map, 0); + cpus_clear(cpu_online_map); + cpu_set(0, cpu_online_map); atomic_set(&cpus_booted, 1); /* Master CPU is already booted... */ smp_tune_scheduling(); diff -Nru a/arch/mips/vmlinux.lds.S b/arch/mips/vmlinux.lds.S --- a/arch/mips/vmlinux.lds.S Mon Aug 18 22:21:02 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,179 +0,0 @@ -#include - -#undef mips /* CPP really sucks for this job */ -#define mips mips -OUTPUT_ARCH(mips) -ENTRY(kernel_entry) -jiffies = JIFFIES; -SECTIONS -{ -#ifdef CONFIG_BOOT_ELF64 - /* Read-only sections, merged into text segment: */ - /* . = 0xc000000000000000; */ - - /* This is the value for an Origin kernel, taken from an IRIX kernel. */ - /* . = 0xc00000000001c000; */ - - /* Set the vaddr for the text segment to a value - >= 0xa800 0000 0001 9000 if no symmon is going to configured - >= 0xa800 0000 0030 0000 otherwise */ - - /* . = 0xa800000000300000; */ - /* . = 0xa800000000300000; */ - . = 0xffffffff80300000; -#endif - . = LOADADDR; - /* read-only */ - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } =0 - - _etext = .; /* End of text section */ - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___dbe_table = .; /* Exception table for data bus errors */ - __dbe_table : { *(__dbe_table) } - __stop___dbe_table = .; - - RODATA - - . = ALIGN(64); - - /* writeable */ - .data : { /* Data */ - *(.data) - - /* Align the initial ramdisk image (INITRD) on page boundaries. */ - . = ALIGN(4096); - __rd_start = .; - *(.initrd) - . = ALIGN(4096); - __rd_end = .; - - CONSTRUCTORS - } - _gp = . + 0x8000; - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } - - . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; /* End of data section */ - -#ifdef CONFIG_MIPS32 - . = ALIGN(8192); /* init_task */ -#endif -#ifdef CONFIG_MIPS64 - . = ALIGN(16384); /* init_task */ -#endif - . = . + MAPPED_OFFSET; /* for CONFIG_MAPPED_KERNEL */ - .data.init_task : { *(.data.init_task) } - - /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - /* /DISCARD/ doesn't work for .reginfo */ - .reginfo : { *(.reginfo) } - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; - /* freed after init ends here */ - - __bss_start = .; /* BSS */ - .sbss : { - *(.sbss) - *(.scommon) - } - .bss : { - *(.bss) - *(COMMON) - } - __bss_stop = .; - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - /* This is the MIPS specific mdebug section. */ - .mdebug : { *(.mdebug) } - /* These are needed for ELF backends which have not yet been - converted to the new style linker. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - /* DWARF debug sections. - Symbols in the .debug DWARF section are relative to the beginning of the - section so we begin .debug at 0. It's not clear yet what needs to happen - for the others. */ - .debug 0 : { *(.debug) } - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_sfnames 0 : { *(.debug_sfnames) } - .line 0 : { *(.line) } - /* These must appear regardless of . */ - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } - .comment : { *(.comment) } - .note : { *(.note) } -} diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile --- a/arch/parisc/kernel/Makefile Mon Aug 18 22:21:02 2003 +++ b/arch/parisc/kernel/Makefile Mon Aug 18 22:21:02 2003 @@ -4,7 +4,7 @@ head-y := head.o head-$(CONFIG_PARISC64) := head64.o -extra-y := init_task.o $(head-y) +extra-y := init_task.o $(head-y) vmlinux.lds.s AFLAGS_entry.o := -traditional AFLAGS_pacache.o := -traditional diff -Nru a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c --- a/arch/parisc/kernel/smp.c Mon Aug 18 22:21:06 2003 +++ b/arch/parisc/kernel/smp.c Mon Aug 18 22:21:06 2003 @@ -62,14 +62,14 @@ static volatile int smp_commenced = 0; /* Set when the idlers are all forked */ static volatile int cpu_now_booting = 0; /* track which CPU is booting */ -volatile unsigned long cpu_online_map = 0; /* Bitmap of online CPUs */ -#define IS_LOGGED_IN(cpunum) (test_bit(cpunum, (atomic_t *)&cpu_online_map)) +cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmap of online CPUs */ +#define IS_LOGGED_IN(cpunum) (cpu_isset(cpunum, cpu_online_map)) int smp_num_cpus = 1; int smp_threads_ready = 0; unsigned long cache_decay_ticks; static int max_cpus = -1; /* Command line */ -unsigned long cpu_present_mask; +cpumask_t cpu_present_mask; struct smp_call_struct { void (*func) (void *info); @@ -139,7 +139,7 @@ #else /* REVISIT : redirect I/O Interrupts to another CPU? */ /* REVISIT : does PM *know* this CPU isn't available? */ - clear_bit(smp_processor_id(), (void *)&cpu_online_map); + cpu_clear(smp_processor_id(), cpu_online_map); local_irq_disable(); for (;;) ; @@ -443,7 +443,7 @@ mb(); /* Well, support 2.4 linux scheme as well. */ - if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map))) + if (cpu_test_and_set(cpunum, cpu_online_map)) { extern void machine_halt(void); /* arch/parisc.../process.c */ @@ -624,13 +624,14 @@ printk(KERN_DEBUG "SMP: bootstrap CPU ID is %d\n",bootstrap_processor); init_task.thread_info->cpu = bootstrap_processor; current->thread_info->cpu = bootstrap_processor; - cpu_online_map = 1 << bootstrap_processor; /* Mark Boostrap processor as present */ + /* Mark Boostrap processor as present */ + cpu_online_map = cpumask_of_cpu(bootstrap_processor); current->active_mm = &init_mm; #ifdef ENTRY_SYS_CPUS cpu_data[0].state = STATE_RUNNING; #endif - cpu_present_mask = 1UL << bootstrap_processor; + cpu_present_mask = cpumask_of_cpu(bootstrap_processor); /* Nothing to do when told not to. */ if (max_cpus == 0) { @@ -709,8 +710,8 @@ void __devinit smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); - set_bit(smp_processor_id(), &cpu_present_mask); + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), cpu_present_mask); } int __devinit __cpu_up(unsigned int cpu) diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile --- a/arch/ppc/kernel/Makefile Mon Aug 18 22:21:05 2003 +++ b/arch/ppc/kernel/Makefile Mon Aug 18 22:21:05 2003 @@ -14,6 +14,7 @@ extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o +extra-y += vmlinux.lds.s obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c --- a/arch/ppc/kernel/irq.c Mon Aug 18 22:21:05 2003 +++ b/arch/ppc/kernel/irq.c Mon Aug 18 22:21:05 2003 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -539,18 +540,6 @@ return 0; } -void __init init_IRQ(void) -{ - static int once = 0; - - if ( once ) - return; - else - once++; - - ppc_md.init_IRQ(); -} - #ifdef CONFIG_SMP void synchronize_irq(unsigned int irq) { @@ -564,29 +553,40 @@ static struct proc_dir_entry *smp_affinity_entry[NR_IRQS]; #ifdef CONFIG_IRQ_ALL_CPUS -#define DEFAULT_CPU_AFFINITY 0xffffffff +#define DEFAULT_CPU_AFFINITY CPU_MASK_ALL #else -#define DEFAULT_CPU_AFFINITY 0x00000001 +#define DEFAULT_CPU_AFFINITY cpumask_of_cpu(0) #endif -unsigned int irq_affinity [NR_IRQS] = - { [0 ... NR_IRQS-1] = DEFAULT_CPU_AFFINITY }; +cpumask_t irq_affinity [NR_IRQS]; -#define HEX_DIGITS 8 +#define HEX_DIGITS (2*sizeof(cpumask_t)) static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + cpumask_t tmp = irq_affinity[(long)data]; + int k, len = 0; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08x\n", irq_affinity[(int)data]); + + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + + len += sprintf(page, "\n"); + return len; } static unsigned int parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) + unsigned long count, cpumask_t *ret) { unsigned char hexnum [HEX_DIGITS]; - unsigned long value; + cpumask_t value = CPU_MASK_NONE; int i; if (!count) @@ -600,10 +600,9 @@ * Parse the first 8 characters as a hex string, any non-hex char * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ - value = 0; - for (i = 0; i < count; i++) { unsigned int c = hexnum[i]; + int k; switch (c) { case '0' ... '9': c -= '0'; break; @@ -612,7 +611,10 @@ default: goto out; } - value = (value << 4) | c; + cpus_shift_left(value, value, 4); + for (k = 0; k < 4; ++k) + if (c & (1 << k)) + cpu_set(k, value); } out: *ret = value; @@ -623,7 +625,7 @@ unsigned long count, void *data) { int irq = (int) data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value, tmp; if (!irq_desc[irq].handler->set_affinity) return -EIO; @@ -640,7 +642,8 @@ * are actually logical cpu #'s then we have no problem. * -- Cort */ - if (!(new_value & cpu_online_map)) + cpus_and(tmp, new_value, cpu_online_map); + if (cpus_empty(tmp)) return -EINVAL; irq_affinity[irq] = new_value; @@ -652,17 +655,27 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; + cpumask_t mask = *(cpumask_t *)data; + int k, len = 0; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", *mask); + + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(mask)); + len += j; + page += j; + cpus_shift_right(mask, mask, 16); + } + len += sprintf(page, "\n"); + return len; } static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + cpumask_t *mask = (cpumask_t *)data, full_count = count, err; + cpumask_t new_value; err = parse_hex_value(buffer, count, &new_value); if (err) @@ -730,4 +743,14 @@ irqreturn_t no_action(int irq, void *dev, struct pt_regs *regs) { return IRQ_NONE; +} + +void __init init_IRQ(void) +{ + int i; + + for (i = 0; i < NR_IRQS; ++i) + irq_affinity[i] = DEFAULT_CPU_AFFINITY; + + ppc_md.init_IRQ(); } diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c --- a/arch/ppc/kernel/setup.c Mon Aug 18 22:21:06 2003 +++ b/arch/ppc/kernel/setup.c Mon Aug 18 22:21:06 2003 @@ -160,7 +160,7 @@ } #ifdef CONFIG_SMP - if (!(cpu_online_map & (1 << i))) + if (!cpu_online(i)) return 0; pvr = cpu_data[i].pvr; lpj = cpu_data[i].loops_per_jiffy; diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c --- a/arch/ppc/kernel/smp.c Mon Aug 18 22:21:06 2003 +++ b/arch/ppc/kernel/smp.c Mon Aug 18 22:21:06 2003 @@ -47,7 +47,7 @@ DEFINE_PER_CPU(unsigned int, prof_multiplier); DEFINE_PER_CPU(unsigned int, prof_counter); unsigned long cache_decay_ticks = HZ/100; -unsigned long cpu_online_map = 1UL; +unsigned long cpu_online_map = cpumask_of_cpu(0); unsigned long cpu_possible_map = 1UL; int smp_hw_index[NR_CPUS]; struct thread_info *secondary_ti; @@ -361,8 +361,8 @@ void __devinit smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); - set_bit(smp_processor_id(), &cpu_possible_map); + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), cpu_possible_map); } int __init setup_profiling_timer(unsigned int multiplier) @@ -444,7 +444,7 @@ printk("Processor %d found.\n", cpu); smp_ops->give_timebase(); - set_bit(cpu, &cpu_online_map); + cpu_set(cpu, cpu_online_map); return 0; } diff -Nru a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/vmlinux.lds.S Mon Aug 18 22:21:06 2003 @@ -0,0 +1,183 @@ +#include + +OUTPUT_ARCH(powerpc) +jiffies = jiffies_64 + 4; +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } +/* .init : { *(.init) } =0*/ + .plt : { *(.plt) } + .text : + { + *(.text) + *(.fixup) + *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; + } + _etext = .; + PROVIDE (etext = .); + + RODATA + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + .fixup : { *(.fixup) } + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___bug_table = .; + __bug_table : { *(__bug_table) } + __stop___bug_table = .; + + /* Read-write section, merged into data segment: */ + . = ALIGN(4096); + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; + PROVIDE (edata = .); + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { + *(.init.data); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + + SECURITY_INIT + + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; + + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4096); + __pmac_begin = .; + .pmac.text : { *(.pmac.text) } + .pmac.data : { *(.pmac.data) } + . = ALIGN(4096); + __pmac_end = .; + + . = ALIGN(4096); + __prep_begin = .; + .prep.text : { *(.prep.text) } + .prep.data : { *(.prep.data) } + . = ALIGN(4096); + __prep_end = .; + + . = ALIGN(4096); + __chrp_begin = .; + .chrp.text : { *(.chrp.text) } + .chrp.data : { *(.chrp.data) } + . = ALIGN(4096); + __chrp_end = .; + + . = ALIGN(4096); + __openfirmware_begin = .; + .openfirmware.text : { *(.openfirmware.text) } + .openfirmware.data : { *(.openfirmware.data) } + . = ALIGN(4096); + __openfirmware_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + __bss_stop = .; + + _end = . ; + PROVIDE (end = .); + + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) + } +} diff -Nru a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig --- a/arch/ppc/platforms/4xx/Kconfig Mon Aug 18 22:21:01 2003 +++ b/arch/ppc/platforms/4xx/Kconfig Mon Aug 18 22:21:01 2003 @@ -70,16 +70,16 @@ depends on ASH default y -# All 405-based cores have this errata. This leaves out the 403GCX +# All 405-based cores up until the 405GPR and 405EP have this errata. config IBM405_ERR77 bool - depends on 40x && !403GCX + depends on 40x && !403GCX && !405GPR default y -# All 40x-based cores have this errata. +# All 40x-based cores, up until the 405GPR and 405EP have this errata. config IBM405_ERR51 bool - depends on 40x + depends on 40x && !405GPR default y config IBM_OCP diff -Nru a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c --- a/arch/ppc/platforms/pmac_feature.c Mon Aug 18 22:21:05 2003 +++ b/arch/ppc/platforms/pmac_feature.c Mon Aug 18 22:21:05 2003 @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -2187,6 +2186,8 @@ macio_chips[0] = macio_chips[1]; macio_chips[1] = temp; } + macio_chips[0].lbus.index = 0; + macio_chips[1].lbus.index = 1; return (macio_chips[0].of_node == NULL) ? -ENODEV : 0; } diff -Nru a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c --- a/arch/ppc/platforms/pmac_setup.c Mon Aug 18 22:21:04 2003 +++ b/arch/ppc/platforms/pmac_setup.c Mon Aug 18 22:21:04 2003 @@ -69,6 +69,7 @@ #include #include #include +#include #include "pmac_pic.h" #include "mem_pieces.h" @@ -670,3 +671,29 @@ } } #endif /* CONFIG_BOOTX_TEXT */ + +static int __init +pmac_declare_of_platform_devices(void) +{ + struct device_node *np; + + np = find_devices("uni-n"); + if (np) { + for (np = np->child; np != NULL; np = np->sibling) + if (strncmp(np->name, "i2c", 3) == 0) { + of_platform_device_create(np, "uni-n-i2c"); + break; + } + } + + np = find_devices("valkyrie"); + if (np) + of_platform_device_create(np, "valkyrie"); + np = find_devices("platinum"); + if (np) + of_platform_device_create(np, "platinum"); + + return 0; +} + +device_initcall(pmac_declare_of_platform_devices); diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile --- a/arch/ppc/syslib/Makefile Mon Aug 18 22:21:01 2003 +++ b/arch/ppc/syslib/Makefile Mon Aug 18 22:21:01 2003 @@ -27,7 +27,7 @@ ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI) += qspan_pci.o i8259.o endif -obj-$(CONFIG_PPC_OF) += prom_init.o prom.o +obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o diff -Nru a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/syslib/of_device.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include +#include +#include + +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * Used by a driver to check whether an of_device present in the + * system is in its list of supported devices. + */ +const struct of_match * +of_match_device(const struct of_match *matches, const struct of_device *dev) +{ + if (!dev->node) + return NULL; + while (matches->name || matches->type || matches->compatible) { + int match = 1; + if (matches->name && matches->name != OF_ANY_MATCH) + match &= dev->node->name + && !strcmp(matches->name, dev->node->name); + if (matches->type && matches->type != OF_ANY_MATCH) + match &= dev->node->type + && !strcmp(matches->type, dev->node->type); + if (matches->compatible && matches->compatible != OF_ANY_MATCH) + match &= device_is_compatible(dev->node, + matches->compatible); + if (match) + return matches; + matches++; + } + return NULL; +} + +static int +of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * of_drv = to_of_platform_driver(drv); + const struct of_match * matches = of_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +struct bus_type of_platform_bus_type = { + name: "of_platform", + match: of_platform_bus_match, +}; + +static int __init +of_bus_driver_init(void) +{ + return bus_register(&of_platform_bus_type); +} + +postcore_initcall(of_bus_driver_init); + +static int +of_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_match *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + +/* if (!try_module_get(driver->owner)) { + printk(KERN_ERR "Can't get a module reference for %s\n", driver->name); + return error; + } +*/ + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); +/* + module_put(driver->owner); +*/ + return error; +} + +static int +of_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + + if (drv && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int +of_device_suspend(struct device *dev, u32 state, u32 level) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + int error = 0; + + if (drv && drv->suspend) + error = drv->suspend(of_dev, state, level); + return error; +} + +static int +of_device_resume(struct device * dev, u32 level) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + int error = 0; + + if (drv && drv->resume) + error = drv->resume(of_dev, level); + return error; +} + +int +of_register_driver(struct of_platform_driver *drv) +{ + int count = 0; + + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &of_platform_bus_type; + drv->driver.probe = of_device_probe; + drv->driver.resume = of_device_resume; + drv->driver.suspend = of_device_suspend; + drv->driver.remove = of_device_remove; + + /* register with core */ + count = driver_register(&drv->driver); + return count ? count : 1; +} + +void +of_unregister_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} + + +static ssize_t +dev_show_devspec(struct device *dev, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s", ofdev->node->full_name); +} + +static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); + +int +of_device_register(struct of_device *ofdev) +{ + int rc; + struct of_device **odprop; + + BUG_ON(ofdev->node == NULL); + + odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); + if (!odprop) { + struct property *new_prop; + + new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *), + GFP_KERNEL); + if (new_prop == NULL) + return -ENOMEM; + new_prop->name = "linux,device"; + new_prop->length = sizeof(sizeof(struct of_device *)); + new_prop->value = (unsigned char *)&new_prop[1]; + odprop = (struct of_device **)new_prop->value; + *odprop = NULL; + prom_add_property(ofdev->node, new_prop); + } + *odprop = ofdev; + + rc = device_register(&ofdev->dev); + if (rc) + return rc; + + device_create_file(&ofdev->dev, &dev_attr_devspec); + + return 0; +} + +void +of_device_unregister(struct of_device *ofdev) +{ + struct of_device **odprop; + + device_remove_file(&ofdev->dev, &dev_attr_devspec); + device_unregister(&ofdev->dev); + + odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); + if (odprop) + *odprop = NULL; +} + +struct of_device* +of_platform_device_create(struct device_node *np, const char *bus_id) +{ + struct of_device *dev; + u32 *reg; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); + + dev->node = np; + dev->dma_mask = 0xffffffffUL; + dev->dev.dma_mask = &dev->dma_mask; + dev->dev.parent = NULL; + dev->dev.bus = &of_platform_bus_type; + + reg = (u32 *)get_property(np, "reg", NULL); + strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); + + if (of_device_register(dev) != 0) { + kfree(dev); + return NULL; + } + + return dev; +} + +EXPORT_SYMBOL(of_match_device); +EXPORT_SYMBOL(of_platform_bus_type); +EXPORT_SYMBOL(of_register_driver); +EXPORT_SYMBOL(of_unregister_driver); +EXPORT_SYMBOL(of_device_register); +EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_platform_device_create); diff -Nru a/arch/ppc/vmlinux.lds.S b/arch/ppc/vmlinux.lds.S --- a/arch/ppc/vmlinux.lds.S Mon Aug 18 22:21:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,183 +0,0 @@ -#include - -OUTPUT_ARCH(powerpc) -jiffies = jiffies_64 + 4; -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } -/* .init : { *(.init) } =0*/ - .plt : { *(.plt) } - .text : - { - *(.text) - *(.fixup) - *(.got1) - __got2_start = .; - *(.got2) - __got2_end = .; - } - _etext = .; - PROVIDE (etext = .); - - RODATA - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - - .fixup : { *(.fixup) } - - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___bug_table = .; - __bug_table : { *(__bug_table) } - __stop___bug_table = .; - - /* Read-write section, merged into data segment: */ - . = ALIGN(4096); - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; - PROVIDE (edata = .); - - . = ALIGN(8192); - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { - *(.init.data); - __vtop_table_begin = .; - *(.vtop_fixup); - __vtop_table_end = .; - __ptov_table_begin = .; - *(.ptov_fixup); - __ptov_table_end = .; - } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - - SECURITY_INIT - - __start___ftr_fixup = .; - __ftr_fixup : { *(__ftr_fixup) } - __stop___ftr_fixup = .; - - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - __pmac_begin = .; - .pmac.text : { *(.pmac.text) } - .pmac.data : { *(.pmac.data) } - . = ALIGN(4096); - __pmac_end = .; - - . = ALIGN(4096); - __prep_begin = .; - .prep.text : { *(.prep.text) } - .prep.data : { *(.prep.data) } - . = ALIGN(4096); - __prep_end = .; - - . = ALIGN(4096); - __chrp_begin = .; - .chrp.text : { *(.chrp.text) } - .chrp.data : { *(.chrp.data) } - . = ALIGN(4096); - __chrp_end = .; - - . = ALIGN(4096); - __openfirmware_begin = .; - .openfirmware.text : { *(.openfirmware.text) } - .openfirmware.data : { *(.openfirmware.data) } - . = ALIGN(4096); - __openfirmware_end = .; - - __bss_start = .; - .bss : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - } - __bss_stop = .; - - _end = . ; - PROVIDE (end = .); - - /* Sections to be discarded. */ - /DISCARD/ : { - *(.exitcall.exit) - } -} diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig --- a/arch/ppc64/Kconfig Mon Aug 18 22:21:03 2003 +++ b/arch/ppc64/Kconfig Mon Aug 18 22:21:03 2003 @@ -93,7 +93,7 @@ CPU. config NR_CPUS - int "Maximum number of CPUs (2-64)" + int "Maximum number of CPUs (2-128)" depends on SMP default "32" diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile --- a/arch/ppc64/kernel/Makefile Mon Aug 18 22:21:06 2003 +++ b/arch/ppc64/kernel/Makefile Mon Aug 18 22:21:06 2003 @@ -3,7 +3,8 @@ # EXTRA_CFLAGS += -mno-minimal-toc -extra-y := head.o +extra-y := head.o vmlinux.lds.s + 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 \ diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c --- a/arch/ppc64/kernel/htab.c Mon Aug 18 22:21:04 2003 +++ b/arch/ppc64/kernel/htab.c Mon Aug 18 22:21:04 2003 @@ -377,6 +377,7 @@ int ret; int user_region = 0; int local = 0; + cpumask_t tmp; /* Check for invalid addresses. */ if (!IS_VALID_EA(ea)) @@ -431,7 +432,8 @@ */ spin_lock(&mm->page_table_lock); - if (user_region && (mm->cpu_vm_mask == (1 << smp_processor_id()))) + tmp = cpumask_of_cpu(smp_processor_id()); + if (user_region && cpus_equal(mm->cpu_vm_mask, tmp)) local = 1; ptep = find_linux_pte(pgdir, ea); diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c --- a/arch/ppc64/kernel/ioctl32.c Mon Aug 18 22:21:06 2003 +++ b/arch/ppc64/kernel/ioctl32.c Mon Aug 18 22:21:06 2003 @@ -28,34 +28,6 @@ #define CODE #include "compat_ioctl.c" -struct hd_big_geometry32 { - unsigned char heads; - unsigned char sectors; - unsigned int cylinders; - u32 start; -}; - -static int hdio_getgeo_big(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - struct hd_big_geometry geo; - int err; - - set_fs (KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&geo); - set_fs (old_fs); - if (!err) { - struct hd_big_geometry32 *up = (struct hd_big_geometry32 *) arg; - - if (put_user(geo.heads, &up->heads) || - __put_user(geo.sectors, &up->sectors) || - __put_user(geo.cylinders, &up->cylinders) || - __put_user(((u32) geo.start), &up->start)) - err = -EFAULT; - } - return err; -} - struct ncp_ioctl_request_32 { unsigned int function; unsigned int size; @@ -773,7 +745,6 @@ COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ /* And these ioctls need translation */ -HANDLE_IOCTL(HDIO_GETGEO_BIG_RAW, hdio_getgeo_big) /* NCPFS */ HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c --- a/arch/ppc64/kernel/irq.c Mon Aug 18 22:21:03 2003 +++ b/arch/ppc64/kernel/irq.c Mon Aug 18 22:21:03 2003 @@ -569,26 +569,37 @@ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; #ifdef CONFIG_IRQ_ALL_CPUS -unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = -1UL}; +cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; #else /* CONFIG_IRQ_ALL_CPUS */ -unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x0}; +cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_NONE }; #endif /* CONFIG_IRQ_ALL_CPUS */ -#define HEX_DIGITS 16 +#define HEX_DIGITS (2*sizeof(cpumask_t)) static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + int k, len; + cpumask_t tmp = irq_affinity[(long)data]; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf(page, "%16lx\n", irq_affinity[(long)data]); + + for (k = 0; k < sizeof(cpumask_t) / sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } static unsigned int parse_hex_value (const char *buffer, - unsigned long count, unsigned long *ret) + unsigned long count, cpumask_t *ret) { unsigned char hexnum [HEX_DIGITS]; - unsigned long value; + cpumask_t value = CPU_MASK_NONE; int i; if (!count) @@ -602,10 +613,10 @@ * Parse the first 16 characters as a hex string, any non-hex char * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ - value = 0; for (i = 0; i < count; i++) { unsigned int c = hexnum[i]; + int k; switch (c) { case '0' ... '9': c -= '0'; break; @@ -614,7 +625,11 @@ default: goto out; } - value = (value << 4) | c; + cpus_shift_left(value, value, 4); + for (k = 0; k < 4; ++k) + if (test_bit(k, (unsigned long *)&c)) + cpu_set(k, value); + } out: *ret = value; @@ -625,7 +640,7 @@ unsigned long count, void *data) { int irq = (long)data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value, tmp; if (!irq_desc[irq].handler->set_affinity) return -EIO; @@ -637,7 +652,8 @@ * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - if (!(new_value & cpu_online_map)) + cpus_and(tmp, new_value, cpu_online_map); + if (cpus_empty(tmp)) return -EINVAL; irq_affinity[irq] = new_value; @@ -658,8 +674,9 @@ static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + cpumask_t *mask = (cpumask_t *)data; + unsigned long full_count = count, err; + cpumask_t new_value; err = parse_hex_value(buffer, count, &new_value); if (err) diff -Nru a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c --- a/arch/ppc64/kernel/open_pic.c Mon Aug 18 22:21:04 2003 +++ b/arch/ppc64/kernel/open_pic.c Mon Aug 18 22:21:04 2003 @@ -46,7 +46,7 @@ OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU]; static void openpic_end_irq(unsigned int irq_nr); -static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask); +static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask); struct hw_interrupt_type open_pic = { " OpenPIC ", @@ -516,7 +516,7 @@ void openpic_init_processor(u_int cpumask) { openpic_write(&OpenPIC->Global.Processor_Initialization, - cpumask & cpu_online_map); + cpumask & cpus_coerce(cpu_online_map)); } #ifdef CONFIG_SMP @@ -550,7 +550,7 @@ CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), - cpumask & cpu_online_map); + cpumask & cpus_coerce(cpu_online_map)); } void openpic_request_IPIs(void) @@ -636,7 +636,7 @@ { check_arg_timer(timer); openpic_write(&OpenPIC->Global.Timer[timer].Destination, - cpumask & cpu_online_map); + cpumask & cpus_coerce(cpu_online_map)); } @@ -757,9 +757,12 @@ openpic_eoi(); } -static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) +static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask) { - openpic_mapirq(irq_nr - open_pic_irq_offset, cpumask & cpu_online_map); + cpumask_t tmp; + + cpus_and(tmp, cpumask, cpu_online_map); + openpic_mapirq(irq_nr - open_pic_irq_offset, cpus_coerce(tmp)); } #ifdef CONFIG_SMP diff -Nru a/arch/ppc64/kernel/open_pic.h b/arch/ppc64/kernel/open_pic.h --- a/arch/ppc64/kernel/open_pic.h Mon Aug 18 22:21:01 2003 +++ b/arch/ppc64/kernel/open_pic.h Mon Aug 18 22:21:01 2003 @@ -13,6 +13,7 @@ #define _PPC64_KERNEL_OPEN_PIC_H #include +#include #define OPENPIC_SIZE 0x40000 diff -Nru a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c --- a/arch/ppc64/kernel/pacaData.c Mon Aug 18 22:21:05 2003 +++ b/arch/ppc64/kernel/pacaData.c Mon Aug 18 22:21:05 2003 @@ -134,5 +134,71 @@ PACAINITDATA(61, 0, 0, 0, 0), PACAINITDATA(62, 0, 0, 0, 0), PACAINITDATA(63, 0, 0, 0, 0), +#if NR_CPUS > 64 + PACAINITDATA(64, 0, 0, 0, 0), + PACAINITDATA(65, 0, 0, 0, 0), + PACAINITDATA(66, 0, 0, 0, 0), + PACAINITDATA(67, 0, 0, 0, 0), + PACAINITDATA(68, 0, 0, 0, 0), + PACAINITDATA(69, 0, 0, 0, 0), + PACAINITDATA(70, 0, 0, 0, 0), + PACAINITDATA(71, 0, 0, 0, 0), + PACAINITDATA(72, 0, 0, 0, 0), + PACAINITDATA(73, 0, 0, 0, 0), + PACAINITDATA(74, 0, 0, 0, 0), + PACAINITDATA(75, 0, 0, 0, 0), + PACAINITDATA(76, 0, 0, 0, 0), + PACAINITDATA(77, 0, 0, 0, 0), + PACAINITDATA(78, 0, 0, 0, 0), + PACAINITDATA(79, 0, 0, 0, 0), + PACAINITDATA(80, 0, 0, 0, 0), + PACAINITDATA(81, 0, 0, 0, 0), + PACAINITDATA(82, 0, 0, 0, 0), + PACAINITDATA(83, 0, 0, 0, 0), + PACAINITDATA(84, 0, 0, 0, 0), + PACAINITDATA(85, 0, 0, 0, 0), + PACAINITDATA(86, 0, 0, 0, 0), + PACAINITDATA(87, 0, 0, 0, 0), + PACAINITDATA(88, 0, 0, 0, 0), + PACAINITDATA(89, 0, 0, 0, 0), + PACAINITDATA(90, 0, 0, 0, 0), + PACAINITDATA(91, 0, 0, 0, 0), + PACAINITDATA(92, 0, 0, 0, 0), + PACAINITDATA(93, 0, 0, 0, 0), + PACAINITDATA(94, 0, 0, 0, 0), + PACAINITDATA(95, 0, 0, 0, 0), + PACAINITDATA(96, 0, 0, 0, 0), + PACAINITDATA(97, 0, 0, 0, 0), + PACAINITDATA(98, 0, 0, 0, 0), + PACAINITDATA(99, 0, 0, 0, 0), + PACAINITDATA(100, 0, 0, 0, 0), + PACAINITDATA(101, 0, 0, 0, 0), + PACAINITDATA(102, 0, 0, 0, 0), + PACAINITDATA(103, 0, 0, 0, 0), + PACAINITDATA(104, 0, 0, 0, 0), + PACAINITDATA(105, 0, 0, 0, 0), + PACAINITDATA(106, 0, 0, 0, 0), + PACAINITDATA(107, 0, 0, 0, 0), + PACAINITDATA(108, 0, 0, 0, 0), + PACAINITDATA(109, 0, 0, 0, 0), + PACAINITDATA(110, 0, 0, 0, 0), + PACAINITDATA(111, 0, 0, 0, 0), + PACAINITDATA(112, 0, 0, 0, 0), + PACAINITDATA(113, 0, 0, 0, 0), + PACAINITDATA(114, 0, 0, 0, 0), + PACAINITDATA(115, 0, 0, 0, 0), + PACAINITDATA(116, 0, 0, 0, 0), + PACAINITDATA(117, 0, 0, 0, 0), + PACAINITDATA(118, 0, 0, 0, 0), + PACAINITDATA(119, 0, 0, 0, 0), + PACAINITDATA(120, 0, 0, 0, 0), + PACAINITDATA(121, 0, 0, 0, 0), + PACAINITDATA(122, 0, 0, 0, 0), + PACAINITDATA(123, 0, 0, 0, 0), + PACAINITDATA(124, 0, 0, 0, 0), + PACAINITDATA(125, 0, 0, 0, 0), + PACAINITDATA(126, 0, 0, 0, 0), + PACAINITDATA(127, 0, 0, 0, 0), +#endif #endif }; diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c --- a/arch/ppc64/kernel/prom.c Mon Aug 18 22:21:04 2003 +++ b/arch/ppc64/kernel/prom.c Mon Aug 18 22:21:04 2003 @@ -1133,7 +1133,7 @@ _prom->cpu = (int)(unsigned long)getprop_rval; _xPaca[_prom->cpu].active = 1; #ifdef CONFIG_SMP - RELOC(cpu_online_map) = 1UL << _prom->cpu; + cpu_set(_prom->cpu, RELOC(cpu_online_map)); #endif RELOC(boot_cpuid) = _prom->cpu; diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c --- a/arch/ppc64/kernel/rtasd.c Mon Aug 18 22:21:02 2003 +++ b/arch/ppc64/kernel/rtasd.c Mon Aug 18 22:21:02 2003 @@ -225,7 +225,7 @@ continue; DEBUG("scheduling on %d\n", cpu); - set_cpus_allowed(current, 1UL << cpu); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id()); do { diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c --- a/arch/ppc64/kernel/setup.c Mon Aug 18 22:21:03 2003 +++ b/arch/ppc64/kernel/setup.c Mon Aug 18 22:21:03 2003 @@ -257,7 +257,7 @@ return 0; } - if (!(cpu_online_map & (1UL << cpu_id))) + if (!cpu_online(cpu_id)) return 0; #ifdef CONFIG_SMP diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c --- a/arch/ppc64/kernel/smp.c Mon Aug 18 22:21:04 2003 +++ b/arch/ppc64/kernel/smp.c Mon Aug 18 22:21:04 2003 @@ -53,7 +53,7 @@ unsigned long cache_decay_ticks; /* initialised so it doesn't end up in bss */ -unsigned long cpu_online_map = 0; +cpumask_t cpu_online_map = CPU_MASK_NONE; static struct smp_ops_t *smp_ops; @@ -574,7 +574,7 @@ void __devinit smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); + cpu_set(smp_processor_id(), cpu_online_map); /* FIXME: what about cpu_possible()? */ } @@ -635,7 +635,7 @@ if (smp_ops->give_timebase) smp_ops->give_timebase(); - set_bit(cpu, &cpu_online_map); + cpu_set(cpu, cpu_online_map); return 0; } diff -Nru a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc64/kernel/vmlinux.lds.S Mon Aug 18 22:21:05 2003 @@ -0,0 +1,140 @@ +#include + +OUTPUT_ARCH(powerpc:common64) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +jiffies = jiffies_64; +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } +/* .init : { *(.init) } =0*/ + .plt : { *(.plt) } + .text : + { + *(.text) + *(.fixup) + *(.got1) + } + . = ALIGN(4096); + _etext = .; + PROVIDE (etext = .); + + RODATA + + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFFFFFFFFFF000; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + . = ALIGN(4096); + _edata = .; + PROVIDE (edata = .); + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___bug_table = .; + __bug_table : { *(__bug_table) } + __stop___bug_table = .; + + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; + + . = ALIGN(16384); /* init_task */ + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + .data.page_aligned : { *(.data.page_aligned) } + + . = ALIGN(128); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + /* will be freed after init */ + . = ALIGN(4096); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + /* freed after init ends here */ + + __toc_start = .; + .toc : { *(.toc) } + . = ALIGN(4096); + __toc_end = .; + + __bss_start = .; + .bss : { *(.bss) } + __bss_stop = .; + + . = ALIGN(4096); + _end = . ; + PROVIDE (end = .); +} diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c --- a/arch/ppc64/kernel/xics.c Mon Aug 18 22:21:03 2003 +++ b/arch/ppc64/kernel/xics.c Mon Aug 18 22:21:03 2003 @@ -34,7 +34,7 @@ void xics_disable_irq(u_int irq); void xics_mask_and_ack_irq(u_int irq); void xics_end_irq(u_int irq); -void xics_set_affinity(unsigned int irq_nr, unsigned long cpumask); +void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask); struct hw_interrupt_type xics_pic = { " XICS ", @@ -524,7 +524,7 @@ } #endif -void xics_set_affinity(unsigned int virq, unsigned long cpumask) +void xics_set_affinity(unsigned int virq, cpumask_t cpumask) { irq_desc_t *desc = irq_desc + virq; unsigned int irq; @@ -532,6 +532,8 @@ long status; unsigned long xics_status[2]; unsigned long newmask; + cpumask_t allcpus = CPU_MASK_ALL; + cpumask_t tmp = CPU_MASK_NONE; virq -= XICS_IRQ_OFFSET; irq = virt_irq_to_real(virq); @@ -549,12 +551,13 @@ } /* For the moment only implement delivery to all cpus or one cpu */ - if (cpumask == -1UL) { + if (cpus_equal(cpumask, allcpus)) { newmask = default_distrib_server; } else { - if (!(cpumask & cpu_online_map)) + cpus_and(tmp, cpu_online_map, cpumask); + if (cpus_empty(tmp)) goto out; - newmask = find_first_bit(&cpumask, 8*sizeof(unsigned long)); + newmask = first_cpu(cpumask); } status = rtas_call(ibm_set_xive, 3, 1, NULL, diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c --- a/arch/ppc64/mm/init.c Mon Aug 18 22:21:04 2003 +++ b/arch/ppc64/mm/init.c Mon Aug 18 22:21:04 2003 @@ -247,7 +247,7 @@ __flush_tlb_range(mm, mp->vm_start, mp->vm_end); /* XXX are there races with checking cpu_vm_mask? - Anton */ - mm->cpu_vm_mask = 0; + cpus_clear(mm->cpu_vm_mask); spin_unlock(&mm->page_table_lock); } @@ -264,6 +264,7 @@ pte_t *ptep; pte_t pte; int local = 0; + cpumask_t tmp; switch( REGION_ID(vmaddr) ) { case VMALLOC_REGION_ID: @@ -277,7 +278,8 @@ context = vma->vm_mm->context; /* XXX are there races with checking cpu_vm_mask? - Anton */ - if (vma->vm_mm->cpu_vm_mask == (1 << smp_processor_id())) + tmp = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) local = 1; break; @@ -313,6 +315,7 @@ struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[smp_processor_id()]; unsigned long i = 0; int local = 0; + cpumask_t tmp; switch(REGION_ID(start)) { case VMALLOC_REGION_ID: @@ -326,7 +329,8 @@ context = mm->context; /* XXX are there races with checking cpu_vm_mask? - Anton */ - if (mm->cpu_vm_mask == (1 << smp_processor_id())) + tmp = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(mm->cpu_vm_mask, tmp)) local = 1; break; @@ -692,6 +696,7 @@ void *pgdir; pte_t *ptep; int local = 0; + cpumask_t tmp; /* handle i-cache coherency */ if (!(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) { @@ -717,7 +722,8 @@ ptep = find_linux_pte(pgdir, ea); vsid = get_vsid(vma->vm_mm->context, ea); - if (vma->vm_mm->cpu_vm_mask == (1 << smp_processor_id())) + tmp = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) local = 1; __hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep, diff -Nru a/arch/ppc64/vmlinux.lds.S b/arch/ppc64/vmlinux.lds.S --- a/arch/ppc64/vmlinux.lds.S Mon Aug 18 22:21:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,140 +0,0 @@ -#include - -OUTPUT_ARCH(powerpc:common64) -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -jiffies = jiffies_64; -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } -/* .init : { *(.init) } =0*/ - .plt : { *(.plt) } - .text : - { - *(.text) - *(.fixup) - *(.got1) - } - . = ALIGN(4096); - _etext = .; - PROVIDE (etext = .); - - RODATA - - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFFFFFFFFFF000; - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - . = ALIGN(4096); - _edata = .; - PROVIDE (edata = .); - - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___bug_table = .; - __bug_table : { *(__bug_table) } - __stop___bug_table = .; - - __start___ftr_fixup = .; - __ftr_fixup : { *(__ftr_fixup) } - __stop___ftr_fixup = .; - - . = ALIGN(16384); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); - .data.page_aligned : { *(.data.page_aligned) } - - . = ALIGN(128); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - /* will be freed after init */ - . = ALIGN(4096); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; - /* freed after init ends here */ - - __toc_start = .; - .toc : { *(.toc) } - . = ALIGN(4096); - __toc_end = .; - - __bss_start = .; - .bss : { *(.bss) } - __bss_stop = .; - - . = ALIGN(4096); - _end = . ; - PROVIDE (end = .); -} diff -Nru a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile --- a/arch/s390/kernel/Makefile Mon Aug 18 22:21:06 2003 +++ b/arch/s390/kernel/Makefile Mon Aug 18 22:21:06 2003 @@ -10,7 +10,7 @@ extra-$(CONFIG_ARCH_S390_31) += head.o extra-$(CONFIG_ARCH_S390X) += head64.o -extra-y += init_task.o +extra-y += init_task.o vmlinux.lds.s obj-$(CONFIG_MODULES) += s390_ksyms.o module.o obj-$(CONFIG_SMP) += smp.o diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c --- a/arch/s390/kernel/setup.c Mon Aug 18 22:21:01 2003 +++ b/arch/s390/kernel/setup.c Mon Aug 18 22:21:01 2003 @@ -56,7 +56,7 @@ #define CHUNK_READ_WRITE 0 #define CHUNK_READ_ONLY 1 int cpus_initialized = 0; -unsigned long cpu_initialized = 0; +static cpumask_t cpu_initialized; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ /* @@ -86,7 +86,7 @@ int nr = smp_processor_id(); int addr = hard_smp_processor_id(); - if (test_and_set_bit(nr,&cpu_initialized)) { + if (cpu_test_and_set(nr,cpu_initialized)) { printk("CPU#%d ALREADY INITIALIZED!!!!!!!!!\n", nr); for (;;) local_irq_enable(); } @@ -565,7 +565,7 @@ num_online_cpus(), loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ))%100); } - if (cpu_online_map & (1 << n)) { + if (cpu_online(n)) { #ifdef CONFIG_SMP if (smp_processor_id() == n) cpuinfo = &S390_lowcore.cpu_data; diff -Nru a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c --- a/arch/s390/kernel/smp.c Mon Aug 18 22:21:00 2003 +++ b/arch/s390/kernel/smp.c Mon Aug 18 22:21:00 2003 @@ -51,8 +51,8 @@ cycles_t cacheflush_time=0; int smp_threads_ready=0; /* Set when the idlers are all forked. */ -volatile unsigned long cpu_online_map; -volatile unsigned long cpu_possible_map; +cpumask_t cpu_online_map; +cpumask_t cpu_possible_map; unsigned long cache_decay_ticks = 0; /* @@ -200,14 +200,14 @@ /* * Reboot, halt and power_off routines for SMP. */ -static volatile unsigned long cpu_restart_map; +static cpumask_t cpu_restart_map; static void do_machine_restart(void * __unused) { - clear_bit(smp_processor_id(), &cpu_restart_map); + cpu_clear(smp_processor_id(), cpu_restart_map); if (smp_processor_id() == 0) { /* Wait for all other cpus to enter do_machine_restart. */ - while (cpu_restart_map != 0); + while (!cpus_empty(cpu_restart_map)); /* Store status of other cpus. */ do_store_status(); /* @@ -427,7 +427,7 @@ if (signal_processor(num_cpus, sigp_sense) == sigp_not_operational) continue; - set_bit(num_cpus, &cpu_possible_map); + cpu_set(num_cpus, cpu_possible_map); num_cpus++; } printk("Detected %d CPU's\n",(int) num_cpus); @@ -452,7 +452,7 @@ pfault_init(); #endif /* Mark this cpu as online */ - set_bit(smp_processor_id(), &cpu_online_map); + cpu_set(smp_processor_id(), cpu_online_map); /* Switch on interrupts */ local_irq_enable(); /* Print info about this processor */ @@ -558,8 +558,8 @@ void __devinit smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); - set_bit(smp_processor_id(), &cpu_possible_map); + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), cpu_possible_map); } void smp_cpus_done(unsigned int max_cpus) diff -Nru a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/s390/kernel/vmlinux.lds.S Mon Aug 18 22:21:02 2003 @@ -0,0 +1,132 @@ +/* ld script to make s390 Linux kernel + * Written by Martin Schwidefsky (schwidefsky@de.ibm.com) + */ + +#include +#include + +#ifndef CONFIG_ARCH_S390X +OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") +OUTPUT_ARCH(s390) +ENTRY(_start) +jiffies = jiffies_64 + 4; +#else +OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") +OUTPUT_ARCH(s390:64-bit) +ENTRY(_start) +jiffies = jiffies_64; +#endif + +SECTIONS +{ + . = 0x00000000; + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x0700 + + _etext = .; /* End of text section */ + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + +#ifdef CONFIG_SHARED_KERNEL + . = ALIGN(1048576); /* VM shared segments are 1MB aligned */ + + _eshared = .; /* End of shareable data */ +#endif + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + + . = ALIGN(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + + /* will be freed after init */ + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(256); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(256); + __initramfs_start = .; + .init.ramfs : { *(.init.initramfs) } + __initramfs_end = .; + . = ALIGN(256); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + /* freed after init ends here */ + + __bss_start = .; /* BSS */ + .bss : { *(.bss) } + __bss_stop = .; + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + *(.eh_frame) + } + + /* 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) } +} diff -Nru a/arch/s390/vmlinux.lds.S b/arch/s390/vmlinux.lds.S --- a/arch/s390/vmlinux.lds.S Mon Aug 18 22:21:02 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,132 +0,0 @@ -/* ld script to make s390 Linux kernel - * Written by Martin Schwidefsky (schwidefsky@de.ibm.com) - */ - -#include -#include - -#ifndef CONFIG_ARCH_S390X -OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") -OUTPUT_ARCH(s390) -ENTRY(_start) -jiffies = jiffies_64 + 4; -#else -OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -OUTPUT_ARCH(s390:64-bit) -ENTRY(_start) -jiffies = jiffies_64; -#endif - -SECTIONS -{ - . = 0x00000000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x0700 - - _etext = .; /* End of text section */ - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - RODATA - -#ifdef CONFIG_SHARED_KERNEL - . = ALIGN(1048576); /* VM shared segments are 1MB aligned */ - - _eshared = .; /* End of shareable data */ -#endif - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(256); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(256); - __initramfs_start = .; - .init.ramfs : { *(.init.initramfs) } - __initramfs_end = .; - . = ALIGN(256); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; - /* freed after init ends here */ - - __bss_start = .; /* BSS */ - .bss : { *(.bss) } - __bss_stop = .; - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - *(.eh_frame) - } - - /* 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) } -} diff -Nru a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile --- a/arch/sh/kernel/Makefile Mon Aug 18 22:21:04 2003 +++ b/arch/sh/kernel/Makefile Mon Aug 18 22:21:04 2003 @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH kernel. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ diff -Nru a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/sh/kernel/vmlinux.lds.S Mon Aug 18 22:21:03 2003 @@ -0,0 +1,148 @@ +/* $Id: vmlinux.lds.S,v 1.8 2003/05/16 17:18:14 lethal Exp $ + * ld script to make SuperH Linux kernel + * Written by Niibe Yutaka + */ +#include +#include + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") +#else +OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") +#endif +OUTPUT_ARCH(sh) +ENTRY(_start) +SECTIONS +{ + . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; + _text = .; /* Text and read-only data */ + text = .; /* Text and read-only data */ + .empty_zero_page : { + *(.empty_zero_page) + } = 0 + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x0009 + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + + _etext = .; /* End of text section */ + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + + . = ALIGN(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + /* stack */ + .stack : { stack = .; _stack = .; } + + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + _sinittext = .; + .init.text : { *(.init.text) } + _einittext = .; + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + __machvec_start = .; + .init.machvec : { *(.init.machvec) } + __machvec_end = .; + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4); + __bss_start = .; /* BSS */ + .bss : { *(.bss) } + + . = ALIGN(4); + _end = . ; + + /* When something in the kernel is NOT compiled as a module, the + * module cleanup code and data are put into these segments. Both + * can then be thrown away, as cleanup code is never called unless + * it's a module. + */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + /* 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 section are relative to the beginning + of the section so we begin .debug 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) } + .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) } + /* These must appear regardless of . */ +} diff -Nru a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S --- a/arch/sh/vmlinux.lds.S Mon Aug 18 22:21:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,148 +0,0 @@ -/* $Id: vmlinux.lds.S,v 1.8 2003/05/16 17:18:14 lethal Exp $ - * ld script to make SuperH Linux kernel - * Written by Niibe Yutaka - */ -#include -#include - -#ifdef CONFIG_CPU_LITTLE_ENDIAN -OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") -#else -OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") -#endif -OUTPUT_ARCH(sh) -ENTRY(_start) -SECTIONS -{ - . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; - _text = .; /* Text and read-only data */ - text = .; /* Text and read-only data */ - .empty_zero_page : { - *(.empty_zero_page) - } = 0 - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x0009 - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - RODATA - - _etext = .; /* End of text section */ - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - /* stack */ - .stack : { stack = .; _stack = .; } - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - _sinittext = .; - .init.text : { *(.init.text) } - _einittext = .; - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - __machvec_start = .; - .init.machvec : { *(.init.machvec) } - __machvec_end = .; - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4); - __bss_start = .; /* BSS */ - .bss : { *(.bss) } - - . = ALIGN(4); - _end = . ; - - /* When something in the kernel is NOT compiled as a module, the - * module cleanup code and data are put into these segments. Both - * can then be thrown away, as cleanup code is never called unless - * it's a module. - */ - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - /* 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 section are relative to the beginning - of the section so we begin .debug 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) } - .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) } - /* These must appear regardless of . */ -} diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile --- a/arch/sparc/Makefile Mon Aug 18 22:21:01 2003 +++ b/arch/sparc/Makefile Mon Aug 18 22:21:01 2003 @@ -7,10 +7,6 @@ # Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) # -# If the solaris /bin/sh wasn't so broken, I wouldn't need the following -# line... -SHELL =/bin/bash - # # Uncomment the first CFLAGS if you are doing kgdb source level # debugging of the kernel to get the proper debugging information. diff -Nru a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile --- a/arch/sparc/kernel/Makefile Mon Aug 18 22:21:05 2003 +++ b/arch/sparc/kernel/Makefile Mon Aug 18 22:21:05 2003 @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s EXTRA_AFLAGS := -ansi diff -Nru a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S --- a/arch/sparc/kernel/entry.S Mon Aug 18 22:21:03 2003 +++ b/arch/sparc/kernel/entry.S Mon Aug 18 22:21:03 2003 @@ -38,7 +38,7 @@ #define curptr g6 -#define NR_SYSCALLS 256 /* Each OS is different... */ +#define NR_SYSCALLS 266 /* Each OS is different... */ /* These are just handy. */ #define _SV save %sp, -STACKFRAME_SZ, %sp diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c --- a/arch/sparc/kernel/process.c Mon Aug 18 22:21:01 2003 +++ b/arch/sparc/kernel/process.c Mon Aug 18 22:21:01 2003 @@ -407,15 +407,13 @@ struct pt_regs *regs, unsigned long stack_size) { - unsigned long parent_tid_ptr = 0; - unsigned long child_tid_ptr = 0; + unsigned long parent_tid_ptr, child_tid_ptr; clone_flags &= ~CLONE_IDLETASK; - if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) { - parent_tid_ptr = regs->u_regs[UREG_G2]; - child_tid_ptr = regs->u_regs[UREG_G3]; - } + parent_tid_ptr = regs->u_regs[UREG_I2]; + child_tid_ptr = regs->u_regs[UREG_I4]; + return do_fork(clone_flags, stack_start, regs, stack_size, (int *) parent_tid_ptr, @@ -539,6 +537,9 @@ /* Set the return value for the parent. */ regs->u_regs[UREG_I1] = 0; + + if (clone_flags & CLONE_SETTLS) + childregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; return 0; } diff -Nru a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S --- a/arch/sparc/kernel/systbls.S Mon Aug 18 22:21:03 2003 +++ b/arch/sparc/kernel/systbls.S Mon Aug 18 22:21:03 2003 @@ -59,8 +59,8 @@ /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl /*195*/ .long sys_epoll_wait, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir -/*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall -/*210*/ .long sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo +/*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 +/*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 @@ -70,7 +70,9 @@ /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl -/*255*/ .long sys_nis_syscall, sys_nis_syscall +/*255*/ .long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep +/*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun +/*261*/ .long sys_timer_delete, sys_nis_syscall #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -165,5 +167,10 @@ .long sunos_nosys, sunos_nosys /*250*/ .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys +/*260*/ .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys #endif diff -Nru a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/sparc/kernel/vmlinux.lds.S Mon Aug 18 22:21:01 2003 @@ -0,0 +1,104 @@ +/* ld script to make SparcLinux kernel */ + +#include + +OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc") +OUTPUT_ARCH(sparc) +ENTRY(_start) +jiffies = jiffies_64 + 4; +SECTIONS +{ + . = 0x10000 + SIZEOF_HEADERS; + .text 0xf0004000 : + { + *(.text) + *(.gnu.warning) + } =0 + _etext = .; + PROVIDE (etext = .); + RODATA + .data : + { + *(.data) + CONSTRUCTORS + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE (edata = .); + __start___fixup = .; + .fixup : { *(.fixup) } + __stop___fixup = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + __init_text_end = .; + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + _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) } + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } +} diff -Nru a/arch/sparc/vmlinux.lds.S b/arch/sparc/vmlinux.lds.S --- a/arch/sparc/vmlinux.lds.S Mon Aug 18 22:21:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,104 +0,0 @@ -/* ld script to make SparcLinux kernel */ - -#include - -OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc") -OUTPUT_ARCH(sparc) -ENTRY(_start) -jiffies = jiffies_64 + 4; -SECTIONS -{ - . = 0x10000 + SIZEOF_HEADERS; - .text 0xf0004000 : - { - *(.text) - *(.gnu.warning) - } =0 - _etext = .; - PROVIDE (etext = .); - RODATA - .data : - { - *(.data) - CONSTRUCTORS - } - .data1 : { *(.data1) } - _edata = .; - PROVIDE (edata = .); - __start___fixup = .; - .fixup : { *(.fixup) } - __stop___fixup = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(4096); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - __init_text_end = .; - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - } - _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) } - .debug 0 : { *(.debug) } - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_sfnames 0 : { *(.debug_sfnames) } - .line 0 : { *(.line) } - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } -} diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile --- a/arch/sparc64/Makefile Mon Aug 18 22:21:06 2003 +++ b/arch/sparc64/Makefile Mon Aug 18 22:21:06 2003 @@ -10,10 +10,6 @@ AFLAGS_vmlinux.lds.o += -Usparc -# If the solaris /bin/sh wasn't so broken, I wouldn't need the following -# line... -SHELL =/bin/bash - CC := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo gcc; else echo sparc64-linux-gcc; fi ) NEW_GCC := $(shell if $(CC) -m64 -mcmodel=medlow -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; ) diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig --- a/arch/sparc64/defconfig Mon Aug 18 22:21:02 2003 +++ b/arch/sparc64/defconfig Mon Aug 18 22:21:02 2003 @@ -7,6 +7,7 @@ # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN=y # # General setup @@ -20,6 +21,7 @@ CONFIG_KALLSYMS=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y @@ -211,20 +213,16 @@ # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # -# 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_IDECD=y +CONFIG_BLK_DEV_IDETAPE=m # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set @@ -234,15 +232,15 @@ # IDE chipset support/bugfixes # CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_OPTI621=m CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDE_TCQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_ONLYDISK=y -CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set @@ -253,12 +251,12 @@ CONFIG_BLK_DEV_TRIFLEX=m CONFIG_BLK_DEV_CY82C693=m CONFIG_BLK_DEV_CS5520=m +CONFIG_BLK_DEV_CS5530=m CONFIG_BLK_DEV_HPT34X=m CONFIG_BLK_DEV_HPT366=m CONFIG_BLK_DEV_SC1200=m CONFIG_BLK_DEV_PIIX=m CONFIG_BLK_DEV_NS87415=m -CONFIG_BLK_DEV_OPTI621=m CONFIG_BLK_DEV_PDC202XX_OLD=m CONFIG_BLK_DEV_PDC202XX_NEW=m CONFIG_BLK_DEV_SVWKS=m @@ -266,8 +264,11 @@ CONFIG_BLK_DEV_SLC90E66=m CONFIG_BLK_DEV_TRM290=m CONFIG_BLK_DEV_VIA82CXXX=m -CONFIG_IDEDMA_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support @@ -408,8 +409,6 @@ CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -430,6 +429,53 @@ CONFIG_INET_IPCOMP=y # +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_TUNNEL=m +CONFIG_DECNET=m +CONFIG_DECNET_SIOCGIFCONF=y +CONFIG_DECNET_ROUTER=y +CONFIG_DECNET_ROUTE_FWMARK=y +CONFIG_BRIDGE=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# # IP: Netfilter Configuration # CONFIG_IP_NF_CONNTRACK=m @@ -486,46 +532,6 @@ CONFIG_IP_NF_COMPAT_IPFWADM=m # -# IP: Virtual Server Configuration -# -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m - -# # IPv6: Netfilter Configuration # CONFIG_IP6_NF_QUEUE=m @@ -547,6 +553,27 @@ CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_TARGET_MARK=m + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_XFRM=y CONFIG_XFRM_USER=m # @@ -574,31 +601,6 @@ # CONFIG_IPX_INTERN is not set CONFIG_ATALK=m # CONFIG_DEV_APPLETALK is not set -CONFIG_DECNET=m -CONFIG_DECNET_SIOCGIFCONF=y -CONFIG_DECNET_ROUTER=y -CONFIG_DECNET_ROUTE_FWMARK=y - -# -# DECnet: Netfilter Configuration -# -CONFIG_DECNET_NF_GRABULATOR=m -CONFIG_BRIDGE=m -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_MARK_T=m CONFIG_X25=m CONFIG_LAPB=m CONFIG_NET_DIVERT=y @@ -717,6 +719,7 @@ CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_R8169=m +# CONFIG_SIS190 is not set CONFIG_SK98LIN=m CONFIG_CONFIG_SK98LIN_T1=y CONFIG_CONFIG_SK98LIN_T2=y @@ -1577,8 +1580,10 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_TEST=m # # Library routines diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile --- a/arch/sparc64/kernel/Makefile Mon Aug 18 22:21:01 2003 +++ b/arch/sparc64/kernel/Makefile Mon Aug 18 22:21:01 2003 @@ -5,7 +5,7 @@ EXTRA_AFLAGS := -ansi EXTRA_CFLAGS := -Werror -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s obj-y := process.o setup.o cpu.o idprom.o \ traps.o devices.o auxio.o \ diff -Nru a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S --- a/arch/sparc64/kernel/entry.S Mon Aug 18 22:21:00 2003 +++ b/arch/sparc64/kernel/entry.S Mon Aug 18 22:21:00 2003 @@ -26,7 +26,7 @@ #define curptr g6 -#define NR_SYSCALLS 256 /* Each OS is different... */ +#define NR_SYSCALLS 266 /* Each OS is different... */ .text .align 32 diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c --- a/arch/sparc64/kernel/ioctl32.c Mon Aug 18 22:21:05 2003 +++ b/arch/sparc64/kernel/ioctl32.c Mon Aug 18 22:21:05 2003 @@ -40,34 +40,6 @@ #define CODE #include "compat_ioctl.c" -struct hd_big_geometry32 { - unsigned char heads; - unsigned char sectors; - unsigned int cylinders; - u32 start; -}; - -static int hdio_getgeo_big(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - struct hd_big_geometry geo; - int err; - - set_fs (KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&geo); - set_fs (old_fs); - if (!err) { - struct hd_big_geometry32 *up = (struct hd_big_geometry32 *) arg; - - if (put_user(geo.heads, &up->heads) || - __put_user(geo.sectors, &up->sectors) || - __put_user(geo.cylinders, &up->cylinders) || - __put_user(((u32) geo.start), &up->start)) - err = -EFAULT; - } - return err; -} - struct fbcmap32 { int index; /* first element (0 origin) */ int count; @@ -1574,7 +1546,6 @@ COMPATIBLE_IOCTL(DM_TARGET_WAIT) #endif /* And these ioctls need translation */ -HANDLE_IOCTL(HDIO_GETGEO_BIG_RAW, hdio_getgeo_big) /* NCPFS */ HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c --- a/arch/sparc64/kernel/irq.c Mon Aug 18 22:21:06 2003 +++ b/arch/sparc64/kernel/irq.c Mon Aug 18 22:21:06 2003 @@ -110,6 +110,10 @@ action->flags |= __irq_ino(irq) << 48; #define get_ino_in_irqaction(action) (action->flags >> 48) +#if NR_CPUS > 64 +#error irqaction embedded smp affinity does not work with > 64 cpus, FIXME +#endif + #define put_smpaff_in_irqaction(action, smpaff) (action)->mask = (smpaff) #define get_smpaff_in_irqaction(action) ((action)->mask) @@ -670,11 +674,11 @@ * Just Do It. */ struct irqaction *ap = bp->irq_info; - unsigned long cpu_mask = get_smpaff_in_irqaction(ap); + cpumask_t cpu_mask = get_smpaff_in_irqaction(ap); unsigned int buddy, ticks; - cpu_mask &= cpu_online_map; - if (cpu_mask == 0) + cpus_and(cpu_mask, cpu_mask, cpu_online_map); + if (cpus_empty(cpu_mask)) cpu_mask = cpu_online_map; if (this_is_starfire != 0 || @@ -689,7 +693,7 @@ buddy = 0; ticks = 0; - while ((cpu_mask & (1UL << buddy)) == 0) { + while (!cpu_isset(buddy, cpu_mask)) { if (++buddy >= NR_CPUS) buddy = 0; if (++ticks > NR_CPUS) { diff -Nru a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c --- a/arch/sparc64/kernel/pci.c Mon Aug 18 22:21:00 2003 +++ b/arch/sparc64/kernel/pci.c Mon Aug 18 22:21:00 2003 @@ -438,7 +438,7 @@ if (err < 0) { printk("PCI: Failed to allocate resource %d for %s\n", - resource, pdev->dev.name); + resource, pci_name(pdev)); } else { /* Update PCI config space. */ pbm->parent->base_address_update(pdev, resource); @@ -465,7 +465,7 @@ if (!r_align) { printk(KERN_WARNING "PCI: Ignore bogus resource %d " "[%lx:%lx] of %s\n", - i, r->start, r->end, dev->dev.name); + i, r->start, r->end, pci_name(dev)); continue; } r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; diff -Nru a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c --- a/arch/sparc64/kernel/pci_common.c Mon Aug 18 22:21:02 2003 +++ b/arch/sparc64/kernel/pci_common.c Mon Aug 18 22:21:02 2003 @@ -391,7 +391,7 @@ if ((res->start >> 32) != 0UL) { printk(KERN_ERR "PCI: OBP assigns out of range MEM address " "%016lx for region %ld on device %s\n", - res->start, (res - &pdev->resource[0]), pdev->dev.name); + res->start, (res - &pdev->resource[0]), pci_name(pdev)); continue; } } @@ -413,7 +413,7 @@ "[%016lx:%016lx] of device %s\n", (res - &pdev->resource[0]), res->start, res->end, - pdev->dev.name); + pci_name(pdev)); } } } @@ -490,7 +490,7 @@ if (allocate_resource(root, res, size + 1, min, max, align, NULL, NULL) < 0) { /* uh oh */ prom_printf("PCI: Failed to allocate resource %d for %s\n", - i, pdev->dev.name); + i, pci_name(pdev)); prom_halt(); } @@ -992,7 +992,7 @@ pci_write_config_word(pdev, PCI_STATUS, error_bits); printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n", p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), - pdev->dev.name, status); + pci_name(pdev), status); } } @@ -1018,7 +1018,7 @@ pci_write_config_word(pdev, PCI_STATUS, error_bits); printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n", p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), - pdev->dev.name, status); + pci_name(pdev), status); } } @@ -1045,7 +1045,7 @@ pci_write_config_word(pdev, PCI_STATUS, error_bits); printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n", p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), - pdev->dev.name, status); + pci_name(pdev), status); } } diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c --- a/arch/sparc64/kernel/process.c Mon Aug 18 22:21:03 2003 +++ b/arch/sparc64/kernel/process.c Mon Aug 18 22:21:03 2003 @@ -573,18 +573,15 @@ struct pt_regs *regs, unsigned long stack_size) { - unsigned long parent_tid_ptr = 0; - unsigned long child_tid_ptr = 0; + unsigned long parent_tid_ptr, child_tid_ptr; clone_flags &= ~CLONE_IDLETASK; - if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) { - parent_tid_ptr = regs->u_regs[UREG_G2]; - child_tid_ptr = regs->u_regs[UREG_G3]; - if (test_thread_flag(TIF_32BIT)) { - parent_tid_ptr &= 0xffffffff; - child_tid_ptr &= 0xffffffff; - } + parent_tid_ptr = regs->u_regs[UREG_I2]; + child_tid_ptr = regs->u_regs[UREG_I4]; + if (test_thread_flag(TIF_32BIT)) { + parent_tid_ptr &= 0xffffffff; + child_tid_ptr &= 0xffffffff; } return do_fork(clone_flags, stack_start, @@ -667,6 +664,9 @@ /* Set the second return value for the parent. */ regs->u_regs[UREG_I1] = 0; + + if (clone_flags & CLONE_SETTLS) + t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; return 0; } diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c --- a/arch/sparc64/kernel/setup.c Mon Aug 18 22:21:02 2003 +++ b/arch/sparc64/kernel/setup.c Mon Aug 18 22:21:02 2003 @@ -607,8 +607,8 @@ "promlib\t\t: Version 3 Revision %d\n" "prom\t\t: %d.%d.%d\n" "type\t\t: sun4u\n" - "ncpus probed\t: %d\n" - "ncpus active\t: %d\n" + "ncpus probed\t: %ld\n" + "ncpus active\t: %ld\n" #ifndef CONFIG_SMP "Cpu0Bogo\t: %lu.%02lu\n" "Cpu0ClkTck\t: %016lx\n" @@ -620,8 +620,8 @@ prom_prev >> 16, (prom_prev >> 8) & 0xff, prom_prev & 0xff, - linux_num_cpus, - num_online_cpus() + (long)linux_num_cpus, + (long)num_online_cpus() #ifndef CONFIG_SMP , loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100, diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c --- a/arch/sparc64/kernel/smp.c Mon Aug 18 22:21:00 2003 +++ b/arch/sparc64/kernel/smp.c Mon Aug 18 22:21:00 2003 @@ -46,12 +46,11 @@ /* Please don't make this stuff initdata!!! --DaveM */ static unsigned char boot_cpu_id; -atomic_t sparc64_num_cpus_online = ATOMIC_INIT(0); -unsigned long cpu_online_map = 0; +cpumask_t cpu_online_map = CPU_MASK_NONE; atomic_t sparc64_num_cpus_possible = ATOMIC_INIT(0); -unsigned long phys_cpu_present_map = 0; -static unsigned long smp_commenced_mask; -static unsigned long cpu_callout_map; +cpumask_t phys_cpu_present_map = CPU_MASK_NONE; +static cpumask_t smp_commenced_mask; +static cpumask_t cpu_callout_map; void smp_info(struct seq_file *m) { @@ -151,11 +150,10 @@ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - while (!test_bit(cpuid, &smp_commenced_mask)) + while (!cpu_isset(cpuid, smp_commenced_mask)) membar("#LoadLoad"); - set_bit(cpuid, &cpu_online_map); - atomic_inc(&sparc64_num_cpus_online); + cpu_set(cpuid, cpu_online_map); } void cpu_panic(void) @@ -334,7 +332,7 @@ if (linux_cpus[no].mid == cpu) break; cpu_new_thread = p->thread_info; - set_bit(cpu, &cpu_callout_map); + cpu_set(cpu, cpu_callout_map); prom_startcpu(linux_cpus[no].prom_node, entry, cookie); for (timeout = 0; timeout < 5000000; timeout++) { if (callin_flag) @@ -346,7 +344,7 @@ ret = 0; } else { printk("Processor %d is stuck.\n", cpu); - clear_bit(cpu, &cpu_callout_map); + cpu_clear(cpu, cpu_callout_map); ret = -ENODEV; } cpu_new_thread = NULL; @@ -420,17 +418,17 @@ } } -static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask) +static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { u64 pstate; int i; __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); for (i = 0; i < NR_CPUS; i++) { - if (mask & (1UL << i)) { + if (cpu_isset(i, mask)) { spitfire_xcall_helper(data0, data1, data2, pstate, i); - mask &= ~(1UL << i); - if (!mask) + cpu_clear(i, mask); + if (cpus_empty(mask)) break; } } @@ -443,12 +441,12 @@ #if NR_CPUS > 32 #error Fixup cheetah_xcall_deliver Dave... #endif -static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask) +static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { u64 pstate, ver; int nack_busy_id, is_jalapeno; - if (!mask) + if (cpus_empty(mask)) return; /* Unfortunately, someone at Sun had the brilliant idea to make the @@ -476,11 +474,11 @@ nack_busy_id = 0; { - unsigned long work_mask = mask; + cpumask_t work_mask = mask; int i; for (i = 0; i < NR_CPUS; i++) { - if (work_mask & (1UL << i)) { + if (cpu_isset(i, work_mask)) { u64 target = (i << 14) | 0x70; if (!is_jalapeno) @@ -491,8 +489,8 @@ : /* no outputs */ : "r" (target), "i" (ASI_INTR_W)); nack_busy_id++; - work_mask &= ~(1UL << i); - if (!work_mask) + cpu_clear(i, work_mask); + if (cpus_empty(work_mask)) break; } } @@ -527,7 +525,7 @@ printk("CPU[%d]: mondo stuckage result[%016lx]\n", smp_processor_id(), dispatch_stat); } else { - unsigned long work_mask = mask; + cpumask_t work_mask = mask; int i, this_busy_nack = 0; /* Delay some random time with interrupts enabled @@ -539,7 +537,7 @@ * NACK us. */ for (i = 0; i < NR_CPUS; i++) { - if (work_mask & (1UL << i)) { + if (cpu_isset(i, work_mask)) { u64 check_mask; if (is_jalapeno) @@ -548,10 +546,10 @@ check_mask = (0x2UL << this_busy_nack); if ((dispatch_stat & check_mask) == 0) - mask &= ~(1UL << i); + cpu_clear(i, mask); this_busy_nack += 2; - work_mask &= ~(1UL << i); - if (!work_mask) + cpu_clear(i, work_mask); + if (cpus_empty(work_mask)) break; } } @@ -564,12 +562,12 @@ /* Send cross call to all processors mentioned in MASK * except self. */ -static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, unsigned long mask) +static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, cpumask_t mask) { u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff)); - mask &= cpu_online_map; - mask &= ~(1UL<mm_users) == 1) { /* See smp_flush_tlb_page for info about this. */ - mm->cpu_vm_mask = (1UL << cpu); + mm->cpu_vm_mask = cpumask_of_cpu(cpu); goto local_flush_and_out; } @@ -892,7 +893,7 @@ end = PAGE_ALIGN(end); if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { - mm->cpu_vm_mask = (1UL << cpu); + mm->cpu_vm_mask = cpumask_of_cpu(cpu); goto local_flush_and_out; } @@ -936,14 +937,16 @@ * is almost certain that all TLB entries for this * context will be replaced by the time that happens. */ - mm->cpu_vm_mask = (1UL << cpu); + mm->cpu_vm_mask = cpumask_of_cpu(cpu); goto local_flush_and_out; } else { + cpumask_t this_cpu_mask = cpumask_of_cpu(cpu); + /* By virtue of running under the mm->page_table_lock, * and mmu_context.h:switch_mm doing the same, the * following operation is safe. */ - if (mm->cpu_vm_mask == (1UL << cpu)) + if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask)) goto local_flush_and_out; } @@ -954,7 +957,7 @@ smp_cross_call_masked(&xcall_flush_tlb_page, ctx, page, 0, mm->cpu_vm_mask); - if (!(mm->cpu_vm_mask & (1UL << cpu))) + if (!cpu_isset(cpu, mm->cpu_vm_mask)) return; local_flush_and_out: @@ -1137,8 +1140,7 @@ prom_halt(); } - atomic_inc(&sparc64_num_cpus_online); - set_bit(boot_cpu_id, &cpu_online_map); + cpu_set(boot_cpu_id, cpu_online_map); prom_cpu_nodes[boot_cpu_id] = linux_cpus[0].prom_node; prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; } @@ -1256,16 +1258,14 @@ for (i = 0; i < linux_num_cpus; i++) { if (linux_cpus[i].mid < max_cpus) { - set_bit(linux_cpus[i].mid, - &phys_cpu_present_map); + cpu_set(linux_cpus[i].mid, phys_cpu_present_map); atomic_inc(&sparc64_num_cpus_possible); } } if (atomic_read(&sparc64_num_cpus_possible) > max_cpus) { for (i = linux_num_cpus - 1; i >= 0; i--) { if (linux_cpus[i].mid != boot_cpu_id) { - clear_bit(linux_cpus[i].mid, - &phys_cpu_present_map); + cpu_clear(linux_cpus[i].mid, phys_cpu_present_map); atomic_dec(&sparc64_num_cpus_possible); if (atomic_read(&sparc64_num_cpus_possible) <= max_cpus) break; @@ -1278,8 +1278,8 @@ void __devinit smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); - set_bit(smp_processor_id(), &phys_cpu_present_map); + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), phys_cpu_present_map); } int __devinit __cpu_up(unsigned int cpu) @@ -1287,10 +1287,10 @@ int ret = smp_boot_one_cpu(cpu); if (!ret) { - set_bit(cpu, &smp_commenced_mask); - while (!test_bit(cpu, &cpu_online_map)) + cpu_set(cpu, smp_commenced_mask); + while (!cpu_isset(cpu, cpu_online_map)) mb(); - if (!test_bit(cpu, &cpu_online_map)) { + if (!cpu_isset(cpu, cpu_online_map)) { ret = -ENODEV; } else { smp_synchronize_one_tick(cpu); @@ -1308,9 +1308,9 @@ if (cpu_online(i)) bogosum += cpu_data[i].udelay_val; } - printk("Total of %d processors activated " + printk("Total of %ld processors activated " "(%lu.%02lu BogoMIPS).\n", - num_online_cpus(), + (long) num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c --- a/arch/sparc64/kernel/sparc64_ksyms.c Mon Aug 18 22:21:05 2003 +++ b/arch/sparc64/kernel/sparc64_ksyms.c Mon Aug 18 22:21:05 2003 @@ -147,7 +147,6 @@ /* CPU online map and active count. */ EXPORT_SYMBOL(cpu_online_map); -EXPORT_SYMBOL(sparc64_num_cpus_online); EXPORT_SYMBOL(phys_cpu_present_map); EXPORT_SYMBOL(sparc64_num_cpus_possible); diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c --- a/arch/sparc64/kernel/sys_sparc32.c Mon Aug 18 22:21:04 2003 +++ b/arch/sparc64/kernel/sys_sparc32.c Mon Aug 18 22:21:04 2003 @@ -2507,6 +2507,17 @@ return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); } +long sys32_fadvise64(int fd, u32 offhi, u32 offlo, s32 len, int advice) +{ + return sys_fadvise64_64(fd, ((loff_t)AA(offhi)<<32)|AA(offlo), len, advice); +} + +long sys32_fadvise64_64(int fd, u32 offhi, u32 offlo, u32 lenhi, u32 lenlo, int advice) +{ + return sys_fadvise64_64(fd, ((loff_t)AA(offhi)<<32)|AA(offlo), + ((loff_t)AA(lenhi)<<32)|AA(lenlo), advice); +} + extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count); asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count) diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S --- a/arch/sparc64/kernel/systbls.S Mon Aug 18 22:21:03 2003 +++ b/arch/sparc64/kernel/systbls.S Mon Aug 18 22:21:03 2003 @@ -13,7 +13,7 @@ #include .text - .align 1024 + .align 4 /* First, the 32-bit Linux native syscall table. */ @@ -60,8 +60,8 @@ /*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask /*200*/ .word sys_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, old32_readdir - .word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys_nis_syscall -/*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo + .word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys32_fadvise64 +/*210*/ .word sys32_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys32_sysinfo .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex /*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 @@ -70,11 +70,13 @@ /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl - .word sys_ni_syscall + .word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep +/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun + .word sys_timer_delete, sys_ni_syscall /* Now the 64-bit native Linux syscall table. */ - .align 1024 + .align 4 .globl sys_call_table64, sys_call_table sys_call_table64: sys_call_table: @@ -119,8 +121,8 @@ /*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall - .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall -/*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo + .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 +/*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid @@ -129,13 +131,15 @@ /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl - .word sys_ni_syscall + .word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep +/*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun + .word sys_timer_delete, sys_ni_syscall #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) /* Now the 32-bit SunOS syscall table. */ - .align 1024 + .align 4 .globl sunos_sys_table sunos_sys_table: /*0*/ .word sunos_indir, sparc_exit, sys_fork @@ -225,5 +229,9 @@ .word sunos_nosys, sunos_nosys /*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sys_ni_syscall + .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall + .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall + .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall + .word sys_ni_syscall, sys_ni_syscall #endif diff -Nru a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c --- a/arch/sparc64/kernel/us2e_cpufreq.c Mon Aug 18 22:21:04 2003 +++ b/arch/sparc64/kernel/us2e_cpufreq.c Mon Aug 18 22:21:04 2003 @@ -232,15 +232,16 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) { - unsigned long new_bits, new_freq, cpus_allowed; + unsigned long new_bits, new_freq; unsigned long clock_tick, divisor, old_divisor, estar; + cpumask_t cpus_allowed; struct cpufreq_freqs freqs; if (!cpu_online(cpu)) return; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, (1UL << cpu)); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); new_freq = clock_tick = sparc64_get_clock_tick(cpu); new_bits = index_to_estar_mode(index); diff -Nru a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c --- a/arch/sparc64/kernel/us3_cpufreq.c Mon Aug 18 22:21:00 2003 +++ b/arch/sparc64/kernel/us3_cpufreq.c Mon Aug 18 22:21:00 2003 @@ -78,14 +78,15 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) { - unsigned long new_bits, new_freq, reg, cpus_allowed; + unsigned long new_bits, new_freq, reg; + cpumask_t cpus_allowed; struct cpufreq_freqs freqs; if (!cpu_online(cpu)) return; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, (1UL << cpu)); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); new_freq = sparc64_get_clock_tick(cpu); switch (index) { diff -Nru a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/sparc64/kernel/vmlinux.lds.S Mon Aug 18 22:21:05 2003 @@ -0,0 +1,107 @@ +/* ld script to make UltraLinux kernel */ + +#include + +OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc") +OUTPUT_ARCH(sparc:v9a) +ENTRY(_start) + +jiffies = jiffies_64; +SECTIONS +{ + swapper_pmd_dir = 0x0000000000402000; + empty_pg_dir = 0x0000000000403000; + . = 0x4000; + .text 0x0000000000404000 : + { + *(.text) + *(.gnu.warning) + } =0 + _etext = .; + PROVIDE (etext = .); + + RODATA + + .data : + { + *(.data) + CONSTRUCTORS + } + .data1 : { *(.data1) } + . = ALIGN(64); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + _edata = .; + PROVIDE (edata = .); + .fixup : { *(.fixup) } + + . = ALIGN(16); + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(8192); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(8192); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(8192); + __init_end = .; + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + _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) } + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } +} diff -Nru a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S --- a/arch/sparc64/solaris/entry64.S Mon Aug 18 22:21:00 2003 +++ b/arch/sparc64/solaris/entry64.S Mon Aug 18 22:21:00 2003 @@ -63,6 +63,8 @@ mov %i4, %o4 linux_syscall_for_solaris: + sethi %hi(sys_call_table32), %l6 + or %l6, %lo(sys_call_table32), %l6 sll %l3, 2, %l4 ba,pt %xcc, 10f lduw [%l6 + %l4], %l3 @@ -77,6 +79,7 @@ bg,pn %icc, solaris_unimplemented srl %g1, 0, %g1 sethi %hi(solaris_sys_table), %l7 + or %l7, %lo(solaris_sys_table), %l7 brz,pn %g1, solaris_sucks mov %i4, %o4 sll %g1, 2, %l4 @@ -88,7 +91,7 @@ ldx [%g6 + TI_FLAGS], %l5 cmp %l3, NR_SYSCALLS bleu,a,pn %xcc, linux_syscall_for_solaris - sethi %hi(sys_call_table32), %l6 + nop andcc %l3, 1, %g0 bne,a,pn %icc, 10f add %sp, PTREGS_OFF, %o0 diff -Nru a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S --- a/arch/sparc64/solaris/systbl.S Mon Aug 18 22:21:00 2003 +++ b/arch/sparc64/solaris/systbl.S Mon Aug 18 22:21:00 2003 @@ -21,7 +21,6 @@ #define solaris_semsys solaris_unimplemented .data - .align 1024 .globl solaris_sys_table solaris_sys_table: .word solaris_unimplemented /* nosys 0 */ @@ -284,4 +283,15 @@ .word solaris_unimplemented /* 253 */ .word solaris_unimplemented /* 254 */ .word solaris_unimplemented /* 255 */ + .word solaris_unimplemented /* 256 */ + .word solaris_unimplemented /* 257 */ + .word solaris_unimplemented /* 258 */ + .word solaris_unimplemented /* 259 */ + .word solaris_unimplemented /* 260 */ + .word solaris_unimplemented /* 261 */ + .word solaris_unimplemented /* 262 */ + .word solaris_unimplemented /* 263 */ + .word solaris_unimplemented /* 264 */ + .word solaris_unimplemented /* 265 */ + .word solaris_unimplemented /* 266 */ diff -Nru a/arch/sparc64/vmlinux.lds.S b/arch/sparc64/vmlinux.lds.S --- a/arch/sparc64/vmlinux.lds.S Mon Aug 18 22:21:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,107 +0,0 @@ -/* ld script to make UltraLinux kernel */ - -#include - -OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc") -OUTPUT_ARCH(sparc:v9a) -ENTRY(_start) - -jiffies = jiffies_64; -SECTIONS -{ - swapper_pmd_dir = 0x0000000000402000; - empty_pg_dir = 0x0000000000403000; - . = 0x4000; - .text 0x0000000000404000 : - { - *(.text) - *(.gnu.warning) - } =0 - _etext = .; - PROVIDE (etext = .); - - RODATA - - .data : - { - *(.data) - CONSTRUCTORS - } - .data1 : { *(.data1) } - . = ALIGN(64); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - _edata = .; - PROVIDE (edata = .); - .fixup : { *(.fixup) } - - . = ALIGN(16); - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(8192); - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(8192); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(8192); - __init_end = .; - __bss_start = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - } - _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) } - .debug 0 : { *(.debug) } - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_sfnames 0 : { *(.debug_sfnames) } - .line 0 : { *(.line) } - /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } -} diff -Nru a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile --- a/arch/um/kernel/Makefile Mon Aug 18 22:21:04 2003 +++ b/arch/um/kernel/Makefile Mon Aug 18 22:21:04 2003 @@ -3,6 +3,8 @@ # Licensed under the GPL # +extra-y := vmlinux.lds.s + 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 \ diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c --- a/arch/um/kernel/irq.c Mon Aug 18 22:21:05 2003 +++ b/arch/um/kernel/irq.c Mon Aug 18 22:21:05 2003 @@ -565,9 +565,9 @@ /* These are read and written as longs, so a read won't see a partial write * even during a race. */ -static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; -#define HEX_DIGITS 8 +#define HEX_DIGITS (2*sizeof(cpumask_t)) static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) @@ -578,10 +578,10 @@ } static unsigned int parse_hex_value (const char *buffer, - unsigned long count, unsigned long *ret) + unsigned long count, cpumask_t *ret) { unsigned char hexnum [HEX_DIGITS]; - unsigned long value; + cpumask_t value = CPU_MASK_NONE; int i; if (!count) @@ -595,10 +595,9 @@ * Parse the first 8 characters as a hex string, any non-hex char * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ - value = 0; for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; + unsigned int k, c = hexnum[i]; switch (c) { case '0' ... '9': c -= '0'; break; @@ -607,7 +606,10 @@ default: goto out; } - value = (value << 4) | c; + cpus_shift_left(value, value, 16); + for (k = 0; k < 4; ++k) + if (c & (1 << k)) + cpu_set(k, value); } out: *ret = value; @@ -618,7 +620,7 @@ unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value, tmp; if (!irq_desc[irq].handler->set_affinity) return -EIO; @@ -631,7 +633,8 @@ * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - if (!(new_value & cpu_online_map)) + cpus_and(tmp, new_value, cpu_online_map); + if (cpus_empty(tmp)) return -EINVAL; #endif @@ -644,17 +647,27 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; + cpumask_t tmp, *mask = (cpumask_t *) data; + int k, len = 0; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", *mask); + tmp = *mask; + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + cpumask_t *mask = (cpumask_t *)data, new_value; + unsigned long full_count = count, err; err = parse_hex_value(buffer, count, &new_value); if (err) @@ -693,7 +706,7 @@ } /* Read and written as a long */ -unsigned long prof_cpu_mask = -1; +cpumask_t prof_cpu_mask = CPU_MASK_ALL; void __init init_irq_proc (void) { 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 Mon Aug 18 22:21:02 2003 +++ b/arch/um/kernel/skas/process_kern.c Mon Aug 18 22:21:02 2003 @@ -152,7 +152,7 @@ cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP - cpu_online_map = 1; + cpu_online_map = cpumask_of_cpu(0); #endif start_kernel(); return(0); diff -Nru a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c --- a/arch/um/kernel/smp.c Mon Aug 18 22:21:02 2003 +++ b/arch/um/kernel/smp.c Mon Aug 18 22:21:02 2003 @@ -5,9 +5,6 @@ #include "linux/config.h" -/* CPU online map, set by smp_boot_cpus */ -unsigned long cpu_online_map = 1; - #ifdef CONFIG_SMP #include "linux/sched.h" @@ -24,6 +21,9 @@ #include "irq_user.h" #include "os.h" +/* CPU online map, set by smp_boot_cpus */ +unsigned long cpu_online_map = cpumask_of_cpu(0); + /* Per CPU bogomips and other parameters * The only piece used here is the ipi pipe, which is set before SMP is * started and never changed. @@ -104,8 +104,8 @@ printk("done\n"); } -static unsigned long smp_commenced_mask; -static volatile unsigned long smp_callin_map = 0; +static cpumask_t smp_commenced_mask; +static cpumask_t smp_callin_map = CPU_MASK_NONE; static int idle_proc(void *cpup) { @@ -120,15 +120,15 @@ current->thread.mode.tt.extern_pid); wmb(); - if (test_and_set_bit(cpu, &smp_callin_map)) { + if (cpu_test_and_set(cpu, &smp_callin_map)) { printk("huh, CPU#%d already present??\n", cpu); BUG(); } - while (!test_bit(cpu, &smp_commenced_mask)) + while (!cpu_isset(cpu, &smp_commenced_mask)) cpu_relax(); - set_bit(cpu, &cpu_online_map); + cpu_set(cpu, cpu_online_map); default_idle(); return(0); } @@ -159,8 +159,8 @@ unsigned long waittime; int err, cpu; - set_bit(0, &cpu_online_map); - set_bit(0, &smp_callin_map); + cpu_set(0, cpu_online_map); + cpu_set(0, smp_callin_map); err = os_pipe(cpu_data[0].ipi_pipe, 1, 1); if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err); @@ -177,10 +177,10 @@ unhash_process(idle); waittime = 200000000; - while (waittime-- && !test_bit(cpu, &smp_callin_map)) + while (waittime-- && !cpu_isset(cpu, smp_callin_map)) cpu_relax(); - if (test_bit(cpu, &smp_callin_map)) + if (cpu_isset(cpu, smp_callin_map)) printk("done\n"); else printk("failed\n"); } @@ -188,13 +188,13 @@ void smp_prepare_boot_cpu(void) { - set_bit(smp_processor_id(), &cpu_online_map); + cpu_set(smp_processor_id(), cpu_online_map); } int __cpu_up(unsigned int cpu) { - set_bit(cpu, &smp_commenced_mask); - while (!test_bit(cpu, &cpu_online_map)) + cpu_set(cpu, smp_commenced_mask); + while (!cpu_isset(cpu, cpu_online_map)) mb(); return(0); } @@ -271,7 +271,7 @@ for (i=0;ithread_info->cpu) && - test_bit(i, &cpu_online_map)) + cpu_isset(i, cpu_online_map)) write(cpu_data[i].ipi_pipe[1], "C", 1); while (atomic_read(&scf_started) != cpus) 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 Mon Aug 18 22:21:05 2003 +++ b/arch/um/kernel/tt/process_kern.c Mon Aug 18 22:21:05 2003 @@ -419,7 +419,7 @@ cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP - cpu_online_map = 1; + cpu_online_map = cpumask_of_cpu(0); #endif if(debug) os_stop_process(pid); start_kernel(); diff -Nru a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c --- a/arch/um/kernel/um_arch.c Mon Aug 18 22:21:05 2003 +++ b/arch/um/kernel/um_arch.c Mon Aug 18 22:21:05 2003 @@ -57,7 +57,7 @@ index = (struct cpuinfo_um *)v - cpu_data; #ifdef CONFIG_SMP - if (!(cpu_online_map & (1 << index))) + if (!cpu_online(index)) return 0; #endif diff -Nru a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/kernel/vmlinux.lds.S Mon Aug 18 22:21:00 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/um/vmlinux.lds.S b/arch/um/vmlinux.lds.S --- a/arch/um/vmlinux.lds.S Mon Aug 18 22:21:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,11 +0,0 @@ -#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/kernel/Makefile b/arch/v850/kernel/Makefile --- a/arch/v850/kernel/Makefile Mon Aug 18 22:21:06 2003 +++ b/arch/v850/kernel/Makefile Mon Aug 18 22:21:06 2003 @@ -9,7 +9,7 @@ # for more details. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o vmlinux.lds.s 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 diff -Nru a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/v850/kernel/vmlinux.lds.S Mon Aug 18 22:21:04 2003 @@ -0,0 +1,254 @@ +/* + * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms + * + * Copyright (C) 2002,03 NEC Electronics Corporation + * Copyright (C) 2002,03 Miles Bader + * + * 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 for more details. + * + * Written by Miles Bader + */ + +#include +#include + + +/* The following macros contain the usual definitions for various data areas. + The prefix `RAMK_' is used to indicate macros suitable for kernels loaded + into RAM, and similarly `ROMK_' for ROM-resident kernels. Note that all + symbols are prefixed with an extra `_' for compatibility with the v850 + toolchain. */ + + +/* Interrupt vectors. */ +#define INTV_CONTENTS \ + . = ALIGN (0x10) ; \ + __intv_start = . ; \ + *(.intv.reset) /* Reset vector */ \ + . = __intv_start + 0x10 ; \ + *(.intv.common) /* Vectors common to all v850e proc */\ + . = __intv_start + 0x80 ; \ + *(.intv.mach) /* Machine-specific int. vectors. */ \ + __intv_end = . ; + +/* Kernel text segment, and some constant data areas. */ +#define TEXT_CONTENTS \ + __stext = . ; \ + *(.text) \ + *(.exit.text) /* 2.5 convention */ \ + *(.text.exit) /* 2.4 convention */ \ + *(.text.lock) \ + *(.exitcall.exit) \ + __real_etext = . ; /* There may be data after here. */ \ + RODATA \ + . = ALIGN (4) ; \ + *(.call_table_data) \ + *(.call_table_text) \ + . = ALIGN (16) ; /* Exception table. */ \ + ___start___ex_table = . ; \ + *(__ex_table) \ + ___stop___ex_table = . ; \ + . = ALIGN (4) ; \ + __etext = . ; + +/* Kernel data segment. */ +#define DATA_CONTENTS \ + __sdata = . ; \ + *(.data) \ + *(.exit.data) /* 2.5 convention */ \ + *(.data.exit) /* 2.4 convention */ \ + . = ALIGN (16) ; \ + *(.data.cacheline_aligned) \ + . = ALIGN (0x2000) ; \ + *(.data.init_task) \ + . = ALIGN (0x2000) ; \ + __edata = . ; + +/* Kernel BSS segment. */ +#define BSS_CONTENTS \ + __sbss = . ; \ + *(.bss) \ + *(COMMON) \ + . = ALIGN (4) ; \ + __init_stack_end = . ; \ + __ebss = . ; + +/* `initcall' tables. */ +#define INITCALL_CONTENTS \ + . = ALIGN (16) ; \ + ___setup_start = . ; \ + *(.init.setup) /* 2.5 convention */ \ + *(.setup.init) /* 2.4 convention */ \ + ___setup_end = . ; \ + ___start___param = . ; \ + *(__param) \ + ___stop___param = . ; \ + ___initcall_start = . ; \ + *(.initcall.init) \ + *(.initcall1.init) \ + *(.initcall2.init) \ + *(.initcall3.init) \ + *(.initcall4.init) \ + *(.initcall5.init) \ + *(.initcall6.init) \ + *(.initcall7.init) \ + . = ALIGN (4) ; \ + ___initcall_end = . ; \ + ___con_initcall_start = .; \ + *(.con_initcall.init) \ + ___con_initcall_end = .; + +/* Contents of `init' section for a kernel that's loaded into RAM. */ +#define RAMK_INIT_CONTENTS \ + RAMK_INIT_CONTENTS_NO_END \ + __init_end = . ; +/* Same as RAMK_INIT_CONTENTS, but doesn't define the `__init_end' symbol. */ +#define RAMK_INIT_CONTENTS_NO_END \ + . = ALIGN (4096) ; \ + __init_start = . ; \ + __sinittext = .; \ + *(.init.text) /* 2.5 convention */ \ + __einittext = .; \ + *(.init.data) \ + *(.text.init) /* 2.4 convention */ \ + *(.data.init) \ + INITCALL_CONTENTS \ + INITRAMFS_CONTENTS + +/* The contents of `init' section for a ROM-resident kernel which + should go into RAM. */ +#define ROMK_INIT_RAM_CONTENTS \ + . = ALIGN (4096) ; \ + __init_start = . ; \ + *(.init.data) /* 2.5 convention */ \ + *(.data.init) /* 2.4 convention */ \ + __init_end = . ; \ + . = ALIGN (4096) ; + +/* The contents of `init' section for a ROM-resident kernel which + should go into ROM. */ +#define ROMK_INIT_ROM_CONTENTS \ + _sinittext = .; \ + *(.init.text) /* 2.5 convention */ \ + _einittext = .; \ + *(.text.init) /* 2.4 convention */ \ + INITCALL_CONTENTS \ + INITRAMFS_CONTENTS + +/* A root filesystem image, for kernels with an embedded root filesystem. */ +#define ROOT_FS_CONTENTS \ + __root_fs_image_start = . ; \ + *(.root) \ + __root_fs_image_end = . ; +/* The initramfs archive. */ +#define INITRAMFS_CONTENTS \ + . = ALIGN (4) ; \ + ___initramfs_start = . ; \ + *(.init.ramfs) \ + ___initramfs_end = . ; +/* Where the initial bootmap (bitmap for the boot-time memory allocator) + should be place. */ +#define BOOTMAP_CONTENTS \ + . = ALIGN (4096) ; \ + __bootmap = . ; \ + . = . + 4096 ; /* enough for 128MB. */ + +/* The contents of a `typical' kram area for a kernel in RAM. */ +#define RAMK_KRAM_CONTENTS \ + __kram_start = . ; \ + TEXT_CONTENTS \ + DATA_CONTENTS \ + BSS_CONTENTS \ + RAMK_INIT_CONTENTS \ + __kram_end = . ; \ + BOOTMAP_CONTENTS + + +/* Define output sections normally used for a ROM-resident kernel. + ROM and RAM should be appropriate memory areas to use for kernel + ROM and RAM data. This assumes that ROM starts at 0 (and thus can + hold the interrupt vectors). */ +#define ROMK_SECTIONS(ROM, RAM) \ + .rom : { \ + INTV_CONTENTS \ + TEXT_CONTENTS \ + ROMK_INIT_ROM_CONTENTS \ + ROOT_FS_CONTENTS \ + } > ROM \ + \ + __rom_copy_src_start = . ; \ + \ + .data : { \ + __kram_start = . ; \ + __rom_copy_dst_start = . ; \ + DATA_CONTENTS \ + ROMK_INIT_RAM_CONTENTS \ + __rom_copy_dst_end = . ; \ + } > RAM AT> ROM \ + \ + .bss ALIGN (4) : { \ + BSS_CONTENTS \ + __kram_end = . ; \ + BOOTMAP_CONTENTS \ + } > RAM + + +/* The 32-bit variable `jiffies' is just the lower 32-bits of `jiffies_64'. */ +_jiffies = _jiffies_64 ; + + +/* Include an appropriate platform-dependent linker-script (which + usually should use the above macros to do most of the work). */ + +#ifdef CONFIG_V850E_SIM +# include "sim.ld" +#endif + +#ifdef CONFIG_V850E2_SIM85E2 +# include "sim85e2.ld" +#endif + +#ifdef CONFIG_V850E2_FPGA85E2C +# include "fpga85e2c.ld" +#endif + +#ifdef CONFIG_V850E2_ANNA +# ifdef CONFIG_ROM_KERNEL +# include "anna-rom.ld" +# else +# include "anna.ld" +# endif +#endif + +#ifdef CONFIG_V850E_AS85EP1 +# ifdef CONFIG_ROM_KERNEL +# include "as85ep1-rom.ld" +# else +# include "as85ep1.ld" +# endif +#endif + +#ifdef CONFIG_RTE_CB_MA1 +# ifdef CONFIG_ROM_KERNEL +# include "rte_ma1_cb-rom.ld" +# else +# include "rte_ma1_cb.ld" +# endif +#endif + +#ifdef CONFIG_RTE_CB_NB85E +# ifdef CONFIG_ROM_KERNEL +# include "rte_nb85e_cb-rom.ld" +# elif defined(CONFIG_RTE_CB_MULTI) +# include "rte_nb85e_cb-multi.ld" +# else +# include "rte_nb85e_cb.ld" +# endif +#endif + +#ifdef CONFIG_RTE_CB_ME2 +# include "rte_me2_cb.ld" +#endif + diff -Nru a/arch/v850/vmlinux.lds.S b/arch/v850/vmlinux.lds.S --- a/arch/v850/vmlinux.lds.S Mon Aug 18 22:21:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,254 +0,0 @@ -/* - * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms - * - * Copyright (C) 2002,03 NEC Electronics Corporation - * Copyright (C) 2002,03 Miles Bader - * - * 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 for more details. - * - * Written by Miles Bader - */ - -#include -#include - - -/* The following macros contain the usual definitions for various data areas. - The prefix `RAMK_' is used to indicate macros suitable for kernels loaded - into RAM, and similarly `ROMK_' for ROM-resident kernels. Note that all - symbols are prefixed with an extra `_' for compatibility with the v850 - toolchain. */ - - -/* Interrupt vectors. */ -#define INTV_CONTENTS \ - . = ALIGN (0x10) ; \ - __intv_start = . ; \ - *(.intv.reset) /* Reset vector */ \ - . = __intv_start + 0x10 ; \ - *(.intv.common) /* Vectors common to all v850e proc */\ - . = __intv_start + 0x80 ; \ - *(.intv.mach) /* Machine-specific int. vectors. */ \ - __intv_end = . ; - -/* Kernel text segment, and some constant data areas. */ -#define TEXT_CONTENTS \ - __stext = . ; \ - *(.text) \ - *(.exit.text) /* 2.5 convention */ \ - *(.text.exit) /* 2.4 convention */ \ - *(.text.lock) \ - *(.exitcall.exit) \ - __real_etext = . ; /* There may be data after here. */ \ - RODATA \ - . = ALIGN (4) ; \ - *(.call_table_data) \ - *(.call_table_text) \ - . = ALIGN (16) ; /* Exception table. */ \ - ___start___ex_table = . ; \ - *(__ex_table) \ - ___stop___ex_table = . ; \ - . = ALIGN (4) ; \ - __etext = . ; - -/* Kernel data segment. */ -#define DATA_CONTENTS \ - __sdata = . ; \ - *(.data) \ - *(.exit.data) /* 2.5 convention */ \ - *(.data.exit) /* 2.4 convention */ \ - . = ALIGN (16) ; \ - *(.data.cacheline_aligned) \ - . = ALIGN (0x2000) ; \ - *(.data.init_task) \ - . = ALIGN (0x2000) ; \ - __edata = . ; - -/* Kernel BSS segment. */ -#define BSS_CONTENTS \ - __sbss = . ; \ - *(.bss) \ - *(COMMON) \ - . = ALIGN (4) ; \ - __init_stack_end = . ; \ - __ebss = . ; - -/* `initcall' tables. */ -#define INITCALL_CONTENTS \ - . = ALIGN (16) ; \ - ___setup_start = . ; \ - *(.init.setup) /* 2.5 convention */ \ - *(.setup.init) /* 2.4 convention */ \ - ___setup_end = . ; \ - ___start___param = . ; \ - *(__param) \ - ___stop___param = . ; \ - ___initcall_start = . ; \ - *(.initcall.init) \ - *(.initcall1.init) \ - *(.initcall2.init) \ - *(.initcall3.init) \ - *(.initcall4.init) \ - *(.initcall5.init) \ - *(.initcall6.init) \ - *(.initcall7.init) \ - . = ALIGN (4) ; \ - ___initcall_end = . ; \ - ___con_initcall_start = .; \ - *(.con_initcall.init) \ - ___con_initcall_end = .; - -/* Contents of `init' section for a kernel that's loaded into RAM. */ -#define RAMK_INIT_CONTENTS \ - RAMK_INIT_CONTENTS_NO_END \ - __init_end = . ; -/* Same as RAMK_INIT_CONTENTS, but doesn't define the `__init_end' symbol. */ -#define RAMK_INIT_CONTENTS_NO_END \ - . = ALIGN (4096) ; \ - __init_start = . ; \ - __sinittext = .; \ - *(.init.text) /* 2.5 convention */ \ - __einittext = .; \ - *(.init.data) \ - *(.text.init) /* 2.4 convention */ \ - *(.data.init) \ - INITCALL_CONTENTS \ - INITRAMFS_CONTENTS - -/* The contents of `init' section for a ROM-resident kernel which - should go into RAM. */ -#define ROMK_INIT_RAM_CONTENTS \ - . = ALIGN (4096) ; \ - __init_start = . ; \ - *(.init.data) /* 2.5 convention */ \ - *(.data.init) /* 2.4 convention */ \ - __init_end = . ; \ - . = ALIGN (4096) ; - -/* The contents of `init' section for a ROM-resident kernel which - should go into ROM. */ -#define ROMK_INIT_ROM_CONTENTS \ - _sinittext = .; \ - *(.init.text) /* 2.5 convention */ \ - _einittext = .; \ - *(.text.init) /* 2.4 convention */ \ - INITCALL_CONTENTS \ - INITRAMFS_CONTENTS - -/* A root filesystem image, for kernels with an embedded root filesystem. */ -#define ROOT_FS_CONTENTS \ - __root_fs_image_start = . ; \ - *(.root) \ - __root_fs_image_end = . ; -/* The initramfs archive. */ -#define INITRAMFS_CONTENTS \ - . = ALIGN (4) ; \ - ___initramfs_start = . ; \ - *(.init.ramfs) \ - ___initramfs_end = . ; -/* Where the initial bootmap (bitmap for the boot-time memory allocator) - should be place. */ -#define BOOTMAP_CONTENTS \ - . = ALIGN (4096) ; \ - __bootmap = . ; \ - . = . + 4096 ; /* enough for 128MB. */ - -/* The contents of a `typical' kram area for a kernel in RAM. */ -#define RAMK_KRAM_CONTENTS \ - __kram_start = . ; \ - TEXT_CONTENTS \ - DATA_CONTENTS \ - BSS_CONTENTS \ - RAMK_INIT_CONTENTS \ - __kram_end = . ; \ - BOOTMAP_CONTENTS - - -/* Define output sections normally used for a ROM-resident kernel. - ROM and RAM should be appropriate memory areas to use for kernel - ROM and RAM data. This assumes that ROM starts at 0 (and thus can - hold the interrupt vectors). */ -#define ROMK_SECTIONS(ROM, RAM) \ - .rom : { \ - INTV_CONTENTS \ - TEXT_CONTENTS \ - ROMK_INIT_ROM_CONTENTS \ - ROOT_FS_CONTENTS \ - } > ROM \ - \ - __rom_copy_src_start = . ; \ - \ - .data : { \ - __kram_start = . ; \ - __rom_copy_dst_start = . ; \ - DATA_CONTENTS \ - ROMK_INIT_RAM_CONTENTS \ - __rom_copy_dst_end = . ; \ - } > RAM AT> ROM \ - \ - .bss ALIGN (4) : { \ - BSS_CONTENTS \ - __kram_end = . ; \ - BOOTMAP_CONTENTS \ - } > RAM - - -/* The 32-bit variable `jiffies' is just the lower 32-bits of `jiffies_64'. */ -_jiffies = _jiffies_64 ; - - -/* Include an appropriate platform-dependent linker-script (which - usually should use the above macros to do most of the work). */ - -#ifdef CONFIG_V850E_SIM -# include "sim.ld" -#endif - -#ifdef CONFIG_V850E2_SIM85E2 -# include "sim85e2.ld" -#endif - -#ifdef CONFIG_V850E2_FPGA85E2C -# include "fpga85e2c.ld" -#endif - -#ifdef CONFIG_V850E2_ANNA -# ifdef CONFIG_ROM_KERNEL -# include "anna-rom.ld" -# else -# include "anna.ld" -# endif -#endif - -#ifdef CONFIG_V850E_AS85EP1 -# ifdef CONFIG_ROM_KERNEL -# include "as85ep1-rom.ld" -# else -# include "as85ep1.ld" -# endif -#endif - -#ifdef CONFIG_RTE_CB_MA1 -# ifdef CONFIG_ROM_KERNEL -# include "rte_ma1_cb-rom.ld" -# else -# include "rte_ma1_cb.ld" -# endif -#endif - -#ifdef CONFIG_RTE_CB_NB85E -# ifdef CONFIG_ROM_KERNEL -# include "rte_nb85e_cb-rom.ld" -# elif defined(CONFIG_RTE_CB_MULTI) -# include "rte_nb85e_cb-multi.ld" -# else -# include "rte_nb85e_cb.ld" -# endif -#endif - -#ifdef CONFIG_RTE_CB_ME2 -# include "rte_me2_cb.ld" -#endif - diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig --- a/arch/x86_64/defconfig Mon Aug 18 22:21:04 2003 +++ b/arch/x86_64/defconfig Mon Aug 18 22:21:04 2003 @@ -22,7 +22,7 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=16 +CONFIG_LOG_BUF_SHIFT=18 # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_FUTEX=y @@ -149,17 +149,12 @@ # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y # CONFIG_IDEDISK_STROKE is not set @@ -174,15 +169,16 @@ # # CONFIG_BLK_DEV_CMD640 is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDE_TCQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set @@ -192,23 +188,25 @@ # CONFIG_BLK_DEV_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SVWKS is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_IDEDMA_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support @@ -251,7 +249,7 @@ # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_IPS=m # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set @@ -301,7 +299,6 @@ CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -317,12 +314,10 @@ # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set # CONFIG_XFRM_USER is not set # @@ -333,8 +328,6 @@ # 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 @@ -546,11 +539,7 @@ # # IPMI # -CONFIG_IPMI_HANDLER=y -CONFIG_IPMI_PANIC_EVENT=y -CONFIG_IPMI_DEVICE_INTERFACE=y -CONFIG_IPMI_KCS=y -CONFIG_IPMI_WATCHDOG=y +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards @@ -570,12 +559,7 @@ # CONFIG_FTAPE is not set CONFIG_AGP=y CONFIG_AGP_AMD_8151=y -CONFIG_DRM=y -# CONFIG_DRM_TDFX is not set -# CONFIG_DRM_GAMMA is not set -# CONFIG_DRM_R128 is not set -CONFIG_DRM_RADEON=y -# CONFIG_DRM_MGA is not set +# CONFIG_DRM is not set # CONFIG_MWAVE is not set CONFIG_RAW_DRIVER=y CONFIG_HANGCHECK_TIMER=y @@ -598,19 +582,25 @@ # File systems # CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_JFS_FS is not set -CONFIG_XFS_FS=m -# CONFIG_XFS_RT is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_POSIX_ACL is not set +CONFIG_JFS_FS=y +CONFIG_JFS_POSIX_ACL=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set @@ -684,6 +674,49 @@ # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +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 # # Graphics support @@ -759,8 +792,10 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_INIT_DEBUG is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_FRAME_POINTER is not set -# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_LEAK=y CONFIG_MCE_DEBUG=y # @@ -771,21 +806,7 @@ # # Cryptographic options # -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO is not set # # Library routines diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c --- a/arch/x86_64/ia32/ia32_binfmt.c Mon Aug 18 22:21:01 2003 +++ b/arch/x86_64/ia32/ia32_binfmt.c Mon Aug 18 22:21:01 2003 @@ -204,10 +204,9 @@ } static inline int -elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *xregs, elf_fpregset_t *fpu) +elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu) { struct _fpstate_ia32 *fpstate = (void*)fpu; - struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0); mm_segment_t oldfs = get_fs(); if (!tsk->used_math) diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S --- a/arch/x86_64/ia32/ia32entry.S Mon Aug 18 22:21:03 2003 +++ b/arch/x86_64/ia32/ia32entry.S Mon Aug 18 22:21:03 2003 @@ -462,11 +462,21 @@ .quad sys_epoll_wait .quad sys_remap_file_pages .quad sys_set_tid_address - + .quad sys32_timer_create + .quad compat_timer_settime + .quad compat_timer_gettime + .quad sys_timer_getoverrun + .quad sys_timer_delete + .quad compat_clock_settime + .quad compat_clock_gettime + .quad compat_clock_getres + .quad compat_clock_nanosleep + .quad compat_statfs64 /* statfs64 */ + .quad compat_fstatfs64 /* fstatfs64 */ + .quad sys_tgkill + .quad compat_sys_utimes /* don't forget to change IA32_NR_syscalls */ ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 .quad ni_syscall .endr - - diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c --- a/arch/x86_64/ia32/sys_ia32.c Mon Aug 18 22:21:03 2003 +++ b/arch/x86_64/ia32/sys_ia32.c Mon Aug 18 22:21:03 2003 @@ -428,6 +428,8 @@ return err; } +extern int do_setitimer(int which, struct itimerval *, struct itimerval *); + asmlinkage long sys32_alarm(unsigned int seconds) { @@ -1991,6 +1993,41 @@ return fd; } +struct sigevent32 { + u32 sigev_value; + u32 sigev_signo; + u32 sigev_notify; + u32 payload[(64 / 4) - 3]; +}; + +extern asmlinkage long +sys_timer_create(clockid_t which_clock, + struct sigevent __user *timer_event_spec, + timer_t __user * created_timer_id); + +long +sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id) +{ + struct sigevent se; + if (se32) { + memset(&se, 0, sizeof(struct sigevent)); + if (get_user(se.sigev_value.sival_int, &se32->sigev_value) || + __get_user(se.sigev_signo, &se32->sigev_signo) || + __get_user(se.sigev_notify, &se32->sigev_notify) || + __copy_from_user(&se._sigev_un._pad, &se32->payload, + sizeof(se32->payload))) + return -EFAULT; + } + if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t))) + return -EFAULT; + + mm_segment_t oldfs = get_fs(); + set_fs(KERNEL_DS); + long err = sys_timer_create(clock, se32 ? &se : NULL, timer_id); + set_fs(oldfs); + + return err; +} long sys32_vm86_warning(void) { diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile --- a/arch/x86_64/kernel/Makefile Mon Aug 18 22:21:04 2003 +++ b/arch/x86_64/kernel/Makefile Mon Aug 18 22:21:04 2003 @@ -2,11 +2,11 @@ # Makefile for the linux kernel. # -extra-y := head.o head64.o init_task.o +extra-y := head.o head64.o init_task.o vmlinux.lds.s EXTRA_AFLAGS := -traditional 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 \ + x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bluesmoke.o bootflag.o e820.o reboot.o warmreboot.o obj-$(CONFIG_MTRR) += mtrr/ @@ -19,7 +19,8 @@ obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o -obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o +obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o + obj-$(CONFIG_MODULES) += module.o $(obj)/bootflag.c: diff -Nru a/arch/x86_64/kernel/acpi/boot.c b/arch/x86_64/kernel/acpi/boot.c --- a/arch/x86_64/kernel/acpi/boot.c Mon Aug 18 22:21:01 2003 +++ b/arch/x86_64/kernel/acpi/boot.c Mon Aug 18 22:21:01 2003 @@ -313,10 +313,11 @@ result = acpi_blacklisted(); if (result) { + printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); acpi_disabled = 1; return result; } else - printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n"); + printk(KERN_NOTICE PREFIX "BIOS not listed in blacklist\n"); extern int disable_apic; diff -Nru a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c --- a/arch/x86_64/kernel/aperture.c Mon Aug 18 22:21:04 2003 +++ b/arch/x86_64/kernel/aperture.c Mon Aug 18 22:21:04 2003 @@ -1,14 +1,14 @@ /* * Firmware replacement code. * - * Work around broken BIOSes that don't set an aperture. - * The IOMMU code needs an aperture even who no AGP is present in the system. - * Map the aperture over some low memory. This is cheaper than doing bounce - * buffering. The memory is lost. This is done at early boot because only - * the bootmem allocator can allocate 32+MB. + * Work around broken BIOSes that don't set an aperture or only set the + * aperture in the AGP bridge. + * If all fails map the aperture over some low memory. This is cheaper than + * doing bounce buffering. The memory is lost. This is done at early boot + * because only the bootmem allocator can allocate 32+MB. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: aperture.c,v 1.2 2002/09/19 19:25:32 ak Exp $ + * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $ */ #include #include @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -45,10 +47,10 @@ aper_size = (32 * 1024 * 1024) << fallback_aper_order; /* - * Aperture has to be naturally aligned it seems. This means an - * 2GB aperture won't have much changes to succeed in the lower 4GB of - * memory. Unfortunately we cannot move it up because that would make - * the IOMMU useless. + * Aperture has to be naturally aligned. This means an 2GB aperture won't + * have much chances to find a place in the lower 4GB of memory. + * Unfortunately we cannot move it up because that would make the + * IOMMU useless. */ p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); if (!p || __pa(p)+aper_size > 0xffffffff) { @@ -63,21 +65,136 @@ return (u32)__pa(p); } +static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) +{ + if (!aper_base) + return 0; + if (aper_size < 64*1024*1024) { + printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20); + return 0; + } + if (aper_base + aper_size >= 0xffffffff) { + printk("Aperture from %s beyond 4GB. Ignoring.\n",name); + return 0; + } + if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { + printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); + return 0; + } + return 1; +} + +/* Find a PCI capability */ +static __u32 __init find_cap(int num, int slot, int func, int cap) +{ + if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST)) + return 0; + u8 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST); + int bytes; + for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { + pos &= ~3; + u8 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID); + if (id == 0xff) + break; + if (id == cap) + return pos; + pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT); + } + return 0; +} + +/* Read a standard AGPv3 bridge header */ +static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order) +{ + printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func); + u32 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14); + + if (apsizereg == 0xffffffff) { + printk("APSIZE in AGP bridge unreadable\n"); + return 0; + } + + u32 apsize = apsizereg & 0xfff; + /* Some BIOS use weird encodings not in the AGPv3 table. */ + if (apsize & 0xff) + apsize |= 0xf00; + int nbits = hweight16(apsize); + *order = 7 - nbits; + if ((int)*order < 0) /* < 32MB */ + *order = 0; + + u32 aper_low = read_pci_config(num,slot,func, 0x10); + u32 aper_hi = read_pci_config(num,slot,func,0x14); + u64 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); + + printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n", + aper, 32 << *order, apsizereg); + + if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order)) + return 0; + return (u32)aper; +} + +/* Look for an AGP bridge. Windows only expects the aperture in the + AGP bridge and some BIOS forget to initialize the Northbridge too. + Work around this here. + + Do an PCI bus scan by hand because we're running before the PCI + subsystem. + + All K8 AGP bridges are AGPv3 compliant, so we can do this scan + generically. It's probably overkill to always scan all slots because + the AGP bridges should be always an own bus on the HT hierarchy, + but do it here for future safety. */ +static __u32 __init search_agp_bridge(u32 *order, int *valid_agp) +{ + int num, slot, func; + + /* Poor man's PCI discovery */ + for (num = 0; num < 32; num++) { + for (slot = 0; slot < 32; slot++) { + for (func = 0; func < 8; func++) { + u32 class, cap; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + switch (class >> 16) { + case PCI_CLASS_BRIDGE_HOST: + case PCI_CLASS_BRIDGE_OTHER: /* needed? */ + /* AGP bridge? */ + cap = find_cap(num,slot,func,PCI_CAP_ID_AGP); + if (!cap) + break; + *valid_agp = 1; + return read_agp(num,slot,func,cap,order); + } + + /* No multi-function device? */ + u8 type = read_pci_config_byte(num,slot,func, + PCI_HEADER_TYPE); + if (!(type & 0x80)) + break; + } + } + } + printk("No AGP bridge found\n"); + return 0; +} + void __init iommu_hole_init(void) { int fix, num; - u32 aper_size, aper_alloc, aper_order; + u32 aper_size, aper_alloc = 0, aper_order; u64 aper_base; - - if (no_iommu) - return; - if (end_pfn < (0xffffffff>>PAGE_SHIFT) && !force_mmu) - return; + int valid_agp = 0; printk("Checking aperture...\n"); fix = 0; for (num = 24; num < 32; num++) { + char name[30]; if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) continue; @@ -86,15 +203,12 @@ aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff; aper_base <<= 25; - printk("CPU %d: aperture @ %Lx size %u KB\n", num-24, - aper_base, aper_size>>10); - if (!aper_base || aper_base + aper_size >= 0xffffffff) { - fix = 1; - break; - } + printk("CPU %d: aperture @ %Lx size %u MB\n", num-24, + aper_base, aper_size>>20); - if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { - printk("Aperture pointing to e820 RAM. Ignoring.\n"); + sprintf(name, "northbridge cpu %d", num-24); + + if (!aperture_valid(name, aper_base, aper_size)) { fix = 1; break; } @@ -103,12 +217,40 @@ if (!fix && !fallback_aper_force) return; + if (!fallback_aper_force) + aper_alloc = search_agp_bridge(&aper_order, &valid_agp); + + if (aper_alloc) { + /* Got the aperture from the AGP bridge */ + } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) || + force_iommu || + valid_agp || + fallback_aper_force) { + /* When there is a AGP bridge in the system assume the + user wants to use the AGP driver too and needs an + aperture. However this case (AGP but no good + aperture) should only happen with a more broken than + usual BIOS, because it would even break Windows. */ + printk("Your BIOS doesn't leave a aperture memory hole\n"); printk("Please enable the IOMMU option in the BIOS setup\n"); + printk("This costs you %d MB of RAM\n", 32 << fallback_aper_order); + + aper_order = fallback_aper_order; aper_alloc = allocate_aperture(); - if (!aper_alloc) + if (!aper_alloc) { + /* Could disable AGP and IOMMU here, but it's probably + not worth it. But the later users cannot deal with + bad apertures and turning on the aperture over memory + causes very strange problems, so it's better to + panic early. */ + panic("Not enough memory for aperture"); + } + } else { return; + } + /* Fix up the north bridges */ for (num = 24; num < 32; num++) { if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) continue; @@ -116,7 +258,7 @@ /* Don't enable translation yet. That is done later. Assume this BIOS didn't initialise the GART so just overwrite all previous bits */ - write_pci_config(0, num, 3, 0x90, fallback_aper_order<<1); + write_pci_config(0, num, 3, 0x90, aper_order<<1); write_pci_config(0, num, 3, 0x94, aper_alloc>>25); } } diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c --- a/arch/x86_64/kernel/apic.c Mon Aug 18 22:21:01 2003 +++ b/arch/x86_64/kernel/apic.c Mon Aug 18 22:21:01 2003 @@ -298,8 +298,8 @@ * Double-check whether this APIC is really registered. * This is meaningless in clustered apic mode, so we skip it. */ - if (!clustered_apic_mode && - !test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map)) + if (!clustered_apic_mode && + !cpu_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map)) BUG(); /* @@ -993,7 +993,7 @@ connect_bsp_APIC(); - phys_cpu_present_map = 1; + phys_cpu_present_map = cpumask_of_cpu(0); apic_write_around(APIC_ID, boot_cpu_id); setup_local_APIC(); diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c --- a/arch/x86_64/kernel/io_apic.c Mon Aug 18 22:21:03 2003 +++ b/arch/x86_64/kernel/io_apic.c Mon Aug 18 22:21:03 2003 @@ -1014,7 +1014,7 @@ static void __init setup_ioapic_ids_from_mpc (void) { union IO_APIC_reg_00 reg_00; - unsigned long phys_id_present_map = phys_cpu_present_map; + cpumask_t phys_id_present_map = phys_cpu_present_map; int apic; int i; unsigned char old_id; @@ -1047,22 +1047,22 @@ * system must have a unique ID or we get lots of nice * 'stuck on smp_invalidate_needed IPI wait' messages. */ - if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) { + if (cpu_isset(mp_ioapics[apic].mpc_apicid, phys_id_present_map)) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", apic, mp_ioapics[apic].mpc_apicid); for (i = 0; i < 0xf; i++) - if (!(phys_id_present_map & (1 << i))) + if (!cpu_isset(i, phys_id_present_map)) break; if (i >= 0xf) panic("Max APIC ID exceeded!\n"); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", i); - phys_id_present_map |= 1 << i; + cpu_set(i, phys_id_present_map); mp_ioapics[apic].mpc_apicid = i; } else { printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid); - phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid; + cpu_set(mp_ioapics[apic].mpc_apicid, phys_id_present_map); } @@ -1278,16 +1278,20 @@ static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } -static void set_ioapic_affinity (unsigned int irq, unsigned long mask) +static void set_ioapic_affinity (unsigned int irq, cpumask_t mask) { unsigned long flags; + unsigned int dest; + + dest = cpu_mask_to_apicid(mk_cpumask_const(mask)); + /* * Only the first 8 bits are valid. */ - mask = mask << 24; + dest = dest << 24; spin_lock_irqsave(&ioapic_lock, flags); - __DO_ACTION(1, = mask, ) + __DO_ACTION(1, = dest, ) spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1638,7 +1642,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; - static unsigned long apic_id_map = 0; + static cpumask_t apic_id_map; unsigned long flags; int i = 0; @@ -1651,7 +1655,7 @@ * advantage of new APIC bus architecture. */ - if (!apic_id_map) + if (!cpus_empty(apic_id_map)) apic_id_map = phys_cpu_present_map; spin_lock_irqsave(&ioapic_lock, flags); @@ -1668,10 +1672,10 @@ * Every APIC in a system must have a unique ID or we get lots of nice * 'stuck on smp_invalidate_needed IPI wait' messages. */ - if (apic_id_map & (1 << apic_id)) { + if (cpu_isset(apic_id, apic_id_map)) { for (i = 0; i < IO_APIC_MAX_ID; i++) { - if (!(apic_id_map & (1 << i))) + if (!cpu_isset(i, apic_id_map)) break; } @@ -1684,7 +1688,7 @@ apic_id = i; } - apic_id_map |= (1 << apic_id); + cpu_set(apic_id, apic_id_map); if (reg_00.bits.ID != apic_id) { reg_00.bits.ID = apic_id; diff -Nru a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c --- a/arch/x86_64/kernel/ioport.c Mon Aug 18 22:21:02 2003 +++ b/arch/x86_64/kernel/ioport.c Mon Aug 18 22:21:02 2003 @@ -21,25 +21,25 @@ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) { unsigned long mask; - unsigned long *bitmap_base = bitmap + (base / sizeof(unsigned long)); - unsigned short low_index = base & 0x3f; + unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG); + unsigned long low_index = base & (BITS_PER_LONG-1); int length = low_index + extent; if (low_index != 0) { mask = (~0UL << low_index); - if (length < 64) + if (length < BITS_PER_LONG) mask &= ~(~0UL << length); if (new_value) *bitmap_base++ |= mask; else *bitmap_base++ &= ~mask; - length -= 64; + length -= BITS_PER_LONG; } mask = (new_value ? ~0UL : 0UL); - while (length >= 64) { + while (length >= BITS_PER_LONG) { *bitmap_base++ = mask; - length -= 64; + length -= BITS_PER_LONG; } if (length > 0) { @@ -58,15 +58,13 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) { struct thread_struct * t = ¤t->thread; - int cpu = get_cpu(); + struct tss_struct *tss; if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) return -EINVAL; if (turn_on && !capable(CAP_SYS_RAWIO)) return -EPERM; - struct tss_struct * tss = init_tss + cpu; - /* * If it's the first ioperm() call in this thread's lifetime, set the * IO bitmap up. ioperm() is much less timing critical than clone(), @@ -74,10 +72,8 @@ */ if (!t->io_bitmap_ptr) { t->io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); - if (!t->io_bitmap_ptr) { - put_cpu(); + if (!t->io_bitmap_ptr) return -ENOMEM; - } memset(t->io_bitmap_ptr,0xff,IO_BITMAP_BYTES); } @@ -86,13 +82,13 @@ * do it in the per-thread copy and in the TSS ... */ set_bitmap((unsigned long *) t->io_bitmap_ptr, from, num, !turn_on); + tss = init_tss + get_cpu(); if (tss->io_map_base != IO_BITMAP_OFFSET) { memcpy(tss->io_bitmap, t->io_bitmap_ptr, sizeof(tss->io_bitmap)); tss->io_map_base = IO_BITMAP_OFFSET; } else { - set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on); + set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on); } - put_cpu(); return 0; } @@ -119,7 +115,7 @@ if (!capable(CAP_SYS_RAWIO)) return -EPERM; } - regs.eflags = (regs.eflags & 0xffffffffffffcfff) | (level << 12); + regs.eflags = (regs.eflags &~ 0x3000UL) | (level << 12); return 0; } diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c --- a/arch/x86_64/kernel/irq.c Mon Aug 18 22:21:03 2003 +++ b/arch/x86_64/kernel/irq.c Mon Aug 18 22:21:03 2003 @@ -792,13 +792,13 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; -#define HEX_DIGITS 8 +#define HEX_DIGITS (2*sizeof(cpumask_t)) static unsigned int parse_hex_value (const char *buffer, - unsigned long count, unsigned long *ret) + unsigned long count, cpumask_t *ret) { unsigned char hexnum [HEX_DIGITS]; - unsigned long value; + cpumask_t value = CPU_MASK_NONE; unsigned i; if (!count) @@ -812,10 +812,9 @@ * Parse the first 8 characters as a hex string, any non-hex char * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ - value = 0; for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; + unsigned int k, c = hexnum[i]; switch (c) { case '0' ... '9': c -= '0'; break; @@ -824,7 +823,10 @@ default: goto out; } - value = (value << 4) | c; + cpus_shift_left(value, value, 4); + for (k = 0; k < 4; ++k) + if (c & (1 << k)) + cpu_set(k, value); } out: *ret = value; @@ -835,20 +837,31 @@ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + int k, len; + cpumask_t tmp = irq_affinity[(long)data]; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", irq_affinity[(long)data]); + + for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value; + cpumask_t tmp, new_value; if (!irq_desc[irq].handler->set_affinity) return -EIO; @@ -860,7 +873,8 @@ * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - if (!(new_value & cpu_online_map)) + cpus_and(tmp, new_value, cpu_online_map); + if (cpus_empty(tmp)) return -EINVAL; irq_affinity[irq] = new_value; @@ -874,17 +888,28 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; + cpumask_t tmp, *mask = (cpumask_t *) data; + int k, len; + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08lx\n", *mask); + + tmp = *mask; + for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); + len += j; + page += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(page, "\n"); + return len; } static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + unsigned long full_count = count, err; + cpumask_t new_value, *mask = (cpumask_t *)data; err = parse_hex_value(buffer, count, &new_value); if (err) diff -Nru a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c --- a/arch/x86_64/kernel/ldt.c Mon Aug 18 22:21:05 2003 +++ b/arch/x86_64/kernel/ldt.c Mon Aug 18 22:21:05 2003 @@ -60,9 +60,12 @@ wmb(); if (reload) { #ifdef CONFIG_SMP + cpumask_t mask; + preempt_disable(); + mask = cpumask_of_cpu(smp_processor_id()); load_LDT(pc); - if (current->mm->cpu_vm_mask != (1UL<mm->cpu_vm_mask, mask)) smp_call_function(flush_ldt, 0, 1, 1); preempt_enable(); #else diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c Mon Aug 18 22:21:02 2003 +++ b/arch/x86_64/kernel/mpparse.c Mon Aug 18 22:21:02 2003 @@ -43,7 +43,7 @@ int apic_version [MAX_APICS]; unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; -unsigned long mp_bus_to_cpumask [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1UL }; +cpumask_t mp_bus_to_cpumask [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = CPU_MASK_ALL }; int mp_current_pci_id = 0; /* I/O APIC entries */ @@ -67,7 +67,7 @@ static unsigned int num_processors = 0; /* Bitmask of physically existing CPUs */ -unsigned long phys_cpu_present_map = 0; +cpumask_t phys_cpu_present_map = CPU_MASK_NONE; /* ACPI MADT entry parsing functions */ #ifdef CONFIG_ACPI_BOOT @@ -126,7 +126,7 @@ } ver = m->mpc_apicver; - phys_cpu_present_map |= 1 << m->mpc_apicid; + cpu_set(m->mpc_apicid, phys_cpu_present_map); /* * Validate version */ diff -Nru a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c --- a/arch/x86_64/kernel/msr.c Mon Aug 18 22:21:01 2003 +++ b/arch/x86_64/kernel/msr.c Mon Aug 18 22:21:01 2003 @@ -242,7 +242,7 @@ int cpu = minor(file->f_dentry->d_inode->i_rdev); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; - if ( !(cpu_online_map & (1UL << cpu)) ) + if (!cpu_online(cpu)) return -ENXIO; /* No such CPU */ if ( !cpu_has(c, X86_FEATURE_MSR) ) return -EIO; /* MSR not supported */ diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c --- a/arch/x86_64/kernel/nmi.c Mon Aug 18 22:21:03 2003 +++ b/arch/x86_64/kernel/nmi.c Mon Aug 18 22:21:03 2003 @@ -40,6 +40,7 @@ * -1: the lapic NMI watchdog is disabled, but can be enabled */ static int nmi_active; +static int panic_on_timeout; unsigned int nmi_watchdog = NMI_IO_APIC; static unsigned int nmi_hz = HZ; @@ -115,6 +116,14 @@ { int nmi; + if (!strncmp(str,"panic",5)) { + panic_on_timeout = 1; + str = strchr(str, ','); + if (!str) + return 1; + ++str; + } + get_option(&str, &nmi); if (nmi >= NMI_INVALID) @@ -327,6 +336,8 @@ bust_spinlocks(1); printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu); show_registers(regs); + if (panic_on_timeout) + panic("nmi watchdog"); printk("console shuts up ...\n"); console_silent(); spin_unlock(&nmi_print_lock); @@ -374,3 +385,4 @@ EXPORT_SYMBOL(enable_lapic_nmi_watchdog); EXPORT_SYMBOL(disable_timer_nmi_watchdog); EXPORT_SYMBOL(enable_timer_nmi_watchdog); +EXPORT_SYMBOL(touch_nmi_watchdog); diff -Nru a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c --- a/arch/x86_64/kernel/pci-dma.c Mon Aug 18 22:21:06 2003 +++ b/arch/x86_64/kernel/pci-dma.c Mon Aug 18 22:21:06 2003 @@ -9,8 +9,6 @@ #include #include -dma_addr_t bad_dma_address = -1UL; - /* Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scatter-gather version of the * above pci_map_single interface. Here the scatter gather list @@ -34,16 +32,9 @@ BUG_ON(direction == PCI_DMA_NONE); for (i = 0; i < nents; i++ ) { struct scatterlist *s = &sg[i]; - BUG_ON(!s->page); - s->dma_address = pci_map_page(hwdev, s->page, s->offset, s->length, direction); - - if (unlikely(s->dma_address == bad_dma_address)) { - pci_unmap_sg(hwdev, sg, i, direction); - return 0; - } } return nents; } diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c --- a/arch/x86_64/kernel/pci-gart.c Mon Aug 18 22:21:03 2003 +++ b/arch/x86_64/kernel/pci-gart.c Mon Aug 18 22:21:03 2003 @@ -8,20 +8,8 @@ * See Documentation/DMA-mapping.txt for the interface specification. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: pci-gart.c,v 1.20 2003/03/12 08:23:29 ak Exp $ */ -/* - * Notebook: - -possible future tuning: - fast path for sg streaming mappings - only take the locks once. - more intelligent flush strategy - flush only the NB of the CPU directly - connected to the device? - move boundary between IOMMU and AGP in GART dynamically - -*/ - #include #include #include @@ -32,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -41,6 +31,8 @@ #include #include +dma_addr_t bad_dma_address; + unsigned long iommu_bus_base; /* GART remapping area (physical) */ static unsigned long iommu_size; /* size of remapping area bytes */ static unsigned long iommu_pages; /* .. and in pages */ @@ -50,9 +42,13 @@ int no_iommu; static int no_agp; #ifdef CONFIG_IOMMU_DEBUG -int force_mmu = 1; +int panic_on_overflow = 1; +int force_iommu = 1; +int sac_force_size = 0; #else -int force_mmu = 0; +int panic_on_overflow = 1; /* for testing */ +int force_iommu = 0; +int sac_force_size = 256*1024*1024; #endif /* Allocation bitmap for the remapping area */ @@ -65,12 +61,18 @@ (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT) #define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28)) +#define to_pages(addr,size) \ + (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) + #define for_all_nb(dev) \ - dev=NULL; \ - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) \ - if (dev->bus->number == 0 && PCI_FUNC(dev->devfn) == 3 && \ + dev = NULL; \ + while ((dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL)\ + if (dev->bus->number == 0 && \ (PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31)) +static struct pci_dev *northbridges[NR_CPUS + 1]; +static u32 northbridge_flush_word[NR_CPUS + 1]; + #define EMERGENCY_PAGES 32 /* = 128KB */ #ifdef CONFIG_AGP @@ -85,15 +87,16 @@ AGPEXTERN __u32 *agp_gatt_table; static unsigned long next_bit; /* protected by iommu_bitmap_lock */ +static int need_flush; /* global flush state. set for each gart wrap */ -static unsigned long alloc_iommu(int size, int *flush) +static unsigned long alloc_iommu(int size) { unsigned long offset, flags; spin_lock_irqsave(&iommu_bitmap_lock, flags); offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size); if (offset == -1) { - *flush = 1; + need_flush = 1; offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size); } if (offset != -1) { @@ -101,7 +104,7 @@ next_bit = offset+size; if (next_bit >= iommu_pages) { next_bit = 0; - *flush = 1; + need_flush = 1; } } spin_unlock_irqrestore(&iommu_bitmap_lock, flags); @@ -110,32 +113,60 @@ static void free_iommu(unsigned long offset, int size) { + if (size == 1) { + clear_bit(offset, iommu_gart_bitmap); + return; + } unsigned long flags; spin_lock_irqsave(&iommu_bitmap_lock, flags); - clear_bit_string(iommu_gart_bitmap, offset, size); + __clear_bit_string(iommu_gart_bitmap, offset, size); spin_unlock_irqrestore(&iommu_bitmap_lock, flags); } -static inline void flush_gart(void) +/* + * Use global flush state to avoid races with multiple flushers. + */ +static void __flush_gart(struct pci_dev *dev) { - struct pci_dev *nb; - for_all_nb(nb) { - u32 flag; - pci_read_config_dword(nb, 0x9c, &flag); /* could cache this */ - /* could complain for PTE walk errors here (bit 1 of flag) */ - flag |= 1; - pci_write_config_dword(nb, 0x9c, flag); + unsigned long flags; + int bus = dev ? dev->bus->number : -1; + cpumask_const_t bus_cpumask = pcibus_to_cpumask(bus); + int flushed = 0; + int i; + + spin_lock_irqsave(&iommu_bitmap_lock, flags); + /* recheck flush count inside lock */ + if (need_flush) { + for (i = 0; northbridges[i]; i++) { + if (bus >= 0 && !(cpu_isset_const(i, bus_cpumask))) + continue; + pci_write_config_dword(northbridges[i], 0x9c, + northbridge_flush_word[i] | 1); + flushed++; + } + if (!flushed) + printk("nothing to flush? %d\n", bus); + need_flush = 0; } + spin_unlock_irqrestore(&iommu_bitmap_lock, flags); } +static inline void flush_gart(struct pci_dev *dev) +{ + if (need_flush) + __flush_gart(dev); +} + +/* + * Allocate memory for a consistent mapping. + * All mappings are consistent here, so this is just a wrapper around + * pci_map_single. + */ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) { void *memory; int gfp = GFP_ATOMIC; - int i; - int flush = 0; - unsigned long iommu_page; unsigned long dma_mask; if (hwdev == NULL) { @@ -149,20 +180,14 @@ if (dma_mask < 0xffffffff || no_iommu) gfp |= GFP_DMA; - /* - * First try to allocate continuous and use directly if already - * in lowmem. - */ - size = round_up(size, PAGE_SIZE); memory = (void *)__get_free_pages(gfp, get_order(size)); if (memory == NULL) { return NULL; } else { - int high = 0, mmu; - if (((unsigned long)virt_to_bus(memory) + size) > dma_mask) - high = 1; - mmu = 1; - if (force_mmu && !(gfp & GFP_DMA)) + int high, mmu; + high = ((unsigned long)virt_to_bus(memory) + size) >= dma_mask; + mmu = high; + if (force_iommu && !(gfp & GFP_DMA)) mmu = 1; if (no_iommu) { if (high) goto error; @@ -175,27 +200,15 @@ } } - size >>= PAGE_SHIFT; - - iommu_page = alloc_iommu(size, &flush); - if (iommu_page == -1) + *dma_handle = pci_map_single(hwdev, memory, size, 0); + if (*dma_handle == bad_dma_address) goto error; - /* Fill in the GATT */ - for (i = 0; i < size; i++) { - unsigned long phys_mem; - void *mem = memory + i*PAGE_SIZE; - phys_mem = virt_to_phys(mem); - BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK); - iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); - } - - if (flush) - flush_gart(); - *dma_handle = iommu_bus_base + (iommu_page << PAGE_SHIFT); return memory; - error: +error: + if (panic_on_overflow) + panic("pci_map_single: overflow %lu bytes\n", size); free_pages((unsigned long)memory, get_order(size)); return NULL; } @@ -207,25 +220,17 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t bus) { - unsigned long iommu_page; - - size = round_up(size, PAGE_SIZE); - if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) { - unsigned pages = size >> PAGE_SHIFT; - int i; - iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT; - vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page])); - for (i = 0; i < pages; i++) { - u64 pte = iommu_gatt_base[iommu_page + i]; - BUG_ON((pte & GPTE_VALID) == 0); - iommu_gatt_base[iommu_page + i] = 0; - } - free_iommu(iommu_page, pages); - } + pci_unmap_single(hwdev, bus, size, 0); free_pages((unsigned long)vaddr, get_order(size)); } #ifdef CONFIG_IOMMU_LEAK + +#define SET_LEAK(x) if (iommu_leak_tab) \ + iommu_leak_tab[x] = __builtin_return_address(0); +#define CLEAR_LEAK(x) if (iommu_leak_tab) \ + iommu_leak_tab[x] = 0; + /* Debugging aid for drivers that don't free their IOMMU tables */ static void **iommu_leak_tab; static int leak_trace; @@ -246,9 +251,12 @@ } printk("\n"); } +#else +#define SET_LEAK(x) +#define CLEAR_LEAK(x) #endif -static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir) +static void iommu_full(struct pci_dev *dev, size_t size, int dir) { /* * Ran out of IOMMU space for this operation. This is very bad. @@ -261,8 +269,8 @@ */ printk(KERN_ERR - "PCI-DMA: Out of IOMMU space for %p size %lu at device %s[%s]\n", - addr,size, dev ? dev->dev.name : "?", dev ? pci_name(dev) : "?"); + "PCI-DMA: Out of IOMMU space for %lu bytes at device %s[%s]\n", + size, dev ? dev->dev.name : "?", dev ? dev->slot_name : "?"); if (size > PAGE_SIZE*EMERGENCY_PAGES) { if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL) @@ -279,24 +287,61 @@ static inline int need_iommu(struct pci_dev *dev, unsigned long addr, size_t size) { u64 mask = dev ? dev->dma_mask : 0xffffffff; - int high = (~mask & (unsigned long)(addr + size)) != 0; + int high = addr + size >= mask; int mmu = high; - if (force_mmu) + if (force_iommu) mmu = 1; if (no_iommu) { if (high) - panic("pci_map_single: high address but no IOMMU.\n"); + panic("PCI-DMA: high address but no IOMMU.\n"); + mmu = 0; + } + return mmu; +} + +static inline int nonforced_iommu(struct pci_dev *dev, unsigned long addr, size_t size) +{ + u64 mask = dev ? dev->dma_mask : 0xffffffff; + int high = addr + size >= mask; + int mmu = high; + if (no_iommu) { + if (high) + panic("PCI-DMA: high address but no IOMMU.\n"); mmu = 0; } return mmu; } +/* Map a single continuous physical area into the IOMMU. + * Caller needs to check if the iommu is needed and flush. + */ +static dma_addr_t pci_map_area(struct pci_dev *dev, unsigned long phys_mem, + size_t size, int dir) +{ + unsigned long npages = to_pages(phys_mem, size); + unsigned long iommu_page = alloc_iommu(npages); + if (iommu_page == -1) { + if (!nonforced_iommu(dev, phys_mem, size)) + return phys_mem; + if (panic_on_overflow) + panic("pci_map_area overflow %lu bytes\n", size); + iommu_full(dev, size, dir); + return bad_dma_address; + } + + int i; + for (i = 0; i < npages; i++) { + iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); + SET_LEAK(iommu_page + i); + phys_mem += PAGE_SIZE; + } + return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK); +} + +/* Map a single area into the IOMMU */ dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, int dir) { - unsigned long iommu_page; unsigned long phys_mem, bus; - int i, npages; - int flush = 0; BUG_ON(dir == PCI_DMA_NONE); @@ -304,39 +349,158 @@ if (!need_iommu(dev, phys_mem, size)) return phys_mem; - npages = round_up(size + ((u64)addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT; + bus = pci_map_area(dev, phys_mem, size, dir); + flush_gart(dev); + return bus; +} - iommu_page = alloc_iommu(npages, &flush); - if (iommu_page == -1) { - iommu_full(dev, addr, size, dir); - return iommu_bus_base; +/* Fallback for pci_map_sg in case of overflow */ +static int pci_map_sg_nonforce(struct pci_dev *dev, struct scatterlist *sg, + int nents, int dir) +{ + int i; + +#ifdef CONFIG_IOMMU_DEBUG + printk(KERN_DEBUG "pci_map_sg overflow\n"); +#endif + + for (i = 0; i < nents; i++ ) { + struct scatterlist *s = &sg[i]; + unsigned long addr = page_to_phys(s->page) + s->offset; + if (nonforced_iommu(dev, addr, s->length)) { + addr = pci_map_area(dev, addr, s->length, dir); + if (addr == bad_dma_address) { + if (i > 0) + pci_unmap_sg(dev, sg, i, dir); + nents = 0; + break; + } + } + s->dma_address = addr; + } + flush_gart(dev); + return nents; +} + +/* Map multiple scatterlist entries continuous into the first. */ +static int __pci_map_cont(struct scatterlist *sg, int start, int stopat, + struct scatterlist *sout, unsigned long pages) +{ + unsigned long iommu_start = alloc_iommu(pages); + if (iommu_start == -1) + return -1; + + unsigned long iommu_page = iommu_start; + int i; + + for (i = start; i < stopat; i++) { + struct scatterlist *s = &sg[i]; + unsigned long start_addr = s->dma_address; + BUG_ON(i > 0 && s->offset); + if (i == start) { + *sout = *s; + sout->dma_address = iommu_bus_base; + sout->dma_address += iommu_page*PAGE_SIZE + s->offset; + } else { + sout->length += s->length; + } + unsigned long addr = start_addr; + while (addr < start_addr + s->length) { + iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); + SET_LEAK(iommu_page); + addr += PAGE_SIZE; + iommu_page++; } + BUG_ON(i > 0 && addr % PAGE_SIZE); + } + BUG_ON(iommu_page - iommu_start != pages); + return 0; +} - phys_mem &= PAGE_MASK; - for (i = 0; i < npages; i++, phys_mem += PAGE_SIZE) { - BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK); +static inline int pci_map_cont(struct scatterlist *sg, int start, int stopat, + struct scatterlist *sout, + unsigned long pages, int need) +{ + if (!need) { + BUG_ON(stopat - start != 1); + *sout = sg[start]; + return 0; + } + return __pci_map_cont(sg, start, stopat, sout, pages); +} + +#define PCI_NO_MERGE 0 - /* - * Set coherent mapping here to avoid needing to flush - * the caches on mapping. +/* + * DMA map all entries in a scatterlist. + * Merge chunks that have page aligned sizes into a continuous mapping. */ - iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); +int pci_map_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, int dir) +{ + int i; + int out; + int start; + unsigned long pages = 0; + int need = 0; -#ifdef CONFIG_IOMMU_LEAK - /* XXX need eventually caller of pci_map_sg */ - if (iommu_leak_tab) - iommu_leak_tab[iommu_page + i] = __builtin_return_address(0); -#endif + unsigned long size = 0; + + BUG_ON(dir == PCI_DMA_NONE); + if (nents == 0) + return 0; + out = 0; + start = 0; + for (i = 0; i < nents; i++) { + struct scatterlist *s = &sg[i]; + dma_addr_t addr = page_to_phys(s->page) + s->offset; + s->dma_address = addr; + BUG_ON(s->length == 0); + + size += s->length; + + /* Handle the previous not yet processed entries */ + if (i > start) { + struct scatterlist *ps = &sg[i-1]; + /* Can only merge when the last chunk ends on a page + boundary. */ + if (PCI_NO_MERGE || !need || (i-1 > start && ps->offset) || + (ps->offset + ps->length) % PAGE_SIZE) { + if (pci_map_cont(sg, start, i, sg+out, pages, + need) < 0) + goto error; + out++; + pages = 0; + start = i; + } } - if (flush) - flush_gart(); - bus = iommu_bus_base + iommu_page*PAGE_SIZE; - return bus + ((unsigned long)addr & ~PAGE_MASK); + need = need_iommu(dev, addr, s->length); + pages += to_pages(s->offset, s->length); + } + if (pci_map_cont(sg, start, i, sg+out, pages, need) < 0) + goto error; + out++; + flush_gart(dev); + if (out < nents) + sg[out].length = 0; + return out; + +error: + flush_gart(NULL); + pci_unmap_sg(dev, sg, nents, dir); + /* When it was forced try again unforced */ + if (force_iommu) + return pci_map_sg_nonforce(dev, sg, nents, dir); + if (panic_on_overflow) + panic("pci_map_sg: overflow on %lu pages\n", pages); + iommu_full(dev, pages << PAGE_SHIFT, dir); + for (i = 0; i < nents; i++) + sg[i].dma_address = bad_dma_address; + return 0; } /* - * Free a temporary PCI mapping. + * Free a PCI mapping. */ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) @@ -347,20 +511,68 @@ dma_addr > iommu_bus_base + iommu_size) return; iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; - npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT; + npages = to_pages(dma_addr, size); int i; for (i = 0; i < npages; i++) { iommu_gatt_base[iommu_page + i] = 0; -#ifdef CONFIG_IOMMU_LEAK - if (iommu_leak_tab) - iommu_leak_tab[iommu_page + i] = 0; -#endif + CLEAR_LEAK(iommu_page + i); } free_iommu(iommu_page, npages); } +/* + * Wrapper for pci_unmap_single working with scatterlists. + */ +void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, + int dir) +{ + int i; + for (i = 0; i < nents; i++) { + struct scatterlist *s = &sg[i]; + if (!s->length) + break; + pci_unmap_single(dev, s->dma_address, s->length, dir); + } +} + +int pci_dma_supported(struct pci_dev *dev, u64 mask) +{ + /* Copied from i386. Doesn't make much sense, because it will + only work for pci_alloc_consistent. + The caller just has to use GFP_DMA in this case. */ + if (mask < 0x00ffffff) + return 0; + + /* Tell the device to use SAC when IOMMU force is on. + This allows the driver to use cheaper accesses in some cases. + + Problem with this is that if we overflow the IOMMU area + and return DAC as fallback address the device may not handle it correctly. + As a compromise we only do this if the IOMMU area is >= 256MB + which should make overflow unlikely enough. + + As a special case some controllers have a 39bit address mode + that is as efficient as 32bit (aic79xx). Don't force SAC for these. + Assume all masks <= 40 bits are of this type. Normally this doesn't + make any difference, but gives more gentle handling of IOMMU overflow. */ + if (force_iommu && (mask > 0xffffffffffULL) && (iommu_size >= sac_force_size)){ + printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->slot_name,mask); + return 0; + } + + if (no_iommu && (mask < (end_pfn << PAGE_SHIFT))) + return 0; + + return 1; +} + +EXPORT_SYMBOL(pci_unmap_sg); +EXPORT_SYMBOL(pci_map_sg); EXPORT_SYMBOL(pci_map_single); EXPORT_SYMBOL(pci_unmap_single); +EXPORT_SYMBOL(pci_dma_supported); +EXPORT_SYMBOL(no_iommu); +EXPORT_SYMBOL(force_iommu); static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size) { @@ -452,13 +664,12 @@ pci_write_config_dword(dev, 0x90, ctl); } - flush_gart(); + flush_gart(NULL); - printk("PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10); + printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); return 0; nommu: - /* XXX: reject 0xffffffff mask now in pci mapping functions */ printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n" KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction."); return -1; @@ -466,11 +677,12 @@ extern int agp_amdk8_init(void); -int __init pci_iommu_init(void) +static int __init pci_iommu_init(void) { struct agp_kern_info info; unsigned long aper_size; unsigned long iommu_start; + struct pci_dev *dev; #ifndef CONFIG_AGP_AMD_8151 no_agp = 1; @@ -482,7 +694,7 @@ (agp_copy_info(&info) < 0); #endif - if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { + if (no_iommu || (!force_iommu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); no_iommu = 1; return -1; @@ -492,7 +704,7 @@ int err = -1; printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); no_agp = 1; - if (force_mmu || end_pfn >= 0xffffffff>>PAGE_SHIFT) + if (force_iommu || end_pfn >= 0xffffffff>>PAGE_SHIFT) err = init_k8_gatt(&info); if (err < 0) { printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); @@ -529,25 +741,38 @@ set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES); agp_memory_reserved = iommu_size; - printk(KERN_INFO"PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n", + printk(KERN_INFO + "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n", iommu_size>>20); iommu_start = aper_size - iommu_size; iommu_bus_base = info.aper_base + iommu_start; - iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT); bad_dma_address = iommu_bus_base; + iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT); /* - * Unmap the IOMMU part of the GART. The alias of the page is always mapped - * with cache enabled and there is no full cache coherency across the GART - * remapping. The unmapping avoids automatic prefetches from the CPU - * allocating cache lines in there. All CPU accesses are done via the - * direct mapping to the backing memory. The GART address is only used by PCI + * Unmap the IOMMU part of the GART. The alias of the page is + * always mapped with cache enabled and there is no full cache + * coherency across the GART remapping. The unmapping avoids + * automatic prefetches from the CPU allocating cache lines in + * there. All CPU accesses are done via the direct mapping to + * the backing memory. The GART address is only used by PCI * devices. */ clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size); - flush_gart(); + for_all_nb(dev) { + u32 flag; + int cpu = PCI_SLOT(dev->devfn) - 24; + if (cpu >= NR_CPUS) + continue; + northbridges[cpu] = dev; + + pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */ + northbridge_flush_word[cpu] = flag; + } + + flush_gart(NULL); return 0; } @@ -561,8 +786,8 @@ off don't use the IOMMU leak turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on) memaper[=order] allocate an own aperture over RAM with size 32MB^order. - noforce don't force IOMMU usage. Should be fastest. - force Force IOMMU and turn on unmap debugging. + noforce don't force IOMMU usage. Default. + force Force IOMMU. */ __init int iommu_setup(char *opt) { @@ -575,15 +800,19 @@ if (!memcmp(p,"off", 3)) no_iommu = 1; if (!memcmp(p,"force", 5)) - force_mmu = 1; + force_iommu = 1; if (!memcmp(p,"noforce", 7)) - force_mmu = 0; + force_iommu = 0; if (!memcmp(p, "memaper", 7)) { fallback_aper_force = 1; p += 7; if (*p == '=' && get_option(&p, &arg)) fallback_aper_order = arg; } + if (!memcmp(p, "panic", 5)) + panic_on_overflow = 1; + if (!memcmp(p, "nopanic", 7)) + panic_on_overflow = 0; #ifdef CONFIG_IOMMU_LEAK if (!memcmp(p,"leak", 4)) { leak_trace = 1; diff -Nru a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c --- a/arch/x86_64/kernel/pci-nommu.c Mon Aug 18 22:21:00 2003 +++ b/arch/x86_64/kernel/pci-nommu.c Mon Aug 18 22:21:00 2003 @@ -33,15 +33,30 @@ free_pages((unsigned long)vaddr, get_order(size)); } +int pci_dma_supported(struct pci_dev *hwdev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + * RED-PEN this won't work for pci_map_single. Caller has to + * use GFP_DMA in the first place. + */ + if (mask < 0x00ffffff) + return 0; -static void __init check_ram(void) + return 1; +} + +EXPORT_SYMBOL(pci_dma_supported); + +static int __init check_ram(void) { if (end_pfn >= 0xffffffff>>PAGE_SHIFT) { printk(KERN_ERR "WARNING more than 4GB of memory but no IOMMU.\n" KERN_ERR "WARNING 32bit PCI may malfunction.\n"); - /* Could play with highmem_start_page here to trick some subsystems - into bounce buffers. Unfortunately that would require setting - CONFIG_HIGHMEM too. - */ } + return 0; } +__initcall(check_ram); + diff -Nru a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c --- a/arch/x86_64/kernel/reboot.c Mon Aug 18 22:21:05 2003 +++ b/arch/x86_64/kernel/reboot.c Mon Aug 18 22:21:05 2003 @@ -110,7 +110,7 @@ } /* Wait for all other CPUs to have run smp_stop_cpu */ - while (cpu_online_map) + while (!cpus_empty(cpu_online_map)) rep_nop(); } #endif diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c Mon Aug 18 22:21:01 2003 +++ b/arch/x86_64/kernel/setup.c Mon Aug 18 22:21:01 2003 @@ -643,7 +643,7 @@ #ifdef CONFIG_SMP - if (!(cpu_online_map & (1<<(c-cpu_data)))) + if (!cpu_online(c-cpu_data)) return 0; #endif diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c --- a/arch/x86_64/kernel/setup64.c Mon Aug 18 22:21:02 2003 +++ b/arch/x86_64/kernel/setup64.c Mon Aug 18 22:21:02 2003 @@ -131,14 +131,16 @@ size = PERCPU_ENOUGH_ROOM; #endif - /* We don't support CPU hotplug, so only allocate as much as needed here */ - - int maxi = max_t(unsigned, numnodes, num_online_cpus()); - - for (i = 0; i < maxi; i++) { + for (i = 0; i < NR_CPUS; i++) { + unsigned char *ptr; /* If possible allocate on the node of the CPU. In case it doesn't exist round-robin nodes. */ - unsigned char *ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size); + if (!NODE_DATA(i % numnodes)) { + printk("cpu with no node %d, numnodes %d\n", i, numnodes); + ptr = alloc_bootmem(size); + } else { + ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size); + } if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); cpu_pda[i].data_offset = ptr - __per_cpu_start; @@ -158,7 +160,6 @@ pda->me = pda; pda->cpunumber = cpu; pda->irqcount = -1; - pda->data_offset = 0; pda->kernelstack = (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; pda->active_mm = &init_mm; @@ -170,14 +171,14 @@ pda->irqstackptr = boot_cpu_stack; level4 = init_level4_pgt; } else { + level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0); + if (!level4) + panic("Cannot allocate top level page for cpu %d", cpu); pda->irqstackptr = (char *) __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); if (!pda->irqstackptr) - panic("cannot allocate irqstack for cpu %d\n", cpu); - level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0); + panic("cannot allocate irqstack for cpu %d", cpu); } - if (!level4) - panic("Cannot allocate top level page for cpu %d", cpu); pda->level4_pgt = (unsigned long *)level4; if (level4 != init_level4_pgt) diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c --- a/arch/x86_64/kernel/smp.c Mon Aug 18 22:21:02 2003 +++ b/arch/x86_64/kernel/smp.c Mon Aug 18 22:21:02 2003 @@ -92,8 +92,9 @@ __send_IPI_shortcut(APIC_DEST_SELF, vector); } -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t cpumask, int vector) { + unsigned long mask = cpus_coerce(cpumask); unsigned long cfg; unsigned long flags; @@ -133,7 +134,7 @@ * Optimizations Manfred Spraul */ -static volatile unsigned long flush_cpumask; +static cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED; @@ -203,7 +204,7 @@ cpu = get_cpu(); - if (!test_bit(cpu, &flush_cpumask)) + if (!cpu_isset(cpu, flush_cpumask)) goto out; /* * This was a BUG() but until someone can quote me the @@ -224,15 +225,16 @@ leave_mm(cpu); } ack_APIC_irq(); - clear_bit(cpu, &flush_cpumask); + cpu_clear(cpu, flush_cpumask); out: put_cpu_no_resched(); } -static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, +static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, unsigned long va) { + cpumask_t tmp; /* * A couple of (to be removed) sanity checks: * @@ -240,12 +242,10 @@ * - current CPU must not be in mask * - mask must exist :) */ - if (!cpumask) - BUG(); - if ((cpumask & cpu_online_map) != cpumask) - BUG(); - if (cpumask & (1 << smp_processor_id())) - BUG(); + BUG_ON(cpus_empty(cpumask)); + cpus_and(tmp, cpumask, cpu_online_map); + BUG_ON(!cpus_equal(tmp, cpumask)); + BUG_ON(cpu_isset(smp_processor_id(), cpumask)); if (!mm) BUG(); @@ -259,15 +259,16 @@ flush_mm = mm; flush_va = va; - atomic_set_mask(cpumask, &flush_cpumask); + cpus_or(flush_cpumask, cpumask, flush_cpumask); + /* * We have to send the IPI only to * CPUs affected. */ send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR); - while (flush_cpumask) - /* nothing. lockup detection does not belong here */; + while (!cpus_empty(flush_cpumask)) + mb(); /* nothing. lockup detection does not belong here */; flush_mm = NULL; flush_va = 0; @@ -277,23 +278,25 @@ void flush_tlb_current_task(void) { struct mm_struct *mm = current->mm; - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); local_flush_tlb(); - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } void flush_tlb_mm (struct mm_struct * mm) { - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); if (current->active_mm == mm) { if (current->mm) @@ -301,7 +304,7 @@ else leave_mm(smp_processor_id()); } - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); @@ -310,10 +313,11 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) { struct mm_struct *mm = vma->vm_mm; - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); if (current->active_mm == mm) { if(current->mm) @@ -322,7 +326,7 @@ leave_mm(smp_processor_id()); } - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, va); preempt_enable(); @@ -355,7 +359,7 @@ void smp_send_reschedule(int cpu) { - send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); + send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); } /* @@ -430,7 +434,7 @@ /* * Remove this CPU: */ - clear_bit(smp_processor_id(), &cpu_online_map); + cpu_clear(smp_processor_id(), cpu_online_map); local_irq_disable(); disable_local_APIC(); local_irq_enable(); @@ -491,8 +495,8 @@ unsigned long sp = (unsigned long)&stack_location; int offset = 0, cpu; - for (offset = 0; (cpu_online_map >> offset); offset = cpu + 1) { - cpu = ffz(~(cpu_online_map >> offset)); + for (offset = 0; next_cpu(offset, cpu_online_map) < NR_CPUS; offset = cpu + 1) { + cpu = next_cpu(offset, cpu_online_map); if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && sp <= (u64)cpu_pda[cpu].irqstackptr) diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c --- a/arch/x86_64/kernel/smpboot.c Mon Aug 18 22:21:06 2003 +++ b/arch/x86_64/kernel/smpboot.c Mon Aug 18 22:21:06 2003 @@ -54,11 +54,11 @@ #include /* Bitmask of currently online CPUs */ -unsigned long cpu_online_map = 1; +cpumask_t cpu_online_map; -static volatile unsigned long cpu_callin_map; -volatile unsigned long cpu_callout_map; -static unsigned long smp_commenced_mask; +static cpumask_t cpu_callin_map; +cpumask_t cpu_callout_map; +static cpumask_t smp_commenced_mask; /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; @@ -174,7 +174,7 @@ sum = 0; for (i = 0; i < NR_CPUS; i++) { - if (test_bit(i, &cpu_callout_map)) { + if (cpu_isset(i, cpu_callout_map)) { t0 = tsc_values[i]; sum += t0; } @@ -183,7 +183,7 @@ sum = 0; for (i = 0; i < NR_CPUS; i++) { - if (!test_bit(i, &cpu_callout_map)) + if (!cpu_isset(i, cpu_callout_map)) continue; delta = tsc_values[i] - avg; @@ -258,7 +258,7 @@ */ phys_id = GET_APIC_ID(apic_read(APIC_ID)); cpuid = smp_processor_id(); - if (test_and_set_bit(cpuid, &cpu_callin_map)) { + if (cpu_test_and_set(cpuid, cpu_callin_map)) { panic("smp_callin: phys CPU#%d, CPU#%d already present??\n", phys_id, cpuid); } @@ -280,7 +280,7 @@ /* * Has the boot CPU finished it's STARTUP sequence? */ - if (test_bit(cpuid, &cpu_callout_map)) + if (cpu_isset(cpuid, cpu_callout_map)) break; rep_nop(); } @@ -320,7 +320,7 @@ /* * Allow the master to continue. */ - set_bit(cpuid, &cpu_callin_map); + cpu_set(cpuid, cpu_callin_map); /* * Synchronize the TSC with the BP @@ -348,7 +348,7 @@ barrier(); Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); - while (!test_bit(smp_processor_id(), &smp_commenced_mask)) + while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); @@ -372,7 +372,7 @@ local_flush_tlb(); Dprintk("cpu %d eSetting cpu_online_map\n", smp_processor_id()); - set_bit(smp_processor_id(), &cpu_online_map); + cpu_set(smp_processor_id(), cpu_online_map); wmb(); cpu_idle(); @@ -630,19 +630,19 @@ * allow APs to start initializing. */ Dprintk("Before Callout %d.\n", cpu); - set_bit(cpu, &cpu_callout_map); + cpu_set(cpu, cpu_callout_map); Dprintk("After Callout %d.\n", cpu); /* * Wait 5s total for a response */ for (timeout = 0; timeout < 50000; timeout++) { - if (test_bit(cpu, &cpu_callin_map)) + if (cpu_isset(cpu, cpu_callin_map)) break; /* It has booted */ udelay(100); } - if (test_bit(cpu, &cpu_callin_map)) { + if (cpu_isset(cpu, cpu_callin_map)) { /* number CPUs logically, starting from 1 (BSP is 0) */ Dprintk("OK.\n"); printk(KERN_INFO "CPU%d: ", cpu); @@ -663,7 +663,7 @@ } } if (boot_error) { - clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */ + cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ cpucount--; } @@ -734,10 +734,10 @@ current_thread_info()->cpu = 0; smp_tune_scheduling(); - if (!test_bit(hard_smp_processor_id(), &phys_cpu_present_map)) { + if (!cpu_isset(hard_smp_processor_id(), phys_cpu_present_map)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", hard_smp_processor_id()); - phys_cpu_present_map |= (1 << hard_smp_processor_id()); + cpu_set(hard_smp_processor_id(), phys_cpu_present_map); } /* @@ -747,8 +747,8 @@ if (!smp_found_config) { printk(KERN_NOTICE "SMP motherboard not detected.\n"); io_apic_irqs = 0; - cpu_online_map = phys_cpu_present_map = 1; - phys_cpu_present_map = 1; + cpu_online_map = cpumask_of_cpu(0); + phys_cpu_present_map = cpumask_of_cpu(0); if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); @@ -759,10 +759,10 @@ * Should not be necessary because the MP table should list the boot * CPU too, but we do it for the sake of robustness anyway. */ - if (!test_bit(boot_cpu_id, &phys_cpu_present_map)) { + if (!cpu_isset(boot_cpu_id, phys_cpu_present_map)) { printk(KERN_NOTICE "weird, boot CPU (#%d) not listed by the BIOS.\n", boot_cpu_id); - phys_cpu_present_map |= (1 << hard_smp_processor_id()); + cpu_set(hard_smp_processor_id(), phys_cpu_present_map); } /* @@ -773,8 +773,8 @@ boot_cpu_id); printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); io_apic_irqs = 0; - cpu_online_map = phys_cpu_present_map = 1; - phys_cpu_present_map = 1; + cpu_online_map = cpumask_of_cpu(0); + phys_cpu_present_map = cpumask_of_cpu(0); disable_apic = 1; goto smp_done; } @@ -788,8 +788,8 @@ smp_found_config = 0; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); io_apic_irqs = 0; - cpu_online_map = phys_cpu_present_map = 1; - phys_cpu_present_map = 1; + cpu_online_map = cpumask_of_cpu(0); + phys_cpu_present_map = cpumask_of_cpu(0); disable_apic = 1; goto smp_done; } @@ -812,7 +812,7 @@ if (apicid == boot_cpu_id) continue; - if (!(phys_cpu_present_map & (1 << apicid))) + if (!cpu_isset(apicid, phys_cpu_present_map)) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; @@ -848,7 +848,7 @@ } else { unsigned long bogosum = 0; for (cpu = 0; cpu < NR_CPUS; cpu++) - if (cpu_callout_map & (1<; + */ + +#include + +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +jiffies_64 = jiffies; +SECTIONS +{ + . = 0xffffffff80100000; + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x9090 + .text.lock : { *(.text.lock) } /* out-of-line lock text */ + + _etext = .; /* End of text section */ + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + _edata = .; /* End of data section */ + + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + __bss_end = .; + + . = ALIGN(64); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) } + __vsyscall_0 = LOADADDR(.vsyscall_0); + . = ALIGN(64); + .xtime_lock : AT ((LOADADDR(.vsyscall_0) + SIZEOF(.vsyscall_0) + 63) & ~(63)) { *(.xtime_lock) } + xtime_lock = LOADADDR(.xtime_lock); + . = ALIGN(16); + .vxtime : AT ((LOADADDR(.xtime_lock) + SIZEOF(.xtime_lock) + 15) & ~(15)) { *(.vxtime) } + vxtime = LOADADDR(.vxtime); + . = ALIGN(16); + .wall_jiffies : AT ((LOADADDR(.vxtime) + SIZEOF(.vxtime) + 15) & ~(15)) { *(.wall_jiffies) } + wall_jiffies = LOADADDR(.wall_jiffies); + . = ALIGN(16); + .sys_tz : AT ((LOADADDR(.wall_jiffies) + SIZEOF(.wall_jiffies) + 15) & ~(15)) { *(.sys_tz) } + sys_tz = LOADADDR(.sys_tz); + . = ALIGN(16); + .sysctl_vsyscall : AT ((LOADADDR(.sys_tz) + SIZEOF(.sys_tz) + 15) & ~(15)) { *(.sysctl_vsyscall) } + sysctl_vsyscall = LOADADDR(.sysctl_vsyscall); + . = ALIGN(16); + .jiffies : AT ((LOADADDR(.sysctl_vsyscall) + SIZEOF(.sysctl_vsyscall) + 15) & ~(15)) { *(.jiffies) } + jiffies = LOADADDR(.jiffies); + . = ALIGN(16); + .xtime : AT ((LOADADDR(.jiffies) + SIZEOF(.jiffies) + 15) & ~(15)) { *(.xtime) } + xtime = LOADADDR(.xtime); + .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) } + . = LOADADDR(.vsyscall_0) + 4096; + + . = ALIGN(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + .data.boot_pgt : { *(.data.boot_pgt) } + + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(32); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.data) + /* *(.exit.text) */ + *(.exitcall.exit) + *(.eh_frame) + } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .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) } + + + .comment 0 : { *(.comment) } +} diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c --- a/arch/x86_64/kernel/x8664_ksyms.c Mon Aug 18 22:21:01 2003 +++ b/arch/x86_64/kernel/x8664_ksyms.c Mon Aug 18 22:21:01 2003 @@ -121,6 +121,7 @@ EXPORT_SYMBOL(synchronize_irq); EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(cpu_callout_map); #endif #ifdef CONFIG_VT diff -Nru a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c --- a/arch/x86_64/mm/k8topology.c Mon Aug 18 22:21:06 2003 +++ b/arch/x86_64/mm/k8topology.c Mon Aug 18 22:21:06 2003 @@ -47,6 +47,7 @@ struct node nodes[MAXNODE]; int nodeid, i, nb; int found = 0; + int nmax; nb = find_northbridge(); if (nb < 0) @@ -54,22 +55,28 @@ printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); - numnodes = (1 << ((read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3)); - - printk(KERN_INFO "Assuming %d nodes\n", numnodes - 1); + nmax = (1 << ((read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3)); + numnodes = nmax; memset(&nodes,0,sizeof(nodes)); prevbase = 0; - for (i = 0; i < numnodes; i++) { + for (i = 0; i < 8; i++) { unsigned long base,limit; base = read_pci_config(0, nb, 1, 0x40 + i*8); limit = read_pci_config(0, nb, 1, 0x44 + i*8); nodeid = limit & 3; + if ((base & 3) == 0) { + if (i < nmax) + printk("Skipping disabled node %d\n", i); + continue; + } + if (!limit) { - printk(KERN_ERR "Skipping node entry %d (base %lx)\n", i, base); - return -1; + printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i, + base); + continue; } if ((base >> 8) & 3 || (limit >> 8) & 3) { printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n", @@ -77,7 +84,8 @@ return -1; } if ((1UL << nodeid) & nodes_present) { - printk(KERN_INFO "Node %d already present. Skipping\n", nodeid); + printk(KERN_INFO "Node %d already present. Skipping\n", + nodeid); continue; } @@ -104,7 +112,7 @@ if (limit < base) { printk(KERN_ERR "Node %d bogus settings %lx-%lx.\n", nodeid, base, limit); - return -1; + continue; } /* Could sort here, but pun for now. Should not happen anyroads. */ @@ -135,11 +143,26 @@ } printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); - for (i = 0; i < numnodes; i++) { + for (i = 0; i < MAXNODE; i++) { if (nodes[i].start != nodes[i].end) setup_node_bootmem(i, nodes[i].start, nodes[i].end); } + /* There are unfortunately some poorly designed mainboards around + that only connect memory to a single CPU. This breaks the 1:1 cpu->node + mapping. To avoid this fill in the mapping for all possible + CPUs, as the number of CPUs is not known yet. + We round robin the existing nodes. */ + int rr = 0; + for (i = 0; i < MAXNODE; i++) { + if (nodes_present & (1UL<> rr) == 0) + rr = 0; + rr = ffz(~nodes_present >> rr); + node_data[i] = node_data[rr]; + rr++; + } + return 0; } - diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c --- a/arch/x86_64/mm/numa.c Mon Aug 18 22:21:05 2003 +++ b/arch/x86_64/mm/numa.c Mon Aug 18 22:21:05 2003 @@ -26,8 +26,6 @@ unsigned long nodes_present; -static int emunodes __initdata; - int __init compute_hash_shift(struct node *nodes) { int i; @@ -103,11 +101,8 @@ reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages< numnodes) { + if (nodeid + 1 > numnodes) numnodes = nodeid + 1; - printk(KERN_INFO - "setup_node_bootmem: enlarging numnodes to %d\n", numnodes); - } nodes_present |= (1UL << nodeid); } @@ -149,26 +144,6 @@ printk(KERN_INFO "%s\n", numa_off ? "NUMA turned off" : "No NUMA configuration found"); - if (!numa_off && emunodes > 0) { - struct node nodes[MAXNODE]; - unsigned long nodesize = (end_pfn << PAGE_SHIFT) / emunodes; - int i; - if (emunodes > MAXNODE) - emunodes = MAXNODE; - memset(&nodes, 0, sizeof(nodes)); - printk(KERN_INFO "Faking %d nodes of size %ld MB\n", emunodes, nodesize>>20); - for (i = 0; i < emunodes; i++) { - unsigned long end = (i+1)*nodesize; - if (i == emunodes-1) - end = end_pfn << PAGE_SHIFT; - nodes[i].start = i * nodesize; - nodes[i].end = end; - setup_node_bootmem(i, nodes[i].start, nodes[i].end); - } - memnode_shift = compute_hash_shift(nodes); - return 0; - } - printk(KERN_INFO "Faking a node at %016lx-%016lx\n", start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); @@ -176,6 +151,7 @@ fake_node = 1; memnode_shift = 63; memnodemap[0] = 0; + numnodes = 1; setup_node_bootmem(0, start_pfn<; - */ - -#include - -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -jiffies_64 = jiffies; -SECTIONS -{ - . = 0xffffffff80100000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ - - _etext = .; /* End of text section */ - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - RODATA - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - _edata = .; /* End of data section */ - - __bss_start = .; /* BSS */ - .bss : { - *(.bss) - } - __bss_end = .; - - . = ALIGN(64); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) } - __vsyscall_0 = LOADADDR(.vsyscall_0); - . = ALIGN(64); - .xtime_lock : AT ((LOADADDR(.vsyscall_0) + SIZEOF(.vsyscall_0) + 63) & ~(63)) { *(.xtime_lock) } - xtime_lock = LOADADDR(.xtime_lock); - . = ALIGN(16); - .vxtime : AT ((LOADADDR(.xtime_lock) + SIZEOF(.xtime_lock) + 15) & ~(15)) { *(.vxtime) } - vxtime = LOADADDR(.vxtime); - . = ALIGN(16); - .wall_jiffies : AT ((LOADADDR(.vxtime) + SIZEOF(.vxtime) + 15) & ~(15)) { *(.wall_jiffies) } - wall_jiffies = LOADADDR(.wall_jiffies); - . = ALIGN(16); - .sys_tz : AT ((LOADADDR(.wall_jiffies) + SIZEOF(.wall_jiffies) + 15) & ~(15)) { *(.sys_tz) } - sys_tz = LOADADDR(.sys_tz); - . = ALIGN(16); - .sysctl_vsyscall : AT ((LOADADDR(.sys_tz) + SIZEOF(.sys_tz) + 15) & ~(15)) { *(.sysctl_vsyscall) } - sysctl_vsyscall = LOADADDR(.sysctl_vsyscall); - . = ALIGN(16); - .jiffies : AT ((LOADADDR(.sysctl_vsyscall) + SIZEOF(.sysctl_vsyscall) + 15) & ~(15)) { *(.jiffies) } - jiffies = LOADADDR(.jiffies); - . = ALIGN(16); - .xtime : AT ((LOADADDR(.jiffies) + SIZEOF(.jiffies) + 15) & ~(15)) { *(.xtime) } - xtime = LOADADDR(.xtime); - .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) } - . = LOADADDR(.vsyscall_0) + 4096; - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); - .data.boot_pgt : { *(.data.boot_pgt) } - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(32); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.data) - /* *(.exit.text) */ - *(.exitcall.exit) - *(.eh_frame) - } - - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info) } - .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) } - - - .comment 0 : { *(.comment) } -} diff -Nru a/crypto/Kconfig b/crypto/Kconfig --- a/crypto/Kconfig Mon Aug 18 22:21:06 2003 +++ b/crypto/Kconfig Mon Aug 18 22:21:06 2003 @@ -126,6 +126,20 @@ See http://csrc.nist.gov/encryption/aes/ for more information. +config CRYPTO_CAST5 + tristate "CAST5 (CAST-128) cipher algorithm" + depends on CRYPTO + help + The CAST5 encryption algorithm (synonymous with CAST-128) is + described in RFC2144. + +config CRYPTO_CAST6 + tristate "CAST6 (CAST-256) cipher algorithm" + depends on CRYPTO + help + The CAST6 encryption algorithm (synonymous with CAST-256) is + described in RFC2612. + config CRYPTO_DEFLATE tristate "Deflate compression algorithm" depends on CRYPTO diff -Nru a/crypto/Makefile b/crypto/Makefile --- a/crypto/Makefile Mon Aug 18 22:21:06 2003 +++ b/crypto/Makefile Mon Aug 18 22:21:06 2003 @@ -20,6 +20,8 @@ obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o obj-$(CONFIG_CRYPTO_AES) += aes.o +obj-$(CONFIG_CRYPTO_CAST5) += cast5.o +obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -Nru a/crypto/aes.c b/crypto/aes.c --- a/crypto/aes.c Mon Aug 18 22:21:03 2003 +++ b/crypto/aes.c Mon Aug 18 22:21:03 2003 @@ -442,7 +442,6 @@ .cipher = { .cia_min_keysize = AES_MIN_KEY_SIZE, .cia_max_keysize = AES_MAX_KEY_SIZE, - .cia_ivsize = AES_BLOCK_SIZE, .cia_setkey = aes_set_key, .cia_encrypt = aes_encrypt, .cia_decrypt = aes_decrypt diff -Nru a/crypto/blowfish.c b/crypto/blowfish.c --- a/crypto/blowfish.c Mon Aug 18 22:21:01 2003 +++ b/crypto/blowfish.c Mon Aug 18 22:21:01 2003 @@ -456,7 +456,6 @@ .cra_u = { .cipher = { .cia_min_keysize = BF_MIN_KEY_SIZE, .cia_max_keysize = BF_MAX_KEY_SIZE, - .cia_ivsize = BF_BLOCK_SIZE, .cia_setkey = bf_setkey, .cia_encrypt = bf_encrypt, .cia_decrypt = bf_decrypt } } diff -Nru a/crypto/cast5.c b/crypto/cast5.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/crypto/cast5.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,851 @@ +/* Kernel cryptographic api. +* cast5.c - Cast5 cipher algorithm (rfc2144). +* +* Derived from GnuPG implementation of cast5. +* +* Major Changes. +* Complete conformance to rfc2144. +* Supports key size from 40 to 128 bits. +* +* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +* Copyright (C) 2003 Kartikey Mahendra Bhatt . +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of GNU General Public License as published by the Free +* Software Foundation; either version 2 of the License, or (at your option) +* any later version. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +*/ + + +#include +#include +#include +#include +#include + +#define CAST5_BLOCK_SIZE 8 +#define CAST5_MIN_KEY_SIZE 5 +#define CAST5_MAX_KEY_SIZE 16 + +struct cast5_ctx { + u32 Km[16]; + u8 Kr[16]; + int rr; /* rr?number of rounds = 16:number of rounds = 12; (rfc 2144) */ +}; + + +static const u32 s1[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, + 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, + 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, + 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, + 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, + 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, + 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, + 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, + 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, + 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, + 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, + 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, + 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, + 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, + 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, + 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, + 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, + 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, + 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, + 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, + 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, + 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, + 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, + 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, + 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, + 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, + 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, + 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, + 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, + 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, + 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, + 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, + 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf +}; +static const u32 s2[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, + 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, + 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, + 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, + 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, + 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, + 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, + 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, + 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, + 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, + 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, + 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, + 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, + 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, + 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, + 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, + 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, + 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, + 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, + 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, + 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, + 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, + 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, + 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, + 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, + 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, + 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, + 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, + 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, + 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, + 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, + 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, + 0x73bfbe70, 0x83877605, 0x4523ecf1 +}; +static const u32 s3[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, + 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, + 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, + 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, + 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, + 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, + 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, + 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, + 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, + 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, + 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, + 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, + 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, + 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, + 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, + 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, + 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, + 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, + 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, + 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, + 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, + 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, + 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, + 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, + 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, + 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, + 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, + 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, + 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, + 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, + 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, + 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, + 0xa133c501, 0xe9d3531c, 0xee353783 +}; +static const u32 s4[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, + 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, + 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, + 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, + 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, + 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, + 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, + 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, + 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, + 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, + 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, + 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, + 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, + 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, + 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, + 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, + 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, + 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, + 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, + 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, + 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, + 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, + 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, + 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, + 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, + 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, + 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, + 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, + 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, + 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, + 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, + 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, + 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 +}; +static const u32 s5[256] = { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, + 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, + 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, + 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, + 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, + 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, + 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, + 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, + 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, + 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, + 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, + 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, + 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, + 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, + 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, + 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, + 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, + 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, + 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, + 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, + 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, + 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, + 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, + 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, + 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, + 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, + 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, + 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, + 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, + 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, + 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, + 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, + 0xb1534546, 0x6d47de08, 0xefe9e7d4 +}; +static const u32 s6[256] = { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, + 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, + 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, + 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, + 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, + 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, + 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, + 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, + 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, + 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, + 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, + 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, + 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, + 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, + 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, + 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, + 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, + 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, + 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, + 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, + 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, + 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, + 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, + 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, + 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, + 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, + 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, + 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, + 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, + 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, + 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, + 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, + 0xa65b1db8, 0x851c97bd, 0xd675cf2f +}; +static const u32 s7[256] = { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, + 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, + 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, + 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, + 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, + 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, + 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, + 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, + 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, + 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, + 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, + 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, + 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, + 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, + 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, + 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, + 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, + 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, + 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, + 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, + 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, + 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, + 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, + 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, + 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, + 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, + 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, + 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, + 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, + 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, + 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, + 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, + 0x94e01be8, 0x90716f4b, 0x954b8aa3 +}; +static const u32 sb8[256] = { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, + 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, + 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, + 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, + 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, + 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, + 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, + 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, + 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, + 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, + 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, + 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, + 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, + 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, + 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, + 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, + 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, + 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, + 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, + 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, + 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, + 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, + 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, + 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, + 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, + 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, + 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, + 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, + 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, + 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, + 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, + 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, + 0xeaee6801, 0x8db2a283, 0xea8bf59e +}; + + +#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) ) + +#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \ + (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) ) +#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \ + (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) ) +#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \ + (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) ) + + +static void cast5_encrypt(void *ctx, u8 * outbuf, const u8 * inbuf) +{ + struct cast5_ctx *c = (struct cast5_ctx *) ctx; + u32 l, r, t; + u32 I; /* used by the Fx macros */ + u32 *Km; + u8 *Kr; + + Km = c->Km; + Kr = c->Kr; + + /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and + * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.) + */ + l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + + /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows: + * Li = Ri-1; + * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2 + * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1. + * Rounds 2, 5, 8, 11, and 14 use f function Type 2. + * Rounds 3, 6, 9, 12, and 15 use f function Type 3. + */ + + if (!(c->rr)) { + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); + t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); + t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); + t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); + t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); + } else { + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); + } + + /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and + * concatenate to form the ciphertext.) */ + outbuf[0] = (r >> 24) & 0xff; + outbuf[1] = (r >> 16) & 0xff; + outbuf[2] = (r >> 8) & 0xff; + outbuf[3] = r & 0xff; + outbuf[4] = (l >> 24) & 0xff; + outbuf[5] = (l >> 16) & 0xff; + outbuf[6] = (l >> 8) & 0xff; + outbuf[7] = l & 0xff; +} + +static void cast5_decrypt(void *ctx, u8 * outbuf, const u8 * inbuf) +{ + struct cast5_ctx *c = (struct cast5_ctx *) ctx; + u32 l, r, t; + u32 I; + u32 *Km; + u8 *Kr; + + Km = c->Km; + Kr = c->Kr; + + l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + + if (!(c->rr)) { + t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); + t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); + t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); + t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); + } else { + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); + } + + outbuf[0] = (r >> 24) & 0xff; + outbuf[1] = (r >> 16) & 0xff; + outbuf[2] = (r >> 8) & 0xff; + outbuf[3] = r & 0xff; + outbuf[4] = (l >> 24) & 0xff; + outbuf[5] = (l >> 16) & 0xff; + outbuf[6] = (l >> 8) & 0xff; + outbuf[7] = l & 0xff; +} + +static void key_schedule(u32 * x, u32 * z, u32 * k) +{ + +#define xi(i) ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff) +#define zi(i) ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff) + + z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^ + s7[xi(8)]; + z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^ + sb8[xi(10)]; + z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^ + s5[xi(9)]; + z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^ + s6[xi(11)]; + k[0] = s5[zi(8)] ^ s6[zi(9)] ^ s7[zi(7)] ^ sb8[zi(6)] ^ s5[zi(2)]; + k[1] = s5[zi(10)] ^ s6[zi(11)] ^ s7[zi(5)] ^ sb8[zi(4)] ^ + s6[zi(6)]; + k[2] = s5[zi(12)] ^ s6[zi(13)] ^ s7[zi(3)] ^ sb8[zi(2)] ^ + s7[zi(9)]; + k[3] = s5[zi(14)] ^ s6[zi(15)] ^ s7[zi(1)] ^ sb8[zi(0)] ^ + sb8[zi(12)]; + + x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^ + s7[zi(0)]; + x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^ + sb8[zi(2)]; + x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^ + s5[zi(1)]; + x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^ + s6[zi(3)]; + k[4] = s5[xi(3)] ^ s6[xi(2)] ^ s7[xi(12)] ^ sb8[xi(13)] ^ + s5[xi(8)]; + k[5] = s5[xi(1)] ^ s6[xi(0)] ^ s7[xi(14)] ^ sb8[xi(15)] ^ + s6[xi(13)]; + k[6] = s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(8)] ^ sb8[xi(9)] ^ s7[xi(3)]; + k[7] = s5[xi(5)] ^ s6[xi(4)] ^ s7[xi(10)] ^ sb8[xi(11)] ^ + sb8[xi(7)]; + + z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^ + s7[xi(8)]; + z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^ + sb8[xi(10)]; + z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^ + s5[xi(9)]; + z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^ + s6[xi(11)]; + k[8] = s5[zi(3)] ^ s6[zi(2)] ^ s7[zi(12)] ^ sb8[zi(13)] ^ + s5[zi(9)]; + k[9] = s5[zi(1)] ^ s6[zi(0)] ^ s7[zi(14)] ^ sb8[zi(15)] ^ + s6[zi(12)]; + k[10] = s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(8)] ^ sb8[zi(9)] ^ s7[zi(2)]; + k[11] = s5[zi(5)] ^ s6[zi(4)] ^ s7[zi(10)] ^ sb8[zi(11)] ^ + sb8[zi(6)]; + + x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^ + s7[zi(0)]; + x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^ + sb8[zi(2)]; + x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^ + s5[zi(1)]; + x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^ + s6[zi(3)]; + k[12] = s5[xi(8)] ^ s6[xi(9)] ^ s7[xi(7)] ^ sb8[xi(6)] ^ s5[xi(3)]; + k[13] = s5[xi(10)] ^ s6[xi(11)] ^ s7[xi(5)] ^ sb8[xi(4)] ^ + s6[xi(7)]; + k[14] = s5[xi(12)] ^ s6[xi(13)] ^ s7[xi(3)] ^ sb8[xi(2)] ^ + s7[xi(8)]; + k[15] = s5[xi(14)] ^ s6[xi(15)] ^ s7[xi(1)] ^ sb8[xi(0)] ^ + sb8[xi(13)]; + +#undef xi +#undef zi +} + + +static int +cast5_setkey(void *ctx, const u8 * key, unsigned key_len, u32 * flags) +{ + int i; + u32 x[4]; + u32 z[4]; + u32 k[16]; + u8 p_key[16]; + struct cast5_ctx *c = (struct cast5_ctx *) ctx; + + if (key_len < 5 || key_len > 16) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + c->rr = key_len <= 10 ? 1 : 0; + + memset(p_key, 0, 16); + memcpy(p_key, key, key_len); + + + x[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3]; + x[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7]; + x[2] = + p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11]; + x[3] = + p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15]; + + key_schedule(x, z, k); + for (i = 0; i < 16; i++) + c->Km[i] = k[i]; + key_schedule(x, z, k); + for (i = 0; i < 16; i++) + c->Kr[i] = k[i] & 0x1f; + return 0; +} + +static struct crypto_alg alg = { + .cra_name = "cast5", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = CAST5_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct cast5_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = CAST5_MIN_KEY_SIZE, + .cia_max_keysize = CAST5_MAX_KEY_SIZE, + .cia_setkey = cast5_setkey, + .cia_encrypt = cast5_encrypt, + .cia_decrypt = cast5_decrypt + } + } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cast5 Cipher Algorithm"); + diff -Nru a/crypto/cast6.c b/crypto/cast6.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/crypto/cast6.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,562 @@ +/* Kernel cryptographic api. + * cast6.c - Cast6 cipher algorithm [rfc2612]. + * + * CAST-256 (*cast6*) is a DES like Substitution-Permutation Network (SPN) + * cryptosystem built upon the CAST-128 (*cast5*) [rfc2144] encryption + * algorithm. + * + * Copyright (C) 2003 Kartikey Mahendra Bhatt . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include +#include +#include +#include +#include + +#define CAST6_BLOCK_SIZE 16 +#define CAST6_MIN_KEY_SIZE 16 +#define CAST6_MAX_KEY_SIZE 32 + +struct cast6_ctx { + u32 Km[12][4]; + u8 Kr[12][4]; +}; + +#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) ) + +#define F1(D,r,m) ( (I = ((m) + (D))), (I=rol((r),I)), \ + (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) ) +#define F2(D,r,m) ( (I = ((m) ^ (D))), (I=rol((r),I)), \ + (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) ) +#define F3(D,r,m) ( (I = ((m) - (D))), (I=rol((r),I)), \ + (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) ) + +static const u32 s1[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, + 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, + 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, + 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, + 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, + 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, + 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, + 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, + 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, + 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, + 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, + 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, + 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, + 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, + 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, + 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, + 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, + 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, + 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, + 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, + 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, + 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, + 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, + 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, + 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, + 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, + 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, + 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, + 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, + 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, + 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, + 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, + 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf +}; + +static const u32 s2[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, + 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, + 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, + 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, + 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, + 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, + 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, + 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, + 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, + 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, + 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, + 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, + 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, + 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, + 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, + 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, + 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, + 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, + 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, + 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, + 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, + 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, + 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, + 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, + 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, + 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, + 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, + 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, + 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, + 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, + 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, + 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, + 0x73bfbe70, 0x83877605, 0x4523ecf1 +}; + +static const u32 s3[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, + 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, + 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, + 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, + 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, + 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, + 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, + 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, + 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, + 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, + 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, + 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, + 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, + 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, + 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, + 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, + 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, + 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, + 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, + 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, + 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, + 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, + 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, + 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, + 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, + 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, + 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, + 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, + 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, + 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, + 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, + 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, + 0xa133c501, 0xe9d3531c, 0xee353783 +}; + +static const u32 s4[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, + 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, + 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, + 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, + 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, + 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, + 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, + 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, + 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, + 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, + 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, + 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, + 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, + 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, + 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, + 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, + 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, + 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, + 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, + 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, + 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, + 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, + 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, + 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, + 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, + 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, + 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, + 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, + 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, + 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, + 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, + 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, + 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 +}; + +static const u32 Tm[24][8] = { + { 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d, + 0x84c413be, 0xf39dff5f, 0x6277eb00 } , + { 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525, + 0xfb9370c6, 0x6a6d5c67, 0xd9474808 } , + { 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d, + 0x7262cdce, 0xe13cb96f, 0x5016a510 } , + { 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35, + 0xe9322ad6, 0x580c1677, 0xc6e60218 } , + { 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d, + 0x600187de, 0xcedb737f, 0x3db55f20 } , + { 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945, + 0xd6d0e4e6, 0x45aad087, 0xb484bc28 } , + { 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d, + 0x4da041ee, 0xbc7a2d8f, 0x2b541930 } , + { 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355, + 0xc46f9ef6, 0x33498a97, 0xa2237638 } , + { 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d, + 0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } , + { 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65, + 0xb20e5906, 0x20e844a7, 0x8fc23048 } , + { 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d, + 0x28ddb60e, 0x97b7a1af, 0x06918d50 } , + { 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775, + 0x9fad1316, 0x0e86feb7, 0x7d60ea58 } , + { 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d, + 0x167c701e, 0x85565bbf, 0xf4304760 } , + { 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185, + 0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } , + { 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d, + 0x041b2a2e, 0x72f515cf, 0xe1cf0170 } , + { 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95, + 0x7aea8736, 0xe9c472d7, 0x589e5e78 } , + { 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d, + 0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } , + { 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5, + 0x68894146, 0xd7632ce7, 0x463d1888 } , + { 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad, + 0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } , + { 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5, + 0x5627fb56, 0xc501e6f7, 0x33dbd298 } , + { 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd, + 0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } , + { 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5, + 0x43c6b566, 0xb2a0a107, 0x217a8ca8 } , + { 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd, + 0xba96126e, 0x296ffe0f, 0x9849e9b0 } , + { 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5, + 0x31656f76, 0xa03f5b17, 0x0f1946b8 } +}; + +static const u8 Tr[4][8] = { + { 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } , + { 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } , + { 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } , + { 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 } +}; + +/* forward octave */ +static inline void W(u32 *key, unsigned int i) { + u32 I; + key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]); + key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]); + key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]); + key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]); + key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]); + key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]); + key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]); + key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]); +} + +static int +cast6_setkey(void *ctx, const u8 * in_key, unsigned key_len, u32 * flags) +{ + int i; + u32 key[8]; + u8 p_key[32]; /* padded key */ + struct cast6_ctx *c = (struct cast6_ctx *) ctx; + + if (key_len < 16 || key_len > 32 || key_len % 4 != 0) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + memset (p_key, 0, 32); + memcpy (p_key, in_key, key_len); + + key[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3]; /* A */ + key[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7]; /* B */ + key[2] = p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11]; /* C */ + key[3] = p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15]; /* D */ + key[4] = p_key[16] << 24 | p_key[17] << 16 | p_key[18] << 8 | p_key[19]; /* E */ + key[5] = p_key[20] << 24 | p_key[21] << 16 | p_key[22] << 8 | p_key[23]; /* F */ + key[6] = p_key[24] << 24 | p_key[25] << 16 | p_key[26] << 8 | p_key[27]; /* G */ + key[7] = p_key[28] << 24 | p_key[29] << 16 | p_key[30] << 8 | p_key[31]; /* H */ + + + + for (i = 0; i < 12; i++) { + W (key, 2 * i); + W (key, 2 * i + 1); + + c->Kr[i][0] = key[0] & 0x1f; + c->Kr[i][1] = key[2] & 0x1f; + c->Kr[i][2] = key[4] & 0x1f; + c->Kr[i][3] = key[6] & 0x1f; + + c->Km[i][0] = key[7]; + c->Km[i][1] = key[5]; + c->Km[i][2] = key[3]; + c->Km[i][3] = key[1]; + } + + return 0; +} + +/*forward quad round*/ +static inline void Q (u32 * block, u8 * Kr, u32 * Km) { + u32 I; + block[2] ^= F1(block[3], Kr[0], Km[0]); + block[1] ^= F2(block[2], Kr[1], Km[1]); + block[0] ^= F3(block[1], Kr[2], Km[2]); + block[3] ^= F1(block[0], Kr[3], Km[3]); +} + +/*reverse quad round*/ +static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) { + u32 I; + block[3] ^= F1(block[0], Kr[3], Km[3]); + block[0] ^= F3(block[1], Kr[2], Km[2]); + block[1] ^= F2(block[2], Kr[1], Km[1]); + block[2] ^= F1(block[3], Kr[0], Km[0]); +} + +static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) { + struct cast6_ctx * c = (struct cast6_ctx *)ctx; + u32 block[4]; + u32 * Km; + u8 * Kr; + + block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11]; + block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15]; + + Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km); + Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km); + Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km); + Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km); + Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km); + Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km); + Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km); + Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km); + Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km); + Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km); + Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km); + Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km); + + outbuf[0] = (block[0] >> 24) & 0xff; + outbuf[1] = (block[0] >> 16) & 0xff; + outbuf[2] = (block[0] >> 8) & 0xff; + outbuf[3] = block[0] & 0xff; + outbuf[4] = (block[1] >> 24) & 0xff; + outbuf[5] = (block[1] >> 16) & 0xff; + outbuf[6] = (block[1] >> 8) & 0xff; + outbuf[7] = block[1] & 0xff; + outbuf[8] = (block[2] >> 24) & 0xff; + outbuf[9] = (block[2] >> 16) & 0xff; + outbuf[10] = (block[2] >> 8) & 0xff; + outbuf[11] = block[2] & 0xff; + outbuf[12] = (block[3] >> 24) & 0xff; + outbuf[13] = (block[3] >> 16) & 0xff; + outbuf[14] = (block[3] >> 8) & 0xff; + outbuf[15] = block[3] & 0xff; +} + +static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) { + struct cast6_ctx * c = (struct cast6_ctx *)ctx; + u32 block[4]; + u32 * Km; + u8 * Kr; + + block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11]; + block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15]; + + Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km); + Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km); + Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km); + Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km); + Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km); + Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km); + Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km); + Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km); + Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km); + Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km); + Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km); + Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km); + + outbuf[0] = (block[0] >> 24) & 0xff; + outbuf[1] = (block[0] >> 16) & 0xff; + outbuf[2] = (block[0] >> 8) & 0xff; + outbuf[3] = block[0] & 0xff; + outbuf[4] = (block[1] >> 24) & 0xff; + outbuf[5] = (block[1] >> 16) & 0xff; + outbuf[6] = (block[1] >> 8) & 0xff; + outbuf[7] = block[1] & 0xff; + outbuf[8] = (block[2] >> 24) & 0xff; + outbuf[9] = (block[2] >> 16) & 0xff; + outbuf[10] = (block[2] >> 8) & 0xff; + outbuf[11] = block[2] & 0xff; + outbuf[12] = (block[3] >> 24) & 0xff; + outbuf[13] = (block[3] >> 16) & 0xff; + outbuf[14] = (block[3] >> 8) & 0xff; + outbuf[15] = block[3] & 0xff; +} + +static struct crypto_alg alg = { + .cra_name = "cast6", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = CAST6_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct cast6_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = CAST6_MIN_KEY_SIZE, + .cia_max_keysize = CAST6_MAX_KEY_SIZE, + .cia_setkey = cast6_setkey, + .cia_encrypt = cast6_encrypt, + .cia_decrypt = cast6_decrypt} + } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cast6 Cipher Algorithm"); diff -Nru a/crypto/cipher.c b/crypto/cipher.c --- a/crypto/cipher.c Mon Aug 18 22:21:03 2003 +++ b/crypto/cipher.c Mon Aug 18 22:21:03 2003 @@ -345,7 +345,6 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) { int ret = 0; - struct crypto_alg *alg = tfm->__crt_alg; struct cipher_tfm *ops = &tfm->crt_cipher; ops->cit_setkey = setkey; @@ -381,8 +380,7 @@ BUG(); } - if (alg->cra_cipher.cia_ivsize && - ops->cit_mode != CRYPTO_TFM_MODE_ECB) { + if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { switch (crypto_tfm_alg_blocksize(tfm)) { case 8: @@ -401,7 +399,8 @@ goto out; } - ops->cit_iv = kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL); + ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); + ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL); if (ops->cit_iv == NULL) ret = -ENOMEM; } diff -Nru a/crypto/crypto_null.c b/crypto/crypto_null.c --- a/crypto/crypto_null.c Mon Aug 18 22:21:03 2003 +++ b/crypto/crypto_null.c Mon Aug 18 22:21:03 2003 @@ -89,7 +89,6 @@ .cra_u = { .cipher = { .cia_min_keysize = NULL_KEY_SIZE, .cia_max_keysize = NULL_KEY_SIZE, - .cia_ivsize = 0, .cia_setkey = null_setkey, .cia_encrypt = null_encrypt, .cia_decrypt = null_decrypt } } diff -Nru a/crypto/des.c b/crypto/des.c --- a/crypto/des.c Mon Aug 18 22:21:06 2003 +++ b/crypto/des.c Mon Aug 18 22:21:06 2003 @@ -1249,7 +1249,6 @@ .cra_u = { .cipher = { .cia_min_keysize = DES_KEY_SIZE, .cia_max_keysize = DES_KEY_SIZE, - .cia_ivsize = DES_BLOCK_SIZE, .cia_setkey = des_setkey, .cia_encrypt = des_encrypt, .cia_decrypt = des_decrypt } } @@ -1265,7 +1264,6 @@ .cra_u = { .cipher = { .cia_min_keysize = DES3_EDE_KEY_SIZE, .cia_max_keysize = DES3_EDE_KEY_SIZE, - .cia_ivsize = DES3_EDE_BLOCK_SIZE, .cia_setkey = des3_ede_setkey, .cia_encrypt = des3_ede_encrypt, .cia_decrypt = des3_ede_decrypt } } diff -Nru a/crypto/hmac.c b/crypto/hmac.c --- a/crypto/hmac.c Mon Aug 18 22:21:03 2003 +++ b/crypto/hmac.c Mon Aug 18 22:21:03 2003 @@ -26,7 +26,7 @@ struct scatterlist tmp; tmp.page = virt_to_page(key); - tmp.offset = ((long)key & ~PAGE_MASK); + tmp.offset = offset_in_page(key); tmp.length = keylen; crypto_digest_digest(tfm, &tmp, 1, key); @@ -71,7 +71,7 @@ ipad[i] ^= 0x36; tmp.page = virt_to_page(ipad); - tmp.offset = ((long)ipad & ~PAGE_MASK); + tmp.offset = offset_in_page(ipad); tmp.length = crypto_tfm_alg_blocksize(tfm); crypto_digest_init(tfm); @@ -105,14 +105,14 @@ opad[i] ^= 0x5c; tmp.page = virt_to_page(opad); - tmp.offset = ((long)opad & ~PAGE_MASK); + tmp.offset = offset_in_page(opad); tmp.length = crypto_tfm_alg_blocksize(tfm); crypto_digest_init(tfm); crypto_digest_update(tfm, &tmp, 1); tmp.page = virt_to_page(out); - tmp.offset = ((long)out & ~PAGE_MASK); + tmp.offset = offset_in_page(out); tmp.length = crypto_tfm_alg_digestsize(tfm); crypto_digest_update(tfm, &tmp, 1); diff -Nru a/crypto/proc.c b/crypto/proc.c --- a/crypto/proc.c Mon Aug 18 22:21:02 2003 +++ b/crypto/proc.c Mon Aug 18 22:21:02 2003 @@ -62,8 +62,6 @@ alg->cra_cipher.cia_min_keysize); seq_printf(m, "max keysize : %u\n", alg->cra_cipher.cia_max_keysize); - seq_printf(m, "ivsize : %u\n", - alg->cra_cipher.cia_ivsize); break; case CRYPTO_ALG_TYPE_DIGEST: diff -Nru a/crypto/serpent.c b/crypto/serpent.c --- a/crypto/serpent.c Mon Aug 18 22:21:02 2003 +++ b/crypto/serpent.c Mon Aug 18 22:21:02 2003 @@ -483,7 +483,6 @@ .cra_u = { .cipher = { .cia_min_keysize = SERPENT_MIN_KEY_SIZE, .cia_max_keysize = SERPENT_MAX_KEY_SIZE, - .cia_ivsize = SERPENT_BLOCK_SIZE, .cia_setkey = setkey, .cia_encrypt = encrypt, .cia_decrypt = decrypt } } diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Mon Aug 18 22:21:05 2003 +++ b/crypto/tcrypt.c Mon Aug 18 22:21:05 2003 @@ -48,8 +48,8 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", - "twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate", - NULL + "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", + "deflate", NULL }; static void @@ -96,7 +96,7 @@ p = md5_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(md5_tv[i].plaintext); crypto_digest_init(tfm); @@ -119,12 +119,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 13; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 13; memset(result, 0, sizeof (result)); @@ -173,7 +173,7 @@ p = hmac_md5_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(hmac_md5_tv[i].plaintext); klen = strlen(hmac_md5_tv[i].key); @@ -195,12 +195,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 16; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 12; memset(result, 0, sizeof (result)); @@ -250,7 +250,7 @@ p = hmac_sha1_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(hmac_sha1_tv[i].plaintext); klen = strlen(hmac_sha1_tv[i].key); @@ -274,12 +274,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 16; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 12; memset(result, 0, sizeof (result)); @@ -329,7 +329,7 @@ p = hmac_sha256_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(hmac_sha256_tv[i].plaintext); klen = strlen(hmac_sha256_tv[i].key); @@ -383,7 +383,7 @@ p = md4_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(md4_tv[i].plaintext); crypto_digest_digest(tfm, sg, 1, result); @@ -433,7 +433,7 @@ p = sha1_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(sha1_tv[i].plaintext); crypto_digest_init(tfm); @@ -456,12 +456,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 28; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 28; memset(result, 0, sizeof (result)); @@ -508,7 +508,7 @@ p = sha256_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(sha256_tv[i].plaintext); crypto_digest_init(tfm); @@ -531,12 +531,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 28; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 28; memset(result, 0, sizeof (result)); @@ -584,7 +584,7 @@ p = sha384_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(sha384_tv[i].plaintext); crypto_digest_init(tfm); @@ -636,7 +636,7 @@ p = sha512_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = strlen(sha512_tv[i].plaintext); crypto_digest_init(tfm); @@ -701,7 +701,7 @@ p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = len; ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { @@ -738,12 +738,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 8; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 8; ret = crypto_cipher_encrypt(tfm, sg, sg, 16); @@ -801,17 +801,17 @@ p = &xbuf[IDX3]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 14; p = &xbuf[IDX4]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 10; p = &xbuf[IDX5]; sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].offset = offset_in_page(p); sg[2].length = 8; ret = crypto_cipher_encrypt(tfm, sg, sg, 32); @@ -872,22 +872,22 @@ p = &xbuf[IDX3]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 2; p = &xbuf[IDX4]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 1; p = &xbuf[IDX5]; sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].offset = offset_in_page(p); sg[2].length = 3; p = &xbuf[IDX6]; sg[3].page = virt_to_page(p); - sg[3].offset = ((long) p & ~PAGE_MASK); + sg[3].offset = offset_in_page(p); sg[3].length = 18; ret = crypto_cipher_encrypt(tfm, sg, sg, 24); @@ -956,27 +956,27 @@ p = &xbuf[IDX3]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 2; p = &xbuf[IDX4]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 2; p = &xbuf[IDX5]; sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].offset = offset_in_page(p); sg[2].length = 2; p = &xbuf[IDX6]; sg[3].page = virt_to_page(p); - sg[3].offset = ((long) p & ~PAGE_MASK); + sg[3].offset = offset_in_page(p); sg[3].length = 2; p = &xbuf[IDX7]; sg[4].page = virt_to_page(p); - sg[4].offset = ((long) p & ~PAGE_MASK); + sg[4].offset = offset_in_page(p); sg[4].length = 8; ret = crypto_cipher_encrypt(tfm, sg, sg, 16); @@ -1040,42 +1040,42 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 1; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 1; p = &xbuf[IDX3]; sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].offset = offset_in_page(p); sg[2].length = 1; p = &xbuf[IDX4]; sg[3].page = virt_to_page(p); - sg[3].offset = ((long) p & ~PAGE_MASK); + sg[3].offset = offset_in_page(p); sg[3].length = 1; p = &xbuf[IDX5]; sg[4].page = virt_to_page(p); - sg[4].offset = ((long) p & ~PAGE_MASK); + sg[4].offset = offset_in_page(p); sg[4].length = 1; p = &xbuf[IDX6]; sg[5].page = virt_to_page(p); - sg[5].offset = ((long) p & ~PAGE_MASK); + sg[5].offset = offset_in_page(p); sg[5].length = 1; p = &xbuf[IDX7]; sg[6].page = virt_to_page(p); - sg[6].offset = ((long) p & ~PAGE_MASK); + sg[6].offset = offset_in_page(p); sg[6].length = 1; p = &xbuf[IDX8]; sg[7].page = virt_to_page(p); - sg[7].offset = ((long) p & ~PAGE_MASK); + sg[7].offset = offset_in_page(p); sg[7].length = 1; ret = crypto_cipher_encrypt(tfm, sg, sg, 8); @@ -1117,7 +1117,7 @@ p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = len; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); @@ -1155,12 +1155,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 8; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 8; ret = crypto_cipher_decrypt(tfm, sg, sg, 16); @@ -1207,17 +1207,17 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 3; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 12; p = &xbuf[IDX3]; sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); + sg[2].offset = offset_in_page(p); sg[2].length = 1; ret = crypto_cipher_decrypt(tfm, sg, sg, 16); @@ -1284,7 +1284,7 @@ p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = len; crypto_cipher_set_iv(tfm, des_tv[i].iv, @@ -1339,12 +1339,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 13; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 11; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); @@ -1392,7 +1392,7 @@ p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = len; crypto_cipher_set_iv(tfm, des_tv[i].iv, @@ -1440,12 +1440,12 @@ p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = 4; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); + sg[1].offset = offset_in_page(p); sg[1].length = 4; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); @@ -1516,7 +1516,7 @@ p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = len; ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { @@ -1559,7 +1559,7 @@ p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = len; ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { @@ -1622,7 +1622,7 @@ p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = bf_tv[i].plen; ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -1664,7 +1664,7 @@ p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = bf_tv[i].plen; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -1713,7 +1713,7 @@ p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = bf_tv[i].plen; crypto_cipher_set_iv(tfm, bf_tv[i].iv, @@ -1758,7 +1758,7 @@ p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = bf_tv[i].plen; crypto_cipher_set_iv(tfm, bf_tv[i].iv, @@ -1827,7 +1827,7 @@ p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = tf_tv[i].plen; ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -1869,7 +1869,7 @@ p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = tf_tv[i].plen; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -1918,7 +1918,7 @@ p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = tf_tv[i].plen; crypto_cipher_set_iv(tfm, tf_tv[i].iv, @@ -1964,7 +1964,7 @@ p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = tf_tv[i].plen; crypto_cipher_set_iv(tfm, tf_tv[i].iv, @@ -2028,7 +2028,7 @@ p = serp_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = sizeof(serp_tv[i].plaintext); ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -2068,7 +2068,7 @@ p = serp_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = sizeof(serp_tv[i].plaintext); ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -2087,6 +2087,105 @@ crypto_free_tfm(tfm); } +static void +test_cast6(void) +{ + unsigned int ret, i, tsize; + u8 *p, *q, *key; + struct crypto_tfm *tfm; + struct cast6_tv *cast_tv; + struct scatterlist sg[1]; + + printk("\ntesting cast6 encryption\n"); + + tfm = crypto_alloc_tfm("cast6", 0); + if (tfm == NULL) { + printk("failed to load transform for cast6 (default ecb)\n"); + return; + } + + tsize = sizeof (cast6_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, cast6_enc_tv_template, tsize); + cast_tv = (void *) tvmem; + for (i = 0; i < CAST6_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", i + 1, cast_tv[i].keylen * 8); + key = cast_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, cast_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!cast_tv[i].fail) + goto out; + } + + p = cast_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = sizeof(cast_tv[i].plaintext); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, sizeof(cast_tv[i].result)); + + printk("%s\n", memcmp(q, cast_tv[i].result, + sizeof(cast_tv[i].result)) ? "fail" : "pass"); + } + + printk("\ntesting cast6 decryption\n"); + + tsize = sizeof (cast6_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, cast6_dec_tv_template, tsize); + cast_tv = (void *) tvmem; + for (i = 0; i < CAST6_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", i + 1, cast_tv[i].keylen * 8); + key = cast_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, cast_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!cast_tv[i].fail) + goto out; + } + + p = cast_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = sizeof(cast_tv[i].plaintext); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, sizeof(cast_tv[i].result)); + + printk("%s\n", memcmp(q, cast_tv[i].result, + sizeof(cast_tv[i].result)) ? "fail" : "pass"); + } + +out: + crypto_free_tfm(tfm); +} + void test_aes(void) { @@ -2131,7 +2230,7 @@ p = aes_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = aes_tv[i].plen; ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -2173,7 +2272,7 @@ p = aes_tv[i].plaintext; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].offset = offset_in_page(p); sg[0].length = aes_tv[i].plen; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { @@ -2192,6 +2291,102 @@ crypto_free_tfm(tfm); } +void +test_cast5(void) +{ + unsigned int ret, i, tsize; + u8 *p, *q, *key; + struct crypto_tfm *tfm; + struct cast5_tv *c5_tv; + struct scatterlist sg[1]; + + printk("\ntesting cast5 encryption\n"); + + tfm = crypto_alloc_tfm("cast5", 0); + if (tfm == NULL) { + printk("failed to load transform for cast5 (default ecb)\n"); + return; + } + + tsize = sizeof (cast5_enc_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, cast5_enc_tv_template, tsize); + c5_tv = (void *) tvmem; + for (i = 0; i < CAST5_ENC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8); + key = c5_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!c5_tv[i].fail) + goto out; + } + + p = c5_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = sizeof(c5_tv[i].plaintext); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("encrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, sizeof(c5_tv[i].ciphertext)); + + printk("%s\n", memcmp(q, c5_tv[i].ciphertext, + sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass"); + } + + tsize = sizeof (cast5_dec_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, cast5_dec_tv_template, tsize); + c5_tv = (void *) tvmem; + for (i = 0; i < CAST5_DEC_TEST_VECTORS; i++) { + printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8); + key = c5_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!c5_tv[i].fail) + goto out; + } + + p = c5_tv[i].plaintext; + sg[0].page = virt_to_page(p); + sg[0].offset = ((long) p & ~PAGE_MASK); + sg[0].length = sizeof(c5_tv[i].plaintext); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); + if (ret) { + printk("decrypt() failed flags=%x\n", tfm->crt_flags); + goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, sizeof(c5_tv[i].ciphertext)); + + printk("%s\n", memcmp(q, c5_tv[i].ciphertext, + sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass"); + } +out: + crypto_free_tfm (tfm); +} + static void test_deflate(void) { @@ -2300,10 +2495,13 @@ test_blowfish(); test_twofish(); test_serpent(); + test_cast6(); test_aes(); test_sha384(); test_sha512(); test_deflate(); + test_cast5(); + test_cast6(); #ifdef CONFIG_CRYPTO_HMAC test_hmac_md5(); test_hmac_sha1(); @@ -2361,6 +2559,14 @@ case 13: test_deflate(); + break; + + case 14: + test_cast5(); + break; + + case 15: + test_cast6(); break; #ifdef CONFIG_CRYPTO_HMAC diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Mon Aug 18 22:21:05 2003 +++ b/crypto/tcrypt.h Mon Aug 18 22:21:05 2003 @@ -1589,6 +1589,93 @@ } }; +/* Cast6 test vectors from RFC 2612 */ +#define CAST6_ENC_TEST_VECTORS 3 +#define CAST6_DEC_TEST_VECTORS 3 + +struct cast6_tv { + unsigned keylen; + unsigned fail; + u8 key[32]; + u8 plaintext[16]; + u8 result[16]; +}; + +struct cast6_tv cast6_enc_tv_template[] = +{ + { + 16, + 0, + { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, + 0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b }, + }, + { + 24, + 0, + { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, + 0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 }, + }, + { + 32, + 0, + { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46, + 0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, + 0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa }, + } +}; + +struct cast6_tv cast6_dec_tv_template[] = +{ + { + 16, + 0, + { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d }, + { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, + 0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + { + 24, + 0, + { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 }, + { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, + 0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + }, + { + 32, + 0, + { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46, + 0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 }, + { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, + 0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + } +}; + + /* * AES test vectors. */ @@ -1680,6 +1767,74 @@ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, }, +}; + +/* Cast5 test vectors from RFC 2144 */ +#define CAST5_ENC_TEST_VECTORS 3 +#define CAST5_DEC_TEST_VECTORS 3 + +struct cast5_tv { + unsigned keylen; + unsigned fail; + u8 key[16]; + u8 plaintext[8]; + u8 ciphertext[8]; +}; + +struct cast5_tv cast5_enc_tv_template[] = +{ + { + 16, + 0, + { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 }, + + }, + { + 10, + 0, + { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b }, + }, + { + 5, + 0, + { 0x01, 0x23, 0x45, 0x67, 0x12 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e }, + } +}; + +struct cast5_tv cast5_dec_tv_template[] = +{ + { + 16, + 0, + { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }, + { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + + }, + { + 10, + 0, + { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45 }, + { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + }, + { + 5, + 0, + { 0x01, 0x23, 0x45, 0x67, 0x12 }, + { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + } }; /* diff -Nru a/crypto/twofish.c b/crypto/twofish.c --- a/crypto/twofish.c Mon Aug 18 22:21:06 2003 +++ b/crypto/twofish.c Mon Aug 18 22:21:06 2003 @@ -877,7 +877,6 @@ .cra_u = { .cipher = { .cia_min_keysize = TF_MIN_KEY_SIZE, .cia_max_keysize = TF_MAX_KEY_SIZE, - .cia_ivsize = TF_BLOCK_SIZE, .cia_setkey = twofish_setkey, .cia_encrypt = twofish_encrypt, .cia_decrypt = twofish_decrypt } } diff -Nru a/drivers/Makefile b/drivers/Makefile --- a/drivers/Makefile Mon Aug 18 22:21:05 2003 +++ b/drivers/Makefile Mon Aug 18 22:21:05 2003 @@ -7,7 +7,7 @@ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PARISC) += parisc/ -obj-$(CONFIG_ACPI) += acpi/ +obj-$(CONFIG_ACPI_BOOT) += acpi/ # PnP must come after ACPI since it will eventually need to check if acpi # was used and do nothing if so obj-$(CONFIG_PNP) += pnp/ diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig --- a/drivers/acpi/Kconfig Mon Aug 18 22:21:06 2003 +++ b/drivers/acpi/Kconfig Mon Aug 18 22:21:06 2003 @@ -2,12 +2,36 @@ # ACPI Configuration # -menu "ACPI Support" +menu "ACPI (Advanced Configuration and Power Interface) Support" + +config ACPI_HT + bool "ACPI Processor Enumeration for HT" + depends on (X86 && X86_LOCAL_APIC) + default y + ---help--- + ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT) + and physical processors. It is designed to obsolete several older + specifications, including the MultiProcessor Specification (MPS), + which supported only physical processors. + + CONFIG_ACPI_HT includes the minimal ACPI boot-time code + necessary to enumerate logical processors and enable HT. + + CONFIG_ACPI includes CONFIG_ACPI_HT, plus IO APIC enumeration, + and the hooks to run the ACPI AML interpreter for run-time events. + + When CONFIG_ACPI is selected, the command-line option "acpi=ht" + is available to run just the ACPI boot-time code -- just as if + only CONFIG_ACPI_HT were selected. + + Note that "acpi=off" can be used to disable all ACPI code in the kernel. config ACPI - bool "ACPI Support" if X86 + bool "Full ACPI Support" depends on !X86_VISWS - default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN) + depends on !IA64_HP_SIM + depends on IA64 || (X86 && ACPI_HT) + default y ---help--- Advanced Configuration and Power Interface (ACPI) support for Linux requires an ACPI compliant platform (hardware/firmware), @@ -36,30 +60,16 @@ available at: -config ACPI_HT_ONLY - bool "CPU Enumeration Only" - depends on X86 && ACPI && X86_LOCAL_APIC - ---help--- - This option enables limited ACPI support -- just enough to - enumerate processors from the ACPI Multiple APIC Description - Table (MADT). Note that ACPI supports both logical (e.g. Hyper- - Threading) and physical processors, where the MultiProcessor - Specification (MPS) table only supports physical processors. - - Full ACPI support (CONFIG_ACPI) is preferred. Use this option - only if you wish to limit ACPI's role to processor enumeration. - - In this configuration, ACPI defaults to off. It must be enabled - on the command-line with the "acpismp=force" option. - config ACPI_BOOT bool - depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI || ACPI_HT default y config ACPI_SLEEP bool "Sleep States (EXPERIMENTAL)" - depends on X86 && ACPI && !ACPI_HT_ONLY && EXPERIMENTAL + depends on X86 && ACPI + depends on EXPERIMENTAL && PM + default y ---help--- This option adds support for ACPI suspend states. @@ -83,7 +93,8 @@ config ACPI_AC tristate "AC Adapter" - depends on X86 && ACPI && !ACPI_HT_ONLY + depends on X86 && ACPI + default m help This driver adds support for the AC Adapter object, which indicates whether a system is on AC, or not. Typically, only mobile systems @@ -91,7 +102,8 @@ config ACPI_BATTERY tristate "Battery" - depends on X86 && ACPI && !ACPI_HT_ONLY + depends on X86 && ACPI + default m help This driver adds support for battery information through /proc/acpi/battery. If you have a mobile system with a battery, @@ -99,7 +111,9 @@ config ACPI_BUTTON tristate "Button" - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN + default m help This driver registers for events based on buttons, such as the power, sleep, and lid switch. In the future, a daemon will read @@ -109,14 +123,18 @@ config ACPI_FAN tristate "Fan" - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN + default m help This driver adds support for ACPI fan devices, allowing user-mode applications to perform basic fan control (on, off, status). config ACPI_PROCESSOR tristate "Processor" - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN + default m help This driver installs ACPI as the idle handler for Linux, and uses ACPI C2 and C3 processor states to save power, on systems that @@ -125,6 +143,7 @@ config ACPI_THERMAL tristate "Thermal Zone" depends on ACPI_PROCESSOR + default m help This driver adds support for ACPI thermal zones. Most mobile and some desktop systems support ACPI thermal zones. It is HIGHLY @@ -132,12 +151,16 @@ may be damaged without it. config ACPI_NUMA - bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64) - default y if IA64 && IA64_SGI_SN + bool "NUMA support" + depends on ACPI + depends on NUMA + depends on !X86_64 + default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS tristate "ASUS/Medion Laptop Extras" - depends on X86 && ACPI && !ACPI_HT_ONLY + depends on X86 && ACPI + default m ---help--- This driver provides support for extra features of ACPI-compatible ASUS laptops. As some of Medion laptops are made by ASUS, it may also @@ -162,7 +185,8 @@ config ACPI_TOSHIBA tristate "Toshiba Laptop Extras" - depends on X86 && ACPI && !ACPI_HT_ONLY + depends on X86 && ACPI + default m ---help--- This driver adds support for access to certain system settings on "legacy free" Toshiba laptops. These laptops can be recognized by @@ -188,7 +212,9 @@ config ACPI_DEBUG bool "Debug Statements" - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN + default n help The ACPI driver can optionally report errors with a great deal of verbosity. Saying Y enables these statements. This will increase @@ -196,17 +222,19 @@ config ACPI_BUS bool - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN default y config ACPI_INTERPRETER bool - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN default y config ACPI_EC bool - depends on X86 && ACPI && !ACPI_HT_ONLY + depends on X86 && ACPI default y help This driver is required on some systems for the proper operation of @@ -215,17 +243,20 @@ config ACPI_POWER bool - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN default y config ACPI_PCI bool - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN default PCI config ACPI_SYSTEM bool - depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY + depends on ACPI + depends on !IA64_SGI_SN default y help This driver will enable your system to shut down using ACPI, and @@ -233,7 +264,8 @@ config ACPI_EFI bool - depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) + depends on ACPI + depends on IA64 default y endmenu diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile --- a/drivers/acpi/Makefile Mon Aug 18 22:21:06 2003 +++ b/drivers/acpi/Makefile Mon Aug 18 22:21:06 2003 @@ -12,12 +12,13 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -obj-y := acpi_ksyms.o +obj-$(CONFIG_ACPI) := acpi_ksyms.o # # ACPI Boot-Time Table Parsing # -obj-$(CONFIG_ACPI_BOOT) += tables.o blacklist.o +obj-$(CONFIG_ACPI_BOOT) += tables.o +obj-$(CONFIG_ACPI) += blacklist.o # # ACPI Core Subsystem (Interpreter) diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c Mon Aug 18 22:21:04 2003 +++ b/drivers/acpi/bus.c Mon Aug 18 22:21:04 2003 @@ -691,7 +691,7 @@ acpi_set_debug(ACPI_DEBUG_LOW); if (acpi_disabled) { - printk(KERN_INFO PREFIX "Disabled via command line (acpi=off)\n"); + printk(KERN_INFO PREFIX "Interpreter disabled.\n"); return -ENODEV; } diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Mon Aug 18 22:21:05 2003 +++ b/drivers/acpi/osl.c Mon Aug 18 22:21:05 2003 @@ -251,7 +251,12 @@ irq = acpi_fadt.sci_int; #ifdef CONFIG_IA64 - irq = gsi_to_vector(irq); + irq = acpi_irq_to_vector(irq); + if (irq < 0) { + printk(KERN_ERR PREFIX "SCI (ACPI interrupt %d) not registered\n", + acpi_fadt.sci_int); + return AE_OK; + } #endif acpi_irq_irq = irq; acpi_irq_handler = handler; @@ -269,7 +274,7 @@ { if (acpi_irq_handler) { #ifdef CONFIG_IA64 - irq = gsi_to_vector(irq); + irq = acpi_irq_to_vector(irq); #endif free_irq(irq, acpi_irq); acpi_irq_handler = NULL; diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c --- a/drivers/acpi/pci_irq.c Mon Aug 18 22:21:03 2003 +++ b/drivers/acpi/pci_irq.c Mon Aug 18 22:21:03 2003 @@ -24,6 +24,8 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include + #include #include #include @@ -36,6 +38,9 @@ #ifdef CONFIG_X86_IO_APIC #include #endif +#ifdef CONFIG_IOSAPIC +# include +#endif #include #include @@ -249,7 +254,7 @@ } if (!entry->irq && entry->link.handle) { - entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index); + entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL); if (!entry->irq) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); return_VALUE(0); @@ -393,7 +398,9 @@ } /* Make sure all link devices have a valid IRQ. */ - acpi_pci_link_check(); + if (acpi_pci_link_check()) { + return_VALUE(-ENODEV); + } #ifdef CONFIG_X86_IO_APIC /* Program IOAPICs using data from PRT entries. */ diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c Mon Aug 18 22:21:01 2003 +++ b/drivers/acpi/pci_link.c Mon Aug 18 22:21:01 2003 @@ -69,6 +69,9 @@ struct acpi_pci_link_irq { u8 active; /* Current IRQ */ + u8 edge_level; /* All IRQs */ + u8 active_high_low; /* All IRQs */ + u8 setonboot; u8 possible_count; u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; }; @@ -118,6 +121,8 @@ link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; } + link->irq.edge_level = p->edge_level; + link->irq.active_high_low = p->active_high_low; break; } case ACPI_RSTYPE_EXT_IRQ: @@ -136,6 +141,8 @@ link->irq.possible[i] = p->interrupts[i]; link->irq.possible_count++; } + link->irq.edge_level = p->edge_level; + link->irq.active_high_low = p->active_high_low; break; } default: @@ -264,7 +271,6 @@ * IRQ a boot-enabled Link device is set to is the correct one. * (Required to support systems such as the Toshiba 5005-S504.) */ - link->irq.active = irq; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active)); @@ -294,29 +300,33 @@ if (!link || !irq) return_VALUE(-EINVAL); - /* See if we're already at the target IRQ. */ - if (irq == link->irq.active) - return_VALUE(0); - - /* Make sure the target IRQ in the list of possible IRQs. */ - for (i=0; iirq.possible_count; i++) { - if (irq == link->irq.possible[i]) - valid = 1; - } - if (!valid) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq)); - return_VALUE(-EINVAL); + /* We don't check irqs the first time around */ + if (link->irq.setonboot) { + /* See if we're already at the target IRQ. */ + if (irq == link->irq.active) + return_VALUE(0); + + /* Make sure the target IRQ in the list of possible IRQs. */ + for (i=0; iirq.possible_count; i++) { + if (irq == link->irq.possible[i]) + valid = 1; + } + if (!valid) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq)); + return_VALUE(-EINVAL); + } } memset(&resource, 0, sizeof(resource)); - /* NOTE: PCI interrupts are always level / active_low / shared. */ + /* NOTE: PCI interrupts are always level / active_low / shared. But not all + interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for + parameters */ if (irq <= 15) { resource.res.id = ACPI_RSTYPE_IRQ; resource.res.length = sizeof(struct acpi_resource); - resource.res.data.irq.edge_level = ACPI_LEVEL_SENSITIVE; - resource.res.data.irq.active_high_low = ACPI_ACTIVE_LOW; - resource.res.data.irq.shared_exclusive = ACPI_SHARED; + resource.res.data.irq.edge_level = link->irq.edge_level; + resource.res.data.irq.active_high_low = link->irq.active_high_low; resource.res.data.irq.number_of_interrupts = 1; resource.res.data.irq.interrupts[0] = irq; } @@ -324,15 +334,15 @@ resource.res.id = ACPI_RSTYPE_EXT_IRQ; resource.res.length = sizeof(struct acpi_resource); resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER; - resource.res.data.extended_irq.edge_level = ACPI_LEVEL_SENSITIVE; - resource.res.data.extended_irq.active_high_low = ACPI_ACTIVE_LOW; - resource.res.data.extended_irq.shared_exclusive = ACPI_SHARED; + resource.res.data.extended_irq.edge_level = link->irq.edge_level; + resource.res.data.extended_irq.active_high_low = link->irq.active_high_low; resource.res.data.extended_irq.number_of_interrupts = 1; resource.res.data.extended_irq.interrupts[0] = irq; /* ignore resource_source, it's optional */ } resource.end.id = ACPI_RSTYPE_END_TAG; + /* Attempt to set the resource */ status = acpi_set_current_resources(link->handle, &buffer); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n")); @@ -355,11 +365,13 @@ if (result) { return_VALUE(result); } + if (link->irq.active != irq) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Attempt to enable at IRQ %d resulted in IRQ %d\n", irq, link->irq.active)); link->irq.active = 0; + acpi_ut_evaluate_object (link->handle, "_DIS", 0, NULL); return_VALUE(-ENODEV); } @@ -407,7 +419,7 @@ ACPI_FUNCTION_TRACE("acpi_pci_link_check"); /* - * Pass #1: Update penalties to facilitate IRQ balancing. + * Update penalties to facilitate IRQ balancing. */ list_for_each(node, &acpi_link.entries) { @@ -428,23 +440,23 @@ } } - /* - * Pass #2: Enable boot-disabled Links at 'best' IRQ. - */ - list_for_each(node, &acpi_link.entries) { - int irq = 0; - int i = 0; + return_VALUE(0); +} - link = list_entry(node, struct acpi_pci_link, node); - if (!link || !link->irq.possible_count) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); - continue; - } +static int acpi_pci_link_allocate(struct acpi_pci_link* link) { + int irq; + int i; - if (link->irq.active) - continue; + ACPI_FUNCTION_TRACE("acpi_pci_link_allocate"); + + if (link->irq.setonboot) + return_VALUE(0); + if (link->irq.active) { + irq = link->irq.active; + } else { irq = link->irq.possible[0]; + } /* * Select the best IRQ. This is done in reverse to promote @@ -455,16 +467,20 @@ irq = link->irq.possible[i]; } - /* Enable the link device at this IRQ. */ - acpi_pci_link_set(link, irq); - + /* Attempt to enable the link device at this IRQ. */ + if (acpi_pci_link_set(link, irq)) { + printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS). Aborting ACPI-based IRQ routing. Try pci=noacpi or acpi=off\n", + acpi_device_name(link->device), + acpi_device_bid(link->device)); + return_VALUE(-ENODEV); + } else { acpi_irq_penalty[link->irq.active] += 100; - printk(PREFIX "%s [%s] enabled at IRQ %d\n", acpi_device_name(link->device), acpi_device_bid(link->device), link->irq.active); } + link->irq.setonboot = 1; return_VALUE(0); } @@ -472,7 +488,9 @@ int acpi_pci_link_get_irq ( acpi_handle handle, - int index) + int index, + int* edge_level, + int* active_high_low) { int result = 0; struct acpi_device *device = NULL; @@ -498,11 +516,17 @@ return_VALUE(0); } + if (acpi_pci_link_allocate(link)) { + return -ENODEV; + } + if (!link->irq.active) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); return_VALUE(0); } + if (edge_level) *edge_level = link->irq.edge_level; + if (active_high_low) *active_high_low = link->irq.active_high_low; return_VALUE(link->irq.active); } diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c Mon Aug 18 22:21:04 2003 +++ b/drivers/acpi/processor.c Mon Aug 18 22:21:04 2003 @@ -1781,7 +1781,6 @@ if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error removing notify handler\n")); - return_VALUE(-ENODEV); } acpi_processor_remove_fs(device); diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c --- a/drivers/acpi/sleep/main.c Mon Aug 18 22:21:00 2003 +++ b/drivers/acpi/sleep/main.c Mon Aug 18 22:21:00 2003 @@ -22,6 +22,7 @@ u8 sleep_states[ACPI_S_STATE_COUNT]; extern void do_suspend_lowlevel_s4bios(int); +extern void do_suspend_lowlevel(int); /** * acpi_system_restore_state - OS-specific restoration of state @@ -71,10 +72,6 @@ * First, we call to the device driver layer to save device state. * Once we have that, we save whatevery processor and kernel state we * need to memory. - * If we're entering S4, we then write the memory image to disk. - * - * Only then is it safe for us to power down devices, since we may need - * the disks and upstream buses to write to. */ acpi_status acpi_system_save_state( @@ -185,12 +182,11 @@ status = acpi_enter_sleep_state(state); break; -#ifdef CONFIG_SOFTWARE_SUSPEND case ACPI_STATE_S2: case ACPI_STATE_S3: do_suspend_lowlevel(0); break; -#endif + case ACPI_STATE_S4: do_suspend_lowlevel_s4bios(0); break; diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Mon Aug 18 22:21:02 2003 +++ b/drivers/acpi/tables.c Mon Aug 18 22:21:02 2003 @@ -96,10 +96,11 @@ else name = header->signature; - printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s %5.5d.%5.5d) @ 0x%p\n", + printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision >> 16, - header->oem_revision & 0xffff, (void *) phys_addr); + header->oem_table_id, header->oem_revision, + header->asl_compiler_id, header->asl_compiler_revision, + (void *) phys_addr); } @@ -219,12 +220,16 @@ return (sum & 0xFF); } +/* + * acpi_get_table_header_early() + * for acpi_blacklisted(), acpi_table_get_sdt() + */ int __init acpi_get_table_header_early ( enum acpi_table_id id, struct acpi_table_header **header) { - int i; + unsigned int i; enum acpi_table_id temp_id; /* DSDT is different from the rest */ @@ -281,7 +286,7 @@ acpi_table_entry_header *entry = NULL; unsigned long count = 0; unsigned long madt_end = 0; - int i = 0; + unsigned int i = 0; if (!handler) return -EINVAL; @@ -343,7 +348,7 @@ acpi_table_handler handler) { int count = 0; - int i = 0; + unsigned int i = 0; if (!handler) return -EINVAL; @@ -364,7 +369,7 @@ struct acpi_table_rsdp *rsdp) { struct acpi_table_header *header = NULL; - int i, id = 0; + unsigned int i, id = 0; if (!rsdp) return -EINVAL; @@ -550,7 +555,7 @@ return -ENODEV; } - printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", + printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", rsdp->revision, rsdp->oem_id, (void *) rsdp_phys); if (rsdp->revision < 2) diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c --- a/drivers/acpi/toshiba_acpi.c Mon Aug 18 22:21:01 2003 +++ b/drivers/acpi/toshiba_acpi.c Mon Aug 18 22:21:01 2003 @@ -33,7 +33,7 @@ * */ -#define TOSHIBA_ACPI_VERSION "0.15" +#define TOSHIBA_ACPI_VERSION "0.16" #define PROC_INTERFACE_VERSION 1 #include @@ -108,6 +108,7 @@ int result; char* str2 = kmalloc(n + 1, GFP_KERNEL); if (str2 == 0) return 0; + /* NOTE: don't even _think_ about replacing this with strlcpy */ strncpy(str2, str, n); str2[n] = 0; va_start(args, format); diff -Nru a/drivers/atm/eni.c b/drivers/atm/eni.c --- a/drivers/atm/eni.c Mon Aug 18 22:21:01 2003 +++ b/drivers/atm/eni.c Mon Aug 18 22:21:02 2003 @@ -2019,8 +2019,7 @@ * segmentation buffer descriptors of this VCC. */ tasklet_disable(&eni_dev->task); - for (skb = eni_dev->tx_queue.next; skb != - (struct sk_buff *) &eni_dev->tx_queue; skb = skb->next) { + skb_queue_walk(&eni_dev->tx_queue, skb) { unsigned long dsc; if (ATM_SKB(skb)->vcc != vcc) continue; diff -Nru a/drivers/atm/lanai.c b/drivers/atm/lanai.c --- a/drivers/atm/lanai.c Mon Aug 18 22:21:02 2003 +++ b/drivers/atm/lanai.c Mon Aug 18 22:21:02 2003 @@ -514,6 +514,16 @@ reg_write(lanai, lanai->conf2, Config2_Reg); } +/* Same as conf2_write(), but defers I/O if we're powered down */ +static inline void conf2_write_if_powerup(const struct lanai_dev *lanai) +{ +#ifdef USE_POWERDOWN + if (unlikely((lanai->conf1 & CONFIG1_POWERDOWN) != 0)) + return; +#endif /* USE_POWERDOWN */ + conf2_write(lanai); +} + static inline void reset_board(const struct lanai_dev *lanai) { DPRINTK("about to reset board\n"); @@ -616,11 +626,12 @@ u32 readback; sram_write(lanai, pattern, offset); readback = sram_read(lanai, offset); - if (readback == pattern) + if (likely(readback == pattern)) return 0; printk(KERN_ERR DEV_LABEL "(itf %d): SRAM word at %d bad: wrote 0x%X, read 0x%X\n", - lanai->number, offset, pattern, readback); + lanai->number, offset, + (unsigned int) pattern, (unsigned int) readback); return -EIO; } @@ -721,9 +732,9 @@ APRINTK(lvcc->vbase != 0, "cardvcc_write: unbound vcc!\n"); APRINTK((val & ~0xFFFF) == 0, "cardvcc_write: bad val 0x%X (vci=%d, addr=0x%02X)\n", - val, lvcc->vci, (int) offset); + (unsigned int) val, lvcc->vci, (unsigned int) offset); RWDEBUG("VW vci=%04d 0x%02X > 0x%08X\n", - lvcc->vci, (int) offset, val); + lvcc->vci, (unsigned int) offset, (unsigned int) val); writel(val, lvcc->vbase + (bus_addr_t) offset); } @@ -981,7 +992,8 @@ clock_l(); udelay(5); send_stop(); lanai->eeprom[address] = data; - DPRINTK("EEPROM 0x%04X %02X\n", address, data); + DPRINTK("EEPROM 0x%04X %02X\n", + (unsigned int) address, (unsigned int) data); } return 0; error: @@ -1032,14 +1044,14 @@ if (s != e[EEPROM_CHECKSUM]) { printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM checksum bad " "(wanted 0x%02X, got 0x%02X)\n", lanai->number, - s, e[EEPROM_CHECKSUM]); + (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM]); return -EIO; } s ^= 0xFF; if (s != e[EEPROM_CHECKSUM_REV]) { printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM inverse checksum " "bad (wanted 0x%02X, got 0x%02X)\n", lanai->number, - s, e[EEPROM_CHECKSUM_REV]); + (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM_REV]); return -EIO; } /* Verify MAC address */ @@ -1048,7 +1060,8 @@ printk(KERN_ERR DEV_LABEL "(itf %d) : EEPROM MAC addresses don't match " "(0x%02X, inverse 0x%02X)\n", lanai->number, - e[EEPROM_MAC + i], e[EEPROM_MAC_REV + i]); + (unsigned int) e[EEPROM_MAC + i], + (unsigned int) e[EEPROM_MAC_REV + i]); return -EIO; } DPRINTK("eeprom: MAC address = %02X:%02X:%02X:%02X:%02X:%02X\n", @@ -1060,10 +1073,10 @@ if ((lanai->serialno ^ v) != 0xFFFFFFFF) { printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM serial numbers " "don't match (0x%08X, inverse 0x%08X)\n", lanai->number, - lanai->serialno, v); + (unsigned int) lanai->serialno, (unsigned int) v); return -EIO; } - DPRINTK("eeprom: Serial number = %d\n", lanai->serialno); + DPRINTK("eeprom: Serial number = %d\n", (unsigned int) lanai->serialno); /* Verify magic number */ lanai->magicno = eeprom_be4(lanai, EEPROM_MAGIC); v = eeprom_be4(lanai, EEPROM_MAGIC_REV); @@ -1077,7 +1090,8 @@ if (lanai->magicno != EEPROM_MAGIC_VALUE) printk(KERN_WARNING DEV_LABEL "(itf %d): warning - EEPROM " "magic not what expected (got 0x%08X, not 0x%08X)\n", - lanai->number, lanai->magicno, EEPROM_MAGIC_VALUE); + lanai->number, (unsigned int) lanai->magicno, + (unsigned int) EEPROM_MAGIC_VALUE); return 0; } @@ -1313,7 +1327,7 @@ * updating the register. Still, we should make sure */ for (i = 0; reg_read(lanai, Status_Reg) & STATUS_BUTTBUSY; i++) { - if (i > 50) { + if (unlikely(i > 50)) { printk(KERN_ERR DEV_LABEL "(itf %d): butt register " "always busy!\n", lanai->number); break; @@ -1508,13 +1522,14 @@ if (n < 0) n += lanai_buf_size(&lvcc->rx.buf); APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15), - "vcc_rx_aal5: n out of range (%d/%d)\n", + "vcc_rx_aal5: n out of range (%d/%Zu)\n", n, lanai_buf_size(&lvcc->rx.buf)); /* Recover the second-to-last word to get true pdu length */ if ((x = &end[-2]) < lvcc->rx.buf.start) x = &lvcc->rx.buf.end[-2]; size = be32_to_cpup(x) & 0xffff; - if (n != aal5_size(size)) { /* Make sure size matches padding */ + if (unlikely(n != aal5_size(size))) { + /* Make sure size matches padding */ printk(KERN_INFO DEV_LABEL "(itf %d): Got bad AAL5 length " "on vci=%d - size=%d n=%d\n", lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n); @@ -1522,7 +1537,7 @@ goto out; } skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC); - if (skb == NULL) { + if (unlikely(skb == NULL)) { lvcc->stats.rx_nomem++; goto out; } @@ -1563,7 +1578,7 @@ #else int bytes = (lanai->num_vci) * sizeof(struct lanai_vcc *); lanai->vccs = (struct lanai_vcc **) vmalloc(bytes); - if (lanai->vccs == NULL) + if (unlikely(lanai->vccs == NULL)) return -ENOMEM; memset(lanai->vccs, 0, bytes); return 0; @@ -1584,7 +1599,7 @@ { struct lanai_vcc *lvcc; lvcc = (struct lanai_vcc *) kmalloc(sizeof(*lvcc), GFP_KERNEL); - if (lvcc != NULL) { + if (likely(lvcc != NULL)) { lvcc->vbase = 0; lvcc->rx.atmvcc = lvcc->tx.atmvcc = NULL; lvcc->nref = 0; @@ -1605,18 +1620,18 @@ int min, const char *name) { int size; - if (max_sdu < 1) + if (unlikely(max_sdu < 1)) max_sdu = 1; max_sdu = aal5_size(max_sdu); size = (max_sdu + 16) * multiplier + 16; lanai_buf_allocate(buf, size, min, lanai->pci); - if (buf->start == NULL) + if (unlikely(buf->start == NULL)) return -ENOMEM; - if (lanai_buf_size(buf) < size) + if (unlikely(lanai_buf_size(buf) < size)) printk(KERN_WARNING DEV_LABEL "(itf %d): wanted %d bytes " - "for %s buffer, got only %d\n", lanai->number, size, name, - lanai_buf_size(buf)); - DPRINTK("Allocated %d byte %s buffer\n", lanai_buf_size(buf), name); + "for %s buffer, got only %Zu\n", lanai->number, size, + name, lanai_buf_size(buf)); + DPRINTK("Allocated %Zu byte %s buffer\n", lanai_buf_size(buf), name); return 0; } @@ -1706,9 +1721,9 @@ { lanai_buf_allocate(&lanai->service, SERVICE_ENTRIES * 4, 8, lanai->pci); - if (lanai->service.start == NULL) + if (unlikely(lanai->service.start == NULL)) return -ENOMEM; - DPRINTK("allocated service buffer at 0x%08lX, size %d(%d)\n", + DPRINTK("allocated service buffer at 0x%08lX, size %Zu(%d)\n", (unsigned long) lanai->service.start, lanai_buf_size(&lanai->service), lanai_buf_size_cardorder(&lanai->service)); @@ -1746,10 +1761,10 @@ struct lanai_vcc *lvcc; vcclist_read_lock(); lvcc = lanai->vccs[vci]; - if (lvcc == NULL) { + if (unlikely(lvcc == NULL)) { vcclist_read_unlock(); DPRINTK("(itf %d) got service entry 0x%X for nonexistent " - "vcc %d\n", lanai->number, s, vci); + "vcc %d\n", lanai->number, (unsigned int) s, vci); if (s & SERVICE_TX) lanai->stats.service_novcc_tx++; else @@ -1757,10 +1772,10 @@ return 0; } if (s & SERVICE_TX) { /* segmentation interrupt */ - if (lvcc->tx.atmvcc == NULL) { + if (unlikely(lvcc->tx.atmvcc == NULL)) { vcclist_read_unlock(); DPRINTK("(itf %d) got service entry 0x%X for non-TX " - "vcc %d\n", lanai->number, s, vci); + "vcc %d\n", lanai->number, (unsigned int) s, vci); lanai->stats.service_notx++; return 0; } @@ -1769,22 +1784,22 @@ vcclist_read_unlock(); return 1; } - if (lvcc->rx.atmvcc == NULL) { + if (unlikely(lvcc->rx.atmvcc == NULL)) { vcclist_read_unlock(); DPRINTK("(itf %d) got service entry 0x%X for non-RX " - "vcc %d\n", lanai->number, s, vci); + "vcc %d\n", lanai->number, (unsigned int) s, vci); lanai->stats.service_norx++; return 0; } - if (lvcc->rx.atmvcc->qos.aal != ATM_AAL5) { + if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) { vcclist_read_unlock(); DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 " - "vcc %d\n", lanai->number, s, vci); + "vcc %d\n", lanai->number, (unsigned int) s, vci); lanai->stats.service_rxnotaal5++; atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); return 0; } - if ((s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)) == 0) { + if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) { vcc_rx_aal5(lvcc, SERVICE_GET_END(s)); vcclist_read_unlock(); return 0; @@ -1917,6 +1932,9 @@ ack |= reason & (INT_AAL0_STR | INT_AAL0); vcc_rx_aal0(lanai); } + /* The rest of the interrupts are pretty rare */ + if (ack == reason) + goto done; if (reason & INT_STATS) { reason &= ~INT_STATS; /* No need to ack */ get_statistics(lanai); @@ -1925,11 +1943,11 @@ ack |= reason & INT_STATUS; lanai_check_status(lanai); } - if (reason & INT_DMASHUT) { + if (unlikely(reason & INT_DMASHUT)) { printk(KERN_ERR DEV_LABEL "(itf %d): driver error - DMA " "shutdown, reason=0x%08X, address=0x%08X\n", - lanai->number, reason & INT_DMASHUT, - reg_read(lanai, DMA_Addr_Reg)); + lanai->number, (unsigned int) (reason & INT_DMASHUT), + (unsigned int) reg_read(lanai, DMA_Addr_Reg)); if (reason & INT_TABORTBM) { lanai_reset(lanai); return; @@ -1941,32 +1959,35 @@ lanai->stats.dma_reenable++; pcistatus_check(lanai, 0); } - if (reason & INT_TABORTSENT) { + if (unlikely(reason & INT_TABORTSENT)) { ack |= (reason & INT_TABORTSENT); printk(KERN_ERR DEV_LABEL "(itf %d): sent PCI target abort\n", lanai->number); pcistatus_check(lanai, 0); } - if (reason & INT_SEGSHUT) { + if (unlikely(reason & INT_SEGSHUT)) { printk(KERN_ERR DEV_LABEL "(itf %d): driver error - " "segmentation shutdown, reason=0x%08X\n", lanai->number, - reason & INT_SEGSHUT); + (unsigned int) (reason & INT_SEGSHUT)); lanai_reset(lanai); return; } - if (reason & (INT_PING | INT_WAKE)) { + if (unlikely(reason & (INT_PING | INT_WAKE))) { printk(KERN_ERR DEV_LABEL "(itf %d): driver error - " "unexpected interrupt 0x%08X, resetting\n", - lanai->number, reason & (INT_PING | INT_WAKE)); + lanai->number, + (unsigned int) (reason & (INT_PING | INT_WAKE))); lanai_reset(lanai); return; } #ifdef DEBUG - if (ack != reason) { - DPRINTK("unacked ints: 0x%08X\n", reason & ~ack); + if (unlikely(ack != reason)) { + DPRINTK("unacked ints: 0x%08X\n", + (unsigned int) (reason & ~ack)); ack = reason; } #endif + done: if (ack != 0) reg_write(lanai, ack, IntAck_Reg); } @@ -1975,24 +1996,31 @@ { struct lanai_dev *lanai = (struct lanai_dev *) devid; u32 reason; - int handled = 0; (void) irq; (void) regs; /* unused variables */ + #ifdef USE_POWERDOWN - if (lanai->conf1 & CONFIG1_POWERDOWN) { - lanai->conf1 &= ~CONFIG1_POWERDOWN; - conf1_write(lanai); - printk(KERN_WARNING DEV_LABEL "(itf %d): Got interrupt " - "0x%08X while in POWERDOWN, powering up\n", lanai->conf1, - intr_pending(lanai)); - conf2_write(lanai); - } + /* + * If we're powered down we shouldn't be generating any interrupts - + * so assume that this is a shared interrupt line and it's for someone + * else + */ + if (unlikely(lanai->conf1 & CONFIG1_POWERDOWN)) + return IRQ_NONE; #endif - while ((reason = intr_pending(lanai)) != 0) { - handled = 1; + + reason = intr_pending(lanai); + if (reason == 0) + return IRQ_NONE; /* Must be for someone else */ + + do { + if (unlikely(reason == 0xFFFFFFFF)) + break; /* Maybe we've been unplugged? */ lanai_int_1(lanai, reason); - } - return IRQ_RETVAL(handled); + reason = intr_pending(lanai); + } while (reason != 0); + + return IRQ_HANDLED; } /* TODO - it would be nice if we could use the "delayed interrupt" system @@ -2009,10 +2037,11 @@ static int check_board_id_and_rev(const char *name, u32 val, int *revp) { DPRINTK("%s says board_id=%d, board_rev=%d\n", name, - RESET_GET_BOARD_ID(val), RESET_GET_BOARD_REV(val)); + (int) RESET_GET_BOARD_ID(val), + (int) RESET_GET_BOARD_REV(val)); if (RESET_GET_BOARD_ID(val) != BOARD_ID_LANAI256) { printk(KERN_ERR DEV_LABEL ": Found %s board-id %d -- not a " - "Lanai 25.6\n", name, RESET_GET_BOARD_ID(val)); + "Lanai 25.6\n", name, (int) RESET_GET_BOARD_ID(val)); return -ENODEV; } if (revp != NULL) @@ -2058,7 +2087,8 @@ "PCI_SUBSYSTEM_ID: %d\n", lanai->number, result); return -EINVAL; } - if ((result = check_board_id_and_rev("PCI", w, NULL)) != 0) + result = check_board_id_and_rev("PCI", w, NULL); + if (result != 0) return result; /* Set latency timer to zero as per lanai docs */ result = pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0); @@ -2089,10 +2119,7 @@ if (lanai->naal0 != 0) return 0; lanai->conf2 |= CONFIG2_VCI0_NORMAL; -#ifdef USE_POWERDOWN - if ((lanai->conf1 & CONFIG1_POWERDOWN) == 0) -#endif - conf2_write(lanai); + conf2_write_if_powerup(lanai); } return 1; } @@ -2107,7 +2134,7 @@ const struct lanai_vcc *lvcc = lanai->vccs[vci]; if (vci == 0 && !vci0_is_ok(lanai, qos)) return 0; - if (lvcc != NULL) { + if (unlikely(lvcc != NULL)) { if (qos->rxtp.traffic_class != ATM_NONE && lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc) return 0; @@ -2124,10 +2151,7 @@ if (vci0 != NULL && vci0->rx.atmvcc != NULL) return 0; lanai->conf2 &= ~CONFIG2_VCI0_NORMAL; -#ifdef USE_POWERDOWN - if ((lanai->conf1 & CONFIG1_POWERDOWN) == 0) -#endif - conf2_write(lanai); + conf2_write_if_powerup(lanai); } return 1; } @@ -2332,15 +2356,16 @@ #endif memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN); lanai_timed_poll_start(lanai); - printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=0x%lx, irq=%d " + printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=0x%lx, irq=%u " "(%02X-%02X-%02X-%02X-%02X-%02X)\n", lanai->number, - lanai->pci_revision, (long) lanai->base, lanai->pci->irq, + (int) lanai->pci_revision, (unsigned long) lanai->base, + lanai->pci->irq, atmdev->esi[0], atmdev->esi[1], atmdev->esi[2], atmdev->esi[3], atmdev->esi[4], atmdev->esi[5]); - printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%d(0x%X), " + printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), " "board_rev=%d\n", lanai->number, - lanai->type==lanai2 ? "2" : "HB", lanai->serialno, - lanai->serialno, lanai->board_rev); + lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno, + (unsigned int) lanai->serialno, lanai->board_rev); return 0; error_vcctable: @@ -2435,7 +2460,8 @@ (vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC)) return -EINVAL; lanai = (struct lanai_dev *) atmvcc->dev->dev_data; - if ((result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci)) != 0) + result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci); + if (unlikely(result != 0)) goto out; atmvcc->vpi = vpi; atmvcc->vci = vci; @@ -2444,14 +2470,18 @@ if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5) return -EINVAL; #if 0 - DPRINTK(DEV_LABEL "(itf %d): open %d.%d flags=0x%X\n", - lanai->number, vpi, vci, (unsigned long) atmvcc->flags); + DPRINTK(DEV_LABEL "(itf %d): open %d.%d flags=0x%lX\n", + lanai->number, (int) vpi, vci, (unsigned long) atmvcc->flags); #else - DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number, vpi, vci); + DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number, + (int) vpi, vci); #endif - if (lvcc == NULL && (lvcc = new_lanai_vcc()) == NULL) - return -ENOMEM; - atmvcc->dev_data = lvcc; + if (lvcc == NULL) { + lvcc = new_lanai_vcc(); + if (unlikely(lvcc == NULL)) + return -ENOMEM; + atmvcc->dev_data = lvcc; + } lvcc->nref++; if (atmvcc->qos.rxtp.traffic_class != ATM_NONE) { APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n", @@ -2462,7 +2492,7 @@ } else result = lanai_setup_rx_vci_aal5( lanai, lvcc, &atmvcc->qos); - if (result != 0) + if (unlikely(result != 0)) goto out_free; lvcc->rx.atmvcc = atmvcc; lvcc->stats.rx_nomem = 0; @@ -2477,7 +2507,7 @@ APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n", vci); result = lanai_setup_tx_vci(lanai, lvcc, &atmvcc->qos); - if (result != 0) + if (unlikely(result != 0)) goto out_free; lvcc->tx.atmvcc = atmvcc; if (atmvcc->qos.txtp.traffic_class == ATM_CBR) { @@ -2526,13 +2556,13 @@ get_statistics(lanai); return 0; case 2200003: { - int i; + unsigned int i; for (i = 0; i <= 0x5C ; i += 4) { if (i==0x48) /* Write-only butt reg */ continue; printk(KERN_CRIT DEV_LABEL " 0x%02X: " "0x%08X\n", i, - (u32) readl(lanai->base + i)); + (unsigned int) readl(lanai->base + i)); barrier(); mb(); pcistatus_check(lanai, 0); barrier(); mb(); @@ -2544,36 +2574,37 @@ u32 dw; struct pci_dev *pci = lanai->pci; (void) pci_read_config_word(pci, PCI_VENDOR_ID, &w); - DPRINTK("vendor = 0x%X\n", w); + DPRINTK("vendor = 0x%X\n", (unsigned int) w); (void) pci_read_config_word(pci, PCI_DEVICE_ID, &w); - DPRINTK("device = 0x%X\n", w); + DPRINTK("device = 0x%X\n", (unsigned int) w); (void) pci_read_config_word(pci, PCI_COMMAND, &w); - DPRINTK("command = 0x%X\n", w); + DPRINTK("command = 0x%X\n", (unsigned int) w); (void) pci_read_config_word(pci, PCI_STATUS, &w); - DPRINTK("status = 0x%X\n", w); + DPRINTK("status = 0x%X\n", (unsigned int) w); (void) pci_read_config_dword(pci, PCI_CLASS_REVISION, &dw); - DPRINTK("class/revision = 0x%X\n", dw); + DPRINTK("class/revision = 0x%X\n", (unsigned int) dw); (void) pci_read_config_byte(pci, PCI_CACHE_LINE_SIZE, &b); - DPRINTK("cache line size = 0x%X\n", b); + DPRINTK("cache line size = 0x%X\n", (unsigned int) b); (void) pci_read_config_byte(pci, PCI_LATENCY_TIMER, &b); - DPRINTK("latency = %d (0x%X)\n", b, b); + DPRINTK("latency = %d (0x%X)\n", + (int) b, (unsigned int) b); (void) pci_read_config_byte(pci, PCI_HEADER_TYPE, &b); - DPRINTK("header type = 0x%X\n", b); + DPRINTK("header type = 0x%X\n", (unsigned int) b); (void) pci_read_config_byte(pci, PCI_BIST, &b); - DPRINTK("bist = 0x%X\n", b); + DPRINTK("bist = 0x%X\n", (unsigned int) b); /* skipping a few here */ (void) pci_read_config_byte(pci, PCI_INTERRUPT_LINE, &b); - DPRINTK("pci_int_line = 0x%X\n", b); + DPRINTK("pci_int_line = 0x%X\n", (unsigned int) b); (void) pci_read_config_byte(pci, PCI_INTERRUPT_PIN, &b); - DPRINTK("pci_int_pin = 0x%X\n", b); + DPRINTK("pci_int_pin = 0x%X\n", (unsigned int) b); (void) pci_read_config_byte(pci, PCI_MIN_GNT, &b); - DPRINTK("min_gnt = 0x%X\n", b); + DPRINTK("min_gnt = 0x%X\n", (unsigned int) b); (void) pci_read_config_byte(pci, PCI_MAX_LAT, &b); - DPRINTK("max_lat = 0x%X\n", b); } + DPRINTK("max_lat = 0x%X\n", (unsigned int) b); } return 0; #ifdef USE_POWERDOWN case 2200005: @@ -2597,14 +2628,15 @@ struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data; struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data; unsigned long flags; - if (lvcc == NULL || lvcc->vbase == 0 || lvcc->tx.atmvcc != atmvcc) + if (unlikely(lvcc == NULL || lvcc->vbase == 0 || + lvcc->tx.atmvcc != atmvcc)) goto einval; #ifdef DEBUG - if (skb == NULL) { + if (unlikely(skb == NULL)) { DPRINTK("lanai_send: skb==NULL for vci=%d\n", atmvcc->vci); goto einval; } - if (lanai == NULL) { + if (unlikely(lanai == NULL)) { DPRINTK("lanai_send: lanai==NULL for vci=%d\n", atmvcc->vci); goto einval; } @@ -2617,7 +2649,7 @@ spin_unlock_irqrestore(&lanai->txlock, flags); return 0; case ATM_AAL0: - if (skb->len != ATM_CELL_SIZE-1) + if (unlikely(skb->len != ATM_CELL_SIZE-1)) goto einval; /* NOTE - this next line is technically invalid - we haven't unshared skb */ cpu_to_be32s((u32 *) skb->data); @@ -2626,7 +2658,7 @@ spin_unlock_irqrestore(&lanai->txlock, flags); return 0; } - DPRINTK("lanai_send: bad aal=%d on vci=%d\n", atmvcc->qos.aal, + DPRINTK("lanai_send: bad aal=%d on vci=%d\n", (int) atmvcc->qos.aal, atmvcc->vci); einval: lanai_free_skb(atmvcc, skb); @@ -2649,12 +2681,13 @@ struct lanai_vcc *lvcc; if (left-- == 0) return sprintf(page, DEV_LABEL "(itf %d): chip=LANAI%s, " - "serial=%d, magic=0x%08X, num_vci=%d\n", + "serial=%u, magic=0x%08X, num_vci=%d\n", atmdev->number, lanai->type==lanai2 ? "2" : "HB", - lanai->serialno, lanai->magicno, lanai->num_vci); + (unsigned int) lanai->serialno, + (unsigned int) lanai->magicno, lanai->num_vci); if (left-- == 0) return sprintf(page, "revision: board=%d, pci_if=%d\n", - lanai->board_rev, lanai->pci_revision); + lanai->board_rev, (int) lanai->pci_revision); if (left-- == 0) return sprintf(page, "EEPROM ESI: " "%02X:%02X:%02X:%02X:%02X:%02X\n", @@ -2671,37 +2704,37 @@ (lanai->status & STATUS_LED) ? 1 : 0, (lanai->status & STATUS_GPIN) ? 1 : 0); if (left-- == 0) - return sprintf(page, "global buffer sizes: service=%d, " - "aal0_rx=%d\n", lanai_buf_size(&lanai->service), + return sprintf(page, "global buffer sizes: service=%Zu, " + "aal0_rx=%Zu\n", lanai_buf_size(&lanai->service), lanai->naal0 ? lanai_buf_size(&lanai->aal0buf) : 0); if (left-- == 0) { get_statistics(lanai); - return sprintf(page, "cells in error: overflow=%d, " - "closed_vci=%d, bad_HEC=%d, rx_fifo=%d\n", + return sprintf(page, "cells in error: overflow=%u, " + "closed_vci=%u, bad_HEC=%u, rx_fifo=%u\n", lanai->stats.ovfl_trash, lanai->stats.vci_trash, lanai->stats.hec_err, lanai->stats.atm_ovfl); } if (left-- == 0) - return sprintf(page, "PCI errors: parity_detect=%d, " - "master_abort=%d, master_target_abort=%d,\n", + return sprintf(page, "PCI errors: parity_detect=%u, " + "master_abort=%u, master_target_abort=%u,\n", lanai->stats.pcierr_parity_detect, lanai->stats.pcierr_serr_set, lanai->stats.pcierr_m_target_abort); if (left-- == 0) - return sprintf(page, " slave_target_abort=%d, " - "master_parity=%d\n", lanai->stats.pcierr_s_target_abort, + return sprintf(page, " slave_target_abort=%u, " + "master_parity=%u\n", lanai->stats.pcierr_s_target_abort, lanai->stats.pcierr_master_parity); if (left-- == 0) - return sprintf(page, "service list errors: no_vcc_rx=%d, " - "no_vcc_tx=%d,\n", lanai->stats.service_novcc_rx, + return sprintf(page, "service list errors: no_vcc_rx=%u, " + "no_vcc_tx=%u,\n", lanai->stats.service_novcc_rx, lanai->stats.service_novcc_tx); if (left-- == 0) - return sprintf(page, " no_tx=%d, " - "no_rx=%d, bad_rx_aal=%d\n", lanai->stats.service_norx, + return sprintf(page, " no_tx=%u, " + "no_rx=%u, bad_rx_aal=%u\n", lanai->stats.service_norx, lanai->stats.service_notx, lanai->stats.service_rxnotaal5); if (left-- == 0) - return sprintf(page, "resets: dma=%d, card=%d\n", + return sprintf(page, "resets: dma=%u, card=%u\n", lanai->stats.dma_reenable, lanai->stats.card_reset); /* At this point, "left" should be the VCI we're looking for */ vcclist_read_lock(); @@ -2715,15 +2748,15 @@ (*pos)++; } /* Note that we re-use "left" here since we're done with it */ - left = sprintf(page, "VCI %4d: nref=%d, rx_nomem=%d", (vci_t) left, + left = sprintf(page, "VCI %4d: nref=%d, rx_nomem=%u", (vci_t) left, lvcc->nref, lvcc->stats.rx_nomem); if (lvcc->rx.atmvcc != NULL) { left += sprintf(&page[left], ",\n rx_AAL=%d", lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0); if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) - left += sprintf(&page[left], ", rx_buf_size=%d, " - "rx_bad_len=%d,\n rx_service_trash=%d, " - "rx_service_stream=%d, rx_bad_crc=%d", + left += sprintf(&page[left], ", rx_buf_size=%Zu, " + "rx_bad_len=%u,\n rx_service_trash=%u, " + "rx_service_stream=%u, rx_bad_crc=%u", lanai_buf_size(&lvcc->rx.buf), lvcc->stats.x.aal5.rx_badlen, lvcc->stats.x.aal5.service_trash, @@ -2732,7 +2765,7 @@ } if (lvcc->tx.atmvcc != NULL) left += sprintf(&page[left], ",\n tx_AAL=%d, " - "tx_buf_size=%d, tx_qos=%cBR, tx_backlogged=%c", + "tx_buf_size=%Zu, tx_qos=%cBR, tx_backlogged=%c", lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0, lanai_buf_size(&lvcc->tx.buf), lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U', diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig --- a/drivers/base/Kconfig Mon Aug 18 22:21:01 2003 +++ b/drivers/base/Kconfig Mon Aug 18 22:21:01 2003 @@ -2,6 +2,7 @@ config FW_LOADER tristate "Hotplug firmware loading support" + depends on HOTPLUG ---help--- This option is provided for the case where no in-kernel-tree modules require hotplug firmware loading support, but a module built outside diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile --- a/drivers/base/Makefile Mon Aug 18 22:21:05 2003 +++ b/drivers/base/Makefile Mon Aug 18 22:21:05 2003 @@ -1,7 +1,8 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o interface.o power.o bus.o \ +obj-y := core.o sys.o interface.o bus.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o +obj-y += power/ obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o memblk.o diff -Nru a/drivers/base/base.h b/drivers/base/base.h --- a/drivers/base/base.h Mon Aug 18 22:21:02 2003 +++ b/drivers/base/base.h Mon Aug 18 22:21:02 2003 @@ -13,3 +13,5 @@ { return container_of(_attr,struct class_device_attribute,attr); } + + diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c --- a/drivers/base/bus.c Mon Aug 18 22:21:02 2003 +++ b/drivers/base/bus.c Mon Aug 18 22:21:02 2003 @@ -16,6 +16,7 @@ #include #include #include "base.h" +#include "power/power.h" #define to_dev(node) container_of(node,struct device,bus_list) #define to_drv(node) container_of(node,struct device_driver,kobj.entry) @@ -287,6 +288,7 @@ { struct bus_type * bus = dev->bus; struct list_head * entry; + int error; if (dev->driver) { device_bind_driver(dev); @@ -296,8 +298,15 @@ if (bus->match) { list_for_each(entry,&bus->drivers.list) { struct device_driver * drv = to_drv(entry); - if (!bus_match(dev,drv)) - return 1; + error = bus_match(dev,drv); + if (!error ) + /* success, driver matched */ + return 1; + if (error != -ENODEV) + /* driver matched but the probe failed */ + printk(KERN_WARNING + "%s: probe of %s failed with error %d\n", + drv->name, dev->bus_id, error); } } @@ -314,13 +323,14 @@ * If bus_match() returns 0 and the @dev->driver is set, we've found * a compatible pair. * - * Note that we ignore the error from bus_match(), since it's perfectly - * valid for a driver not to bind to any devices. + * Note that we ignore the -ENODEV error from bus_match(), since it's + * perfectly valid for a driver not to bind to any devices. */ void driver_attach(struct device_driver * drv) { struct bus_type * bus = drv->bus; struct list_head * entry; + int error; if (!bus->match) return; @@ -328,7 +338,12 @@ list_for_each(entry,&bus->devices.list) { struct device * dev = container_of(entry,struct device,bus_list); if (!dev->driver) { - bus_match(dev,drv); + error = bus_match(dev,drv); + if (error && (error != -ENODEV)) + /* driver matched but the probe failed */ + printk(KERN_WARNING + "%s: probe of %s failed with error %d\n", + drv->name, dev->bus_id, error); } } } @@ -350,6 +365,7 @@ if (drv) { sysfs_remove_link(&drv->kobj,dev->kobj.name); list_del_init(&dev->driver_list); + device_detach_shutdown(dev); if (drv->remove) drv->remove(dev); dev->driver = NULL; diff -Nru a/drivers/base/class.c b/drivers/base/class.c --- a/drivers/base/class.c Mon Aug 18 22:21:06 2003 +++ b/drivers/base/class.c Mon Aug 18 22:21:06 2003 @@ -59,7 +59,7 @@ static decl_subsys(class,&ktype_class,NULL); -int class_create_file(struct class * cls, struct class_attribute * attr) +int class_create_file(struct class * cls, const struct class_attribute * attr) { int error; if (cls) { @@ -69,7 +69,7 @@ return error; } -void class_remove_file(struct class * cls, struct class_attribute * attr) +void class_remove_file(struct class * cls, const struct class_attribute * attr) { if (cls) sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr); @@ -110,7 +110,7 @@ /* Class Device Stuff */ int class_device_create_file(struct class_device * class_dev, - struct class_device_attribute * attr) + const struct class_device_attribute * attr) { int error = -EINVAL; if (class_dev) @@ -119,7 +119,7 @@ } void class_device_remove_file(struct class_device * class_dev, - struct class_device_attribute * attr) + const struct class_device_attribute * attr) { if (class_dev) sysfs_remove_file(&class_dev->kobj, &attr->attr); @@ -194,6 +194,12 @@ if (cls->release) cls->release(cd); + else { + printk(KERN_ERR "Device class '%s' does not have a release() function, " + "it is broken and must be fixed.\n", + cd->class_id); + WARN_ON(1); + } } static struct kobj_type ktype_class_device = { diff -Nru a/drivers/base/core.c b/drivers/base/core.c --- a/drivers/base/core.c Mon Aug 18 22:21:01 2003 +++ b/drivers/base/core.c Mon Aug 18 22:21:01 2003 @@ -20,6 +20,7 @@ #include #include "base.h" +#include "power/power.h" int (*platform_notify)(struct device * dev) = NULL; int (*platform_notify_remove)(struct device * dev) = NULL; @@ -77,6 +78,12 @@ struct device * dev = to_dev(kobj); if (dev->release) dev->release(dev); + else { + printk(KERN_ERR "Device '%s' does not have a release() function, " + "it is broken and must be fixed.\n", + dev->bus_id); + WARN_ON(1); + } } static struct kobj_type ktype_device = { @@ -210,8 +217,7 @@ parent = get_device(dev->parent); - pr_debug("DEV: registering device: ID = '%s', name = %s\n", - dev->bus_id, dev->name); + pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); /* first, register with generic layer. */ strlcpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN); @@ -230,6 +236,8 @@ bus_add_device(dev); + device_pm_add(dev); + /* notify platform of device entry */ if (platform_notify) platform_notify(dev); @@ -304,6 +312,8 @@ { struct device * parent = dev->parent; + device_pm_remove(dev); + down_write(&devices_subsys.rwsem); if (parent) list_del_init(&dev->node); @@ -337,8 +347,7 @@ */ void device_unregister(struct device * dev) { - pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n", - dev->bus_id,dev->name); + pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id); device_del(dev); put_device(dev); } diff -Nru a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c --- a/drivers/base/firmware_class.c Mon Aug 18 22:21:00 2003 +++ b/drivers/base/firmware_class.c Mon Aug 18 22:21:00 2003 @@ -149,7 +149,7 @@ if (offset + count > fw->size) count = fw->size - offset; - memcpy(buffer + offset, fw->data + offset, count); + memcpy(buffer, fw->data + offset, count); return count; } static int @@ -198,7 +198,7 @@ if (retval) return retval; - memcpy(fw->data + offset, buffer + offset, count); + memcpy(fw->data + offset, buffer, count); fw->size = max_t(size_t, offset + count, fw->size); diff -Nru a/drivers/base/interface.c b/drivers/base/interface.c --- a/drivers/base/interface.c Mon Aug 18 22:21:01 2003 +++ b/drivers/base/interface.c Mon Aug 18 22:21:01 2003 @@ -14,84 +14,38 @@ #include #include -static ssize_t device_read_name(struct device * dev, char * buf) -{ - return sprintf(buf,"%s\n",dev->name); -} - -static DEVICE_ATTR(name,S_IRUGO,device_read_name,NULL); +/** + * detach_state - control the default power state for the device. + * + * This is the state the device enters when it's driver module is + * unloaded. The value is an unsigned integer, in the range of 0-4. + * '0' indicates 'On', so no action will be taken when the driver is + * unloaded. This is the default behavior. + * '4' indicates 'Off', meaning the driver core will call the driver's + * shutdown method to quiesce the device. + * 1-3 indicate a low-power state for the device to enter via the + * driver's suspend method. + */ -static ssize_t -device_read_power(struct device * dev, char * page) +static ssize_t detach_show(struct device * dev, char * buf) { - return sprintf(page,"%d\n",dev->power_state); + return sprintf(buf,"%u\n",dev->detach_state); } -static ssize_t -device_write_power(struct device * dev, const char * buf, size_t count) +static ssize_t detach_store(struct device * dev, const char * buf, size_t n) { - char str_command[20]; - char str_level[20]; - int num_args; - u32 state; - u32 int_level; - int error = 0; - - if (!dev->driver) - goto done; - - num_args = sscanf(buf,"%10s %10s %u",str_command,str_level,&state); - - error = -EINVAL; - - if (!num_args) - goto done; - - if (!strnicmp(str_command,"suspend",7)) { - if (num_args != 3) - goto done; - if (!strnicmp(str_level,"notify",6)) - int_level = SUSPEND_NOTIFY; - else if (!strnicmp(str_level,"save",4)) - int_level = SUSPEND_SAVE_STATE; - else if (!strnicmp(str_level,"disable",7)) - int_level = SUSPEND_DISABLE; - else if (!strnicmp(str_level,"powerdown",8)) - int_level = SUSPEND_POWER_DOWN; - else - goto done; - - if (dev->driver->suspend) - error = dev->driver->suspend(dev,state,int_level); - else - error = 0; - } else if (!strnicmp(str_command,"resume",6)) { - if (num_args != 2) - goto done; - - if (!strnicmp(str_level,"poweron",7)) - int_level = RESUME_POWER_ON; - else if (!strnicmp(str_level,"restore",7)) - int_level = RESUME_RESTORE_STATE; - else if (!strnicmp(str_level,"enable",6)) - int_level = RESUME_ENABLE; - else - goto done; - - if (dev->driver->resume) - error = dev->driver->resume(dev,int_level); - else - error = 0; - } - done: - return error < 0 ? error : count; + u32 state; + state = simple_strtoul(buf,NULL,10); + if (state > 4) + return -EINVAL; + dev->detach_state = state; + return n; } -static DEVICE_ATTR(power,S_IWUSR | S_IRUGO, - device_read_power,device_write_power); +static DEVICE_ATTR(detach_state,0644,detach_show,detach_store); + struct attribute * dev_default_attrs[] = { - &dev_attr_name.attr, - &dev_attr_power.attr, + &dev_attr_detach_state.attr, NULL, }; diff -Nru a/drivers/base/node.c b/drivers/base/node.c --- a/drivers/base/node.c Mon Aug 18 22:21:01 2003 +++ b/drivers/base/node.c Mon Aug 18 22:21:01 2003 @@ -7,6 +7,7 @@ #include #include #include +#include #include static struct sysdev_class node_class = { @@ -17,7 +18,17 @@ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf) { struct node *node_dev = to_node(dev); - return sprintf(buf,"%lx\n",node_dev->cpumap); + cpumask_t tmp = node_dev->cpumap; + int k, len = 0; + + for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + int j = sprintf(buf, "%04hx", (u16)cpus_coerce(tmp)); + len += j; + buf += j; + cpus_shift_right(tmp, tmp, 16); + } + len += sprintf(buf, "\n"); + return len; } static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL); diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c --- a/drivers/base/platform.c Mon Aug 18 22:21:01 2003 +++ b/drivers/base/platform.c Mon Aug 18 22:21:01 2003 @@ -15,7 +15,6 @@ #include struct device legacy_bus = { - .name = "legacy bus", .bus_id = "legacy", }; diff -Nru a/drivers/base/power/Makefile b/drivers/base/power/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/Makefile Mon Aug 18 22:21:06 2003 @@ -0,0 +1,2 @@ +obj-y := shutdown.o +obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o diff -Nru a/drivers/base/power/main.c b/drivers/base/power/main.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/main.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,98 @@ +/* + * drivers/base/power/main.c - Where the driver meets power management. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * + * This file is released under the GPLv2 + * + * + * The driver model core calls device_pm_add() when a device is registered. + * This will intialize the embedded device_pm_info object in the device + * and add it to the list of power-controlled devices. sysfs entries for + * controlling device power management will also be added. + * + * A different set of lists than the global subsystem list are used to + * keep track of power info because we use different lists to hold + * devices based on what stage of the power management process they + * are in. The power domain dependencies may also differ from the + * ancestral dependencies that the subsystem list maintains. + */ + +#define DEBUG + +#include +#include "power.h" + +LIST_HEAD(dpm_active); +LIST_HEAD(dpm_suspended); +LIST_HEAD(dpm_off); +LIST_HEAD(dpm_off_irq); + +DECLARE_MUTEX(dpm_sem); + +/* + * PM Reference Counting. + */ + +static inline void device_pm_hold(struct device * dev) +{ + atomic_inc(&dev->power.pm_users); +} + +static inline void device_pm_release(struct device * dev) +{ + atomic_inc(&dev->power.pm_users); +} + + +/** + * device_pm_set_parent - Specify power dependency. + * @dev: Device who needs power. + * @parent: Device that supplies power. + * + * This function is used to manually describe a power-dependency + * relationship. It may be used to specify a transversal relationship + * (where the power supplier is not the physical (or electrical) + * ancestor of a specific device. + * The effect of this is that the supplier will not be powered down + * before the power dependent. + */ + +void device_pm_set_parent(struct device * dev, struct device * parent) +{ + struct device * old_parent = dev->power.pm_parent; + if (old_parent) + device_pm_release(old_parent); + dev->power.pm_parent = parent; + if (parent) + device_pm_hold(parent); +} +EXPORT_SYMBOL(device_pm_set_parent); + +int device_pm_add(struct device * dev) +{ + int error; + + pr_debug("PM: Adding info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); + down(&dpm_sem); + list_add_tail(&dev->power.entry,&dpm_active); + device_pm_set_parent(dev,dev->parent); + if ((error = dpm_sysfs_add(dev))) + list_del(&dev->power.entry); + up(&dpm_sem); + return error; +} + +void device_pm_remove(struct device * dev) +{ + pr_debug("PM: Removing info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); + down(&dpm_sem); + dpm_sysfs_remove(dev); + list_del(&dev->power.entry); + up(&dpm_sem); +} + + diff -Nru a/drivers/base/power/power.h b/drivers/base/power/power.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/power.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,104 @@ + + +enum { + DEVICE_PM_ON, + DEVICE_PM1, + DEVICE_PM2, + DEVICE_PM3, + DEVICE_PM_OFF, +}; + +/* + * shutdown.c + */ + +extern int device_detach_shutdown(struct device *); +extern void device_shutdown(void); + + +#ifdef CONFIG_PM + +/* + * main.c + */ + +/* + * Used to synchronize global power management operations. + */ +extern struct semaphore dpm_sem; + +/* + * The PM lists. + */ +extern struct list_head dpm_active; +extern struct list_head dpm_suspended; +extern struct list_head dpm_off; +extern struct list_head dpm_off_irq; + + +static inline struct dev_pm_info * to_pm_info(struct list_head * entry) +{ + return container_of(entry,struct dev_pm_info,entry); +} + +static inline struct device * to_device(struct list_head * entry) +{ + return container_of(to_pm_info(entry),struct device,power); +} + +extern int device_pm_add(struct device *); +extern void device_pm_remove(struct device *); + +/* + * sysfs.c + */ + +extern int dpm_sysfs_add(struct device *); +extern void dpm_sysfs_remove(struct device *); + +/* + * resume.c + */ +extern int dpm_resume(void); +extern void dpm_power_up(void); +extern void dpm_power_up_irq(void); +extern void power_up_device(struct device *); +extern int resume_device(struct device *); + +/* + * suspend.c + */ +extern int suspend_device(struct device *, u32); +extern int power_down_device(struct device *, u32); + + +/* + * runtime.c + */ + +extern int dpm_runtime_suspend(struct device *, u32); +extern void dpm_runtime_resume(struct device *); + +#else /* CONFIG_PM */ + + +static inline int device_pm_add(struct device * dev) +{ + return 0; +} +static inline void device_pm_remove(struct device * dev) +{ + +} + +static inline int dpm_runtime_suspend(struct device * dev, u32 state) +{ + return 0; +} + +static inline void dpm_runtime_resume(struct device * dev) +{ + +} + +#endif diff -Nru a/drivers/base/power/resume.c b/drivers/base/power/resume.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/resume.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,153 @@ +/* + * resume.c - Functions for waking devices up. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Labs + * + * This file is released under the GPLv2 + * + */ + +#include +#include "power.h" + +extern int sysdev_resume(void); +extern int sysdev_restore(void); + + +/** + * resume_device - Restore state for one device. + * @dev: Device. + * + */ + +int resume_device(struct device * dev) +{ + struct device_driver * drv = dev->driver; + + if (drv && drv->resume) + return drv->resume(dev,RESUME_RESTORE_STATE); + return 0; +} + +/** + * dpm_resume - Restore all device state. + * + * Walk the dpm_suspended list and restore each device. As they are + * resumed, move the devices to the dpm_active list. + */ + +int dpm_resume(void) +{ + while(!list_empty(&dpm_suspended)) { + struct list_head * entry = dpm_suspended.next; + struct device * dev = to_device(entry); + list_del_init(entry); + resume_device(dev); + list_add_tail(entry,&dpm_active); + } + return 0; +} + + +/** + * device_pm_resume - Restore state of each device in system. + * + * Restore system device state, then common device state. Finally, + * release dpm_sem, as we're done with device PM. + */ + +void device_pm_resume(void) +{ + sysdev_restore(); + dpm_resume(); + up(&dpm_sem); +} + + +/** + * power_up_device - Power one device on. + * @dev: Device. + */ + +void power_up_device(struct device * dev) +{ + struct device_driver * drv = dev->driver; + if (drv && drv->resume) + drv->resume(dev,RESUME_POWER_ON); +} + + +/** + * device_power_up_irq - Power on some devices. + * + * Walk the dpm_off_irq list and power each device up. This + * is used for devices that required they be powered down with + * interrupts disabled. As devices are powered on, they are moved to + * the dpm_suspended list. + * + * Interrupts must be disabled when calling this. + */ + +void dpm_power_up_irq(void) +{ + while(!list_empty(&dpm_off_irq)) { + struct list_head * entry = dpm_off_irq.next; + list_del_init(entry); + power_up_device(to_device(entry)); + list_add_tail(entry,&dpm_suspended); + } +} + + +/** + * dpm_power_up - Power on most devices. + * + * Walk the dpm_off list and power each device up. This is used + * to power on devices that were able to power down with interrupts + * enabled. + */ + +void dpm_power_up(void) +{ + while (!list_empty(&dpm_off)) { + struct list_head * entry = dpm_off.next; + list_del_init(entry); + power_up_device(to_device(entry)); + list_add_tail(entry,&dpm_suspended); + } +} + + +/** + * device_pm_power_up - Turn on all devices. + * + * First, power on system devices, which must happen with interrupts + * disbled. Then, power on devices that also require interrupts disabled. + * Turn interrupts back on, and finally power up the rest of the normal + * devices. + */ + +void device_pm_power_up(void) +{ + sysdev_resume(); + dpm_power_up_irq(); + local_irq_enable(); + dpm_power_up(); +} + +/** + * device_resume - resume all the devices in the system + * @level: stage of resume process we're at + * + * This function is deprecated, and should be replaced with appropriate + * calls to device_pm_power_up() and device_pm_resume() above. + */ + +void device_resume(u32 level) +{ + + printk("%s is deprecated. Called from:\n",__FUNCTION__); + dump_stack(); +} + diff -Nru a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/runtime.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,89 @@ +/* + * drivers/base/power/runtime.c - Handling dynamic device power management. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * + */ + +#include +#include "power.h" + + +static void runtime_resume(struct device * dev) +{ + if (!dev->power.power_state) + return; + + power_up_device(dev); + resume_device(dev); +} + + +/** + * dpm_runtime_resume - Power one device back on. + * @dev: Device. + * + * Bring one device back to the on state by first powering it + * on, then restoring state. We only operate on devices that aren't + * already on. + * FIXME: We need to handle devices that are in an unknown state. + */ + +void dpm_runtime_resume(struct device * dev) +{ + down(&dpm_sem); + runtime_resume(dev); + up(&dpm_sem); +} + + +/** + * dpm_runtime_suspend - Put one device in low-power state. + * @dev: Device. + * @state: State to enter. + */ + +int dpm_runtime_suspend(struct device * dev, u32 state) +{ + int error = 0; + + down(&dpm_sem); + if (dev->power.power_state == state) + goto Done; + + if (dev->power.power_state) + dpm_runtime_resume(dev); + + error = suspend_device(dev,state); + if (!error) { + error = power_down_device(dev,state); + if (error) + goto ErrResume; + dev->power.power_state = state; + } + Done: + up(&dpm_sem); + return error; + ErrResume: + resume_device(dev); + goto Done; +} + + +/** + * dpm_set_power_state - Update power_state field. + * @dev: Device. + * @state: Power state device is in. + * + * This is an update mechanism for drivers to notify the core + * what power state a device is in. Device probing code may not + * always be able to tell, but we need accurate information to + * work reliably. + */ +void dpm_set_power_state(struct device * dev, u32 state) +{ + down(&dpm_sem); + dev->power.power_state = state; + up(&dpm_sem); +} diff -Nru a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/shutdown.c Mon Aug 18 22:21:04 2003 @@ -0,0 +1,68 @@ +/* + * shutdown.c - power management functions for the device tree. + * + * Copyright (c) 2002-3 Patrick Mochel + * 2002-3 Open Source Development Lab + * + * This file is released under the GPLv2 + * + */ + +#undef DEBUG + +#include +#include + +#include "power.h" + +#define to_dev(node) container_of(node,struct device,kobj.entry) + +extern struct subsystem devices_subsys; + + +int device_detach_shutdown(struct device * dev) +{ + if (!dev->detach_state) + return 0; + + if (dev->detach_state == DEVICE_PM_OFF) { + if (dev->driver && dev->driver->shutdown) + dev->driver->shutdown(dev); + return 0; + } + return dpm_runtime_suspend(dev,dev->detach_state); +} + + +/** + * We handle system devices differently - we suspend and shut them + * down first and resume them first. That way, we do anything stupid like + * shutting down the interrupt controller before any devices.. + * + * Note that there are not different stages for power management calls - + * they only get one called once when interrupts are disabled. + */ + +extern int sysdev_shutdown(void); + +/** + * device_shutdown - call ->remove() on each device to shutdown. + */ +void device_shutdown(void) +{ + struct device * dev; + + down_write(&devices_subsys.rwsem); + list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) { + pr_debug("shutting down %s: ",dev->name); + if (dev->driver && dev->driver->shutdown) { + pr_debug("Ok\n"); + dev->driver->shutdown(dev); + } else + pr_debug("Ignored.\n"); + } + up_write(&devices_subsys.rwsem); + + sysdev_shutdown(); +} + diff -Nru a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/suspend.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,235 @@ +/* + * suspend.c - Functions for putting devices to sleep. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Labs + * + * This file is released under the GPLv2 + * + */ + +#include +#include "power.h" + +extern int sysdev_save(u32 state); +extern int sysdev_suspend(u32 state); + +/* + * The entries in the dpm_active list are in a depth first order, simply + * because children are guaranteed to be discovered after parents, and + * are inserted at the back of the list on discovery. + * + * All list on the suspend path are done in reverse order, so we operate + * on the leaves of the device tree (or forests, depending on how you want + * to look at it ;) first. As nodes are removed from the back of the list, + * they are inserted into the front of their destintation lists. + * + * Things are the reverse on the resume path - iterations are done in + * forward order, and nodes are inserted at the back of their destination + * lists. This way, the ancestors will be accessed before their descendents. + */ + + +/** + * suspend_device - Save state of one device. + * @dev: Device. + * @state: Power state device is entering. + */ + +int suspend_device(struct device * dev, u32 state) +{ + struct device_driver * drv = dev->driver; + int error = 0; + + if (drv && drv->suspend) + error = drv->suspend(dev,state,SUSPEND_SAVE_STATE); + + if (!error) { + list_del(&dev->power.entry); + list_add(&dev->power.entry,&dpm_suspended); + } + return error; +} + + +/** + * device_pm_suspend - Save state and stop all devices in system. + * @state: Power state to put each device in. + * + * Walk the dpm_active list, call ->suspend() for each device, and move + * it to dpm_suspended. If we hit a failure with any of the devices, call + * dpm_resume() above to bring the suspended devices back to life. + * + * Have system devices save state last. + * + * Note this function leaves dpm_sem held to + * a) block other devices from registering. + * b) prevent other PM operations from happening after we've begun. + * c) make sure we're exclusive when we disable interrupts. + * + * device_pm_resume() will release dpm_sem after restoring state to + * all devices (as will this on error). You must call it once you've + * called device_pm_suspend(). + */ + +int device_pm_suspend(u32 state) +{ + int error = 0; + + down(&dpm_sem); + while(!list_empty(&dpm_active)) { + struct list_head * entry = dpm_active.prev; + struct device * dev = to_device(entry); + if ((error = suspend_device(dev,state))) + goto Error; + } + + if ((error = sysdev_save(state))) + goto Error; + Done: + return error; + Error: + dpm_resume(); + up(&dpm_sem); + goto Done; +} + + +/** + * power_down_device - Put one device in low power state. + * @dev: Device. + * @state: Power state to enter. + */ + +int power_down_device(struct device * dev, u32 state) +{ + struct device_driver * drv = dev->driver; + int error = 0; + + if (drv && drv->suspend) + error = drv->suspend(dev,state,SUSPEND_POWER_DOWN); + if (!error) { + list_del(&dev->power.entry); + list_add(&dev->power.entry,&dpm_off); + } + return error; +} + + +/** + * dpm_power_down - Put all devices in low power state. + * @state: Power state to enter. + * + * Walk the dpm_suspended list (with interrupts enabled) and try + * to power down each each. If any fail with -EAGAIN, they require + * the call to be done with interrupts disabled. So, we move them to + * the dpm_off_irq list. + * + * If the call succeeds, we move each device to the dpm_off list. + */ + +static int dpm_power_down(u32 state) +{ + while(!list_empty(&dpm_suspended)) { + struct list_head * entry = dpm_suspended.prev; + int error; + error = power_down_device(to_device(entry),state); + if (error) { + if (error == -EAGAIN) { + list_del(entry); + list_add(entry,&dpm_off_irq); + continue; + } + return error; + } + } + return 0; +} + + +/** + * dpm_power_down_irq - Power down devices without interrupts. + * @state: State to enter. + * + * Walk the dpm_off_irq list (built by dpm_power_down) and power + * down each device that requires the call to be made with interrupts + * disabled. + */ + +static int dpm_power_down_irq(u32 state) +{ + struct device * dev; + int error = 0; + + list_for_each_entry_reverse(dev,&dpm_off_irq,power.entry) { + if ((error = power_down_device(dev,state))) + break; + } + return error; +} + + +/** + * device_pm_power_down - Put all devices in low power state. + * @state: Power state to enter. + * + * Walk the dpm_suspended list, calling ->power_down() for each device. + * Check the return value for each. If it returns 0, then we move the + * the device to the dpm_off list. If it returns -EAGAIN, we move it to + * the dpm_off_irq list. If we get a different error, try and back out. + * + * dpm_irq_off is for devices that require interrupts to be disabled to + * either to power down the device or power it back on. + * + * When we're done, we disable interrrupts (!!) and walk the dpm_off_irq + * list to shut down the devices that need interrupts disabled. + * + * This function leaves interrupts disabled on exit, since powering down + * devices should be the very last thing before the system is put into a + * low-power state. + * + * device_pm_power_on() should be called to re-enable interrupts and power + * the devices back on. + */ + +int device_pm_power_down(u32 state) +{ + int error = 0; + + if ((error = dpm_power_down(state))) + goto ErrorIRQOn; + local_irq_disable(); + if ((error = dpm_power_down_irq(state))) + goto ErrorIRQOff; + + sysdev_suspend(state); + Done: + return error; + + ErrorIRQOff: + dpm_power_up_irq(); + local_irq_enable(); + ErrorIRQOn: + dpm_power_up(); + goto Done; +} + + +/** + * device_suspend - suspend all devices on the device ree + * @state: state we're entering + * @level: Stage of suspend sequence we're in. + * + * + * This function is deprecated. Calls should be replaced with + * appropriate calls to device_pm_suspend() and device_pm_power_down(). + */ + +int device_suspend(u32 state, u32 level) +{ + + printk("%s Called from:\n",__FUNCTION__); + dump_stack(); + return -EFAULT; +} + diff -Nru a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/base/power/sysfs.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,68 @@ +/* + * drivers/base/power/sysfs.c - sysfs entries for device PM + */ + +#include +#include "power.h" + + +/** + * state - Control current power state of device + * + * show() returns the current power state of the device. '0' indicates + * the device is on. Other values (1-3) indicate the device is in a low + * power state. + * + * store() sets the current power state, which is an integer value + * between 0-3. If the device is on ('0'), and the value written is + * greater than 0, then the device is placed directly into the low-power + * state (via its driver's ->suspend() method). + * If the device is currently in a low-power state, and the value is 0, + * the device is powered back on (via the ->resume() method). + * If the device is in a low-power state, and a different low-power state + * is requested, the device is first resumed, then suspended into the new + * low-power state. + */ + +static ssize_t state_show(struct device * dev, char * buf) +{ + return sprintf(buf,"%u\n",dev->power.power_state); +} + +static ssize_t state_store(struct device * dev, const char * buf, size_t n) +{ + u32 state; + char * rest; + int error = 0; + + state = simple_strtoul(buf,&rest,10); + if (rest) + return -EINVAL; + if (state) + error = dpm_runtime_suspend(dev,state); + else + dpm_runtime_resume(dev); + return error ? error : n; +} + +static DEVICE_ATTR(state,0644,state_show,state_store); + + +static struct attribute * power_attrs[] = { + &dev_attr_state.attr, + NULL, +}; +static struct attribute_group pm_attr_group = { + .name = "power", + .attrs = power_attrs, +}; + +int dpm_sysfs_add(struct device * dev) +{ + return sysfs_create_group(&dev->kobj,&pm_attr_group); +} + +void dpm_sysfs_remove(struct device * dev) +{ + sysfs_remove_group(&dev->kobj,&pm_attr_group); +} diff -Nru a/drivers/base/power.c b/drivers/base/power.c --- a/drivers/base/power.c Mon Aug 18 22:21:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,140 +0,0 @@ -/* - * power.c - power management functions for the device tree. - * - * Copyright (c) 2002-3 Patrick Mochel - * 2002-3 Open Source Development Lab - * - * This file is released under the GPLv2 - * - * Kai Germaschewski contributed to the list walking routines. - * - */ - -#undef DEBUG - -#include -#include -#include -#include "base.h" - -#define to_dev(node) container_of(node,struct device,kobj.entry) - -extern struct subsystem devices_subsys; - -/** - * We handle system devices differently - we suspend and shut them - * down first and resume them first. That way, we do anything stupid like - * shutting down the interrupt controller before any devices.. - * - * Note that there are not different stages for power management calls - - * they only get one called once when interrupts are disabled. - */ - -extern int sysdev_shutdown(void); -extern int sysdev_save(u32 state); -extern int sysdev_suspend(u32 state); -extern int sysdev_resume(void); -extern int sysdev_restore(void); - -/** - * device_suspend - suspend/remove all devices on the device ree - * @state: state we're entering - * @level: what stage of the suspend process we're at - * (emb: it seems that these two arguments are described backwards of what - * they actually mean .. is this correct?) - * - * The entries in the global device list are inserted such that they're in a - * depth-first ordering. So, simply interate over the list, and call the - * driver's suspend or remove callback for each device. - */ -int device_suspend(u32 state, u32 level) -{ - struct device * dev; - int error = 0; - - down_write(&devices_subsys.rwsem); - list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) { - if (dev->driver && dev->driver->suspend) { - pr_debug("suspending device %s\n",dev->name); - error = dev->driver->suspend(dev,state,level); - if (error) - printk(KERN_ERR "%s: suspend returned %d\n", - dev->name,error); - } - } - up_write(&devices_subsys.rwsem); - - /* - * Make sure system devices are suspended. - */ - switch(level) { - case SUSPEND_SAVE_STATE: - sysdev_save(state); - break; - case SUSPEND_POWER_DOWN: - sysdev_suspend(state); - break; - default: - break; - } - - return error; -} - -/** - * device_resume - resume all the devices in the system - * @level: stage of resume process we're at - * - * Similar to device_suspend above, though we want to do a breadth-first - * walk of the tree to make sure we wake up parents before children. - * So, we iterate over the list backward. - */ -void device_resume(u32 level) -{ - struct device * dev; - - switch (level) { - case RESUME_POWER_ON: - sysdev_resume(); - break; - case RESUME_RESTORE_STATE: - sysdev_restore(); - break; - default: - break; - } - - down_write(&devices_subsys.rwsem); - list_for_each_entry(dev,&devices_subsys.kset.list,kobj.entry) { - if (dev->driver && dev->driver->resume) { - pr_debug("resuming device %s\n",dev->name); - dev->driver->resume(dev,level); - } - } - up_write(&devices_subsys.rwsem); -} - -/** - * device_shutdown - call ->remove() on each device to shutdown. - */ -void device_shutdown(void) -{ - struct device * dev; - - down_write(&devices_subsys.rwsem); - list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) { - pr_debug("shutting down %s: ",dev->name); - if (dev->driver && dev->driver->shutdown) { - pr_debug("Ok\n"); - dev->driver->shutdown(dev); - } else - pr_debug("Ignored.\n"); - } - up_write(&devices_subsys.rwsem); - - sysdev_shutdown(); -} - -EXPORT_SYMBOL(device_suspend); -EXPORT_SYMBOL(device_resume); -EXPORT_SYMBOL(device_shutdown); diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c --- a/drivers/block/DAC960.c Mon Aug 18 22:21:05 2003 +++ b/drivers/block/DAC960.c Mon Aug 18 22:21:05 2003 @@ -82,7 +82,7 @@ } else { DAC960_V2_LogicalDeviceInfo_T *i = p->V2.LogicalDeviceInformation[drive_nr]; - if (i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) + if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) return -ENXIO; } @@ -2487,6 +2487,8 @@ for (n = 0; n < DAC960_MaxLogicalDrives; n++) { struct gendisk *disk = Controller->disks[n]; + + disk->queue = RequestQueue; sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); sprintf(disk->devfs_name, "rd/c%dd%d", Controller->ControllerNumber, n); disk->major = MajorNumber; @@ -2717,7 +2719,6 @@ if (!Controller->disks[i]) goto Failure; Controller->disks[i]->private_data = (void *)i; - Controller->disks[i]->queue = Controller->RequestQueue; } init_waitqueue_head(&Controller->CommandWaitQueue); init_waitqueue_head(&Controller->HealthStatusWaitQueue); diff -Nru a/drivers/block/DAC960.h b/drivers/block/DAC960.h --- a/drivers/block/DAC960.h Mon Aug 18 22:21:05 2003 +++ b/drivers/block/DAC960.h Mon Aug 18 22:21:05 2003 @@ -65,7 +65,7 @@ */ #define DAC690_V1_PciDmaMask 0xffffffff -#define DAC690_V2_PciDmaMask 0xffffffffffffffff +#define DAC690_V2_PciDmaMask 0xffffffffffffffffULL /* Define a Boolean data type. diff -Nru a/drivers/block/Kconfig.iosched b/drivers/block/Kconfig.iosched --- a/drivers/block/Kconfig.iosched Mon Aug 18 22:21:01 2003 +++ b/drivers/block/Kconfig.iosched Mon Aug 18 22:21:01 2003 @@ -1,8 +1,29 @@ +config IOSCHED_NOOP + bool "No-op I/O scheduler" if EMBEDDED + default y + ---help--- + The no-op I/O scheduler is a minimal scheduler that does basic merging + and sorting. Its main uses include non-disk based block devices like + memory devices, and specialised software or hardware environments + that do their own scheduling and require only minimal assistance from + the kernel. + config IOSCHED_AS bool "Anticipatory I/O scheduler" if EMBEDDED default y + ---help--- + The anticipatory I/O scheduler is the default disk scheduler. It is + generally a good choice for most environments, but is quite large and + complex when compared to the deadline I/O scheduler, it can also be + slower in some cases especially some database loads. config IOSCHED_DEADLINE bool "Deadline I/O scheduler" if EMBEDDED default y + ---help--- + The deadline I/O scheduler is simple and compact, and is often as + good as the anticipatory I/O scheduler, and in some database + workloads, better. In the case of a single process performing I/O to + a disk at any one time, its behaviour is almost identical to the + anticipatory I/O scheduler and so is a good choice. diff -Nru a/drivers/block/Makefile b/drivers/block/Makefile --- a/drivers/block/Makefile Mon Aug 18 22:21:05 2003 +++ b/drivers/block/Makefile Mon Aug 18 22:21:05 2003 @@ -15,6 +15,7 @@ obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o +obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o obj-$(CONFIG_IOSCHED_AS) += as-iosched.o obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o diff -Nru a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c --- a/drivers/block/as-iosched.c Mon Aug 18 22:21:00 2003 +++ b/drivers/block/as-iosched.c Mon Aug 18 22:21:00 2003 @@ -99,10 +99,10 @@ sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */ struct list_head *dispatch; /* driver dispatch queue */ struct list_head *hash; /* request hash */ - unsigned long hash_valid_count; /* barrier hash count */ unsigned long current_batch_expires; unsigned long last_check_fifo[2]; - int changed_batch; + int changed_batch; /* 1: waiting for old batch to end */ + int new_batch; /* 1: waiting on first read complete */ int batch_data_dir; /* current batch REQ_SYNC / REQ_ASYNC */ int write_batch_count; /* max # of reqs in a write batch */ int current_write_count; /* how many requests left this batch */ @@ -153,7 +153,7 @@ * request hash, key is the ending offset (for back merge lookup) */ struct list_head hash; - unsigned long hash_valid_count; + unsigned int on_hash; /* * expire fifo @@ -161,7 +161,7 @@ struct list_head fifo; unsigned long expires; - int is_sync; + unsigned int is_sync; enum arq_state state; /* debug only */ }; @@ -238,23 +238,16 @@ #define AS_HASH_ENTRIES (1 << as_hash_shift) #define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) #define list_entry_hash(ptr) list_entry((ptr), struct as_rq, hash) -#define ON_HASH(arq) (arq)->hash_valid_count - -#define AS_INVALIDATE_HASH(ad) \ - do { \ - if (!++(ad)->hash_valid_count) \ - (ad)->hash_valid_count = 1; \ - } while (0) static inline void __as_del_arq_hash(struct as_rq *arq) { - arq->hash_valid_count = 0; + arq->on_hash = 0; list_del_init(&arq->hash); } static inline void as_del_arq_hash(struct as_rq *arq) { - if (ON_HASH(arq)) + if (arq->on_hash) __as_del_arq_hash(arq); } @@ -270,9 +263,9 @@ { struct request *rq = arq->request; - BUG_ON(ON_HASH(arq)); + BUG_ON(arq->on_hash); - arq->hash_valid_count = ad->hash_valid_count; + arq->on_hash = 1; list_add(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]); } @@ -284,7 +277,7 @@ struct request *rq = arq->request; struct list_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))]; - if (!ON_HASH(arq)) { + if (!arq->on_hash) { WARN_ON(1); return; } @@ -306,10 +299,9 @@ next = entry->next; - BUG_ON(!ON_HASH(arq)); + BUG_ON(!arq->on_hash); - if (!rq_mergeable(__rq) - || arq->hash_valid_count != ad->hash_valid_count) { + if (!rq_mergeable(__rq)) { __as_del_arq_hash(arq); continue; } @@ -919,8 +911,13 @@ return; if (ad->changed_batch && ad->nr_dispatched == 1) { + WARN_ON(ad->batch_data_dir == arq->is_sync); + kblockd_schedule_work(&ad->antic_work); - ad->changed_batch = 2; + ad->changed_batch = 0; + + if (ad->batch_data_dir == REQ_SYNC) + ad->new_batch = 1; } ad->nr_dispatched--; @@ -929,12 +926,12 @@ * actually serviced. This should help devices with big TCQ windows * and writeback caches */ - if (ad->batch_data_dir == REQ_SYNC && ad->changed_batch - && ad->batch_data_dir == arq->is_sync) { + if (ad->new_batch && ad->batch_data_dir == arq->is_sync) { + WARN_ON(ad->batch_data_dir != REQ_SYNC); update_write_batch(ad); ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; - ad->changed_batch = 0; + ad->new_batch = 0; } if (!arq->io_context) @@ -1079,7 +1076,7 @@ */ static inline int as_batch_expired(struct as_data *ad) { - if (ad->changed_batch) + if (ad->changed_batch || ad->new_batch) return 0; if (ad->batch_data_dir == REQ_SYNC) @@ -1159,7 +1156,7 @@ if (!(reads || writes) || ad->antic_status == ANTIC_WAIT_REQ || ad->antic_status == ANTIC_WAIT_NEXT - || ad->changed_batch == 1) + || ad->changed_batch) return 0; if (!(reads && writes && as_batch_expired(ad)) ) { @@ -1201,8 +1198,10 @@ */ goto dispatch_writes; - if (ad->batch_data_dir == REQ_ASYNC) + if (ad->batch_data_dir == REQ_ASYNC) { + WARN_ON(ad->new_batch); ad->changed_batch = 1; + } ad->batch_data_dir = REQ_SYNC; arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); ad->last_check_fifo[ad->batch_data_dir] = jiffies; @@ -1217,8 +1216,16 @@ dispatch_writes: BUG_ON(RB_EMPTY(&ad->sort_list[REQ_ASYNC])); - if (ad->batch_data_dir == REQ_SYNC) + if (ad->batch_data_dir == REQ_SYNC) { ad->changed_batch = 1; + + /* + * new_batch might be 1 when the queue runs out of + * reads. A subsequent submission of a write might + * cause a change of batch before the read is finished. + */ + ad->new_batch = 0; + } ad->batch_data_dir = REQ_ASYNC; ad->current_write_count = ad->write_batch_count; ad->write_batch_idled = 0; @@ -1241,14 +1248,19 @@ } if (ad->changed_batch) { - if (ad->changed_batch == 1 && ad->nr_dispatched) + WARN_ON(ad->new_batch); + + if (ad->nr_dispatched) return 0; - if (ad->batch_data_dir == REQ_ASYNC) { + + if (ad->batch_data_dir == REQ_ASYNC) ad->current_batch_expires = jiffies + ad->batch_expire[REQ_ASYNC]; - ad->changed_batch = 0; - } else - ad->changed_batch = 2; + else + ad->new_batch = 1; + + ad->changed_batch = 0; + arq->request->flags |= REQ_SOFTBARRIER; } @@ -1307,12 +1319,28 @@ } /* - * FIXME: HACK for AS requeue problems + * requeue the request. The request has not been completed, nor is it a + * new request, so don't touch accounting. */ static void as_requeue_request(request_queue_t *q, struct request *rq) { - elv_completed_request(q, rq); - __elv_add_request(q, rq, 0, 0); + struct as_data *ad = q->elevator.elevator_data; + struct as_rq *arq = RQ_DATA(rq); + + if (arq) { + arq->state = AS_RQ_DISPATCHED; + if (arq->io_context && arq->io_context->aic) + atomic_inc(&arq->io_context->aic->nr_dispatched); + } else + WARN_ON(blk_fs_request(rq) + && (!(rq->flags & REQ_HARDBARRIER)) ); + + list_add_tail(&rq->queuelist, ad->dispatch); + + /* Stop anticipating - let this request get through */ + as_antic_stop(ad); + + return; } static void @@ -1323,7 +1351,6 @@ struct as_rq *arq = RQ_DATA(rq); if (unlikely(rq->flags & REQ_HARDBARRIER)) { - AS_INVALIDATE_HASH(ad); q->last_merge = NULL; while (ad->next_arq[REQ_SYNC]) @@ -1573,7 +1600,7 @@ arq->state = AS_RQ_NEW; arq->io_context = NULL; INIT_LIST_HEAD(&arq->hash); - arq->hash_valid_count = 0; + arq->on_hash = 0; INIT_LIST_HEAD(&arq->fifo); rq->elevator_private = arq; return 0; @@ -1662,7 +1689,6 @@ ad->dispatch = &q->queue_head; ad->fifo_expire[REQ_SYNC] = default_read_expire; ad->fifo_expire[REQ_ASYNC] = default_write_expire; - ad->hash_valid_count = 1; ad->antic_expire = default_antic_expire; ad->batch_expire[REQ_SYNC] = default_read_batch_expire; ad->batch_expire[REQ_ASYNC] = default_write_batch_expire; diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c --- a/drivers/block/cciss.c Mon Aug 18 22:21:06 2003 +++ b/drivers/block/cciss.c Mon Aug 18 22:21:06 2003 @@ -2457,7 +2457,7 @@ hba[i]->pdev = pdev; /* configure PCI DMA stuff */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) + if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) printk("cciss: using DAC cycles\n"); else if (!pci_set_dma_mask(pdev, 0xffffffff)) printk("cciss: not using DAC cycles\n"); diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c --- a/drivers/block/cciss_scsi.c Mon Aug 18 22:21:02 2003 +++ b/drivers/block/cciss_scsi.c Mon Aug 18 22:21:02 2003 @@ -896,12 +896,13 @@ spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); cp = scsi_cmd_alloc(c); spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); - ei = cp->err_info; if (cp == NULL) { /* trouble... */ printk("cmd_alloc returned NULL!\n"); return -1; } + + ei = cp->err_info; cdb[0] = CISS_INQUIRY; cdb[1] = 0; diff -Nru a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c --- a/drivers/block/cryptoloop.c Mon Aug 18 22:21:04 2003 +++ b/drivers/block/cryptoloop.c Mon Aug 18 22:21:04 2003 @@ -79,20 +79,70 @@ return err; } -typedef int (*encdec_t)(struct crypto_tfm *tfm, + +typedef int (*encdec_ecb_t)(struct crypto_tfm *tfm, + struct scatterlist *sg_out, + struct scatterlist *sg_in, + unsigned int nsg); + + +static int +cryptoloop_transfer_ecb(struct loop_device *lo, int cmd, char *raw_buf, + char *loop_buf, int size, sector_t IV) +{ + struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data; + struct scatterlist sg_out = { 0, }; + struct scatterlist sg_in = { 0, }; + + encdec_ecb_t encdecfunc; + char const *in; + char *out; + + if (cmd == READ) { + in = raw_buf; + out = loop_buf; + encdecfunc = tfm->crt_u.cipher.cit_decrypt; + } else { + in = loop_buf; + out = raw_buf; + encdecfunc = tfm->crt_u.cipher.cit_encrypt; + } + + while (size > 0) { + const int sz = min(size, LOOP_IV_SECTOR_SIZE); + + sg_in.page = virt_to_page(in); + sg_in.offset = (unsigned long)in & ~PAGE_MASK; + sg_in.length = sz; + + sg_out.page = virt_to_page(out); + sg_out.offset = (unsigned long)out & ~PAGE_MASK; + sg_out.length = sz; + + encdecfunc(tfm, &sg_out, &sg_in, sz); + + size -= sz; + in += sz; + out += sz; + } + + return 0; +} + +typedef int (*encdec_cbc_t)(struct crypto_tfm *tfm, struct scatterlist *sg_out, struct scatterlist *sg_in, unsigned int nsg, u8 *iv); static int -cryptoloop_transfer(struct loop_device *lo, int cmd, char *raw_buf, +cryptoloop_transfer_cbc(struct loop_device *lo, int cmd, char *raw_buf, char *loop_buf, int size, sector_t IV) { struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data; struct scatterlist sg_out = { 0, }; struct scatterlist sg_in = { 0, }; - encdec_t encdecfunc; + encdec_cbc_t encdecfunc; char const *in; char *out; @@ -112,11 +162,11 @@ iv[0] = cpu_to_le32(IV & 0xffffffff); sg_in.page = virt_to_page(in); - sg_in.offset = (unsigned long)in & ~PAGE_MASK; + sg_in.offset = offset_in_page(in); sg_in.length = sz; sg_out.page = virt_to_page(out); - sg_out.offset = (unsigned long)out & ~PAGE_MASK; + sg_out.offset = offset_in_page(out); sg_out.length = sz; encdecfunc(tfm, &sg_out, &sg_in, sz, (u8 *)iv); @@ -130,6 +180,27 @@ return 0; } +static int +cryptoloop_transfer(struct loop_device *lo, int cmd, char *raw_buf, + char *loop_buf, int size, sector_t IV) +{ + struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data; + if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB) + { + lo->transfer = cryptoloop_transfer_ecb; + return cryptoloop_transfer_ecb(lo, cmd, raw_buf, loop_buf, size, IV); + } + if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_CBC) + { + lo->transfer = cryptoloop_transfer_cbc; + return cryptoloop_transfer_cbc(lo, cmd, raw_buf, loop_buf, size, IV); + } + + /* This is not supposed to happen */ + + printk( KERN_ERR "cryptoloop: unsupported cipher mode in cryptoloop_transfer!\n"); + return -EINVAL; +} static int cryptoloop_ioctl(struct loop_device *lo, int cmd, unsigned long arg) diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c --- a/drivers/block/elevator.c Mon Aug 18 22:21:05 2003 +++ b/drivers/block/elevator.c Mon Aug 18 22:21:05 2003 @@ -87,72 +87,6 @@ } /* - * elevator noop - * - * See if we can find a request that this buffer can be coalesced with. - */ -int elevator_noop_merge(request_queue_t *q, struct list_head **insert, - struct bio *bio) -{ - struct list_head *entry = &q->queue_head; - struct request *__rq; - int ret; - - if ((ret = elv_try_last_merge(q, bio))) { - *insert = q->last_merge; - return ret; - } - - while ((entry = entry->prev) != &q->queue_head) { - __rq = list_entry_rq(entry); - - if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) - break; - else if (__rq->flags & REQ_STARTED) - break; - - if (!blk_fs_request(__rq)) - continue; - - if ((ret = elv_try_merge(__rq, bio))) { - *insert = &__rq->queuelist; - q->last_merge = &__rq->queuelist; - return ret; - } - } - - return ELEVATOR_NO_MERGE; -} - -void elevator_noop_merge_requests(request_queue_t *q, struct request *req, - struct request *next) -{ - list_del_init(&next->queuelist); -} - -void elevator_noop_add_request(request_queue_t *q, struct request *rq, - struct list_head *insert_here) -{ - list_add_tail(&rq->queuelist, &q->queue_head); - - /* - * new merges must not precede this barrier - */ - if (rq->flags & REQ_HARDBARRIER) - q->last_merge = NULL; - else if (!q->last_merge) - q->last_merge = &rq->queuelist; -} - -struct request *elevator_noop_next_request(request_queue_t *q) -{ - if (!list_empty(&q->queue_head)) - return list_entry_rq(q->queue_head.next); - - return NULL; -} - -/* * general block -> elevator interface starts here */ int elevator_init(request_queue_t *q, elevator_t *type) @@ -415,17 +349,7 @@ } } -elevator_t elevator_noop = { - .elevator_merge_fn = elevator_noop_merge, - .elevator_merge_req_fn = elevator_noop_merge_requests, - .elevator_next_req_fn = elevator_noop_next_request, - .elevator_add_req_fn = elevator_noop_add_request, - .elevator_name = "noop", -}; - module_init(elevator_global_init); - -EXPORT_SYMBOL(elevator_noop); EXPORT_SYMBOL(elv_add_request); EXPORT_SYMBOL(__elv_add_request); diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c --- a/drivers/block/floppy.c Mon Aug 18 22:21:01 2003 +++ b/drivers/block/floppy.c Mon Aug 18 22:21:01 2003 @@ -135,6 +135,10 @@ * requires many non-obvious changes in arch dependent code. */ +/* 2003/07/28 -- Daniele Bellucci . + * Better audit of register_blkdev. + */ + #define FLOPPY_SANITY_CHECK #undef FLOPPY_SILENT_DCL_CLEAR @@ -4228,9 +4232,6 @@ static struct platform_device floppy_device = { .name = "floppy", .id = 0, - .dev = { - .name = "Floppy Drive", - }, }; static struct kobject *floppy_find(dev_t dev, int *part, void *data) @@ -4260,10 +4261,8 @@ } devfs_mk_dir ("floppy"); - if (register_blkdev(FLOPPY_MAJOR,"fd")) { - err = -EBUSY; + if ((err = register_blkdev(FLOPPY_MAJOR,"fd"))) goto out; - } floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); blk_queue_max_sectors(floppy_queue, 64); @@ -4409,6 +4408,7 @@ out: for (i=0; imax_sectors = min(t->max_sectors,b->max_sectors); + t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments); + t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments); + t->max_segment_size = min(t->max_segment_size,b->max_segment_size); + t->hardsect_size = max(t->hardsect_size,b->hardsect_size); +} + +/** * blk_queue_segment_boundary - set boundary rules for segment merging * @q: the request queue for the device * @mask: the memory boundary mask @@ -1218,11 +1232,14 @@ &iosched_as; #elif defined(CONFIG_IOSCHED_DEADLINE) &iosched_deadline; -#else +#elif defined(CONFIG_IOSCHED_NOOP) &elevator_noop; +#else + NULL; +#error "You must have at least 1 I/O scheduler selected" #endif -#if defined(CONFIG_IOSCHED_AS) || defined(CONFIG_IOSCHED_DEADLINE) +#if defined(CONFIG_IOSCHED_AS) || defined(CONFIG_IOSCHED_DEADLINE) || defined (CONFIG_IOSCHED_NOOP) static int __init elevator_setup(char *str) { #ifdef CONFIG_IOSCHED_DEADLINE @@ -1233,11 +1250,15 @@ if (!strcmp(str, "as")) chosen_elevator = &iosched_as; #endif +#ifdef CONFIG_IOSCHED_NOOP + if (!strcmp(str, "noop")) + chosen_elevator = &elevator_noop; +#endif return 1; } __setup("elevator=", elevator_setup); -#endif /* CONFIG_IOSCHED_AS || CONFIG_IOSCHED_DEADLINE */ +#endif /* CONFIG_IOSCHED_AS || CONFIG_IOSCHED_DEADLINE || CONFIG_IOSCHED_NOOP */ request_queue_t *blk_alloc_queue(int gfp_mask) { @@ -2804,6 +2825,7 @@ EXPORT_SYMBOL(blk_queue_max_hw_segments); EXPORT_SYMBOL(blk_queue_max_segment_size); EXPORT_SYMBOL(blk_queue_hardsect_size); +EXPORT_SYMBOL(blk_queue_stack_limits); EXPORT_SYMBOL(blk_queue_segment_boundary); EXPORT_SYMBOL(blk_queue_dma_alignment); EXPORT_SYMBOL(blk_rq_map_sg); diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c --- a/drivers/block/loop.c Mon Aug 18 22:21:04 2003 +++ b/drivers/block/loop.c Mon Aug 18 22:21:04 2003 @@ -513,6 +513,7 @@ from_bvec->bv_len, IV); kunmap(from_bvec->bv_page); kunmap(to_bvec->bv_page); + IV += from_bvec->bv_len >> 9; } return ret; @@ -734,15 +735,6 @@ lo->lo_bio = lo->lo_biotail = NULL; - lo->lo_queue = blk_alloc_queue(GFP_KERNEL); - if (!lo->lo_queue) { - error = -ENOMEM; - fput(file); - goto out_putf; - } - - disks[lo->lo_number]->queue = lo->lo_queue; - /* * set queue make_request_fn, and add limits based on lower level * device @@ -856,7 +848,6 @@ filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp; lo->lo_state = Lo_unbound; fput(filp); - blk_put_queue(lo->lo_queue); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); return 0; @@ -1185,6 +1176,7 @@ loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); if (!loop_dev) goto out_mem1; + memset(loop_dev, 0, max_loop * sizeof(struct loop_device)); disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); if (!disks) @@ -1201,7 +1193,12 @@ for (i = 0; i < max_loop; i++) { struct loop_device *lo = &loop_dev[i]; struct gendisk *disk = disks[i]; + memset(lo, 0, sizeof(*lo)); + lo->lo_queue = blk_alloc_queue(GFP_KERNEL); + if (!lo->lo_queue) + goto out_mem4; + disks[i]->queue = lo->lo_queue; init_MUTEX(&lo->lo_ctl_mutex); init_MUTEX_LOCKED(&lo->lo_sem); init_MUTEX_LOCKED(&lo->lo_bh_mutex); @@ -1219,6 +1216,10 @@ printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); return 0; +out_mem4: + while (i--) + blk_put_queue(loop_dev[i].lo_queue); + i = max_loop; out_mem3: while (i--) put_disk(disks[i]); @@ -1236,6 +1237,7 @@ int i; for (i = 0; i < max_loop; i++) { + blk_put_queue(loop_dev[i].lo_queue); del_gendisk(disks[i]); put_disk(disks[i]); } diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c --- a/drivers/block/nbd.c Mon Aug 18 22:21:02 2003 +++ b/drivers/block/nbd.c Mon Aug 18 22:21:02 2003 @@ -136,10 +136,23 @@ { int uptodate = (req->errors == 0) ? 1 : 0; request_queue_t *q = req->q; + struct nbd_device *lo = req->rq_disk->private_data; unsigned long flags; dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, req, uptodate? "done": "failed"); + + spin_lock(&lo->queue_lock); + while (req->ref_count > 1) { /* still in send */ + spin_unlock(&lo->queue_lock); + printk(KERN_DEBUG "%s: request %p still in use (%d), waiting\n", + lo->disk->disk_name, req, req->ref_count); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); /* wait a second */ + spin_lock(&lo->queue_lock); + } + spin_unlock(&lo->queue_lock); + #ifdef PARANOIA requests_out++; #endif @@ -490,6 +503,7 @@ } list_add(&req->queuelist, &lo->queue_head); + req->ref_count++; /* make sure req does not get freed */ spin_unlock(&lo->queue_lock); nbd_send_req(lo, req); @@ -499,12 +513,16 @@ lo->disk->disk_name); spin_lock(&lo->queue_lock); list_del_init(&req->queuelist); + req->ref_count--; spin_unlock(&lo->queue_lock); nbd_end_request(req); spin_lock_irq(q->queue_lock); continue; } + spin_lock(&lo->queue_lock); + req->ref_count--; + spin_unlock(&lo->queue_lock); spin_lock_irq(q->queue_lock); continue; @@ -548,27 +566,27 @@ if (!lo->sock) return -EINVAL; nbd_send_req(lo, &sreq); - return 0 ; + return 0; case NBD_CLEAR_SOCK: + error = 0; + down(&lo->tx_lock); + lo->sock = NULL; + up(&lo->tx_lock); + spin_lock(&lo->queue_lock); + file = lo->file; + lo->file = NULL; + spin_unlock(&lo->queue_lock); nbd_clear_que(lo); spin_lock(&lo->queue_lock); if (!list_empty(&lo->queue_head)) { - spin_unlock(&lo->queue_lock); - printk(KERN_ERR "%s: Some requests are in progress -> can not turn off.\n", - lo->disk->disk_name); - return -EBUSY; + printk(KERN_ERR "nbd: disconnect: some requests are in progress -> please try again.\n"); + error = -EBUSY; } - file = lo->file; - if (!file) { - spin_unlock(&lo->queue_lock); - return -EINVAL; - } - lo->file = NULL; - lo->sock = NULL; spin_unlock(&lo->queue_lock); - fput(file); - return 0; + if (file) + fput(file); + return error; case NBD_SET_SOCK: if (lo->file) return -EBUSY; @@ -616,10 +634,13 @@ * there should be a more generic interface rather than * calling socket ops directly here */ down(&lo->tx_lock); - printk(KERN_WARNING "%s: shutting down socket\n", + if (lo->sock) { + printk(KERN_WARNING "%s: shutting down socket\n", lo->disk->disk_name); - lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN); - lo->sock = NULL; + lo->sock->ops->shutdown(lo->sock, + SEND_SHUTDOWN|RCV_SHUTDOWN); + lo->sock = NULL; + } up(&lo->tx_lock); spin_lock(&lo->queue_lock); file = lo->file; @@ -631,6 +652,13 @@ fput(file); return lo->harderror; case NBD_CLEAR_QUE: + down(&lo->tx_lock); + if (lo->sock) { + up(&lo->tx_lock); + return 0; /* probably should be error, but that would + * break "nbd-client -d", so just return 0 */ + } + up(&lo->tx_lock); nbd_clear_que(lo); return 0; case NBD_PRINT_DEBUG: diff -Nru a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/block/noop-iosched.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,89 @@ +/* + * elevator noop + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * See if we can find a request that this buffer can be coalesced with. + */ +int elevator_noop_merge(request_queue_t *q, struct list_head **insert, + struct bio *bio) +{ + struct list_head *entry = &q->queue_head; + struct request *__rq; + int ret; + + if ((ret = elv_try_last_merge(q, bio))) { + *insert = q->last_merge; + return ret; + } + + while ((entry = entry->prev) != &q->queue_head) { + __rq = list_entry_rq(entry); + + if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) + break; + else if (__rq->flags & REQ_STARTED) + break; + + if (!blk_fs_request(__rq)) + continue; + + if ((ret = elv_try_merge(__rq, bio))) { + *insert = &__rq->queuelist; + q->last_merge = &__rq->queuelist; + return ret; + } + } + + return ELEVATOR_NO_MERGE; +} + +void elevator_noop_merge_requests(request_queue_t *q, struct request *req, + struct request *next) +{ + list_del_init(&next->queuelist); +} + +void elevator_noop_add_request(request_queue_t *q, struct request *rq, + struct list_head *insert_here) +{ + list_add_tail(&rq->queuelist, &q->queue_head); + + /* + * new merges must not precede this barrier + */ + if (rq->flags & REQ_HARDBARRIER) + q->last_merge = NULL; + else if (!q->last_merge) + q->last_merge = &rq->queuelist; +} + +struct request *elevator_noop_next_request(request_queue_t *q) +{ + if (!list_empty(&q->queue_head)) + return list_entry_rq(q->queue_head.next); + + return NULL; +} + +elevator_t elevator_noop = { + .elevator_merge_fn = elevator_noop_merge, + .elevator_merge_req_fn = elevator_noop_merge_requests, + .elevator_next_req_fn = elevator_noop_next_request, + .elevator_add_req_fn = elevator_noop_add_request, + .elevator_name = "noop", +}; + +EXPORT_SYMBOL(elevator_noop); diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c --- a/drivers/block/paride/pd.c Mon Aug 18 22:21:05 2003 +++ b/drivers/block/paride/pd.c Mon Aug 18 22:21:05 2003 @@ -654,7 +654,7 @@ return pd_identify(disk); } -static struct request_queue pd_queue; +static struct request_queue *pd_queue; static int pd_detect(void) { @@ -704,7 +704,7 @@ set_capacity(p, disk->capacity); disk->gd = p; p->private_data = disk; - p->queue = &pd_queue; + p->queue = pd_queue; add_disk(p); } } @@ -782,7 +782,7 @@ spin_lock_irqsave(&pd_lock, saved_flags); end_request(pd_req, success); pd_busy = 0; - do_pd_request(&pd_queue); + do_pd_request(pd_queue); spin_unlock_irqrestore(&pd_lock, saved_flags); } @@ -890,20 +890,30 @@ { if (disable) return -1; - if (register_blkdev(major, name)) - return -1; - blk_init_queue(&pd_queue, do_pd_request, &pd_lock); - blk_queue_max_sectors(&pd_queue, cluster); + pd_queue = blk_init_queue(do_pd_request, &pd_lock); + if (!pd_queue) + goto out1; + + blk_queue_max_sectors(pd_queue, cluster); + + if (register_blkdev(major, name)) + goto out2; printk("%s: %s version %s, major %d, cluster %d, nice %d\n", name, name, PD_VERSION, major, cluster, nice); pd_init_units(); - if (!pd_detect()) { - unregister_blkdev(major, name); - return -1; - } + if (!pd_detect()) + goto out3; + return 0; + +out3: + unregister_blkdev(major, name); +out2: + blk_cleanup_queue(pd_queue); +out1: + return -1; } static void __exit pd_exit(void) @@ -920,7 +930,7 @@ pi_release(disk->pi); } } - blk_cleanup_queue(&pd_queue); + blk_cleanup_queue(pd_queue); } MODULE_LICENSE("GPL"); diff -Nru a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c --- a/drivers/bluetooth/bluecard_cs.c Mon Aug 18 22:21:03 2003 +++ b/drivers/bluetooth/bluecard_cs.c Mon Aug 18 22:21:03 2003 @@ -90,7 +90,7 @@ void bluecard_config(dev_link_t *link); -void bluecard_release(u_long arg); +void bluecard_release(dev_link_t *link); int bluecard_event(event_t event, int priority, event_callback_args_t *args); static dev_info_t dev_info = "bluecard_cs"; @@ -838,9 +838,6 @@ link = &info->link; link->priv = info; - init_timer(&link->release); - link->release.function = &bluecard_release; - link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; @@ -897,9 +894,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) - bluecard_release((u_long)link); + bluecard_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -1004,13 +1000,12 @@ cs_error(link->handle, last_fn, last_ret); failed: - bluecard_release((u_long)link); + bluecard_release(link); } -void bluecard_release(u_long arg) +void bluecard_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; bluecard_info_t *info = link->priv; if (link->state & DEV_PRESENT) @@ -1036,7 +1031,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { bluecard_close(info); - mod_timer(&link->release, jiffies + HZ / 20); + bluecard_release(link); } break; case CS_EVENT_CARD_INSERTION: diff -Nru a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c --- a/drivers/bluetooth/bt3c_cs.c Mon Aug 18 22:21:06 2003 +++ b/drivers/bluetooth/bt3c_cs.c Mon Aug 18 22:21:06 2003 @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -94,7 +93,7 @@ void bt3c_config(dev_link_t *link); -void bt3c_release(u_long arg); +void bt3c_release(dev_link_t *link); int bt3c_event(event_t event, int priority, event_callback_args_t *args); static dev_info_t dev_info = "bt3c_cs"; @@ -585,9 +584,6 @@ link = &info->link; link->priv = info; - init_timer(&link->release); - link->release.function = &bt3c_release; - link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; @@ -644,10 +640,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); - if (link->state & DEV_CONFIG) - bt3c_release((u_long)link); + bt3c_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -790,13 +784,12 @@ cs_error(link->handle, last_fn, last_ret); failed: - bt3c_release((u_long)link); + bt3c_release(link); } -void bt3c_release(u_long arg) +void bt3c_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; bt3c_info_t *info = link->priv; if (link->state & DEV_PRESENT) @@ -822,7 +815,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { bt3c_close(info); - mod_timer(&link->release, jiffies + HZ / 20); + bt3c_release(link); } break; case CS_EVENT_CARD_INSERTION: diff -Nru a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c --- a/drivers/bluetooth/btuart_cs.c Mon Aug 18 22:21:06 2003 +++ b/drivers/bluetooth/btuart_cs.c Mon Aug 18 22:21:06 2003 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -92,7 +91,7 @@ void btuart_config(dev_link_t *link); -void btuart_release(u_long arg); +void btuart_release(dev_link_t *link); int btuart_event(event_t event, int priority, event_callback_args_t *args); static dev_info_t dev_info = "btuart_cs"; @@ -592,9 +591,6 @@ link = &info->link; link->priv = info; - init_timer(&link->release); - link->release.function = &btuart_release; - link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; @@ -651,9 +647,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) - btuart_release((u_long)link); + btuart_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -797,13 +792,12 @@ cs_error(link->handle, last_fn, last_ret); failed: - btuart_release((u_long) link); + btuart_release(link); } -void btuart_release(u_long arg) +void btuart_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; btuart_info_t *info = link->priv; if (link->state & DEV_PRESENT) @@ -829,7 +823,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { btuart_close(info); - mod_timer(&link->release, jiffies + HZ / 20); + btuart_release(link); } break; case CS_EVENT_CARD_INSERTION: diff -Nru a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c --- a/drivers/bluetooth/dtl1_cs.c Mon Aug 18 22:21:02 2003 +++ b/drivers/bluetooth/dtl1_cs.c Mon Aug 18 22:21:02 2003 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -95,7 +94,7 @@ void dtl1_config(dev_link_t *link); -void dtl1_release(u_long arg); +void dtl1_release(dev_link_t *link); int dtl1_event(event_t event, int priority, event_callback_args_t *args); static dev_info_t dev_info = "dtl1_cs"; @@ -571,9 +570,6 @@ link = &info->link; link->priv = info; - init_timer(&link->release); - link->release.function = &dtl1_release; - link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; @@ -630,9 +626,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) - dtl1_release((u_long)link); + dtl1_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -749,13 +744,12 @@ cs_error(link->handle, last_fn, last_ret); failed: - dtl1_release((u_long)link); + dtl1_release(link); } -void dtl1_release(u_long arg) +void dtl1_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; dtl1_info_t *info = link->priv; if (link->state & DEV_PRESENT) @@ -781,7 +775,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { dtl1_close(info); - mod_timer(&link->release, jiffies + HZ / 20); + dtl1_release(link); } break; case CS_EVENT_CARD_INSERTION: diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c --- a/drivers/bluetooth/hci_usb.c Mon Aug 18 22:21:06 2003 +++ b/drivers/bluetooth/hci_usb.c Mon Aug 18 22:21:06 2003 @@ -783,7 +783,7 @@ BT_DBG("udev %p ifnum %d", udev, ifnum); - iface = &udev->actconfig->interface[0]; + iface = udev->actconfig->interface[0]; /* Check our black list */ if (usb_match_id(intf, ignore_ids)) @@ -807,7 +807,7 @@ ifn = min_t(unsigned int, udev->actconfig->desc.bNumInterfaces, HCI_MAX_IFACE_NUM); for (i = 0; i < ifn; i++) { - iface = &udev->actconfig->interface[i]; + iface = udev->actconfig->interface[i]; for (a = 0; a < iface->num_altsetting; a++) { uif = &iface->altsetting[a]; for (e = 0; e < uif->desc.bNumEndpoints; e++) { diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig --- a/drivers/char/agp/Kconfig Mon Aug 18 22:21:04 2003 +++ b/drivers/char/agp/Kconfig Mon Aug 18 22:21:04 2003 @@ -43,6 +43,16 @@ You should say Y here if you use XFree86 3.3.6 or 4.x and want to use GLX or DRI. If unsure, say N. +config AGP_ATI + tristate "ATI chipset support" + depends on AGP && X86 && !X86_64 + ---help--- + This option gives you AGP support for the GLX component of + XFree86 4.x on the ATI RadeonIGP family of chipsets. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + config AGP_AMD tristate "AMD Irongate, 761, and 762 chipset support" depends on AGP && X86 && !X86_64 diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile --- a/drivers/char/agp/Makefile Mon Aug 18 22:21:02 2003 +++ b/drivers/char/agp/Makefile Mon Aug 18 22:21:02 2003 @@ -2,6 +2,7 @@ obj-$(CONFIG_AGP) += agpgart.o obj-$(CONFIG_AGP_ALI) += ali-agp.o +obj-$(CONFIG_AGP_ATI) += ati-agp.o obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o obj-$(CONFIG_AGP_AMD_8151) += amd-k8-agp.o obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h --- a/drivers/char/agp/agp.h Mon Aug 18 22:21:03 2003 +++ b/drivers/char/agp/agp.h Mon Aug 18 22:21:03 2003 @@ -326,6 +326,21 @@ #define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000 #define ALI_CACHE_FLUSH_EN 0x100 +/* ATI register */ +#define ATI_APBASE 0x10 +#define ATI_GART_MMBASE_ADDR 0x14 +#define ATI_RS100_APSIZE 0xac +#define ATI_RS300_APSIZE 0xf8 +#define ATI_RS100_IG_AGPMODE 0xb0 +#define ATI_RS300_IG_AGPMODE 0xfc + +#define ATI_GART_FEATURE_ID 0x00 +#define ATI_GART_BASE 0x04 +#define ATI_GART_CACHE_SZBASE 0x08 +#define ATI_GART_CACHE_CNTRL 0x0c +#define ATI_GART_CACHE_ENTRY_CNTRL 0x10 + + /* Serverworks Registers */ #define SVWRKS_APSIZE 0x10 #define SVWRKS_SIZE_MASK 0xfe000000 @@ -395,6 +410,7 @@ #define AGPSTAT 0x4 #define AGPCMD 0x8 #define AGPNISTAT 0xc +#define AGPCTRL 0x10 #define AGPNEPG 0x16 #define AGPNICMD 0x20 diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c --- a/drivers/char/agp/ali-agp.c Mon Aug 18 22:21:04 2003 +++ b/drivers/char/agp/ali-agp.c Mon Aug 18 22:21:04 2003 @@ -9,8 +9,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - static int ali_fetch_size(void) { int i; @@ -233,7 +231,7 @@ }; -struct agp_device_ids ali_agp_device_ids[] __initdata = +static struct agp_device_ids ali_agp_device_ids[] __initdata = { { .device_id = PCI_DEVICE_ID_AL_M1541, @@ -292,16 +290,10 @@ goto found; } - if (!agp_try_unsupported) { - printk(KERN_ERR PFX - "Unsupported ALi chipset (device id: %04x)," - " you might want to try agp_try_unsupported=1.\n", - pdev->device); - return -ENODEV; - } + printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)\n", + pdev->device); + return -ENODEV; - printk(KERN_WARNING PFX "Trying generic ALi routines" - " for device id: %04x\n", pdev->device); found: bridge = agp_alloc_bridge(); @@ -328,6 +320,7 @@ devs[j].chipset_name = "M1641"; break; case 0x43: + devs[j].chipset_name = "M????"; break; case 0x47: devs[j].chipset_name = "M1647"; @@ -397,7 +390,6 @@ module_init(agp_ali_init); module_exit(agp_ali_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_AUTHOR("Dave Jones "); MODULE_LICENSE("GPL and additional rights"); diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c --- a/drivers/char/agp/amd-k7-agp.c Mon Aug 18 22:21:06 2003 +++ b/drivers/char/agp/amd-k7-agp.c Mon Aug 18 22:21:06 2003 @@ -11,8 +11,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - struct amd_page_map { unsigned long *real; unsigned long *remapped; @@ -367,7 +365,7 @@ .agp_destroy_page = agp_generic_destroy_page, }; -struct agp_device_ids amd_agp_device_ids[] __initdata = +static struct agp_device_ids amd_agp_device_ids[] __initdata = { { .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006, @@ -404,16 +402,9 @@ } } - if (!agp_try_unsupported) { - printk(KERN_ERR PFX - "Unsupported AMD chipset (device id: %04x)," - " you might want to try agp_try_unsupported=1.\n", + printk(KERN_ERR PFX "Unsupported AMD chipset (device id: %04x)\n", pdev->device); - return -ENODEV; - } - - printk(KERN_WARNING PFX "Trying generic AMD routines" - " for device id: %04x\n", pdev->device); + return -ENODEV; found: bridge = agp_alloc_bridge(); @@ -476,5 +467,4 @@ module_init(agp_amdk7_init); module_exit(agp_amdk7_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); diff -Nru a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/agp/ati-agp.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,530 @@ +/* + * ALi AGPGART routines. + */ + +#include +#include +#include +#include +#include +#include +#include "agp.h" + +static struct aper_size_info_lvl2 ati_generic_sizes[7] = +{ + {2048, 524288, 0x0000000c}, + {1024, 262144, 0x0000000a}, + {512, 131072, 0x00000008}, + {256, 65536, 0x00000006}, + {128, 32768, 0x00000004}, + {64, 16384, 0x00000002}, + {32, 8192, 0x00000000} +}; + +static struct gatt_mask ati_generic_masks[] = +{ + { .mask = 1, .type = 0} +}; + + + +typedef struct _ati_page_map { + unsigned long *real; + unsigned long *remapped; +} ati_page_map; + +static struct _ati_generic_private { + volatile u8 *registers; + ati_page_map **gatt_pages; + int num_tables; +} ati_generic_private; + +static int ati_create_page_map(ati_page_map *page_map) +{ + int i, err = 0; + + page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL); + if (page_map->real == NULL) + return -ENOMEM; + + SetPageReserved(virt_to_page(page_map->real)); + err = map_page_into_agp(virt_to_page(page_map->real)); + + /* CACHE_FLUSH(); */ + global_cache_flush(); + page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + PAGE_SIZE); + if (page_map->remapped == NULL || err) { + ClearPageReserved(virt_to_page(page_map->real)); + free_page((unsigned long) page_map->real); + page_map->real = NULL; + return -ENOMEM; + } + /*CACHE_FLUSH();*/ + global_cache_flush(); + + for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) + page_map->remapped[i] = agp_bridge->scratch_page; + + return 0; +} + + +static void ati_free_page_map(ati_page_map *page_map) +{ + unmap_page_from_agp(virt_to_page(page_map->real)); + iounmap(page_map->remapped); + ClearPageReserved(virt_to_page(page_map->real)); + free_page((unsigned long) page_map->real); +} + + +static void ati_free_gatt_pages(void) +{ + int i; + ati_page_map **tables; + ati_page_map *entry; + + tables = ati_generic_private.gatt_pages; + for(i = 0; i < ati_generic_private.num_tables; i++) { + entry = tables[i]; + if (entry != NULL) { + if (entry->real != NULL) + ati_free_page_map(entry); + kfree(entry); + } + } + kfree(tables); +} + + +static int ati_create_gatt_pages(int nr_tables) +{ + ati_page_map **tables; + ati_page_map *entry; + int retval = 0; + int i; + + tables = kmalloc((nr_tables + 1) * sizeof(ati_page_map *), + GFP_KERNEL); + if (tables == NULL) + return -ENOMEM; + + memset(tables, 0, sizeof(ati_page_map *) * (nr_tables + 1)); + for (i = 0; i < nr_tables; i++) { + entry = kmalloc(sizeof(ati_page_map), GFP_KERNEL); + if (entry == NULL) { + while (i>0) { + kfree (tables[i-1]); + i--; + } + kfree (tables); + retval = -ENOMEM; + break; + } + memset(entry, 0, sizeof(ati_page_map)); + tables[i] = entry; + retval = ati_create_page_map(entry); + if (retval != 0) break; + } + ati_generic_private.num_tables = nr_tables; + ati_generic_private.gatt_pages = tables; + + if (retval != 0) ati_free_gatt_pages(); + + return retval; +} + + +static int ati_fetch_size(void) +{ + int i; + u32 temp; + struct aper_size_info_lvl2 *values; + + if ((agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp); + } else { + pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp); + } + + temp = (temp & 0x0000000e); + values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes); + for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { + if (temp == values[i].size_value) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + + agp_bridge->aperture_size_idx = i; + return values[i].size; + } + } + + return 0; +} + +static void ati_tlbflush(struct agp_memory * mem) +{ + OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1); +} + +static void ati_cleanup(void) +{ + struct aper_size_info_lvl2 *previous_size; + u32 temp; + + previous_size = A_SIZE_LVL2(agp_bridge->previous_size); + + /* Write back the previous size and disable gart translation */ + if ((agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp); + temp = ((temp & ~(0x0000000f)) | previous_size->size_value); + pci_write_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, temp); + } else { + pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp); + temp = ((temp & ~(0x0000000f)) | previous_size->size_value); + pci_write_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, temp); + } + iounmap((void *) ati_generic_private.registers); +} + + +static int ati_configure(void) +{ + u32 temp; + + /* Get the memory mapped registers */ + pci_read_config_dword(agp_bridge->dev, ATI_GART_MMBASE_ADDR, &temp); + temp = (temp & 0xfffff000); + ati_generic_private.registers = (volatile u8 *) ioremap(temp, 4096); + + if ((agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); + } else { + pci_write_config_dword(agp_bridge->dev, ATI_RS300_IG_AGPMODE, 0x20000); + } + + /* address to map too */ + /* + pci_read_config_dword(agp_bridge.dev, ATI_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + printk(KERN_INFO "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr); + */ + OUTREG32(ati_generic_private.registers, ATI_GART_FEATURE_ID, 0x60000); + + /* SIGNALED_SYSTEM_ERROR @ NB_STATUS */ + pci_read_config_dword(agp_bridge->dev, 4, &temp); + pci_write_config_dword(agp_bridge->dev, 4, temp | (1<<14)); + + /* Write out the address of the gatt table */ + OUTREG32(ati_generic_private.registers, ATI_GART_BASE, + agp_bridge->gatt_bus_addr); + + /* Flush the tlb */ + OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1); + return 0; +} + + +/* + *Since we don't need contigious memory we just try + * to get the gatt table once + */ + +#define GET_PAGE_DIR_OFF(addr) (addr >> 22) +#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ + GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr)) +#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) +#undef GET_GATT +#define GET_GATT(addr) (ati_generic_private.gatt_pages[\ + GET_PAGE_DIR_IDX(addr)]->remapped) + +static int ati_insert_memory(struct agp_memory * mem, + off_t pg_start, int type) +{ + int i, j, num_entries; + unsigned long *cur_gatt; + unsigned long addr; + + num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; + + if (type != 0 || mem->type != 0) + return -EINVAL; + + if ((pg_start + mem->page_count) > num_entries) + return -EINVAL; + + j = pg_start; + while (j < (pg_start + mem->page_count)) { + addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; + cur_gatt = GET_GATT(addr); + if (!PGE_EMPTY(agp_bridge,cur_gatt[GET_GATT_OFF(addr)])) + return -EBUSY; + j++; + } + + if (mem->is_flushed == FALSE) { + /*CACHE_FLUSH(); */ + global_cache_flush(); + mem->is_flushed = TRUE; + } + + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { + addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; + cur_gatt = GET_GATT(addr); + cur_gatt[GET_GATT_OFF(addr)] = + agp_bridge->driver->mask_memory(mem->memory[i], mem->type); + } + agp_bridge->driver->tlb_flush(mem); + return 0; +} + +static int ati_remove_memory(struct agp_memory * mem, off_t pg_start, + int type) +{ + int i; + unsigned long *cur_gatt; + unsigned long addr; + + if (type != 0 || mem->type != 0) { + return -EINVAL; + } + for (i = pg_start; i < (mem->page_count + pg_start); i++) { + addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; + cur_gatt = GET_GATT(addr); + cur_gatt[GET_GATT_OFF(addr)] = + (unsigned long) agp_bridge->scratch_page; + } + + agp_bridge->driver->tlb_flush(mem); + return 0; +} + +static int ati_create_gatt_table(void) +{ + struct aper_size_info_lvl2 *value; + ati_page_map page_dir; + unsigned long addr; + int retval; + u32 temp; + int i; + struct aper_size_info_lvl2 *current_size; + + value = A_SIZE_LVL2(agp_bridge->current_size); + retval = ati_create_page_map(&page_dir); + if (retval != 0) + return retval; + + retval = ati_create_gatt_pages(value->num_entries / 1024); + if (retval != 0) { + ati_free_page_map(&page_dir); + return retval; + } + + agp_bridge->gatt_table_real = (u32 *)page_dir.real; + agp_bridge->gatt_table = (u32 *)page_dir.remapped; + agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); + + /* Write out the size register */ + current_size = A_SIZE_LVL2(agp_bridge->current_size); + + if ((agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS100) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS250)) { + pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp); + temp = (((temp & ~(0x0000000e)) | current_size->size_value) + | 0x00000001); + pci_write_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, temp); + pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp); + } else { + pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp); + temp = (((temp & ~(0x0000000e)) | current_size->size_value) + | 0x00000001); + pci_write_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, temp); + pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp); + } + + /* + * Get the address for the gart region. + * This is a bus address even on the alpha, b/c its + * used to program the agp master not the cpu + */ + pci_read_config_dword(agp_bridge->dev, ATI_APBASE, &temp); + addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->gart_bus_addr = addr; + + /* Calculate the agp offset */ + for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { + page_dir.remapped[GET_PAGE_DIR_OFF(addr)] = + virt_to_bus(ati_generic_private.gatt_pages[i]->real); + page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001; + } + + return 0; +} + +static int ati_free_gatt_table(void) +{ + ati_page_map page_dir; + + page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; + page_dir.remapped = (unsigned long *)agp_bridge->gatt_table; + + ati_free_gatt_pages(); + ati_free_page_map(&page_dir); + return 0; +} + +struct agp_bridge_driver ati_generic_bridge = { + .owner = THIS_MODULE, + .aperture_sizes = ati_generic_sizes, + .size_type = LVL2_APER_SIZE, + .num_aperture_sizes = 7, + .configure = ati_configure, + .fetch_size = ati_fetch_size, + .cleanup = ati_cleanup, + .tlb_flush = ati_tlbflush, + .mask_memory = agp_generic_mask_memory, + .masks = ati_generic_masks, + .agp_enable = agp_generic_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = ati_create_gatt_table, + .free_gatt_table = ati_free_gatt_table, + .insert_memory = ati_insert_memory, + .remove_memory = ati_remove_memory, + .alloc_by_type = agp_generic_alloc_by_type, + .free_by_type = agp_generic_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = agp_generic_destroy_page, +}; + + +static struct agp_device_ids ati_agp_device_ids[] __initdata = +{ + { + .device_id = PCI_DEVICE_ID_ATI_RS100, + .chipset_name = "IGP320/M", + }, + { + .device_id = PCI_DEVICE_ID_ATI_RS200, + .chipset_name = "IGP330/340/345/350/M", + }, + { + .device_id = PCI_DEVICE_ID_ATI_RS250, + .chipset_name = "IGP7000/M", + }, + { + .device_id = PCI_DEVICE_ID_ATI_RS300_100, + .chipset_name = "IGP9100/M", + }, + { + .device_id = PCI_DEVICE_ID_ATI_RS300_133, + .chipset_name = "IGP9100/M", + }, + { + .device_id = PCI_DEVICE_ID_ATI_RS300_166, + .chipset_name = "IGP9100/M", + }, + { + .device_id = PCI_DEVICE_ID_ATI_RS300_200, + .chipset_name = "IGP9100/M", + }, + { }, /* dummy final entry, always present */ +}; + +static int __init agp_ati_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct agp_device_ids *devs = ati_agp_device_ids; + struct agp_bridge_data *bridge; + u8 cap_ptr; + int j; + + cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); + if (!cap_ptr) + return -ENODEV; + + /* probe for known chipsets */ + for (j = 0; devs[j].chipset_name; j++) { + if (pdev->device == devs[j].device_id) + goto found; + } + + printk(KERN_ERR PFX + "Unsupported Ati chipset (device id: %04x)\n", pdev->device); + return -ENODEV; + +found: + bridge = agp_alloc_bridge(); + if (!bridge) + return -ENOMEM; + + bridge->dev = pdev; + bridge->capndx = cap_ptr; + + bridge->driver = &ati_generic_bridge; + + + printk(KERN_INFO PFX "Detected Ati %s chipset\n", + devs[j].chipset_name); + + /* Fill in the mode register */ + pci_read_config_dword(pdev, + bridge->capndx+PCI_AGP_STATUS, + &bridge->mode); + + pci_set_drvdata(pdev, bridge); + return agp_add_bridge(bridge); +} + +static void __devexit agp_ati_remove(struct pci_dev *pdev) +{ + struct agp_bridge_data *bridge = pci_get_drvdata(pdev); + + agp_remove_bridge(bridge); + agp_put_bridge(bridge); +} + +static struct pci_device_id agp_ati_pci_table[] __initdata = { + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_ATI, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { } +}; + +MODULE_DEVICE_TABLE(pci, agp_ati_pci_table); + +static struct pci_driver agp_ati_pci_driver = { + .name = "agpgart-ati", + .id_table = agp_ati_pci_table, + .probe = agp_ati_probe, + .remove = agp_ati_remove, +}; + +static int __init agp_ati_init(void) +{ + return pci_module_init(&agp_ati_pci_driver); +} + +static void __exit agp_ati_cleanup(void) +{ + pci_unregister_driver(&agp_ati_pci_driver); +} + +module_init(agp_ati_init); +module_exit(agp_ati_cleanup); + +MODULE_AUTHOR("Dave Jones "); +MODULE_LICENSE("GPL and additional rights"); + diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c --- a/drivers/char/agp/backend.c Mon Aug 18 22:21:04 2003 +++ b/drivers/char/agp/backend.c Mon Aug 18 22:21:04 2003 @@ -106,7 +106,11 @@ { long memory, index, result; - memory = (num_physpages << PAGE_SHIFT) >> 20; +#if PAGE_SHIFT < 20 + memory = num_physpages >> (20 - PAGE_SHIFT); +#else + memory = num_physpages << (PAGE_SHIFT - 20); +#endif index = 1; while ((memory > maxes_table[index].mem) && (index < 8)) diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c --- a/drivers/char/agp/generic.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/agp/generic.c Mon Aug 18 22:21:02 2003 @@ -459,9 +459,9 @@ /* Clear out unwanted bits. */ if (*cmd & AGPSTAT3_8X) - *cmd = ~(AGPSTAT3_4X | AGPSTAT3_RSVD); + *cmd &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); if (*cmd & AGPSTAT3_4X) - *cmd = ~(AGPSTAT3_8X | AGPSTAT3_RSVD); + *cmd &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); } //FIXME: This doesn't smell right. @@ -545,7 +545,7 @@ void agp_generic_enable(u32 mode) { - u32 command; + u32 command, temp; u32 agp3; get_agp_version(agp_bridge); @@ -577,7 +577,13 @@ agp_device_command(command, TRUE); return; } else { - printk (KERN_INFO PFX "Device is in legacy mode," + /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/ + command &= ~(7<<10) ; + pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &temp); + temp |= (1<<9); + pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, temp); + + printk (KERN_INFO PFX "Device is in legacy mode," " falling back to 2.x\n"); } } diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c --- a/drivers/char/agp/intel-agp.c Mon Aug 18 22:21:03 2003 +++ b/drivers/char/agp/intel-agp.c Mon Aug 18 22:21:03 2003 @@ -13,9 +13,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - - static struct aper_size_info_fixed intel_i810_sizes[] = { {64, 16384, 4}, @@ -78,6 +75,10 @@ temp &= 0xfff80000; intel_i810_private.registers = (volatile u8 *) ioremap(temp, 128 * 4096); + if (!intel_i810_private.registers) { + printk(KERN_ERR PFX "Unable to remap memory.\n"); + return -ENOMEM; + } if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL) & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { @@ -1358,15 +1359,9 @@ name = "E7205"; break; default: - if (!agp_try_unsupported) { - printk(KERN_ERR PFX - "Unsupported Intel chipset (device id: %04x)," - " you might want to try agp_try_unsupported=1.\n", + printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)\n", pdev->device); - return -ENODEV; - } - bridge->driver = &intel_generic_driver; - break; + return -ENODEV; }; bridge->dev = pdev; @@ -1485,6 +1480,5 @@ module_init(agp_intel_init); module_exit(agp_intel_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_AUTHOR("Dave Jones "); MODULE_LICENSE("GPL and additional rights"); diff -Nru a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c --- a/drivers/char/agp/nvidia-agp.c Mon Aug 18 22:21:01 2003 +++ b/drivers/char/agp/nvidia-agp.c Mon Aug 18 22:21:01 2003 @@ -25,9 +25,6 @@ #define NVIDIA_3_APBASE 0x50 #define NVIDIA_3_APLIMIT 0x54 - -static int agp_try_unsupported __initdata = 0; - static struct _nvidia_private { struct pci_dev *dev_1; struct pci_dev *dev_2; @@ -279,9 +276,8 @@ pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) { - printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " - "nForce/nForce2 chipset, but could not find " - "the secondary devices.\n"); + printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 " + "chipset, but could not find the secondary devices.\n"); return -ENODEV; } @@ -299,17 +295,9 @@ nvidia_private.wbc_mask = 0x80000000; break; default: - if (!agp_try_unsupported) { - printk(KERN_ERR PFX - "Unsupported NVIDIA chipset (device id: %04x)," - " you might want to try agp_try_unsupported=1.\n", + printk(KERN_ERR PFX "Unsupported NVIDIA chipset (device id: %04x)\n", pdev->device); - return -ENODEV; - } - printk(KERN_WARNING PFX - "Trying generic NVIDIA routines for device id: %04x\n", - pdev->device); - break; + return -ENODEV; } bridge = agp_alloc_bridge(); @@ -372,7 +360,6 @@ module_init(agp_nvidia_init); module_exit(agp_nvidia_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("NVIDIA Corporation"); diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c --- a/drivers/char/agp/sis-agp.c Mon Aug 18 22:21:01 2003 +++ b/drivers/char/agp/sis-agp.c Mon Aug 18 22:21:01 2003 @@ -8,8 +8,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - static int sis_fetch_size(void) { u8 temp_size; @@ -97,7 +95,7 @@ .agp_destroy_page = agp_generic_destroy_page, }; -struct agp_device_ids sis_agp_device_ids[] __initdata = +static struct agp_device_ids sis_agp_device_ids[] __initdata = { { .device_id = PCI_DEVICE_ID_SI_530, @@ -187,16 +185,9 @@ } } - if (!agp_try_unsupported) { - printk(KERN_ERR PFX - "Unsupported SiS chipset (device id: %04x)," - " you might want to try agp_try_unsupported=1.\n", + printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n", pdev->device); - return -ENODEV; - } - - printk(KERN_WARNING PFX "Trying generic SiS routines" - " for device id: %04x\n", pdev->device); + return -ENODEV; found: bridge = agp_alloc_bridge(); @@ -258,5 +249,4 @@ module_init(agp_sis_init); module_exit(agp_sis_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c --- a/drivers/char/agp/sworks-agp.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/agp/sworks-agp.c Mon Aug 18 22:21:02 2003 @@ -8,8 +8,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - struct serverworks_page_map { unsigned long *real; unsigned long *remapped; @@ -268,6 +266,10 @@ pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); serverworks_private.registers = (volatile u8 *) ioremap(temp, 4096); + if (!serverworks_private.registers) { + printk (KERN_ERR PFX "Unable to ioremap() memory.\n"); + return -ENOMEM; + } OUTREG8(serverworks_private.registers, SVWRKS_GART_CACHE, 0x0a); @@ -446,8 +448,8 @@ bridge_dev = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); if (!bridge_dev) { - printk(KERN_INFO PFX "agpgart: Detected a Serverworks " - "Chipset, but could not find the secondary device.\n"); + printk(KERN_INFO PFX "Detected a Serverworks chipset " + "but could not find the secondary device.\n"); return -ENODEV; } @@ -457,9 +459,9 @@ case 0x0007: break; default: - if (!agp_try_unsupported) - return -ENODEV; - break; + printk(KERN_ERR PFX "Unsupported Serverworks chipset " + "(device id: %04x)\n", pdev->device); + return -ENODEV; } serverworks_private.svrwrks_dev = bridge_dev; @@ -542,6 +544,5 @@ module_init(agp_serverworks_init); module_exit(agp_serverworks_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); diff -Nru a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c --- a/drivers/char/agp/uninorth-agp.c Mon Aug 18 22:21:03 2003 +++ b/drivers/char/agp/uninorth-agp.c Mon Aug 18 22:21:03 2003 @@ -10,8 +10,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - static int uninorth_fetch_size(void) { int i; @@ -284,7 +282,7 @@ .cant_use_aperture = 1, }; -struct agp_device_ids uninorth_agp_device_ids[] __initdata = { +static struct agp_device_ids uninorth_agp_device_ids[] __initdata = { { .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP, .chipset_name = "UniNorth", @@ -324,15 +322,9 @@ } } - if (!agp_try_unsupported) { - printk(KERN_ERR PFX "Unsupported Apple chipset" - " (device id: %04x).\n", pdev->device); - printk(KERN_ERR PFX "You might want to try" - " agp_try_unsupported=1\n"); - return -ENODEV; - } - printk(KERN_ERR PFX "Trying generic Uninorth routines" - " for device id %04x\n", pdev->device); + printk(KERN_ERR PFX "Unsupported Apple chipset (device id: %04x).\n", + pdev->device); + return -ENODEV; found: bridge = agp_alloc_bridge(); @@ -392,6 +384,5 @@ module_init(agp_uninorth_init); module_exit(agp_uninorth_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c --- a/drivers/char/agp/via-agp.c Mon Aug 18 22:21:05 2003 +++ b/drivers/char/agp/via-agp.c Mon Aug 18 22:21:05 2003 @@ -9,9 +9,6 @@ #include #include "agp.h" -static int agp_try_unsupported __initdata = 0; - - static int via_fetch_size(void) { int i; @@ -123,6 +120,14 @@ /* attbase - aperture GATT base */ pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE, agp_bridge->gatt_bus_addr & 0xfffff000); + + /* 1. Enable GTLB in RX90<7>, all AGP aperture access needs to fetch + * translation table first. + * 2. Enable AGP aperture in RX91<0>. This bit controls the enabling of the + * graphics AGP aperture for the AGP3.0 port. + */ + pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp | (3<<7)); return 0; } @@ -382,16 +387,9 @@ } } - if (!agp_try_unsupported) { - printk(KERN_ERR PFX - "Unsupported VIA chipset (device id: %04x)," - " you might want to try agp_try_unsupported=1.\n", + printk(KERN_ERR PFX "Unsupported VIA chipset (device id: %04x)\n", pdev->device); - return -ENODEV; - } - - printk(KERN_WARNING PFX "Trying generic VIA routines" - " for device id: %04x\n", pdev->device); + return -ENODEV; found: bridge = agp_alloc_bridge(); @@ -470,6 +468,5 @@ module_init(agp_via_init); module_exit(agp_via_cleanup); -MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Dave Jones "); diff -Nru a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h --- a/drivers/char/drm/drm_agpsupport.h Mon Aug 18 22:21:00 2003 +++ b/drivers/char/drm/drm_agpsupport.h Mon Aug 18 22:21:00 2003 @@ -105,7 +105,8 @@ if (!dev->agp || dev->agp->acquired || !drm_agp->acquire) return -EINVAL; - if ((retcode = drm_agp->acquire())) return retcode; + if ((retcode = drm_agp->acquire())) + return retcode; dev->agp->acquired = 1; return 0; } @@ -142,7 +143,8 @@ */ void DRM(agp_do_release)(void) { - if (drm_agp->release) drm_agp->release(); + if (drm_agp->release) + drm_agp->release(); } /** @@ -200,7 +202,8 @@ unsigned long pages; u32 type; - if (!dev->agp || !dev->agp->acquired) return -EINVAL; + if (!dev->agp || !dev->agp->acquired) + return -EINVAL; if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request))) return -EFAULT; if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS))) @@ -222,11 +225,12 @@ entry->pages = pages; entry->prev = NULL; entry->next = dev->agp->memory; - if (dev->agp->memory) dev->agp->memory->prev = entry; + if (dev->agp->memory) + dev->agp->memory->prev = entry; dev->agp->memory = entry; request.handle = entry->handle; - request.physical = memory->physical; + request.physical = memory->physical; if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) { dev->agp->memory = entry->next; @@ -253,7 +257,8 @@ drm_agp_mem_t *entry; for (entry = dev->agp->memory; entry; entry = entry->next) { - if (entry->handle == handle) return entry; + if (entry->handle == handle) + return entry; } return NULL; } @@ -279,12 +284,14 @@ drm_agp_mem_t *entry; int ret; - if (!dev->agp || !dev->agp->acquired) return -EINVAL; + if (!dev->agp || !dev->agp->acquired) + return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) return -EFAULT; if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; - if (!entry->bound) return -EINVAL; + if (!entry->bound) + return -EINVAL; ret = DRM(unbind_agp)(entry->memory); if (ret == 0) entry->bound = 0; @@ -320,9 +327,11 @@ return -EFAULT; if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; - if (entry->bound) return -EINVAL; + if (entry->bound) + return -EINVAL; page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; - if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode; + if ((retcode = DRM(bind_agp)(entry->memory, page))) + return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", dev->agp->base, entry->bound); @@ -351,16 +360,23 @@ drm_agp_buffer_t request; drm_agp_mem_t *entry; - if (!dev->agp || !dev->agp->acquired) return -EINVAL; + if (!dev->agp || !dev->agp->acquired) + return -EINVAL; if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request))) return -EFAULT; if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; - if (entry->bound) DRM(unbind_agp)(entry->memory); + if (entry->bound) + DRM(unbind_agp)(entry->memory); + + if (entry->prev) + entry->prev->next = entry->next; + else + dev->agp->memory = entry->next; + + if (entry->next) + entry->next->prev = entry->prev; - if (entry->prev) entry->prev->next = entry->next; - else dev->agp->memory = entry->next; - if (entry->next) entry->next->prev = entry->prev; DRM(free_agp)(entry->memory, entry->pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; @@ -415,14 +431,16 @@ /** Calls drm_agp->allocate_memory() */ struct agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type) { - if (!drm_agp->allocate_memory) return NULL; + if (!drm_agp->allocate_memory) + return NULL; return drm_agp->allocate_memory(pages, type); } /** Calls drm_agp->free_memory() */ int DRM(agp_free_memory)(struct agp_memory *handle) { - if (!handle || !drm_agp->free_memory) return 0; + if (!handle || !drm_agp->free_memory) + return 0; drm_agp->free_memory(handle); return 1; } @@ -430,14 +448,16 @@ /** Calls drm_agp->bind_memory() */ int DRM(agp_bind_memory)(struct agp_memory *handle, off_t start) { - if (!handle || !drm_agp->bind_memory) return -EINVAL; + if (!handle || !drm_agp->bind_memory) + return -EINVAL; return drm_agp->bind_memory(handle, start); } /** Calls drm_agp->unbind_memory() */ int DRM(agp_unbind_memory)(struct agp_memory *handle) { - if (!handle || !drm_agp->unbind_memory) return -EINVAL; + if (!handle || !drm_agp->unbind_memory) + return -EINVAL; return drm_agp->unbind_memory(handle); } diff -Nru a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c --- a/drivers/char/drm/gamma_dma.c Mon Aug 18 22:21:05 2003 +++ b/drivers/char/drm/gamma_dma.c Mon Aug 18 22:21:05 2003 @@ -44,9 +44,14 @@ drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; mb(); - while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2) + cpu_relax(); + GAMMA_WRITE(GAMMA_DMAADDRESS, address); - while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4); + + while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) + cpu_relax(); + GAMMA_WRITE(GAMMA_DMACOUNT, length / 4); } @@ -54,16 +59,18 @@ { drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; - while (GAMMA_READ(GAMMA_DMACOUNT)); + while (GAMMA_READ(GAMMA_DMACOUNT)) + cpu_relax(); - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2) + cpu_relax(); GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) - ; + cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); } @@ -71,9 +78,11 @@ { drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; - while (GAMMA_READ(GAMMA_DMACOUNT)); + while (GAMMA_READ(GAMMA_DMACOUNT)) + cpu_relax(); - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) + cpu_relax(); GAMMA_WRITE(GAMMA_BROADCASTMASK, 3); GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); @@ -81,12 +90,14 @@ /* Read from first MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)); + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) + cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); /* Read from second MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)); + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) + cpu_relax(); } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG); } @@ -94,14 +105,15 @@ { drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; - while (GAMMA_READ(GAMMA_DMACOUNT)); + while (GAMMA_READ(GAMMA_DMACOUNT)) + cpu_relax(); } static inline int gamma_dma_is_ready(drm_device_t *dev) { drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; - return(!GAMMA_READ(GAMMA_DMACOUNT)); + return (!GAMMA_READ(GAMMA_DMACOUNT)); } irqreturn_t gamma_dma_service(int irq, void *device, struct pt_regs *regs) @@ -113,7 +125,9 @@ atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) + cpu_relax(); + GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); @@ -824,7 +838,8 @@ drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2) + cpu_relax(); GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); @@ -834,7 +849,8 @@ drm_gamma_private_t *dev_priv = (drm_gamma_private_t *)dev->dev_private; - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3) + cpu_relax(); GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); @@ -847,7 +863,8 @@ if (!dev_priv) return; - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3) + cpu_relax(); GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); diff -Nru a/drivers/char/drm/i810.h b/drivers/char/drm/i810.h --- a/drivers/char/drm/i810.h Mon Aug 18 22:21:02 2003 +++ b/drivers/char/drm/i810.h Mon Aug 18 22:21:02 2003 @@ -55,9 +55,10 @@ * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) * - Remove requirement for interrupt (leave stubs again) * 1.3 - Add page flipping. + * 1.4 - fix DRM interface */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 +#define DRIVER_MINOR 4 #define DRIVER_PATCHLEVEL 0 #define DRIVER_IOCTLS \ diff -Nru a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c --- a/drivers/char/drm/i810_dma.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/drm/i810_dma.c Mon Aug 18 22:21:02 2003 @@ -443,6 +443,49 @@ return 0; } +/* i810 DRM version 1.1 used a smaller init structure with different + * ordering of values than is currently used (drm >= 1.2). There is + * no defined way to detect the XFree version to correct this problem, + * however by checking using this procedure we can detect the correct + * thing to do. + * + * #1 Read the Smaller init structure from user-space + * #2 Verify the overlay_physical is a valid physical address, or NULL + * If it isn't then we have a v1.1 client. Fix up params. + * If it is, then we have a 1.2 client... get the rest of the data. + */ +int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg) +{ + + /* Get v1.1 init data */ + if (copy_from_user(init, (drm_i810_pre12_init_t *)arg, + sizeof(drm_i810_pre12_init_t))) { + return -EFAULT; + } + + if ((!init->overlay_physical) || (init->overlay_physical > 4096)) { + + /* This is a v1.2 client, just get the v1.2 init data */ + DRM_INFO("Using POST v1.2 init.\n"); + if(copy_from_user(init, (drm_i810_init_t *)arg, + sizeof(drm_i810_init_t))) { + return -EFAULT; + } + } else { + + /* This is a v1.1 client, fix the params */ + DRM_INFO("Using PRE v1.2 init.\n"); + init->pitch_bits = init->h; + init->pitch = init->w; + init->h = init->overlay_physical; + init->w = init->overlay_offset; + init->overlay_physical = 0; + init->overlay_offset = 0; + } + + return 0; +} + int i810_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -452,22 +495,46 @@ drm_i810_init_t init; int retcode = 0; - if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init))) + /* Get only the init func */ + if (copy_from_user(&init, (void *)arg, sizeof(drm_i810_init_func_t))) return -EFAULT; switch(init.func) { case I810_INIT_DMA: + /* This case is for backward compatibility. It + * handles XFree 4.1.0 and 4.2.0, and has to + * do some parameter checking as described below. + * It will someday go away. + */ + retcode = i810_dma_init_compat(&init, arg); + if (retcode) + return retcode; + + dev_priv = DRM(alloc)(sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + retcode = i810_dma_initialize(dev, dev_priv, &init); + break; + + default: + case I810_INIT_DMA_1_4: + DRM_INFO("Using v1.4 init.\n"); + if (copy_from_user(&init, (drm_i810_init_t *)arg, + sizeof(drm_i810_init_t))) { + return -EFAULT; + } dev_priv = DRM(alloc)(sizeof(drm_i810_private_t), DRM_MEM_DRIVER); - if(dev_priv == NULL) return -ENOMEM; + if (dev_priv == NULL) + return -ENOMEM; retcode = i810_dma_initialize(dev, dev_priv, &init); - break; + break; + case I810_CLEANUP_DMA: + DRM_INFO("DMA Cleanup\n"); retcode = i810_dma_cleanup(dev); - break; - default: - retcode = -EINVAL; - break; + break; } return retcode; @@ -477,12 +544,16 @@ /* Most efficient way to verify state for the i810 is as it is * emitted. Non-conformant state is silently dropped. + * + * Use 'volatile' & local var tmp to force the emitted values to be + * identical to the verified ones. */ static void i810EmitContextVerified( drm_device_t *dev, - unsigned int *code ) + volatile unsigned int *code ) { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; + unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); @@ -494,10 +565,12 @@ OUT_RING( code[I810_CTXREG_ST1] ); for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { - if ((code[i] & (7<<29)) == (3<<29) && - (code[i] & (0x1f<<24)) < (0x1d<<24)) + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( code[i] ); + OUT_RING( tmp ); j++; } else printk("constext state dropped!!!\n"); @@ -514,6 +587,7 @@ { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; + unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); @@ -524,11 +598,12 @@ OUT_RING( code[I810_TEXREG_MI3] ); for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; - if ((code[i] & (7<<29)) == (3<<29) && - (code[i] & (0x1f<<24)) < (0x1d<<24)) + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( code[i] ); + OUT_RING( tmp ); j++; } else printk("texture state dropped!!!\n"); @@ -556,9 +631,9 @@ if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( tmp ); - } - else - printk("buffer state dropped\n"); + } else + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); /* invarient: */ @@ -986,6 +1061,9 @@ return -EINVAL; } + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; i810_dma_dispatch_vertex( dev, @@ -1034,6 +1112,8 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + DRM_DEBUG("i810_swap_bufs\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_swap_buf called without lock held\n"); return -EINVAL; @@ -1080,6 +1160,9 @@ d.granted = 0; retcode = i810_dma_get_buffer(dev, &d, filp); + + DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", + current->pid, retcode, d.granted); if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) return -EFAULT; diff -Nru a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h --- a/drivers/char/drm/i810_drm.h Mon Aug 18 22:21:00 2003 +++ b/drivers/char/drm/i810_drm.h Mon Aug 18 22:21:00 2003 @@ -94,12 +94,15 @@ #define I810_BACK 0x2 #define I810_DEPTH 0x4 +typedef enum _drm_i810_init_func { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02, + I810_INIT_DMA_1_4 = 0x03 + } drm_i810_init_func_t; +/* This is the init structure after v1.2 */ typedef struct _drm_i810_init { - enum { - I810_INIT_DMA = 0x01, - I810_CLEANUP_DMA = 0x02 - } func; + drm_i810_init_func_t func; #if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) int ring_map_idx; int buffer_map_idx; @@ -121,6 +124,24 @@ unsigned int pitch; unsigned int pitch_bits; } drm_i810_init_t; + +/* This is the init structure prior to v1.2 */ +typedef struct _drm_i810_pre12_init { + drm_i810_init_func_t func; + unsigned int mmio_offset; + unsigned int buffers_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; +} drm_i810_pre12_init_t; /* Warning: If you change the SAREA structure you must change the Xserver * structure as well */ diff -Nru a/drivers/char/drm/r128.h b/drivers/char/drm/r128.h --- a/drivers/char/drm/r128.h Mon Aug 18 22:21:02 2003 +++ b/drivers/char/drm/r128.h Mon Aug 18 22:21:02 2003 @@ -57,6 +57,7 @@ * * ?? - ?? * 2.4 - Add support for ycbcr textures (no new ioctls) + * 2.5 - Add FLIP ioctl, disable FULLSCREEN. */ #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ diff -Nru a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h --- a/drivers/char/drm/radeon.h Mon Aug 18 22:21:05 2003 +++ b/drivers/char/drm/radeon.h Mon Aug 18 22:21:05 2003 @@ -80,6 +80,7 @@ * 1.8 - Remove need to call cleanup ioctls on last client exit (keith) * Add 'GET' queries for starting additional clients on different VT's. * Add DRM_IOCTL_RADEON_CP_RESUME ioctl. + * 1.9 - Add texture rectangle support for r100. */ #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ diff -Nru a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h --- a/drivers/char/drm/radeon_drm.h Mon Aug 18 22:21:04 2003 +++ b/drivers/char/drm/radeon_drm.h Mon Aug 18 22:21:04 2003 @@ -529,8 +529,10 @@ #define RADEON_PARAM_LAST_FRAME 2 #define RADEON_PARAM_LAST_DISPATCH 3 #define RADEON_PARAM_LAST_CLEAR 4 +/* Added with DRM version 1.6. */ #define RADEON_PARAM_IRQ_NR 5 #define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */ +/* Added with DRM version 1.8. */ #define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */ #define RADEON_PARAM_STATUS_HANDLE 8 #define RADEON_PARAM_SAREA_HANDLE 9 diff -Nru a/drivers/char/esp.c b/drivers/char/esp.c --- a/drivers/char/esp.c Mon Aug 18 22:21:00 2003 +++ b/drivers/char/esp.c Mon Aug 18 22:21:00 2003 @@ -107,8 +107,6 @@ static char serial_name[] __initdata = "ESP serial driver"; static char serial_version[] __initdata = "2.2"; -static DECLARE_TASK_QUEUE(tq_esp); - static struct tty_driver *esp_driver; /* serial subtype definitions */ @@ -272,9 +270,9 @@ int event) { info->event |= 1 << event; - queue_task(&info->tqueue, &tq_esp); - mark_bh(ESP_BH); + schedule_work(&info->tqueue); } + static _INLINE_ struct esp_pio_buffer *get_pio_buffer(void) { struct esp_pio_buffer *buf; @@ -368,7 +366,7 @@ } } - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; release_pio_buffer(pio_buf); @@ -443,7 +441,7 @@ tty->flip.flag_buf_ptr++; - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); } if (dma_bytes != num_bytes) { @@ -636,7 +634,7 @@ #ifdef SERIAL_DEBUG_OPEN printk("scheduling hangup..."); #endif - schedule_task(&info->tqueue_hangup); + schedule_work(&info->tqueue_hangup); } } } @@ -754,20 +752,6 @@ * ------------------------------------------------------------------- */ -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_esp); -} - static void do_softint(void *private_) { struct esp_struct *info = (struct esp_struct *) private_; @@ -2477,8 +2461,6 @@ if (!esp_driver) return -ENOMEM; - init_bh(ESP_BH, do_serial_bh); - for (i = 0; i < NR_PRIMARY; i++) { if (irq[i] != 0) { if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) || @@ -2568,10 +2550,8 @@ info->magic = ESP_MAGIC; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->tqueue_hangup.routine = do_serial_hangup; - info->tqueue_hangup.data = info; + INIT_WORK(&info->tqueue, do_softint, info); + INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info); info->config.rx_timeout = rx_timeout; info->config.flow_on = flow_on; info->config.flow_off = flow_off; @@ -2640,7 +2620,6 @@ /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ save_flags(flags); cli(); - remove_bh(ESP_BH); if ((e1 = tty_unregister_driver(esp_driver))) printk("SERIAL: failed to unregister serial driver (%d)\n", e1); diff -Nru a/drivers/char/ipmi/ipmi_kcs_intf.c b/drivers/char/ipmi/ipmi_kcs_intf.c --- a/drivers/char/ipmi/ipmi_kcs_intf.c Mon Aug 18 22:21:00 2003 +++ b/drivers/char/ipmi/ipmi_kcs_intf.c Mon Aug 18 22:21:00 2003 @@ -1018,52 +1018,81 @@ #ifdef CONFIG_ACPI_INTERPRETER -/* Retrieve the base physical address from ACPI tables. Originally - from Hewlett-Packard simple bmc.c, a GPL KCS driver. */ - #include struct SPMITable { - s8 Signature[4]; - u32 Length; - u8 Revision; - u8 Checksum; - s8 OEMID[6]; - s8 OEMTableID[8]; - s8 OEMRevision[4]; - s8 CreatorID[4]; - s8 CreatorRevision[4]; - s16 InterfaceType; - s16 SpecificationRevision; - u8 InterruptType; - u8 GPE; - s16 Reserved; - u64 GlobalSystemInterrupt; - u8 BaseAddress[12]; - u8 UID[4]; -} __attribute__ ((packed)); + s8 Signature[4]; + u32 Length; + u8 Revision; + u8 Checksum; + s8 OEMID[6]; + s8 OEMTableID[8]; + s8 OEMRevision[4]; + s8 CreatorID[4]; + s8 CreatorRevision[4]; + u8 InterfaceType[2]; + s16 SpecificationRevision; + + /* + * Bit 0 - SCI interrupt supported + * Bit 1 - I/O APIC/SAPIC + */ + u8 InterruptType; + + /* If bit 0 of InterruptType is set, then this is the SCI + interrupt in the GPEx_STS register. */ + u8 GPE; + + s16 Reserved; + + /* If bit 1 of InterruptType is set, then this is the I/O + APIC/SAPIC interrupt. */ + u32 GlobalSystemInterrupt; + + /* The actual register address. */ + struct acpi_generic_address addr; -static unsigned long acpi_find_bmc(void) -{ - acpi_status status; - struct acpi_table_header *spmi; - static unsigned long io_base = 0; + u8 UID[4]; - if (io_base != 0) - return io_base; + s8 spmi_id[1]; /* A '\0' terminated array starts here. */ +}; +static int acpi_find_bmc(unsigned long *physaddr, int *port) +{ + acpi_status status; + struct SPMITable *spmi; + status = acpi_get_firmware_table("SPMI", 1, - ACPI_LOGICAL_ADDRESSING, &spmi); + ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) &spmi); + if (status != AE_OK) + goto not_found; + + if (spmi->InterfaceType[0] != 1) + /* Not IPMI. */ + goto not_found; + + if (spmi->InterfaceType[1] != 1) + /* Not KCS. */ + goto not_found; + + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + *physaddr = spmi->addr.address; + printk("ipmi_kcs_intf: Found ACPI-specified state machine" + " at memory address 0x%lx\n", + (unsigned long) spmi->addr.address); + } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + *port = spmi->addr.address; + printk("ipmi_kcs_intf: Found ACPI-specified state machine" + " at I/O address 0x%lx\n", + (unsigned long) spmi->addr.address); + } else + goto not_found; /* Not an address type we recognise. */ - if (status != AE_OK) { - printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n"); - return 0; - } + return 0; - memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress, - sizeof(io_base)); - - return io_base; + not_found: + return -ENODEV; } #endif @@ -1074,6 +1103,7 @@ int i = 0; #ifdef CONFIG_ACPI_INTERPRETER unsigned long physaddr = 0; + int port = 0; #endif if (initialized) @@ -1101,20 +1131,19 @@ /* Only try the defaults if enabled and resources are available (because they weren't already specified above). */ - if (kcs_trydefaults) { + if (kcs_trydefaults && (pos == 0)) { + rv = -EINVAL; #ifdef CONFIG_ACPI_INTERPRETER - if ((physaddr = acpi_find_bmc())) { - if (!check_mem_region(physaddr, 2)) { - rv = init_one_kcs(0, - 0, - physaddr, - &(kcs_infos[pos])); - if (rv == 0) - pos++; - } + if (rv && (physaddr = acpi_find_bmc(&physaddr, &port) == 0)) { + rv = init_one_kcs(port, + 0, + physaddr, + &(kcs_infos[pos])); + if (rv == 0) + pos++; } #endif - if (!check_region(DEFAULT_IO_PORT, 2)) { + if (rv) { rv = init_one_kcs(DEFAULT_IO_PORT, 0, 0, diff -Nru a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c --- a/drivers/char/ipmi/ipmi_watchdog.c Mon Aug 18 22:21:06 2003 +++ b/drivers/char/ipmi/ipmi_watchdog.c Mon Aug 18 22:21:06 2003 @@ -559,7 +559,10 @@ case WDIOC_GETSTATUS: val = 0; - return copy_to_user((void *) arg, &val, sizeof(val)); + i = copy_to_user((void *) arg, &val, sizeof(val)); + if (i) + return -EFAULT; + return 0; default: return -ENOIOCTLCMD; diff -Nru a/drivers/char/isicom.c b/drivers/char/isicom.c --- a/drivers/char/isicom.c Mon Aug 18 22:21:00 2003 +++ b/drivers/char/isicom.c Mon Aug 18 22:21:00 2003 @@ -80,8 +80,6 @@ static struct isi_board isi_card[BOARD_COUNT]; static struct isi_port isi_ports[PORT_COUNT]; -DECLARE_TASK_QUEUE(tq_isicom); - static struct timer_list tx; static char re_schedule = 1; #ifdef ISICOM_DEBUG @@ -354,12 +352,6 @@ return 0; } -static inline void schedule_bh(struct isi_port * port) -{ - queue_task(&port->bh_tqueue, &tq_isicom); - mark_bh(ISICOM_BH); -} - /* Transmitter */ static void isicom_tx(unsigned long _data) @@ -464,7 +456,7 @@ if (port->xmit_cnt <= 0) port->status &= ~ISI_TXOK; if (port->xmit_cnt <= WAKEUP_CHARS) - schedule_bh(port); + schedule_work(&port->bh_tqueue); restore_flags(flags); } @@ -483,12 +475,6 @@ /* Interrupt handlers */ -static void do_isicom_bh(void) -{ - run_task_queue(&tq_isicom); -} - - static void isicom_bottomhalf(void * data) { @@ -584,7 +570,7 @@ printk(KERN_DEBUG "ISICOM: interrupt: DCD->low.\n"); #endif port->status &= ~ISI_DCD; - schedule_task(&port->hangup_tq); + schedule_work(&port->hangup_tq); } } else { @@ -611,7 +597,7 @@ port->tty->hw_stopped = 0; /* start tx ing */ port->status |= (ISI_TXOK | ISI_CTS); - schedule_bh(port); + schedule_work(&port->bh_tqueue); } } else { @@ -650,7 +636,7 @@ tty->flip.count++; if (port->flags & ASYNC_SAK) do_SAK(tty); - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); break; case 2: /* Statistics */ @@ -688,7 +674,7 @@ byte_count -= 2; } } - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); } if (card->isa == YES) ClearInterrupt(base); @@ -1806,10 +1792,6 @@ return 0; } - /* initialize bottom half */ - init_bh(ISICOM_BH, do_isicom_bh); - - memset(isi_ports, 0, sizeof(isi_ports)); for (card = 0; card < BOARD_COUNT; card++) { port = &isi_ports[card * 16]; @@ -1821,10 +1803,8 @@ port->channel = channel; port->close_delay = 50 * HZ/100; port->closing_wait = 3000 * HZ/100; - port->hangup_tq.routine = do_isicom_hangup; - port->hangup_tq.data = port; - port->bh_tqueue.routine = isicom_bottomhalf; - port->bh_tqueue.data = port; + INIT_WORK(&port->hangup_tq, do_isicom_hangup, port); + INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port); port->status = 0; init_waitqueue_head(&port->open_wait); init_waitqueue_head(&port->close_wait); @@ -1956,8 +1936,6 @@ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); - remove_bh(ISICOM_BH); - #ifdef ISICOM_DEBUG printk("ISICOM: isicom_tx tx_count = %ld.\n", tx_count); #endif diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c --- a/drivers/char/keyboard.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/keyboard.c Mon Aug 18 22:21:02 2003 @@ -660,9 +660,12 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { + unsigned v; + if (up_flag) return; - if (value < ARRAY_SIZE(func_table)) { + v = value; + if (v < ARRAY_SIZE(func_table)) { if (func_table[value]) puts_queue(vc, func_table[value]); } else diff -Nru a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c --- a/drivers/char/mwave/mwavedd.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/mwave/mwavedd.c Mon Aug 18 22:21:02 2003 @@ -643,7 +643,6 @@ /* sysfs */ memset(&mwave_device, 0, sizeof (struct device)); - snprintf(mwave_device.name, DEVICE_NAME_SIZE, "mwave"); snprintf(mwave_device.bus_id, BUS_ID_SIZE, "mwave"); if (device_register(&mwave_device)) diff -Nru a/drivers/char/random.c b/drivers/char/random.c --- a/drivers/char/random.c Mon Aug 18 22:21:01 2003 +++ b/drivers/char/random.c Mon Aug 18 22:21:01 2003 @@ -1850,27 +1850,62 @@ } ctl_table random_table[] = { - {RANDOM_POOLSIZE, "poolsize", - &sysctl_poolsize, sizeof(int), 0644, NULL, - &proc_do_poolsize, &poolsize_strategy}, - {RANDOM_ENTROPY_COUNT, "entropy_avail", - NULL, sizeof(int), 0444, NULL, - &proc_dointvec}, - {RANDOM_READ_THRESH, "read_wakeup_threshold", - &random_read_wakeup_thresh, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, 0, - &min_read_thresh, &max_read_thresh}, - {RANDOM_WRITE_THRESH, "write_wakeup_threshold", - &random_write_wakeup_thresh, sizeof(int), 0644, NULL, - &proc_dointvec_minmax, &sysctl_intvec, 0, - &min_write_thresh, &max_write_thresh}, - {RANDOM_BOOT_ID, "boot_id", - &sysctl_bootid, 16, 0444, NULL, - &proc_do_uuid, &uuid_strategy}, - {RANDOM_UUID, "uuid", - NULL, 16, 0444, NULL, - &proc_do_uuid, &uuid_strategy}, - {0} + { + .ctl_name = RANDOM_POOLSIZE, + .procname = "poolsize", + .data = &sysctl_poolsize, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_do_poolsize, + .strategy = &poolsize_strategy, + }, + { + .ctl_name = RANDOM_ENTROPY_COUNT, + .procname = "entropy_avail", + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = RANDOM_READ_THRESH, + .procname = "read_wakeup_threshold", + .data = &random_read_wakeup_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_read_thresh, + .extra2 = &max_read_thresh, + }, + { + .ctl_name = RANDOM_WRITE_THRESH, + .procname = "write_wakeup_threshold", + .data = &random_write_wakeup_thresh, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_write_thresh, + .extra2 = &max_write_thresh, + }, + { + .ctl_name = RANDOM_BOOT_ID, + .procname = "boot_id", + .data = &sysctl_bootid, + .maxlen = 16, + .mode = 0444, + .proc_handler = &proc_do_uuid, + .strategy = &uuid_strategy, + }, + { + .ctl_name = RANDOM_UUID, + .procname = "uuid", + .maxlen = 16, + .mode = 0444, + .proc_handler = &proc_do_uuid, + .strategy = &uuid_strategy, + }, + { .ctl_name = 0 } }; static void sysctl_init_random(struct entropy_store *random_state) diff -Nru a/drivers/char/riscom8.c b/drivers/char/riscom8.c --- a/drivers/char/riscom8.c Mon Aug 18 22:21:03 2003 +++ b/drivers/char/riscom8.c Mon Aug 18 22:21:03 2003 @@ -81,8 +81,6 @@ #define RS_EVENT_WRITE_WAKEUP 0 -static DECLARE_TASK_QUEUE(tq_riscom); - static struct riscom_board * IRQ_to_board[16]; static struct tty_driver *riscom_driver; static unsigned char * tmp_buf; @@ -332,17 +330,8 @@ static inline void rc_mark_event(struct riscom_port * port, int event) { - /* - * I'm not quite happy with current scheme all serial - * drivers use their own BH routine. - * It seems this easily can be done with one BH routine - * serving for all serial drivers. - * For now I must introduce another one - RISCOM8_BH. - * Still hope this will be changed in near future. - */ set_bit(event, &port->event); - queue_task(&port->tqueue, &tq_riscom); - mark_bh(RISCOM8_BH); + schedule_work(&port->tqueue); } static inline struct riscom_port * rc_get_port(struct riscom_board const * bp, @@ -425,7 +414,7 @@ *tty->flip.char_buf_ptr++ = ch; tty->flip.count++; - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); } static inline void rc_receive(struct riscom_board const * bp) @@ -456,7 +445,7 @@ *tty->flip.flag_buf_ptr++ = 0; tty->flip.count++; } - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); } static inline void rc_transmit(struct riscom_board const * bp) @@ -544,7 +533,7 @@ if (rc_in(bp, CD180_MSVR) & MSVR_CD) wake_up_interruptible(&port->open_wait); else - schedule_task(&port->tqueue_hangup); + schedule_work(&port->tqueue_hangup); } #ifdef RISCOM_BRAIN_DAMAGED_CTS @@ -1598,11 +1587,11 @@ } /* - * This routine is called from the scheduler tqueue when the interrupt + * This routine is called from the work queue when the interrupt * routine has signalled that a hangup has occurred. The path of * hangup processing is: * - * serial interrupt routine -> (scheduler tqueue) -> + * serial interrupt routine -> (workqueue) -> * do_rc_hangup() -> tty->hangup() -> rc_hangup() * */ @@ -1657,11 +1646,6 @@ } } -static void do_riscom_bh(void) -{ - run_task_queue(&tq_riscom); -} - static void do_softint(void *private_) { struct riscom_port *port = (struct riscom_port *) private_; @@ -1710,7 +1694,6 @@ put_tty_driver(riscom_driver); return 1; } - init_bh(RISCOM8_BH, do_riscom_bh); memset(IRQ_to_board, 0, sizeof(IRQ_to_board)); riscom_driver->owner = THIS_MODULE; riscom_driver->name = "ttyL"; @@ -1734,10 +1717,8 @@ memset(rc_port, 0, sizeof(rc_port)); for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { rc_port[i].magic = RISCOM8_MAGIC; - rc_port[i].tqueue.routine = do_softint; - rc_port[i].tqueue.data = &rc_port[i]; - rc_port[i].tqueue_hangup.routine = do_rc_hangup; - rc_port[i].tqueue_hangup.data = &rc_port[i]; + INIT_WORK(&rc_port[i].tqueue, do_softint, &rc_port[i]); + INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup, &rc_port[i]); rc_port[i].close_delay = 50 * HZ/100; rc_port[i].closing_wait = 3000 * HZ/100; init_waitqueue_head(&rc_port[i].open_wait); @@ -1753,7 +1734,6 @@ save_flags(flags); cli(); - remove_bh(RISCOM8_BH); free_page((unsigned long)tmp_buf); tty_unregister_driver(riscom_driver); put_tty_driver(riscom_driver); diff -Nru a/drivers/char/riscom8.h b/drivers/char/riscom8.h --- a/drivers/char/riscom8.h Mon Aug 18 22:21:06 2003 +++ b/drivers/char/riscom8.h Mon Aug 18 22:21:06 2003 @@ -81,8 +81,8 @@ int xmit_cnt; wait_queue_head_t open_wait; wait_queue_head_t close_wait; - struct tq_struct tqueue; - struct tq_struct tqueue_hangup; + struct work_struct tqueue; + struct work_struct tqueue_hangup; short wakeup_chars; short break_length; unsigned short closing_wait; diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c --- a/drivers/char/rtc.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/rtc.c Mon Aug 18 22:21:02 2003 @@ -43,9 +43,11 @@ * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. * 1.11 Takashi Iwai: Kernel access functions * rtc_register/rtc_unregister/rtc_control + * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init + * */ -#define RTC_VERSION "1.11" +#define RTC_VERSION "1.11a" #define RTC_IO_EXTENT 0x8 @@ -881,15 +883,13 @@ } no_irq: #else - if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) - { + if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) { printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0)); return -EIO; } #if RTC_IRQ - if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) - { + if (request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) { /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); release_region(RTC_PORT(0), RTC_IO_EXTENT); @@ -899,15 +899,21 @@ #endif /* __sparc__ vs. others */ - if (misc_register(&rtc_dev)) - { + if (misc_register(&rtc_dev)) { #if RTC_IRQ free_irq(RTC_IRQ, NULL); #endif release_region(RTC_PORT(0), RTC_IO_EXTENT); return -ENODEV; - } - create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL); + } + if (create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL) == NULL) { +#if RTC_IRQ + free_irq(RTC_IRQ, NULL); +#endif + release_region(RTC_PORT(0), RTC_IO_EXTENT); + misc_deregister(&rtc_dev); + return -ENOMEM; + } #if defined(__alpha__) || defined(__mips__) rtc_freq = HZ; diff -Nru a/drivers/char/specialix.c b/drivers/char/specialix.c --- a/drivers/char/specialix.c Mon Aug 18 22:21:05 2003 +++ b/drivers/char/specialix.c Mon Aug 18 22:21:05 2003 @@ -593,18 +593,8 @@ static inline void sx_mark_event(struct specialix_port * port, int event) { - /* - * I'm not quite happy with current scheme all serial - * drivers use their own BH routine. - * It seems this easily can be done with one BH routine - * serving for all serial drivers. - * For now I must introduce another one - SPECIALIX_BH. - * Still hope this will be changed in near future. - * -- Dmitry. - */ set_bit(event, &port->event); - queue_task(&port->tqueue, &tq_specialix); - mark_bh(SPECIALIX_BH); + schedule_work(&port->tqueue); } @@ -689,7 +679,7 @@ *tty->flip.char_buf_ptr++ = ch; tty->flip.count++; - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); } @@ -720,7 +710,7 @@ *tty->flip.flag_buf_ptr++ = 0; tty->flip.count++; } - queue_task(&tty->flip.tqueue, &tq_timer); + schedule_delayed_work(&tty->flip.work, 1); } @@ -824,7 +814,7 @@ #ifdef SPECIALIX_DEBUG printk ( "Sending HUP.\n"); #endif - schedule_task(&port->tqueue_hangup); + schedule_work(&port->tqueue_hangup); } } @@ -2067,11 +2057,11 @@ /* - * This routine is called from the scheduler tqueue when the interrupt + * This routine is called from the work-queue when the interrupt * routine has signalled that a hangup has occurred. The path of * hangup processing is: * - * serial interrupt routine -> (scheduler tqueue) -> + * serial interrupt routine -> (workqueue) -> * do_sx_hangup() -> tty->hangup() -> sx_hangup() * */ @@ -2129,12 +2119,6 @@ } -static void do_specialix_bh(void) -{ - run_task_queue(&tq_specialix); -} - - static void do_softint(void *private_) { struct specialix_port *port = (struct specialix_port *) private_; @@ -2185,7 +2169,6 @@ put_tty_driver(specialix_driver); return 1; } - init_bh(SPECIALIX_BH, do_specialix_bh); specialix_driver->owner = THIS_MODULE; specialix_driver->name = "ttyW"; specialix_driver->major = SPECIALIX_NORMAL_MAJOR; @@ -2207,10 +2190,8 @@ memset(sx_port, 0, sizeof(sx_port)); for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { sx_port[i].magic = SPECIALIX_MAGIC; - sx_port[i].tqueue.routine = do_softint; - sx_port[i].tqueue.data = &sx_port[i]; - sx_port[i].tqueue_hangup.routine = do_sx_hangup; - sx_port[i].tqueue_hangup.data = &sx_port[i]; + INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]); + INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]); sx_port[i].close_delay = 50 * HZ/100; sx_port[i].closing_wait = 3000 * HZ/100; init_waitqueue_head(&sx_port[i].open_wait); diff -Nru a/drivers/char/specialix_io8.h b/drivers/char/specialix_io8.h --- a/drivers/char/specialix_io8.h Mon Aug 18 22:21:00 2003 +++ b/drivers/char/specialix_io8.h Mon Aug 18 22:21:00 2003 @@ -120,8 +120,8 @@ int xmit_cnt; wait_queue_head_t open_wait; wait_queue_head_t close_wait; - struct tq_struct tqueue; - struct tq_struct tqueue_hangup; + struct work_struct tqueue; + struct work_struct tqueue_hangup; short wakeup_chars; short break_length; unsigned short closing_wait; diff -Nru a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c --- a/drivers/char/vt_ioctl.c Mon Aug 18 22:21:04 2003 +++ b/drivers/char/vt_ioctl.c Mon Aug 18 22:21:04 2003 @@ -82,8 +82,6 @@ if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry))) return -EFAULT; - if (i >= NR_KEYS || s >= MAX_NR_KEYMAPS) - return -EINVAL; switch (cmd) { case KDGKBENT: @@ -208,10 +206,6 @@ goto reterr; } kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0'; - if (kbs->kb_func >= MAX_NR_FUNC) { - ret = -EINVAL; - goto reterr; - } i = kbs->kb_func; switch (cmd) { diff -Nru a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c --- a/drivers/char/watchdog/advantechwdt.c Mon Aug 18 22:21:02 2003 +++ b/drivers/char/watchdog/advantechwdt.c Mon Aug 18 22:21:02 2003 @@ -44,6 +44,7 @@ #include #define WATCHDOG_NAME "Advantech WDT" +#define PFX WATCHDOG_NAME ": " #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ static unsigned long advwdt_is_open; @@ -70,7 +71,7 @@ static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=60."); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -206,7 +207,7 @@ if (adv_expect_close == 42) { advwdt_disable(); } else { - printk(KERN_CRIT WATCHDOG_NAME ": Unexpected close, not stopping watchdog!\n"); + printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); advwdt_ping(); } clear_bit(0, &advwdt_is_open); @@ -268,13 +269,13 @@ if (timeout < 1 || timeout > 63) { timeout = WATCHDOG_TIMEOUT; - printk (KERN_INFO WATCHDOG_NAME ": timeout value must be 1<=x<=63, using %d\n", + printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", timeout); } if (wdt_stop != wdt_start) { if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { - printk (KERN_ERR WATCHDOG_NAME ": I/O address 0x%04x already in use\n", + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_stop); ret = -EIO; goto out; @@ -282,7 +283,7 @@ } if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { - printk (KERN_ERR WATCHDOG_NAME ": I/O address 0x%04x already in use\n", + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_start); ret = -EIO; goto unreg_stop; @@ -290,19 +291,19 @@ ret = register_reboot_notifier(&advwdt_notifier); if (ret != 0) { - printk (KERN_ERR WATCHDOG_NAME ": cannot register reboot notifier (err=%d)\n", + printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto unreg_regions; } ret = misc_register(&advwdt_miscdev); if (ret != 0) { - printk (KERN_ERR WATCHDOG_NAME ": cannot register miscdev on minor=%d (err=%d)\n", + printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto unreg_reboot; } - printk (KERN_INFO WATCHDOG_NAME ": initialized. timeout=%d sec (nowayout=%d)\n", + printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); out: diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c --- a/drivers/char/watchdog/alim7101_wdt.c Mon Aug 18 22:21:04 2003 +++ b/drivers/char/watchdog/alim7101_wdt.c Mon Aug 18 22:21:04 2003 @@ -1,26 +1,11 @@ /* - * ALi M7101 PMU Computer Watchdog Timer driver for Linux 2.4.x + * ALi M7101 PMU Computer Watchdog Timer driver * - * Based on w83877f_wdt.c by Scott Jennings + * Based on w83877f_wdt.c by Scott Jennings * and the Cobalt kernel WDT timer driver by Tim Hockin * * * (c)2002 Steve Hill - * - * Theory of operation: - * A Watchdog Timer (WDT) is a hardware circuit that can - * reset the computer system in case of a software fault. - * You probably knew that already. - * - * Usually a userspace daemon will notify the kernel WDT driver - * via the /proc/watchdog special device file that userspace is - * still alive, at regular intervals. When such a notification - * occurs, the driver will usually tell the hardware watchdog - * that everything is in order, and that the watchdog should wait - * for yet another little while to reset the system. - * If userspace fails (RAM error, kernel bug, whatever), the - * notifications cease to occur, and the hardware watchdog will - * reset the system (causing a reboot) after the timeout occurs. * * This WDT driver is different from most other Linux WDT * drivers in that the driver will ping the watchdog by itself, @@ -30,6 +15,7 @@ */ #include +#include #include #include #include @@ -38,7 +24,6 @@ #include #include #include -#include #include #include @@ -46,6 +31,7 @@ #include #define OUR_NAME "alim7101_wdt" +#define PFX OUR_NAME ": " #define WDT_ENABLE 0x9C #define WDT_DISABLE 0x8C @@ -65,13 +51,16 @@ * char to /dev/watchdog every 30 seconds. */ -#define WDT_HEARTBEAT (HZ * 30) +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ +static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); static void wdt_timer_ping(unsigned long); static struct timer_list timer; static unsigned long next_heartbeat; static unsigned long wdt_is_open; -static int wdt_expect_close; +static char wdt_expect_close; static struct pci_dev *alim7101_pmu; #ifdef CONFIG_WATCHDOG_NOWAYOUT @@ -79,7 +68,7 @@ #else static int nowayout = 0; #endif - + module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); @@ -90,25 +79,25 @@ static void wdt_timer_ping(unsigned long data) { /* If we got a heartbeat pulse within the WDT_US_INTERVAL - * we agree to ping the WDT + * we agree to ping the WDT */ char tmp; - if(time_before(jiffies, next_heartbeat)) + if(time_before(jiffies, next_heartbeat)) { /* Ping the WDT (this is actually a disarm/arm sequence) */ pci_read_config_byte(alim7101_pmu, 0x92, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); } else { - printk(KERN_INFO OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n"); + printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); } /* Re-set the timer interval */ timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); } -/* +/* * Utility routines */ @@ -125,7 +114,7 @@ static void wdt_startup(void) { - next_heartbeat = jiffies + WDT_HEARTBEAT; + next_heartbeat = jiffies + (timeout * HZ); /* We must enable before we kick off the timer in case the timer occurs as we ping it */ @@ -133,11 +122,11 @@ wdt_change(WDT_ENABLE); /* Start the timer */ - timer.expires = jiffies + WDT_INTERVAL; + timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); - printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled.\n"); + printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); } static void wdt_turnoff(void) @@ -145,7 +134,13 @@ /* Stop the timer */ del_timer_sync(&timer); wdt_change(WDT_DISABLE); - printk(KERN_INFO OUR_NAME ": Watchdog timer is now disabled...\n"); + printk(KERN_INFO PFX "Watchdog timer is now disabled...\n"); +} + +static void wdt_keepalive(void) +{ + /* user land ping */ + next_heartbeat = jiffies + (timeout * HZ); } /* @@ -158,7 +153,7 @@ if(ppos != &file->f_pos) return -ESPIPE; - /* See if we got the magic character */ + /* See if we got the magic character 'V' and reload the timer */ if(count) { if (!nowayout) { size_t ofs; @@ -173,14 +168,13 @@ if (get_user(c, buf+ofs)) return -EFAULT; if (c == 'V') - wdt_expect_close = 1; + wdt_expect_close = 42; } } /* someone wrote to us, we should restart timer */ - next_heartbeat = jiffies + WDT_HEARTBEAT; - return 1; - }; - return 0; + wdt_keepalive(); + } + return count; } static int fop_open(struct inode * inode, struct file * file) @@ -195,12 +189,14 @@ static int fop_close(struct inode * inode, struct file * file) { - if(wdt_expect_close) + if(wdt_expect_close == 42) wdt_turnoff(); - else - printk(KERN_INFO OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); - + else { + /* wim: shouldn't there be a: del_timer(&timer); */ + printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); + } clear_bit(0, &wdt_is_open); + wdt_expect_close = 0; return 0; } @@ -208,20 +204,58 @@ { static struct watchdog_info ident = { - .options = WDIOF_MAGICCLOSE, + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "ALiM7101" + .identity = "ALiM7101", }; - + switch(cmd) { case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: - next_heartbeat = jiffies + WDT_HEARTBEAT; + wdt_keepalive(); return 0; + case WDIOC_SETOPTIONS: + { + int new_options, retval = -EINVAL; + + if(get_user(new_options, (int *)arg)) + return -EFAULT; + + if(new_options & WDIOS_DISABLECARD) { + wdt_turnoff(); + retval = 0; + } + + if(new_options & WDIOS_ENABLECARD) { + wdt_startup(); + retval = 0; + } + + return retval; + } + case WDIOC_SETTIMEOUT: + { + int new_timeout; + + if(get_user(new_timeout, (int *)arg)) + return -EFAULT; + + if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ + return -EINVAL; + + timeout = new_timeout; + wdt_keepalive(); + /* Fall through */ + } + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); default: - return -ENOTTY; + return -ENOIOCTLCMD; } } @@ -231,13 +265,13 @@ .write= fop_write, .open= fop_open, .release= fop_close, - .ioctl= fop_ioctl + .ioctl= fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor=WATCHDOG_MINOR, .name="watchdog", - .fops=&wdt_fops + .fops=&wdt_fops, }; /* @@ -256,21 +290,21 @@ * reboot with no heartbeat */ wdt_change(WDT_ENABLE); - printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); + printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); } return NOTIFY_DONE; } - + /* * The WDT needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * turn the timebomb registers off. */ - + static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, .next = 0, - .priority = 0 + .priority = 0, }; static void __exit alim7101_wdt_unload(void) @@ -287,10 +321,10 @@ struct pci_dev *ali1543_south; char tmp; - printk(KERN_INFO OUR_NAME ": Steve Hill .\n"); + printk(KERN_INFO PFX "Steve Hill .\n"); alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL); if (!alim7101_pmu) { - printk(KERN_INFO OUR_NAME ": ALi M7101 PMU not present - WDT not set\n"); + printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n"); return -EBUSY; } @@ -299,35 +333,53 @@ ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!ali1543_south) { - printk(KERN_INFO OUR_NAME ": ALi 1543 South-Bridge not present - WDT not set\n"); + printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); return -EBUSY; } pci_read_config_byte(ali1543_south, 0x5e, &tmp); if ((tmp & 0x1e) != 0x12) { - printk(KERN_INFO OUR_NAME ": ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); + printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); return -EBUSY; } + if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ + { + timeout = WATCHDOG_TIMEOUT; + printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", + timeout); + } + init_timer(&timer); timer.function = wdt_timer_ping; timer.data = 1; rc = misc_register(&wdt_miscdev); - if (rc) - return rc; + if (rc) { + printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + wdt_miscdev.minor, rc); + goto err_out; + } rc = register_reboot_notifier(&wdt_notifier); if (rc) { - misc_deregister(&wdt_miscdev); - return rc; + printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + rc); + goto err_out_miscdev; } - printk(KERN_INFO OUR_NAME ": WDT driver for ALi M7101 initialised.\n"); + printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", + timeout, nowayout); return 0; + +err_out_miscdev: + misc_deregister(&wdt_miscdev); +err_out: + return rc; } module_init(alim7101_wdt_init); module_exit(alim7101_wdt_unload); MODULE_AUTHOR("Steve Hill"); +MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver"); MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c --- a/drivers/char/watchdog/sbc60xxwdt.c Mon Aug 18 22:21:04 2003 +++ b/drivers/char/watchdog/sbc60xxwdt.c Mon Aug 18 22:21:04 2003 @@ -7,51 +7,40 @@ * 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. - * - * The author does NOT admit liability nor provide warranty for - * any of this software. This material is provided "AS-IS" in - * the hope that it may be useful for others. * - * (c) Copyright 2000 Jakob Oestergaard + * The author does NOT admit liability nor provide warranty for + * any of this software. This material is provided "AS-IS" in + * the hope that it may be useful for others. + * + * (c) Copyright 2000 Jakob Oestergaard * * 12/4 - 2000 [Initial revision] * 25/4 - 2000 Added /dev/watchdog support * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" on success + * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read + * fix possible wdt_is_open race + * add CONFIG_WATCHDOG_NOWAYOUT support + * remove lock_kernel/unlock_kernel pairs + * added KERN_* to printk's + * got rid of extraneous comments + * changed watchdog_info to correctly reflect what the driver offers + * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, + * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls + * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces + * use module_param + * made timeout (the emulated heartbeat) a module_param + * made the keepalive ping an internal subroutine + * made wdt_stop and wdt_start module params + * added extra printk's for startup problems + * added MODULE_AUTHOR and MODULE_DESCRIPTION info * * - * Theory of operation: - * A Watchdog Timer (WDT) is a hardware circuit that can - * reset the computer system in case of a software fault. - * You probably knew that already. - * - * Usually a userspace daemon will notify the kernel WDT driver - * via the /proc/watchdog special device file that userspace is - * still alive, at regular intervals. When such a notification - * occurs, the driver will usually tell the hardware watchdog - * that everything is in order, and that the watchdog should wait - * for yet another little while to reset the system. - * If userspace fails (RAM error, kernel bug, whatever), the - * notifications cease to occur, and the hardware watchdog will - * reset the system (causing a reboot) after the timeout occurs. - * - * This WDT driver is different from the other Linux WDT - * drivers in several ways: + * This WDT driver is different from the other Linux WDT + * drivers in the following ways: * *) The driver will ping the watchdog by itself, because this * particular WDT has a very short timeout (one second) and it * would be insane to count on any userspace daemon always * getting scheduled within that time frame. - * *) This driver expects the userspace daemon to send a specific - * character code ('V') to /dev/watchdog before closing the - * /dev/watchdog file. If the userspace daemon closes the file - * without sending this special character, the driver will assume - * that the daemon (and userspace in general) died, and will - * stop pinging the WDT without disabling it first. This will - * cause a reboot. - * - * Why `V' ? Well, `V' is the character in ASCII for the value 86, - * and we all know that 86 is _the_ most random number in the universe. - * Therefore it is the letter that has the slightest chance of occurring - * by chance, when the system becomes corrupted. * */ @@ -73,13 +62,19 @@ #include #define OUR_NAME "sbc60xxwdt" +#define PFX OUR_NAME ": " /* * You must set these - The driver cannot probe for the settings */ - -#define WDT_STOP 0x45 -#define WDT_START 0x443 + +static int wdt_stop = 0x45; +module_param(wdt_stop, int, 0); +MODULE_PARM_DESC(wdt_stop, "SBC60xx WDT 'stop' io port (default 0x45)"); + +static int wdt_start = 0x443; +module_param(wdt_start, int, 0); +MODULE_PARM_DESC(wdt_start, "SBC60xx WDT 'start' io port (default 0x443)"); /* * The 60xx board can use watchdog timeout values from one second @@ -92,19 +87,16 @@ /* * We must not require too good response from the userspace daemon. * Here we require the userspace daemon to send us a heartbeat - * char to /dev/watchdog every 10 seconds. - * If the daemon pulses us every 5 seconds, we can still afford + * char to /dev/watchdog every 30 seconds. + * If the daemon pulses us every 25 seconds, we can still afford * a 5 second scheduling delay on the (high priority) daemon. That * should be sufficient for a box under any load. */ -#define WDT_HEARTBEAT (HZ * 10) - -static void wdt_timer_ping(unsigned long); -static struct timer_list timer; -static unsigned long next_heartbeat; -static int wdt_is_open; -static int wdt_expect_close; +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ +static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -115,6 +107,12 @@ module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); +static void wdt_timer_ping(unsigned long); +static struct timer_list timer; +static unsigned long next_heartbeat; +static unsigned long wdt_is_open; +static char wdt_expect_close; + /* * Whack the dog */ @@ -122,42 +120,47 @@ static void wdt_timer_ping(unsigned long data) { /* If we got a heartbeat pulse within the WDT_US_INTERVAL - * we agree to ping the WDT + * we agree to ping the WDT */ - if(time_before(jiffies, next_heartbeat)) + if(time_before(jiffies, next_heartbeat)) { - /* Ping the WDT by reading from WDT_START */ - inb_p(WDT_START); + /* Ping the WDT by reading from wdt_start */ + inb_p(wdt_start); /* Re-set the timer interval */ timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); } else { - printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n"); + printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); } } -/* +/* * Utility routines */ static void wdt_startup(void) { - next_heartbeat = jiffies + WDT_HEARTBEAT; + next_heartbeat = jiffies + (timeout * HZ); /* Start the timer */ - timer.expires = jiffies + WDT_INTERVAL; + timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); - printk(OUR_NAME ": Watchdog timer is now enabled.\n"); + printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); } static void wdt_turnoff(void) { /* Stop the timer */ del_timer(&timer); - inb_p(WDT_STOP); - printk(OUR_NAME ": Watchdog timer is now disabled...\n"); + inb_p(wdt_stop); + printk(KERN_INFO PFX "Watchdog timer is now disabled...\n"); } +static void wdt_keepalive(void) +{ + /* user land ping */ + next_heartbeat = jiffies + (timeout * HZ); +} /* * /dev/watchdog handling @@ -169,63 +172,58 @@ if(ppos != &file->f_pos) return -ESPIPE; - /* See if we got the magic character */ - if(count) + /* See if we got the magic character 'V' and reload the timer */ + if(count) { - size_t ofs; - - /* note: just in case someone wrote the magic character - * five months ago... */ - wdt_expect_close = 0; - - /* now scan */ - for(ofs = 0; ofs != count; ofs++) + if (!nowayout) { - char c; - if(get_user(c, buf+ofs)) - return -EFAULT; - if(c == 'V') - wdt_expect_close = 1; + size_t ofs; + + /* note: just in case someone wrote the magic character + * five months ago... */ + wdt_expect_close = 0; + + /* scan to see wether or not we got the magic character */ + for(ofs = 0; ofs != count; ofs++) + { + char c; + if(get_user(c, buf+ofs)) + return -EFAULT; + if(c == 'V') + wdt_expect_close = 42; + } } + /* Well, anyhow someone wrote to us, we should return that favour */ - next_heartbeat = jiffies + WDT_HEARTBEAT; - return 1; + wdt_keepalive(); } - return 0; + return count; } static int fop_open(struct inode * inode, struct file * file) { - switch(minor(inode->i_rdev)) - { - case WATCHDOG_MINOR: - /* Just in case we're already talking to someone... */ - if(wdt_is_open) - return -EBUSY; - if (nowayout) - __module_get(THIS_MODULE); - /* Good, fire up the show */ - wdt_is_open = 1; - wdt_startup(); - return 0; + /* Just in case we're already talking to someone... */ + if(test_and_set_bit(0, &wdt_is_open)) + return -EBUSY; - default: - return -ENODEV; - } + if (nowayout) + __module_get(THIS_MODULE); + + /* Good, fire up the show */ + wdt_startup(); + return 0; } static int fop_close(struct inode * inode, struct file * file) { - if(minor(inode->i_rdev) == WATCHDOG_MINOR) - { - if(wdt_expect_close && !nowayout) - wdt_turnoff(); - else { - del_timer(&timer); - printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); - } + if(wdt_expect_close == 42) + wdt_turnoff(); + else { + del_timer(&timer); + printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); } - wdt_is_open = 0; + clear_bit(0, &wdt_is_open); + wdt_expect_close = 0; return 0; } @@ -234,20 +232,58 @@ { static struct watchdog_info ident= { - .options = WDIOF_MAGICCLOSE, + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "SB60xx" + .identity = "SBC60xx", }; - + switch(cmd) { default: - return -ENOTTY; + return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: - next_heartbeat = jiffies + WDT_HEARTBEAT; + wdt_keepalive(); return 0; + case WDIOC_SETOPTIONS: + { + int new_options, retval = -EINVAL; + + if(get_user(new_options, (int *)arg)) + return -EFAULT; + + if(new_options & WDIOS_DISABLECARD) { + wdt_turnoff(); + retval = 0; + } + + if(new_options & WDIOS_ENABLECARD) { + wdt_startup(); + retval = 0; + } + + return retval; + } + case WDIOC_SETTIMEOUT: + { + int new_timeout; + + if(get_user(new_timeout, (int *)arg)) + return -EFAULT; + + if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ + return -EINVAL; + + timeout = new_timeout; + wdt_keepalive(); + /* Fall through */ + } + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); } } @@ -257,13 +293,13 @@ .write = fop_write, .open = fop_open, .release = fop_close, - .ioctl = fop_ioctl + .ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &wdt_fops + .fops = &wdt_fops, }; /* @@ -273,21 +309,21 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if(code==SYS_DOWN || code==SYS_HALT) + if(code==SYS_DOWN || code==SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } - + /* * The WDT needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * turn the timebomb registers off. */ - + static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, .next = NULL, - .priority = 0 + .priority = 0, }; static void __exit sbc60xxwdt_unload(void) @@ -298,19 +334,41 @@ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); - release_region(WDT_START,1); -// release_region(WDT_STOP,1); + if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) + release_region(wdt_stop,1); + release_region(wdt_start,1); } static int __init sbc60xxwdt_init(void) { int rc = -EBUSY; -// We cannot reserve 0x45 - the kernel already has! -// if (!request_region(WDT_STOP, 1, "SBC 60XX WDT")) -// goto err_out; - if (!request_region(WDT_START, 1, "SBC 60XX WDT")) - goto err_out_region1; + if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ + { + timeout = WATCHDOG_TIMEOUT; + printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", + timeout); + } + + if (!request_region(wdt_start, 1, "SBC 60XX WDT")) + { + printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_start); + rc = -EIO; + goto err_out; + } + + /* We cannot reserve 0x45 - the kernel already has! */ + if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) + { + if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) + { + printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_stop); + rc = -EIO; + goto err_out_region1; + } + } init_timer(&timer); timer.function = wdt_timer_ping; @@ -318,27 +376,39 @@ rc = misc_register(&wdt_miscdev); if (rc) + { + printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + wdt_miscdev.minor, rc); goto err_out_region2; + } rc = register_reboot_notifier(&wdt_notifier); if (rc) + { + printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + rc); goto err_out_miscdev; + } + + printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", + timeout, nowayout); - printk(KERN_INFO OUR_NAME ": WDT driver for 60XX single board computer initialised.\n"); - return 0; err_out_miscdev: misc_deregister(&wdt_miscdev); err_out_region2: - release_region(WDT_START,1); + if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) + release_region(wdt_stop,1); err_out_region1: - release_region(WDT_STOP,1); -/* err_out: */ + release_region(wdt_start,1); +err_out: return rc; } module_init(sbc60xxwdt_init); module_exit(sbc60xxwdt_unload); +MODULE_AUTHOR("Jakob Oestergaard "); +MODULE_DESCRIPTION("60xx Single Board Computer Watchdog Timer driver"); MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c --- a/drivers/char/watchdog/sc520_wdt.c Mon Aug 18 22:21:03 2003 +++ b/drivers/char/watchdog/sc520_wdt.c Mon Aug 18 22:21:03 2003 @@ -1,21 +1,21 @@ /* - * AMD Elan SC520 processor Watchdog Timer driver for Linux 2.4.x + * AMD Elan SC520 processor Watchdog Timer driver * * Based on acquirewdt.c by Alan Cox, - * and sbc60xxwdt.c by Jakob Oestergaard - * + * and sbc60xxwdt.c by Jakob Oestergaard + * * 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. - * - * The authors do NOT admit liability nor provide warranty for - * any of this software. This material is provided "AS-IS" in + * + * The authors do NOT admit liability nor provide warranty for + * any of this software. This material is provided "AS-IS" in * the hope that it may be useful for others. * * (c) Copyright 2001 Scott Jennings * 9/27 - 2001 [Initial release] - * + * * Additional fixes Alan Cox * - Fixed formatting * - Removed debug printks @@ -24,20 +24,21 @@ * - Used ioremap/writew/readw * - Added NOWAYOUT support * - * Theory of operation: - * A Watchdog Timer (WDT) is a hardware circuit that can - * reset the computer system in case of a software fault. - * You probably knew that already. - * - * Usually a userspace daemon will notify the kernel WDT driver - * via the /proc/watchdog special device file that userspace is - * still alive, at regular intervals. When such a notification - * occurs, the driver will usually tell the hardware watchdog - * that everything is in order, and that the watchdog should wait - * for yet another little while to reset the system. - * If userspace fails (RAM error, kernel bug, whatever), the - * notifications cease to occur, and the hardware watchdog will - * reset the system (causing a reboot) after the timeout occurs. + * 4/12 - 2002 Changes by Rob Radez + * - Change comments + * - Eliminate fop_llseek + * - Change CONFIG_WATCHDOG_NOWAYOUT semantics + * - Add KERN_* tags to printks + * - fix possible wdt_is_open race + * - Report proper capabilities in watchdog_info + * - Add WDIOC_{GETSTATUS, GETBOOTSTATUS, SETTIMEOUT, + * GETTIMEOUT, SETOPTIONS} ioctls + * 09/8 - 2003 Changes by Wim Van Sebroeck + * - cleanup of trailing spaces + * - added extra printk's for startup problems + * - use module_param + * - made timeout (the emulated heartbeat) a module_param + * - made the keepalive ping an internal subroutine * * This WDT driver is different from most other Linux WDT * drivers in that the driver will ping the watchdog by itself, @@ -77,7 +78,10 @@ * char to /dev/watchdog every 30 seconds. */ -#define WDT_HEARTBEAT (HZ * 30) +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ +static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); /* * AMD Elan SC520 timeout value is 492us times a power of 2 (0-7) @@ -95,6 +99,7 @@ #define WDT_WRST_ENB 0x4000 /* [14] Watchdog Timer Reset Enable */ #define OUR_NAME "sc520_wdt" +#define PFX OUR_NAME ": " #define WRT_DOG(data) *wdtmrctl=data @@ -104,7 +109,8 @@ static struct timer_list timer; static unsigned long next_heartbeat; static unsigned long wdt_is_open; -static int wdt_expect_close; +static char wdt_expect_close; +static spinlock_t wdt_spinlock; #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -115,7 +121,6 @@ module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); -static spinlock_t wdt_spinlock; /* * Whack the dog */ @@ -123,9 +128,9 @@ static void wdt_timer_ping(unsigned long data) { /* If we got a heartbeat pulse within the WDT_US_INTERVAL - * we agree to ping the WDT + * we agree to ping the WDT */ - if(time_before(jiffies, next_heartbeat)) + if(time_before(jiffies, next_heartbeat)) { /* Ping the WDT */ spin_lock(&wdt_spinlock); @@ -137,11 +142,11 @@ timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); } else { - printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n"); + printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); } } -/* +/* * Utility routines */ @@ -165,14 +170,14 @@ static void wdt_startup(void) { - next_heartbeat = jiffies + WDT_HEARTBEAT; + next_heartbeat = jiffies + (timeout * HZ); /* Start the timer */ - timer.expires = jiffies + WDT_INTERVAL; + timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); wdt_config(WDT_ENB | WDT_WRST_ENB | TIMEOUT_EXPONENT); - printk(OUR_NAME ": Watchdog timer is now enabled.\n"); + printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); } static void wdt_turnoff(void) @@ -181,10 +186,15 @@ /* Stop the timer */ del_timer(&timer); wdt_config(0); - printk(OUR_NAME ": Watchdog timer is now disabled...\n"); + printk(KERN_INFO PFX "Watchdog timer is now disabled...\n"); } } +static void wdt_keepalive(void) +{ + /* user land ping */ + next_heartbeat = jiffies + (timeout * HZ); +} /* * /dev/watchdog handling @@ -196,62 +206,56 @@ if(ppos != &file->f_pos) return -ESPIPE; - /* See if we got the magic character */ - if(count) + /* See if we got the magic character 'V' and reload the timer */ + if(count) { - size_t ofs; - - /* note: just in case someone wrote the magic character - * five months ago... */ - wdt_expect_close = 0; - - /* now scan */ - for(ofs = 0; ofs != count; ofs++) { - char c; - if (get_user(c, buf + ofs)) - return -EFAULT; - if(c == 'V') - wdt_expect_close = 1; + if (!nowayout) + { + size_t ofs; + + /* note: just in case someone wrote the magic character + * five months ago... */ + wdt_expect_close = 0; + + /* now scan */ + for(ofs = 0; ofs != count; ofs++) { + char c; + if (get_user(c, buf + ofs)) + return -EFAULT; + if(c == 'V') + wdt_expect_close = 42; + } } /* Well, anyhow someone wrote to us, we should return that favour */ - next_heartbeat = jiffies + WDT_HEARTBEAT; - return 1; + wdt_keepalive(); } - return 0; + return count; } static int fop_open(struct inode * inode, struct file * file) { - switch(minor(inode->i_rdev)) - { - case WATCHDOG_MINOR: - /* Just in case we're already talking to someone... */ - if(test_and_set_bit(0, &wdt_is_open)) - return -EBUSY; - /* Good, fire up the show */ - wdt_startup(); - if (nowayout) - __module_get(THIS_MODULE); + /* Just in case we're already talking to someone... */ + if(test_and_set_bit(0, &wdt_is_open)) + return -EBUSY; + if (nowayout) + __module_get(THIS_MODULE); - return 0; - default: - return -ENODEV; - } + /* Good, fire up the show */ + wdt_startup(); + return 0; } static int fop_close(struct inode * inode, struct file * file) { - if(minor(inode->i_rdev) == WATCHDOG_MINOR) - { - if(wdt_expect_close) - wdt_turnoff(); - else { - del_timer(&timer); - printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); - } + if(wdt_expect_close == 42) + wdt_turnoff(); + else { + del_timer(&timer); + printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); } clear_bit(0, &wdt_is_open); + wdt_expect_close = 0; return 0; } @@ -260,20 +264,58 @@ { static struct watchdog_info ident= { - .options = WDIOF_MAGICCLOSE, + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "SC520" + .identity = "SC520", }; - + switch(cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: - next_heartbeat = jiffies + WDT_HEARTBEAT; + wdt_keepalive(); return 0; + case WDIOC_SETOPTIONS: + { + int new_options, retval = -EINVAL; + + if(get_user(new_options, (int *)arg)) + return -EFAULT; + + if(new_options & WDIOS_DISABLECARD) { + wdt_turnoff(); + retval = 0; + } + + if(new_options & WDIOS_ENABLECARD) { + wdt_startup(); + retval = 0; + } + + return retval; + } + case WDIOC_SETTIMEOUT: + { + int new_timeout; + + if(get_user(new_timeout, (int *)arg)) + return -EFAULT; + + if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ + return -EINVAL; + + timeout = new_timeout; + wdt_keepalive(); + /* Fall through */ + } + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); } } @@ -283,13 +325,13 @@ .write = fop_write, .open = fop_open, .release = fop_close, - .ioctl = fop_ioctl + .ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &wdt_fops + .fops = &wdt_fops, }; /* @@ -299,21 +341,21 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if(code==SYS_DOWN || code==SYS_HALT) + if(code==SYS_DOWN || code==SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } - + /* * The WDT needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * turn the timebomb registers off. */ - + static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, .next = NULL, - .priority = 0 + .priority = 0, }; static void __exit sc520_wdt_unload(void) @@ -333,27 +375,42 @@ spin_lock_init(&wdt_spinlock); + if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ + { + timeout = WATCHDOG_TIMEOUT; + printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", + timeout); + } + init_timer(&timer); timer.function = wdt_timer_ping; timer.data = 0; rc = misc_register(&wdt_miscdev); if (rc) + { + printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + wdt_miscdev.minor, rc); goto err_out_region2; + } rc = register_reboot_notifier(&wdt_notifier); if (rc) + { + printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + rc); goto err_out_miscdev; + } /* get the Base Address Register */ cbar = inl_p(0xfffc); - printk(OUR_NAME ": CBAR: 0x%08lx\n", cbar); + printk(KERN_INFO PFX "CBAR: 0x%08lx\n", cbar); /* check if MMCR aliasing bit is set */ if (cbar & 0x80000000) { - printk(OUR_NAME ": MMCR Aliasing enabled.\n"); + printk(KERN_INFO PFX "MMCR Aliasing enabled.\n"); wdtmrctl = (__u16 *)(cbar & 0x3fffffff); } else { - printk(OUR_NAME "!!! WARNING !!!\n" + printk(KERN_INFO PFX "!!! WARNING !!!\n" "\t MMCR Aliasing found NOT enabled!\n" "\t Using default value of: %p\n" "\t This has not been tested!\n" @@ -366,7 +423,8 @@ wdtmrctl = (__u16 *)((char *)wdtmrctl + OFFS_WDTMRCTL); wdtmrctl = ioremap((unsigned long)wdtmrctl, 2); - printk(KERN_INFO OUR_NAME ": WDT driver for SC520 initialised.\n"); + printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", + timeout,nowayout); return 0; diff -Nru a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c --- a/drivers/char/watchdog/w83877f_wdt.c Mon Aug 18 22:21:04 2003 +++ b/drivers/char/watchdog/w83877f_wdt.c Mon Aug 18 22:21:04 2003 @@ -1,38 +1,36 @@ /* - * W83877F Computer Watchdog Timer driver for Linux 2.4.x + * W83877F Computer Watchdog Timer driver * * Based on acquirewdt.c by Alan Cox, - * and sbc60xxwdt.c by Jakob Oestergaard - * + * and sbc60xxwdt.c by Jakob Oestergaard + * * 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. - * - * The authors do NOT admit liability nor provide warranty for - * any of this software. This material is provided "AS-IS" in + * + * The authors do NOT admit liability nor provide warranty for + * any of this software. This material is provided "AS-IS" in * the hope that it may be useful for others. * * (c) Copyright 2001 Scott Jennings * * 4/19 - 2001 [Initial revision] * 9/27 - 2001 Added spinlocking - * - * - * Theory of operation: - * A Watchdog Timer (WDT) is a hardware circuit that can - * reset the computer system in case of a software fault. - * You probably knew that already. - * - * Usually a userspace daemon will notify the kernel WDT driver - * via the /proc/watchdog special device file that userspace is - * still alive, at regular intervals. When such a notification - * occurs, the driver will usually tell the hardware watchdog - * that everything is in order, and that the watchdog should wait - * for yet another little while to reset the system. - * If userspace fails (RAM error, kernel bug, whatever), the - * notifications cease to occur, and the hardware watchdog will - * reset the system (causing a reboot) after the timeout occurs. + * 4/12 - 2002 [rob@osinvestor.com] Eliminate extra comments + * Eliminate fop_read + * Eliminate extra spin_unlock + * Added KERN_* tags to printks + * add CONFIG_WATCHDOG_NOWAYOUT support + * fix possible wdt_is_open race + * changed watchdog_info to correctly reflect what the driver offers + * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, + * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls + * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces + * added extra printk's for startup problems + * use module_param + * made timeout (the emulated heartbeat) a module_param + * made the keepalive ping an internal subroutine * * This WDT driver is different from most other Linux WDT * drivers in that the driver will ping the watchdog by itself, @@ -42,6 +40,7 @@ */ #include +#include #include #include #include @@ -57,6 +56,7 @@ #include #define OUR_NAME "w83877f_wdt" +#define PFX OUR_NAME ": " #define ENABLE_W83877F_PORT 0x3F0 #define ENABLE_W83877F 0x87 @@ -79,13 +79,26 @@ * char to /dev/watchdog every 30 seconds. */ -#define WDT_HEARTBEAT (HZ * 30) +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ +static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + + +#ifdef CONFIG_WATCHDOG_NOWAYOUT +static int nowayout = 1; +#else +static int nowayout = 0; +#endif + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); static void wdt_timer_ping(unsigned long); static struct timer_list timer; static unsigned long next_heartbeat; static unsigned long wdt_is_open; -static int wdt_expect_close; +static char wdt_expect_close; static spinlock_t wdt_spinlock; /* @@ -95,9 +108,9 @@ static void wdt_timer_ping(unsigned long data) { /* If we got a heartbeat pulse within the WDT_US_INTERVAL - * we agree to ping the WDT + * we agree to ping the WDT */ - if(time_before(jiffies, next_heartbeat)) + if(time_before(jiffies, next_heartbeat)) { /* Ping the WDT */ spin_lock(&wdt_spinlock); @@ -112,11 +125,11 @@ spin_unlock(&wdt_spinlock); } else { - printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n"); + printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); } } -/* +/* * Utility routines */ @@ -144,15 +157,15 @@ static void wdt_startup(void) { - next_heartbeat = jiffies + WDT_HEARTBEAT; + next_heartbeat = jiffies + (timeout * HZ); /* Start the timer */ - timer.expires = jiffies + WDT_INTERVAL; + timer.expires = jiffies + WDT_INTERVAL; add_timer(&timer); wdt_change(WDT_ENABLE); - printk(OUR_NAME ": Watchdog timer is now enabled.\n"); + printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); } static void wdt_turnoff(void) @@ -162,9 +175,14 @@ wdt_change(WDT_DISABLE); - printk(OUR_NAME ": Watchdog timer is now disabled...\n"); + printk(KERN_INFO PFX "Watchdog timer is now disabled...\n"); } +static void wdt_keepalive(void) +{ + /* user land ping */ + next_heartbeat = jiffies + (timeout * HZ); +} /* * /dev/watchdog handling @@ -176,64 +194,55 @@ if(ppos != &file->f_pos) return -ESPIPE; - /* See if we got the magic character */ - if(count) + /* See if we got the magic character 'V' and reload the timer */ + if(count) { - size_t ofs; - - /* note: just in case someone wrote the magic character - * five months ago... */ - wdt_expect_close = 0; - - /* now scan */ - for(ofs = 0; ofs != count; ofs++) + if (!nowayout) { - char c; - if (get_user(c, buf + ofs)) - return -EFAULT; - if (c == 'V') - wdt_expect_close = 1; + size_t ofs; + + /* note: just in case someone wrote the magic character + * five months ago... */ + wdt_expect_close = 0; + + /* scan to see wether or not we got the magic character */ + for(ofs = 0; ofs != count; ofs++) + { + char c; + if (get_user(c, buf + ofs)) + return -EFAULT; + if (c == 'V') + wdt_expect_close = 42; + } } /* someone wrote to us, we should restart timer */ - next_heartbeat = jiffies + WDT_HEARTBEAT; - return 1; - }; - return 0; + wdt_keepalive(); + } + return count; } static int fop_open(struct inode * inode, struct file * file) { - switch(minor(inode->i_rdev)) - { - case WATCHDOG_MINOR: - /* Just in case we're already talking to someone... */ - if(test_and_set_bit(0, &wdt_is_open)) { - /* Davej: Is this unlock bogus? */ - spin_unlock(&wdt_spinlock); - return -EBUSY; - } - /* Good, fire up the show */ - wdt_startup(); - return 0; + /* Just in case we're already talking to someone... */ + if(test_and_set_bit(0, &wdt_is_open)) + return -EBUSY; - default: - return -ENODEV; - } + /* Good, fire up the show */ + wdt_startup(); + return 0; } static int fop_close(struct inode * inode, struct file * file) { - if(minor(inode->i_rdev) == WATCHDOG_MINOR) - { - if(wdt_expect_close) - wdt_turnoff(); - else { - del_timer(&timer); - printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); - } + if(wdt_expect_close == 42) + wdt_turnoff(); + else { + del_timer(&timer); + printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); } clear_bit(0, &wdt_is_open); + wdt_expect_close = 0; return 0; } @@ -242,20 +251,58 @@ { static struct watchdog_info ident= { - .options = WDIOF_MAGICCLOSE, + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "W83877F" + .identity = "W83877F", }; - + switch(cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: - next_heartbeat = jiffies + WDT_HEARTBEAT; + wdt_keepalive(); return 0; + case WDIOC_SETOPTIONS: + { + int new_options, retval = -EINVAL; + + if(get_user(new_options, (int *)arg)) + return -EFAULT; + + if(new_options & WDIOS_DISABLECARD) { + wdt_turnoff(); + retval = 0; + } + + if(new_options & WDIOS_ENABLECARD) { + wdt_startup(); + retval = 0; + } + + return retval; + } + case WDIOC_SETTIMEOUT: + { + int new_timeout; + + if(get_user(new_timeout, (int *)arg)) + return -EFAULT; + + if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ + return -EINVAL; + + timeout = new_timeout; + wdt_keepalive(); + /* Fall through */ + } + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); } } @@ -265,13 +312,13 @@ .write = fop_write, .open = fop_open, .release = fop_close, - .ioctl = fop_ioctl + .ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &wdt_fops + .fops = &wdt_fops, }; /* @@ -281,21 +328,21 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if(code==SYS_DOWN || code==SYS_HALT) + if(code==SYS_DOWN || code==SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } - + /* * The WDT needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * turn the timebomb registers off. */ - + static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, .next = NULL, - .priority = 0 + .priority = 0, }; static void __exit w83877f_wdt_unload(void) @@ -316,10 +363,28 @@ spin_lock_init(&wdt_spinlock); + if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ + { + timeout = WATCHDOG_TIMEOUT; + printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", + timeout); + } + if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) + { + printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", + ENABLE_W83877F_PORT); + rc = -EIO; goto err_out; + } + if (!request_region(WDT_PING, 1, "W8387FF WDT")) + { + printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", + WDT_PING); + rc = -EIO; goto err_out_region1; + } init_timer(&timer); timer.function = wdt_timer_ping; @@ -327,14 +392,23 @@ rc = misc_register(&wdt_miscdev); if (rc) + { + printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + wdt_miscdev.minor, rc); goto err_out_region2; + } rc = register_reboot_notifier(&wdt_notifier); if (rc) + { + printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + rc); goto err_out_miscdev; + } + + printk(KERN_INFO PFX "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", + timeout, nowayout); - printk(KERN_INFO OUR_NAME ": WDT driver for W83877F initialised.\n"); - return 0; err_out_miscdev: diff -Nru a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c --- a/drivers/eisa/eisa-bus.c Mon Aug 18 22:21:02 2003 +++ b/drivers/eisa/eisa-bus.c Mon Aug 18 22:21:02 2003 @@ -25,13 +25,12 @@ char name[DEVICE_NAME_SIZE]; }; -static struct eisa_device_info __initdata eisa_table[] = { #ifdef CONFIG_EISA_NAMES +static struct eisa_device_info __initdata eisa_table[] = { #include "devlist.h" -#endif }; - #define EISA_INFOS (sizeof (eisa_table) / (sizeof (struct eisa_device_info))) +#endif #define EISA_MAX_FORCED_DEV 16 #define EISA_FORCED_OFFSET 2 @@ -59,11 +58,11 @@ static void __init eisa_name_device (struct eisa_device *edev) { +#ifdef CONFIG_EISA_NAMES int i; - for (i = 0; i < EISA_INFOS; i++) { if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) { - strlcpy (edev->dev.name, + strlcpy (edev->pretty_name, eisa_table[i].name, DEVICE_NAME_SIZE); return; @@ -71,7 +70,8 @@ } /* No name was found */ - sprintf (edev->dev.name, "EISA device %.7s", edev->id.sig); + sprintf (edev->pretty_name, "EISA device %.7s", edev->id.sig); +#endif } static char __init *decode_eisa_sig(unsigned long addr) @@ -172,7 +172,6 @@ { char *sig; unsigned long sig_addr; - int i; sig_addr = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET; @@ -190,8 +189,13 @@ edev->dev.dma_mask = &edev->dma_mask; sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot); - for (i = 0; i < EISA_MAX_RESOURCES; i++) - edev->res[i].name = edev->dev.name; +#ifdef CONFIG_EISA_NAMES + { + int i; + for (i = 0; i < EISA_MAX_RESOURCES; i++) + edev->res[i].name = edev->pretty_name; + } +#endif if (is_forced_dev (enable_dev, root, edev)) edev->state = EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED; @@ -270,8 +274,7 @@ int i, c; struct eisa_device *edev; - printk (KERN_INFO "EISA: Probing bus %d at %s\n", - root->bus_nr, root->dev->name); + printk (KERN_INFO "EISA: Probing bus %d\n", root->bus_nr); /* First try to get hold of slot 0. If there is no device * here, simply fail, unless root->force_probe is set. */ diff -Nru a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c --- a/drivers/eisa/virtual_root.c Mon Aug 18 22:21:04 2003 +++ b/drivers/eisa/virtual_root.c Mon Aug 18 22:21:04 2003 @@ -29,9 +29,6 @@ static struct platform_device eisa_root_dev = { .name = "eisa", .id = 0, - .dev = { - .name = "Virtual EISA Bridge", - }, }; static struct eisa_root_device eisa_bus_root = { diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c --- a/drivers/i2c/busses/i2c-nforce2.c Mon Aug 18 22:21:01 2003 +++ b/drivers/i2c/busses/i2c-nforce2.c Mon Aug 18 22:21:01 2003 @@ -51,10 +51,6 @@ #ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 #endif -/* TODO: sync with lm-sensors */ -#ifndef I2C_HW_SMBUS_NFORCE2 -#define I2C_HW_SMBUS_NFORCE2 0x0c -#endif struct nforce2_smbus { @@ -128,20 +124,10 @@ .name = "unset", }; - -#if 0 -/* Internally used pause function */ -static void nforce2_do_pause(unsigned int amount) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(amount); -} -#endif - /* Return -1 on error. See smbus.h for more information */ -static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, - char read_write, u8 command, int size, - union i2c_smbus_data * data) +static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data * data) { struct nforce2_smbus *smbus = adap->algo_data; unsigned char protocol, pec, temp; @@ -249,7 +235,7 @@ #if 0 do { - nforce2_do_pause(1); + i2c_do_pause(1); temp = inb_p(NVIDIA_SMB_STS); } while (((temp & NVIDIA_SMB_STS_DONE) == 0) && (timeout++ < MAX_TIMEOUT)); #endif @@ -332,13 +318,8 @@ smbus->base, smbus->base+smbus->size-1, name); return -1; } -/* - smbus->adapter.owner = THIS_MODULE; - smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2; - smbus->adapter.algo = &smbus_algorithm; - smbus->adapter.algo_data = smbus; -*/ smbus->adapter = nforce2_adapter; + smbus->adapter.algo_data = smbus; smbus->adapter.dev.parent = &dev->dev; snprintf(smbus->adapter.name, DEVICE_NAME_SIZE, "SMBus nForce2 adapter at %04x", smbus->base); diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c --- a/drivers/i2c/busses/i2c-piix4.c Mon Aug 18 22:21:02 2003 +++ b/drivers/i2c/busses/i2c-piix4.c Mon Aug 18 22:21:02 2003 @@ -160,6 +160,15 @@ } pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); + + /* Some BIOS will set up the chipset incorrectly and leave a register + in an undefined state (causing I2C to act very strangely). */ + if (temp & 0x02) { + dev_info(&PIIX4_dev->dev, "Worked around buggy BIOS (I2C)\n"); + temp = temp & 0xfd; + pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp); + } + /* If force_addr is set, we program the new address here. Just to make sure, we disable the PIIX4 first. */ if (force_addr) { diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile --- a/drivers/i2c/chips/Makefile Mon Aug 18 22:21:00 2003 +++ b/drivers/i2c/chips/Makefile Mon Aug 18 22:21:00 2003 @@ -2,10 +2,12 @@ # Makefile for the kernel hardware sensors chip drivers. # +# w83781d goes first, as it can override other driver's addresses. +obj-$(CONFIG_SENSORS_W83781D) += w83781d.o + obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_LM75) += lm75.o obj-$(CONFIG_SENSORS_LM78) += lm78.o obj-$(CONFIG_SENSORS_LM85) += lm85.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o -obj-$(CONFIG_SENSORS_W83781D) += w83781d.o diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c --- a/drivers/i2c/chips/adm1021.c Mon Aug 18 22:21:00 2003 +++ b/drivers/i2c/chips/adm1021.c Mon Aug 18 22:21:00 2003 @@ -356,13 +356,13 @@ { /* Initialize the adm1021 chip */ adm1021_write_value(client, ADM1021_REG_TOS_W, - TEMP_TO_REG(adm1021_INIT_TOS)); + adm1021_INIT_TOS); adm1021_write_value(client, ADM1021_REG_THYST_W, - TEMP_TO_REG(adm1021_INIT_THYST)); + adm1021_INIT_THYST); adm1021_write_value(client, ADM1021_REG_REMOTE_TOS_W, - TEMP_TO_REG(adm1021_INIT_REMOTE_TOS)); + adm1021_INIT_REMOTE_TOS); adm1021_write_value(client, ADM1021_REG_REMOTE_THYST_W, - TEMP_TO_REG(adm1021_INIT_REMOTE_THYST)); + adm1021_INIT_REMOTE_THYST); /* Enable ADC and disable suspend mode */ adm1021_write_value(client, ADM1021_REG_CONFIG_W, 0); /* Set Conversion rate to 1/sec (this can be tinkered with) */ diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c --- a/drivers/i2c/i2c-core.c Mon Aug 18 22:21:01 2003 +++ b/drivers/i2c/i2c-core.c Mon Aug 18 22:21:01 2003 @@ -79,12 +79,36 @@ .release = &i2c_adapter_class_dev_release, }; +static ssize_t show_adapter_name(struct device *dev, char *buf) +{ + struct i2c_adapter *adap = dev_to_i2c_adapter(dev); + return sprintf(buf, "%s\n", adap->name); +} +static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); + + static void i2c_client_release(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); complete(&client->released); } +static ssize_t show_client_name(struct device *dev, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%s\n", client->name); +} + +/* + * We can't use the DEVICE_ATTR() macro here as we want the same filename for a + * different type of a device. So beware if the DEVICE_ATTR() macro ever + * changes, this definition will also have to change. + */ +static struct device_attribute dev_attr_client_name = { + .attr = {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE }, + .show = &show_client_name, +}; + /* --------------------------------------------------- * registering functions @@ -120,6 +144,7 @@ adap->dev.driver = &i2c_adapter_driver; adap->dev.release = &i2c_adapter_dev_release; device_register(&adap->dev); + device_create_file(&adap->dev, &dev_attr_name); /* Add this adapter to the i2c_adapter class */ memset(&adap->class_dev, 0x00, sizeof(struct class_device)); @@ -184,6 +209,7 @@ init_completion(&adap->dev_released); init_completion(&adap->class_dev_released); class_device_unregister(&adap->class_dev); + device_remove_file(&adap->dev, &dev_attr_name); device_unregister(&adap->dev); list_del(&adap->list); @@ -361,6 +387,7 @@ "%d-%04x", i2c_adapter_id(adapter), client->addr); printk("registering %s\n", client->dev.bus_id); device_register(&client->dev); + device_create_file(&client->dev, &dev_attr_client_name); return 0; } @@ -387,6 +414,7 @@ down(&adapter->clist_lock); list_del(&client->list); init_completion(&client->released); + device_remove_file(&client->dev, &dev_attr_client_name); device_unregister(&client->dev); up(&adapter->clist_lock); wait_for_completion(&client->released); diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c --- a/drivers/i2c/i2c-dev.c Mon Aug 18 22:21:05 2003 +++ b/drivers/i2c/i2c-dev.c Mon Aug 18 22:21:05 2003 @@ -181,6 +181,7 @@ struct i2c_smbus_ioctl_data data_arg; union i2c_smbus_data temp; struct i2c_msg *rdwr_pa; + u8 **data_ptrs; int i,datasize,res; unsigned long funcs; @@ -214,7 +215,7 @@ return (copy_to_user((unsigned long __user *)arg, &funcs, sizeof(unsigned long)))?-EFAULT:0; - case I2C_RDWR: + case I2C_RDWR: if (copy_from_user(&rdwr_arg, (struct i2c_rdwr_ioctl_data __user *)arg, sizeof(rdwr_arg))) @@ -231,28 +232,37 @@ if (rdwr_pa == NULL) return -ENOMEM; + if (copy_from_user(rdwr_pa, rdwr_arg.msgs, + rdwr_arg.nmsgs * sizeof(struct i2c_msg))) { + kfree(rdwr_pa); + return -EFAULT; + } + + data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *), + GFP_KERNEL); + if (data_ptrs == NULL) { + kfree(rdwr_pa); + return -ENOMEM; + } + res = 0; for( i=0; i 8192) { res = -EINVAL; break; } + data_ptrs[i] = rdwr_pa[i].buf; rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL); if(rdwr_pa[i].buf == NULL) { res = -ENOMEM; break; } if(copy_from_user(rdwr_pa[i].buf, - rdwr_arg.msgs[i].buf, + data_ptrs[i], rdwr_pa[i].len)) { - res = -EFAULT; + ++i; /* Needs to be kfreed too */ + res = -EFAULT; break; } } @@ -260,18 +270,18 @@ int j; for (j = 0; j < i; ++j) kfree(rdwr_pa[j].buf); + kfree(data_ptrs); kfree(rdwr_pa); return res; } - if (!res) { - res = i2c_transfer(client->adapter, - rdwr_pa, - rdwr_arg.nmsgs); - } + + res = i2c_transfer(client->adapter, + rdwr_pa, + rdwr_arg.nmsgs); while(i-- > 0) { if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) { if(copy_to_user( - rdwr_arg.msgs[i].buf, + data_ptrs[i], rdwr_pa[i].buf, rdwr_pa[i].len)) { res = -EFAULT; @@ -279,6 +289,7 @@ } kfree(rdwr_pa[i].buf); } + kfree(data_ptrs); kfree(rdwr_pa); return res; diff -Nru a/drivers/i2c/scx200_i2c.c b/drivers/i2c/scx200_i2c.c --- a/drivers/i2c/scx200_i2c.c Mon Aug 18 22:21:03 2003 +++ b/drivers/i2c/scx200_i2c.c Mon Aug 18 22:21:03 2003 @@ -84,9 +84,7 @@ .owner = THIS_MODULE, .id = I2C_HW_B_VELLE, .algo_data = &scx200_i2c_data, - .dev = { - .name = "NatSemi SCx200 I2C", - }, + .name = "NatSemi SCx200 I2C", }; int scx200_i2c_init(void) @@ -112,7 +110,7 @@ if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) { printk(KERN_ERR NAME ": adapter %s registration failed\n", - scx200_i2c_ops.dev.name); + scx200_i2c_ops.name); return -ENODEV; } diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig --- a/drivers/ide/Kconfig Mon Aug 18 22:21:03 2003 +++ b/drivers/ide/Kconfig Mon Aug 18 22:21:03 2003 @@ -206,7 +206,31 @@ say M here and read . The module will be called ide-cd. -#dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE +config BLK_DEV_IDETAPE + tristate "Include IDE/ATAPI TAPE support (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + If you have an IDE tape drive using the ATAPI protocol, say Y. + ATAPI is a newer protocol used by IDE tape and CD-ROM drives, + similar to the SCSI protocol. If you have an SCSI tape drive + however, you can say N here. + + You should also say Y if you have an OnStream DI-30 tape drive; this + will not work with the SCSI protocol, until there is support for the + SC-30 and SC-50 versions. + + If you say Y here, the tape drive will be identified at boot time + along with other IDE devices, as "hdb" or "hdc", or something + similar, and will be mapped to a character device such as "ht0" + (check the boot messages with dmesg). Be sure to consult the + and files + for usage information. + + 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-tape.o. + config BLK_DEV_IDEFLOPPY tristate "Include IDE/ATAPI FLOPPY support" ---help--- diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c --- a/drivers/ide/arm/icside.c Mon Aug 18 22:21:03 2003 +++ b/drivers/ide/arm/icside.c Mon Aug 18 22:21:03 2003 @@ -233,7 +233,7 @@ memset(sg, 0, sizeof(*sg)); sg->page = virt_to_page(rq->buffer); - sg->offset = ((unsigned long)rq->buffer) & ~PAGE_MASK; + sg->offset = offset_in_page(rq->buffer); sg->length = rq->nr_sectors * SECTOR_SIZE; nents = 1; } else { diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c --- a/drivers/ide/ide-disk.c Mon Aug 18 22:21:03 2003 +++ b/drivers/ide/ide-disk.c Mon Aug 18 22:21:03 2003 @@ -86,11 +86,6 @@ { unsigned long lba_sects, chs_sects, head, tail; - if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) { - printk("48-bit Drive: %llu \n", id->lba_capacity_2); - return 1; - } - /* * The ATA spec tells large drives to return * C/H/S = 16383/16/63 independent of their size. @@ -1074,52 +1069,51 @@ return n; } -static inline void idedisk_check_hpa_lba28(ide_drive_t *drive) +/* + * Bits 10 of command_set_1 and cfs_enable_1 must be equal, + * so on non-buggy drives we need test only one. + * However, we should also check whether these fields are valid. + */ +static inline int idedisk_supports_hpa(const struct hd_driveid *id) { - unsigned long capacity, set_max; - - capacity = drive->id->lba_capacity; - set_max = idedisk_read_native_max_address(drive); - - if (set_max <= capacity) - return; + return (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400); +} - printk(KERN_INFO "%s: Host Protected Area detected.\n" - "\tcurrent capacity is %ld sectors (%ld MB)\n" - "\tnative capacity is %ld sectors (%ld MB)\n", - drive->name, - capacity, (capacity - capacity/625 + 974)/1950, - set_max, (set_max - set_max/625 + 974)/1950); -#ifdef CONFIG_IDEDISK_STROKE - set_max = idedisk_set_max_address(drive, set_max); - if (set_max) { - drive->id->lba_capacity = set_max; - printk(KERN_INFO "%s: Host Protected Area disabled.\n", - drive->name); - } -#endif +/* + * The same here. + */ +static inline int idedisk_supports_lba48(const struct hd_driveid *id) +{ + return (id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400); } -static inline void idedisk_check_hpa_lba48(ide_drive_t *drive) +static inline void idedisk_check_hpa(ide_drive_t *drive) { - unsigned long long capacity_2, set_max_ext; + unsigned long long capacity, set_max; + int lba48 = idedisk_supports_lba48(drive->id); - capacity_2 = drive->id->lba_capacity_2; - set_max_ext = idedisk_read_native_max_address_ext(drive); + capacity = drive->capacity64; + if (lba48) + set_max = idedisk_read_native_max_address_ext(drive); + else + set_max = idedisk_read_native_max_address(drive); - if (set_max_ext <= capacity_2) + if (set_max <= capacity) return; printk(KERN_INFO "%s: Host Protected Area detected.\n" - "\tcurrent capacity is %lld sectors (%lld MB)\n" - "\tnative capacity is %lld sectors (%lld MB)\n", + "\tcurrent capacity is %llu sectors (%llu MB)\n" + "\tnative capacity is %llu sectors (%llu MB)\n", drive->name, - capacity_2, sectors_to_MB(capacity_2), - set_max_ext, sectors_to_MB(set_max_ext)); + capacity, sectors_to_MB(capacity), + set_max, sectors_to_MB(set_max)); #ifdef CONFIG_IDEDISK_STROKE - set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext); - if (set_max_ext) { - drive->id->lba_capacity_2 = set_max_ext; + if (lba48) + set_max = idedisk_set_max_address_ext(drive, set_max); + else + set_max = idedisk_set_max_address(drive, set_max); + if (set_max) { + drive->capacity64 = set_max; printk(KERN_INFO "%s: Host Protected Area disabled.\n", drive->name); } @@ -1147,43 +1141,29 @@ * If this drive supports the Host Protected Area feature set, * then we may need to change our opinion about the drive's capacity. */ - int hpa = (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400); + int hpa = idedisk_supports_hpa(id); - if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) { + if (idedisk_supports_lba48(id)) { /* drive speaks 48-bit LBA */ - unsigned long long capacity_2; - drive->select.b.lba = 1; + drive->capacity64 = id->lba_capacity_2; if (hpa) - idedisk_check_hpa_lba48(drive); - capacity_2 = id->lba_capacity_2; - drive->head = drive->bios_head = 255; - drive->sect = drive->bios_sect = 63; - drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect); - drive->bios_cyl = drive->cyl; - drive->capacity48 = capacity_2; - drive->capacity = (unsigned long) capacity_2; + idedisk_check_hpa(drive); } else if ((id->capability & 2) && lba_capacity_is_ok(id)) { /* drive speaks 28-bit LBA */ - unsigned long capacity; - drive->select.b.lba = 1; + drive->capacity64 = id->lba_capacity; if (hpa) - idedisk_check_hpa_lba28(drive); - capacity = id->lba_capacity; - drive->cyl = capacity / (drive->head * drive->sect); - drive->capacity = capacity; + idedisk_check_hpa(drive); } else { /* drive speaks boring old 28-bit CHS */ - drive->capacity = drive->cyl * drive->head * drive->sect; + drive->capacity64 = drive->cyl * drive->head * drive->sect; } } static sector_t idedisk_capacity (ide_drive_t *drive) { - if (drive->id->cfs_enable_2 & 0x0400) - return (drive->capacity48 - drive->sect0); - return (drive->capacity - drive->sect0); + return drive->capacity64 - drive->sect0; } static ide_startstop_t idedisk_special (ide_drive_t *drive) @@ -1465,24 +1445,25 @@ } #endif -static int probe_lba_addressing (ide_drive_t *drive, int arg) +/* + * drive->addressing: + * 0: 28-bit + * 1: 48-bit + * 2: 48-bit capable doing 28-bit + */ +static int set_lba_addressing(ide_drive_t *drive, int arg) { drive->addressing = 0; - if (HWIF(drive)->addressing) + if (HWIF(drive)->no_lba48) return 0; - if (!(drive->id->cfs_enable_2 & 0x0400)) + if (!idedisk_supports_lba48(drive->id)) return -EIO; drive->addressing = arg; return 0; } -static int set_lba_addressing (ide_drive_t *drive, int arg) -{ - return probe_lba_addressing(drive, arg); -} - static void idedisk_add_settings(ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -1598,7 +1579,7 @@ } } - (void) probe_lba_addressing(drive, 1); + (void)set_lba_addressing(drive, 1); if (drive->addressing == 1) { ide_hwif_t *hwif = HWIF(drive); @@ -1637,24 +1618,42 @@ /* calculate drive capacity, and select LBA if possible */ init_idedisk_capacity (drive); + /* limit drive capacity to 137GB if LBA48 cannot be used */ + if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) { + printk("%s: cannot use LBA48 - full capacity " + "%llu sectors (%llu MB)\n", + drive->name, + drive->capacity64, sectors_to_MB(drive->capacity64)); + drive->capacity64 = 1ULL << 28; + } + /* * if possible, give fdisk access to more of the drive, * by correcting bios_cyls: */ capacity = idedisk_capacity (drive); - if (!drive->forced_geom && drive->bios_sect && drive->bios_head) { - unsigned int cap0 = capacity; /* truncate to 32 bits */ - unsigned int cylsz, cyl; - - if (cap0 != capacity) - drive->bios_cyl = 65535; - else { - cylsz = drive->bios_sect * drive->bios_head; - cyl = cap0 / cylsz; - if (cyl > 65535) - cyl = 65535; - if (cyl > drive->bios_cyl) - drive->bios_cyl = cyl; + if (!drive->forced_geom) { + + if (idedisk_supports_lba48(drive->id)) { + /* compatibility */ + drive->bios_sect = 63; + drive->bios_head = 255; + } + + if (drive->bios_sect && drive->bios_head) { + unsigned int cap0 = capacity; /* truncate to 32 bits */ + unsigned int cylsz, cyl; + + if (cap0 != capacity) + drive->bios_cyl = 65535; + else { + cylsz = drive->bios_sect * drive->bios_head; + cyl = cap0 / cylsz; + if (cyl > 65535) + cyl = 65535; + if (cyl > drive->bios_cyl) + drive->bios_cyl = cyl; + } } } printk(KERN_INFO "%s: %llu sectors (%llu MB)", diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c --- a/drivers/ide/ide-dma.c Mon Aug 18 22:21:03 2003 +++ b/drivers/ide/ide-dma.c Mon Aug 18 22:21:03 2003 @@ -255,7 +255,7 @@ #endif memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); - sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; + sg[nents].offset = offset_in_page(virt_addr); sg[nents].length = 128 * SECTOR_SIZE; nents++; virt_addr = virt_addr + (128 * SECTOR_SIZE); @@ -263,7 +263,7 @@ } memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); - sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; + sg[nents].offset = offset_in_page(virt_addr); sg[nents].length = sector_count * SECTOR_SIZE; nents++; diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c --- a/drivers/ide/ide-probe.c Mon Aug 18 22:21:04 2003 +++ b/drivers/ide/ide-probe.c Mon Aug 18 22:21:04 2003 @@ -648,7 +648,6 @@ { /* register with global device tree */ strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); - snprintf(hwif->gendev.name,DEVICE_NAME_SIZE,"IDE Controller"); hwif->gendev.driver_data = hwif; if (hwif->pci_dev) hwif->gendev.parent = &hwif->pci_dev->dev; @@ -930,7 +929,7 @@ blk_queue_segment_boundary(q, 0xffff); if (!hwif->rqsize) - hwif->rqsize = hwif->addressing ? 256 : 65536; + hwif->rqsize = hwif->no_lba48 ? 256 : 65536; if (hwif->rqsize < max_sectors) max_sectors = hwif->rqsize; blk_queue_max_sectors(q, max_sectors); @@ -1217,8 +1216,6 @@ ide_add_generic_settings(drive); snprintf(drive->gendev.bus_id,BUS_ID_SIZE,"%u.%u", hwif->index,unit); - snprintf(drive->gendev.name,DEVICE_NAME_SIZE, - "%s","IDE Drive"); drive->gendev.parent = &hwif->gendev; drive->gendev.bus = &ide_bus_type; drive->gendev.driver_data = drive; diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c --- a/drivers/ide/ide-tape.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ide/ide-tape.c Mon Aug 18 22:21:02 2003 @@ -734,6 +734,13 @@ idetape_direction_write } idetape_chrdev_direction_t; +struct idetape_bh { + unsigned short b_size; + atomic_t b_count; + struct idetape_bh *b_reqnext; + char *b_data; +}; + /* * Our view of a packet command. */ @@ -744,7 +751,7 @@ int request_transfer; /* Bytes to transfer */ int actually_transferred; /* Bytes actually transferred */ int buffer_size; /* Size of our data buffer */ - struct bio *bio; + struct idetape_bh *bh; char *b_data; int b_count; u8 *buffer; /* Data buffer */ @@ -757,12 +764,18 @@ /* * Packet command flag bits. */ -#define PC_ABORT 0 /* Set when an error is considered normal - We won't retry */ -#define PC_WAIT_FOR_DSC 1 /* 1 When polling for DSC on a media access command */ -#define PC_DMA_RECOMMENDED 2 /* 1 when we prefer to use DMA if possible */ -#define PC_DMA_IN_PROGRESS 3 /* 1 while DMA in progress */ -#define PC_DMA_ERROR 4 /* 1 when encountered problem during DMA */ -#define PC_WRITING 5 /* Data direction */ +/* Set when an error is considered normal - We won't retry */ +#define PC_ABORT 0 +/* 1 When polling for DSC on a media access command */ +#define PC_WAIT_FOR_DSC 1 +/* 1 when we prefer to use DMA if possible */ +#define PC_DMA_RECOMMENDED 2 +/* 1 while DMA in progress */ +#define PC_DMA_IN_PROGRESS 3 +/* 1 when encountered problem during DMA */ +#define PC_DMA_ERROR 4 +/* Data direction */ +#define PC_WRITING 5 /* * Capabilities and Mechanical Status Page @@ -828,7 +841,7 @@ */ typedef struct idetape_stage_s { struct request rq; /* The corresponding request */ - struct bio *bio; /* The data buffers */ + struct idetape_bh *bh; /* The data buffers */ struct idetape_stage_s *next; /* Pointer to the next stage */ os_aux_t *aux; /* OnStream aux ptr */ } idetape_stage_t; @@ -881,12 +894,17 @@ * required since an additional packet command is needed before the * retry, to get detailed information on what went wrong. */ - idetape_pc_t *pc; /* Current packet command */ - idetape_pc_t *failed_pc; /* Last failed packet command */ - idetape_pc_t pc_stack[IDETAPE_PC_STACK];/* Packet command stack */ - int pc_stack_index; /* Next free packet command storage space */ + /* Current packet command */ + idetape_pc_t *pc; + /* Last failed packet command */ + idetape_pc_t *failed_pc; + /* Packet command stack */ + idetape_pc_t pc_stack[IDETAPE_PC_STACK]; + /* Next free packet command storage space */ + int pc_stack_index; struct request rq_stack[IDETAPE_PC_STACK]; - int rq_stack_index; /* We implement a circular array */ + /* We implement a circular array */ + int rq_stack_index; /* * DSC polling variables. @@ -900,17 +918,23 @@ * to ide.c only one at a time. */ struct request *postponed_rq; - unsigned long dsc_polling_start; /* The time in which we started polling for DSC */ - struct timer_list dsc_timer; /* Timer used to poll for dsc */ - unsigned long best_dsc_rw_frequency; /* Read/Write dsc polling frequency */ - unsigned long dsc_polling_frequency; /* The current polling frequency */ - unsigned long dsc_timeout; /* Maximum waiting time */ + /* The time in which we started polling for DSC */ + unsigned long dsc_polling_start; + /* Timer used to poll for dsc */ + struct timer_list dsc_timer; + /* Read/Write dsc polling frequency */ + unsigned long best_dsc_rw_frequency; + /* The current polling frequency */ + unsigned long dsc_polling_frequency; + /* Maximum waiting time */ + unsigned long dsc_timeout; /* * Read position information */ u8 partition; - unsigned int first_frame_position; /* Current block */ + /* Current block */ + unsigned int first_frame_position; unsigned int last_frame_position; unsigned int blocks_in_buffer; @@ -923,15 +947,19 @@ * Character device operation */ unsigned int minor; - char name[4]; /* device name */ - idetape_chrdev_direction_t chrdev_direction; /* Current character device data transfer direction */ + /* device name */ + char name[4]; + /* Current character device data transfer direction */ + idetape_chrdev_direction_t chrdev_direction; /* * Device information */ - unsigned short tape_block_size; /* Usually 512 or 1024 bytes */ + /* Usually 512 or 1024 bytes */ + unsigned short tape_block_size; int user_bs_factor; - idetape_capabilities_page_t capabilities; /* Copy of the tape's Capabilities and Mechanical Page */ + /* Copy of the tape's Capabilities and Mechanical Page */ + idetape_capabilities_page_t capabilities; /* * Active data transfer request parameters. @@ -946,11 +974,13 @@ * The data buffer size is chosen based on the tape's * recommendation. */ - struct request *active_data_request; /* Pointer to the request which is waiting in the device request queue */ - int stage_size; /* Data buffer size (chosen based on the tape's recommendation */ + /* Pointer to the request which is waiting in the device request queue */ + struct request *active_data_request; + /* Data buffer size (chosen based on the tape's recommendation */ + int stage_size; idetape_stage_t *merge_stage; int merge_stage_size; - struct bio *bio; + struct idetape_bh *bh; char *b_data; int b_count; @@ -960,19 +990,30 @@ * To accomplish non-pipelined mode, we simply set the following * variables to zero (or NULL, where appropriate). */ - int nr_stages; /* Number of currently used stages */ - int nr_pending_stages; /* Number of pending stages */ - int max_stages, min_pipeline, max_pipeline; /* We will not allocate more than this number of stages */ - idetape_stage_t *first_stage; /* The first stage which will be removed from the pipeline */ - idetape_stage_t *active_stage; /* The currently active stage */ - idetape_stage_t *next_stage; /* Will be serviced after the currently active request */ - idetape_stage_t *last_stage; /* New requests will be added to the pipeline here */ - idetape_stage_t *cache_stage; /* Optional free stage which we can use */ + /* Number of currently used stages */ + int nr_stages; + /* Number of pending stages */ + int nr_pending_stages; + /* We will not allocate more than this number of stages */ + int max_stages, min_pipeline, max_pipeline; + /* The first stage which will be removed from the pipeline */ + idetape_stage_t *first_stage; + /* The currently active stage */ + idetape_stage_t *active_stage; + /* Will be serviced after the currently active request */ + idetape_stage_t *next_stage; + /* New requests will be added to the pipeline here */ + idetape_stage_t *last_stage; + /* Optional free stage which we can use */ + idetape_stage_t *cache_stage; int pages_per_stage; - int excess_bh_size; /* Wasted space in each stage */ + /* Wasted space in each stage */ + int excess_bh_size; - unsigned long flags; /* Status/Action flags: long for set_bit */ - spinlock_t spinlock; /* protects the ide-tape queue */ + /* Status/Action flags: long for set_bit */ + unsigned long flags; + /* protects the ide-tape queue */ + spinlock_t spinlock; /* * Measures average tape speed @@ -981,31 +1022,44 @@ int avg_size; int avg_speed; - idetape_request_sense_result_t sense; /* last sense information */ + /* last sense information */ + idetape_request_sense_result_t sense; char vendor_id[10]; char product_id[18]; char firmware_revision[6]; int firmware_revision_num; - int door_locked; /* the door is currently locked */ + /* the door is currently locked */ + int door_locked; /* * OnStream flags */ - int onstream; /* the tape is an OnStream tape */ - int raw; /* OnStream raw access (32.5KB block size) */ - int cur_frames; /* current number of frames in internal buffer */ - int max_frames; /* max number of frames in internal buffer */ - int logical_blk_num; /* logical block number */ - __u16 wrt_pass_cntr; /* write pass counter */ - __u32 update_frame_cntr; /* update frame counter */ + /* the tape is an OnStream tape */ + int onstream; + /* OnStream raw access (32.5KB block size) */ + int raw; + /* current number of frames in internal buffer */ + int cur_frames; + /* max number of frames in internal buffer */ + int max_frames; + /* logical block number */ + int logical_blk_num; + /* write pass counter */ + __u16 wrt_pass_cntr; + /* update frame counter */ + __u32 update_frame_cntr; struct completion *waiting; - int onstream_write_error; /* write error recovery active */ - int header_ok; /* header frame verified ok */ - int linux_media; /* reading linux-specific media */ + /* write error recovery active */ + int onstream_write_error; + /* header frame verified ok */ + int header_ok; + /* reading linux-specific media */ + int linux_media; int linux_media_version; - char application_sig[5]; /* application signature */ + /* application signature */ + char application_sig[5]; int filemark_cnt; int first_mark_addr; int last_mark_addr; @@ -1018,8 +1072,10 @@ * Optimize the number of "buffer filling" * mode sense commands. */ - unsigned long last_buffer_fill; /* last time in which we issued fill cmd */ - int req_buffer_fill; /* buffer fill command requested */ + /* last time in which we issued fill cmd */ + unsigned long last_buffer_fill; + /* buffer fill command requested */ + int req_buffer_fill; int writes_since_buffer_fill; int reads_since_buffer_fill; @@ -1028,13 +1084,14 @@ * be postponed, to avoid an infinite postpone * deadlock. */ - int postpone_cnt; /* request postpone count limit */ + /* request postpone count limit */ + int postpone_cnt; /* * Measures number of frames: * * 1. written/read to/from the driver pipeline (pipeline_head). - * 2. written/read to/from the tape buffers (bio). + * 2. written/read to/from the tape buffers (idetape_bh). * 3. written/read by the tape to/from the media (tape_head). */ int pipeline_head; @@ -1061,11 +1118,17 @@ * Speed regulation negative feedback loop */ int speed_control; - int pipeline_head_speed, controlled_pipeline_head_speed, uncontrolled_pipeline_head_speed; - int controlled_last_pipeline_head, uncontrolled_last_pipeline_head; - unsigned long uncontrolled_pipeline_head_time, controlled_pipeline_head_time; - int controlled_previous_pipeline_head, uncontrolled_previous_pipeline_head; - unsigned long controlled_previous_head_time, uncontrolled_previous_head_time; + int pipeline_head_speed; + int controlled_pipeline_head_speed; + int uncontrolled_pipeline_head_speed; + int controlled_last_pipeline_head; + int uncontrolled_last_pipeline_head; + unsigned long uncontrolled_pipeline_head_time; + unsigned long controlled_pipeline_head_time; + int controlled_previous_pipeline_head; + int uncontrolled_previous_pipeline_head; + unsigned long controlled_previous_head_time; + unsigned long uncontrolled_previous_head_time; int restart_speed_control_req; /* @@ -1372,23 +1435,40 @@ char *idetape_command_key_verbose(u8 idetape_command_key) { switch (idetape_command_key) { - case IDETAPE_TEST_UNIT_READY_CMD: return("TEST_UNIT_READY_CMD"); - case IDETAPE_REWIND_CMD: return("REWIND_CMD"); - case IDETAPE_REQUEST_SENSE_CMD: return("REQUEST_SENSE_CMD"); - case IDETAPE_READ_CMD: return("READ_CMD"); - case IDETAPE_WRITE_CMD: return("WRITE_CMD"); - case IDETAPE_WRITE_FILEMARK_CMD: return("WRITE_FILEMARK_CMD"); - case IDETAPE_SPACE_CMD: return("SPACE_CMD"); - case IDETAPE_INQUIRY_CMD: return("INQUIRY_CMD"); - case IDETAPE_ERASE_CMD: return("ERASE_CMD"); - case IDETAPE_MODE_SENSE_CMD: return("MODE_SENSE_CMD"); - case IDETAPE_MODE_SELECT_CMD: return("MODE_SELECT_CMD"); - case IDETAPE_LOAD_UNLOAD_CMD: return("LOAD_UNLOAD_CMD"); - case IDETAPE_PREVENT_CMD: return("PREVENT_CMD"); - case IDETAPE_LOCATE_CMD: return("LOCATE_CMD"); - case IDETAPE_READ_POSITION_CMD: return("READ_POSITION_CMD"); - case IDETAPE_READ_BUFFER_CMD: return("READ_BUFFER_CMD"); - case IDETAPE_SET_SPEED_CMD: return("SET_SPEED_CMD"); + case IDETAPE_TEST_UNIT_READY_CMD: + return("TEST_UNIT_READY_CMD"); + case IDETAPE_REWIND_CMD: + return("REWIND_CMD"); + case IDETAPE_REQUEST_SENSE_CMD: + return("REQUEST_SENSE_CMD"); + case IDETAPE_READ_CMD: + return("READ_CMD"); + case IDETAPE_WRITE_CMD: + return("WRITE_CMD"); + case IDETAPE_WRITE_FILEMARK_CMD: + return("WRITE_FILEMARK_CMD"); + case IDETAPE_SPACE_CMD: + return("SPACE_CMD"); + case IDETAPE_INQUIRY_CMD: + return("INQUIRY_CMD"); + case IDETAPE_ERASE_CMD: + return("ERASE_CMD"); + case IDETAPE_MODE_SENSE_CMD: + return("MODE_SENSE_CMD"); + case IDETAPE_MODE_SELECT_CMD: + return("MODE_SELECT_CMD"); + case IDETAPE_LOAD_UNLOAD_CMD: + return("LOAD_UNLOAD_CMD"); + case IDETAPE_PREVENT_CMD: + return("PREVENT_CMD"); + case IDETAPE_LOCATE_CMD: + return("LOCATE_CMD"); + case IDETAPE_READ_POSITION_CMD: + return("READ_POSITION_CMD"); + case IDETAPE_READ_BUFFER_CMD: + return("READ_BUFFER_CMD"); + case IDETAPE_SET_SPEED_CMD: + return("SET_SPEED_CMD"); default: { char buf[20]; sprintf(buf, "CMD (0x%02x)", idetape_command_key); @@ -1413,59 +1493,59 @@ static void idetape_discard_data (ide_drive_t *drive, unsigned int bcount) { while (bcount--) - IN_BYTE(IDE_DATA_REG); + (void) HWIF(drive)->INB(IDE_DATA_REG); } static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount) { - struct bio *bio = pc->bio; + struct idetape_bh *bh = pc->bh; int count; while (bcount) { #if IDETAPE_DEBUG_BUGS - if (bio == NULL) { - printk(KERN_ERR "ide-tape: bio == NULL in " + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_input_buffers\n"); idetape_discard_data(drive, bcount); return; } #endif /* IDETAPE_DEBUG_BUGS */ - count = min(bio->bi_size - pc->b_count, bcount); - HWIF(drive)->atapi_input_bytes(drive, bio_data(bio) + pc->b_count, count); + count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount); + HWIF(drive)->atapi_input_bytes(drive, bh->b_data + atomic_read(&bh->b_count), count); bcount -= count; - pc->b_count += bio->bi_size; - if (pc->b_count == bio->bi_size) { - bio = bio->bi_next; - if (bio) - pc->b_count = 0; + atomic_add(count, &bh->b_count); + if (atomic_read(&bh->b_count) == bh->b_size) { + bh = bh->b_reqnext; + if (bh) + atomic_set(&bh->b_count, 0); } } - pc->bio = bio; + pc->bh = bh; } static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount) { - struct bio *bio = pc->bio; + struct idetape_bh *bh = pc->bh; int count; while (bcount) { #if IDETAPE_DEBUG_BUGS - if (bio == NULL) { - printk(KERN_ERR "ide-tape: bio == NULL in " + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_output_buffers\n"); return; } #endif /* IDETAPE_DEBUG_BUGS */ - count = min((unsigned long) pc->b_count, (unsigned long) bcount); - HWIF(drive)->atapi_output_bytes(drive, bio_data(bio), count); + count = min((unsigned int)pc->b_count, (unsigned int)bcount); + HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count); bcount -= count; pc->b_data += count; pc->b_count -= count; if (!pc->b_count) { - pc->bio = bio = bio->bi_next; - if (bio) { - pc->b_data = bio_data(bio); - pc->b_count = bio->bi_size; + pc->bh = bh = bh->b_reqnext; + if (bh) { + pc->b_data = bh->b_data; + pc->b_count = atomic_read(&bh->b_count); } } } @@ -1473,7 +1553,7 @@ static void idetape_update_buffers (idetape_pc_t *pc) { - struct bio *bio = pc->bio; + struct idetape_bh *bh = pc->bh; int count; unsigned int bcount = pc->actually_transferred; @@ -1481,19 +1561,19 @@ return; while (bcount) { #if IDETAPE_DEBUG_BUGS - if (bio == NULL) { - printk(KERN_ERR "ide-tape: bio == NULL in " + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_update_buffers\n"); return; } #endif /* IDETAPE_DEBUG_BUGS */ - count = min((unsigned long) bio->bi_size, (unsigned long) bcount); - pc->b_count = count; - if (pc->b_count == bio->bi_size) - bio = bio->bi_next; + count = min((unsigned int)bh->b_size, (unsigned int)bcount); + atomic_set(&bh->b_count, count); + if (atomic_read(&bh->b_count) == bh->b_size) + bh = bh->b_reqnext; bcount -= count; } - pc->bio = bio; + pc->bh = bh; } /* @@ -1538,7 +1618,7 @@ printk(KERN_INFO "ide-tape: rq_stack_index=%d\n", tape->rq_stack_index); #endif /* IDETAPE_DEBUG_LOG */ - if (tape->rq_stack_index==IDETAPE_PC_STACK) + if (tape->rq_stack_index == IDETAPE_PC_STACK) tape->rq_stack_index=0; return (&tape->rq_stack[tape->rq_stack_index++]); } @@ -1554,7 +1634,7 @@ pc->request_transfer = 0; pc->buffer = pc->pc_buffer; pc->buffer_size = IDETAPE_PC_BUFFER_SIZE; - pc->bio = NULL; + pc->bh = NULL; pc->b_data = NULL; } @@ -1652,7 +1732,7 @@ #endif /* IDETAPE_DEBUG_BUGS */ rq->buffer = NULL; - rq->bio = stage->bio; + rq->special = (void *)stage->bh; tape->active_data_request = rq; tape->active_stage = stage; tape->next_stage = stage->next; @@ -1686,21 +1766,21 @@ */ static void __idetape_kfree_stage (idetape_stage_t *stage) { - struct bio *prev_bio, *bio = stage->bio; + struct idetape_bh *prev_bh, *bh = stage->bh; int size; - while (bio != NULL) { - if (bio_data(bio) != NULL) { - size = (int) bio->bi_size; + while (bh != NULL) { + if (bh->b_data != NULL) { + size = (int) bh->b_size; while (size > 0) { - free_page((unsigned long) bio_data(bio)); + free_page((unsigned long) bh->b_data); size -= PAGE_SIZE; - bio->bi_size += PAGE_SIZE; + bh->b_data += PAGE_SIZE; } } - prev_bio = bio; - bio = bio->bi_next; - kfree(prev_bio); + prev_bh = bh; + bh = bh->b_reqnext; + kfree(prev_bh); } kfree(stage); } @@ -1775,7 +1855,7 @@ * idetape_end_request is used to finish servicing a request, and to * insert a pending pipeline request into the main device queue. */ -static int idetape_end_request (ide_drive_t *drive, int uptodate) +static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) { struct request *rq = HWGROUP(drive)->rq; idetape_tape_t *tape = drive->driver_data; @@ -1817,7 +1897,7 @@ if (tape->onstream) { stage = tape->first_stage; aux = stage->aux; - p = bio_data(stage->bio); + p = stage->bh->b_data; if (ntohl(aux->logical_blk_num) < 11300 && ntohl(aux->logical_blk_num) > 11100) printk(KERN_INFO "ide-tape: finished writing logical blk %u (data %x %x %x %x)\n", ntohl(aux->logical_blk_num), *p++, *p++, *p++, *p++); } @@ -1872,7 +1952,7 @@ (void) ide_do_drive_cmd(drive, tape->active_data_request, ide_end); } else if (!error) { if (!tape->onstream) - idetape_increase_max_pipeline_stages (drive); + idetape_increase_max_pipeline_stages(drive); } } ide_end_drive_cmd(drive, 0, 0); @@ -1898,10 +1978,10 @@ #endif /* IDETAPE_DEBUG_LOG */ if (!tape->pc->error) { idetape_analyze_error(drive, (idetape_request_sense_result_t *) tape->pc->buffer); - idetape_end_request(drive, 1); + idetape_end_request(drive, 1, 0); } else { printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n"); - idetape_end_request(drive, 0); + idetape_end_request(drive, 0, 0); } return ide_stopped; } @@ -1954,7 +2034,7 @@ struct request *rq; atapi_error_t error; - error.all = IN_BYTE(IDE_ERROR_REG); + error.all = HWIF(drive)->INB(IDE_ERROR_REG); pc = idetape_next_pc_storage(drive); rq = idetape_next_rq_storage(drive); idetape_create_request_sense_cmd(pc); @@ -1990,6 +2070,7 @@ */ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; atapi_status_t status; atapi_bcount_t bcount; @@ -2082,21 +2163,25 @@ if (tape->debug_level >= 1) printk(KERN_INFO "ide-tape: [cmd %x]: check condition\n", pc->c[0]); #endif - return idetape_retry_pc(drive); /* Retry operation */ + /* Retry operation */ + return idetape_retry_pc(drive); } pc->error = 0; if (!tape->onstream && - test_bit(PC_WAIT_FOR_DSC, &pc->flags) && !status.b.dsc) { + test_bit(PC_WAIT_FOR_DSC, &pc->flags) && + !status.b.dsc) { /* Media access command */ tape->dsc_polling_start = jiffies; tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST; tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; - idetape_postpone_request(drive); /* Allow ide.c to handle other requests */ + /* Allow ide.c to handle other requests */ + idetape_postpone_request(drive); return ide_stopped; } if (tape->failed_pc == pc) tape->failed_pc = NULL; - return pc->callback(drive); /* Command finished - Call the callback function */ + /* Command finished - Call the callback function */ + return pc->callback(drive); } if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { printk(KERN_ERR "ide-tape: The tape wants to issue more " @@ -2105,22 +2190,26 @@ (void) HWIF(drive)->ide_dma_off(drive); return ide_do_reset(drive); } - bcount.b.high = IN_BYTE(IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ - bcount.b.low = IN_BYTE(IDE_BCOUNTL_REG); /* on this interrupt */ - ireason.all = IN_BYTE(IDE_IREASON_REG); + /* Get the number of bytes to transfer on this interrupt. */ + bcount.b.high = hwif->INB(IDE_BCOUNTH_REG); + bcount.b.low = hwif->INB(IDE_BCOUNTL_REG); + + ireason.all = hwif->INB(IDE_IREASON_REG); if (ireason.b.cod) { printk(KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); return ide_do_reset(drive); } - if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ + if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { + /* Hopefully, we will never get here */ printk(KERN_ERR "ide-tape: We wanted to %s, ", ireason.b.io ? "Write":"Read"); printk(KERN_ERR "ide-tape: but the tape wants us to %s !\n", ireason.b.io ? "Read":"Write"); return ide_do_reset(drive); } - if (!test_bit(PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */ + if (!test_bit(PC_WRITING, &pc->flags)) { + /* Reading - Check that we have enough space */ temp = pc->actually_transferred + bcount.all; if (temp > pc->request_transfer) { if (temp > pc->buffer_size) { @@ -2136,23 +2225,27 @@ } } if (test_bit(PC_WRITING, &pc->flags)) { - if (pc->bio != NULL) + if (pc->bh != NULL) idetape_output_buffers(drive, pc, bcount.all); else - HWIF(drive)->atapi_output_bytes(drive, pc->current_position, bcount.all); /* Write the current buffer */ + /* Write the current buffer */ + HWIF(drive)->atapi_output_bytes(drive, pc->current_position, bcount.all); } else { - if (pc->bio != NULL) + if (pc->bh != NULL) idetape_input_buffers(drive, pc, bcount.all); else - HWIF(drive)->atapi_input_bytes(drive, pc->current_position, bcount.all); /* Read the current buffer */ + /* Read the current buffer */ + HWIF(drive)->atapi_input_bytes(drive, pc->current_position, bcount.all); } - pc->actually_transferred += bcount.all; /* Update the current position */ + /* Update the current position */ + pc->actually_transferred += bcount.all; pc->current_position += bcount.all; #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 2) printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); #endif - ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */ + /* And set the interrupt handler again */ + ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); return ide_started; } @@ -2189,9 +2282,9 @@ * * 4. When the packet command is finished, it will be checked for errors. * - * 5. In case an error was found, we queue a request sense packet command - * in front of the request queue and retry the operation up to - * IDETAPE_MAX_PC_RETRIES times. + * 5. In case an error was found, we queue a request sense packet + * command in front of the request queue and retry the operation + * up to IDETAPE_MAX_PC_RETRIES times. * * 6. In case no error was found, or we decided to give up and not * to retry again, the callback function will be called and then @@ -2200,6 +2293,7 @@ */ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; idetape_pc_t *pc = tape->pc; atapi_ireason_t ireason; @@ -2210,12 +2304,12 @@ printk(KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); return startstop; } - ireason.all = IN_BYTE(IDE_IREASON_REG); + ireason.all = hwif->INB(IDE_IREASON_REG); while (retries-- && (!ireason.b.cod || ireason.b.io)) { printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing " "a packet command, retrying\n"); udelay(100); - ireason.all = IN_BYTE(IDE_IREASON_REG); + ireason.all = hwif->INB(IDE_IREASON_REG); if (retries == 0) { printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while " "issuing a packet command, ignoring\n"); @@ -2232,7 +2326,8 @@ /* Set the interrupt routine */ ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); #ifdef CONFIG_BLK_DEV_IDEDMA - if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) /* Begin DMA, if necessary */ + /* Begin DMA, if necessary */ + if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) (void) (HWIF(drive)->ide_dma_begin(drive)); #endif /* Send the actual packet */ @@ -2242,6 +2337,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape_pc_t *pc) { + ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; atapi_bcount_t bcount; int dma_ok = 0; @@ -2256,7 +2352,8 @@ if (tape->failed_pc == NULL && pc->c[0] != IDETAPE_REQUEST_SENSE_CMD) tape->failed_pc = pc; - tape->pc = pc; /* Set the current packet command */ + /* Set the current packet command */ + tape->pc = pc; if (pc->retries > IDETAPE_MAX_PC_RETRIES || test_bit(PC_ABORT, &pc->flags)) { @@ -2278,10 +2375,12 @@ if (tape->onstream && pc->c[0] == IDETAPE_READ_CMD && tape->sense_key == 3 && - tape->asc == 0x11) /* AJN-1: 11 should be 0x11 */ + tape->asc == 0x11) + /* AJN-1: 11 should be 0x11 */ printk(KERN_ERR "ide-tape: %s: enabling read error recovery\n", tape->name); } - pc->error = IDETAPE_ERROR_GENERAL; /* Giving up */ + /* Giving up */ + pc->error = IDETAPE_ERROR_GENERAL; } tape->failed_pc = NULL; return pc->callback(drive); @@ -2292,9 +2391,11 @@ #endif /* IDETAPE_DEBUG_LOG */ pc->retries++; - pc->actually_transferred = 0; /* We haven't transferred any data yet */ + /* We haven't transferred any data yet */ + pc->actually_transferred = 0; pc->current_position = pc->buffer; - bcount.all = pc->request_transfer; /* Request to transfer the entire buffer at once */ + /* Request to transfer the entire buffer at once */ + bcount.all = pc->request_transfer; if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { printk(KERN_WARNING "ide-tape: DMA disabled, " @@ -2309,19 +2410,19 @@ } if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); - OUT_BYTE(dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */ - OUT_BYTE(bcount.b.high, IDE_BCOUNTH_REG); - OUT_BYTE(bcount.b.low, IDE_BCOUNTL_REG); - OUT_BYTE(drive->select.all, IDE_SELECT_REG); + hwif->OUTB(drive->ctl, IDE_CONTROL_REG); + hwif->OUTB(dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */ + hwif->OUTB(bcount.b.high, IDE_BCOUNTH_REG); + hwif->OUTB(bcount.b.low, IDE_BCOUNTL_REG); + hwif->OUTB(drive->select.all, IDE_SELECT_REG); if (dma_ok) /* Will begin DMA later */ set_bit(PC_DMA_IN_PROGRESS, &pc->flags); if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); - OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); + hwif->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); return ide_started; } else { - OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); + hwif->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); return idetape_transfer_pc(drive); } } @@ -2338,7 +2439,7 @@ printk(KERN_INFO "ide-tape: Reached idetape_pc_callback\n"); #endif /* IDETAPE_DEBUG_LOG */ - idetape_end_request(drive, tape->pc->error ? 0 : 1); + idetape_end_request(drive, tape->pc->error ? 0 : 1, 0); return ide_stopped; } @@ -2389,7 +2490,7 @@ printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames); #endif - idetape_end_request(drive, tape->pc->error ? 0 : 1); + idetape_end_request(drive, tape->pc->error ? 0 : 1, 0); return ide_stopped; } @@ -2421,7 +2522,8 @@ else if (time_after(jiffies, tape->controlled_previous_head_time)) tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_previous_head_time); - if (tape->nr_pending_stages < tape->max_stages /*- 1 */) { /* -1 for read mode error recovery */ + if (tape->nr_pending_stages < tape->max_stages /*- 1 */) { + /* -1 for read mode error recovery */ if (time_after(jiffies, tape->uncontrolled_previous_head_time + 10 * HZ)) { tape->uncontrolled_pipeline_head_time = jiffies; tape->uncontrolled_pipeline_head_speed = (tape->pipeline_head - tape->uncontrolled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->uncontrolled_previous_head_time); @@ -2463,9 +2565,12 @@ printk(KERN_INFO "ide-tape: bug: onstream, media_access_finished\n"); status.all = HWIF(drive)->INB(IDE_STATUS_REG); if (status.b.dsc) { - if (status.b.check) { /* Error detected */ + if (status.b.check) { + /* Error detected */ printk(KERN_ERR "ide-tape: %s: I/O error, ",tape->name); - return idetape_retry_pc(drive); /* Retry operation */ + + /* Retry operation */ + return idetape_retry_pc(drive); } pc->error = 0; if (tape->failed_pc == pc) @@ -2509,28 +2614,27 @@ rq->current_nr_sectors -= blocks; if (!tape->pc->error) - idetape_end_request(drive, 1); + idetape_end_request(drive, 1, 0); else - idetape_end_request(drive, tape->pc->error); + idetape_end_request(drive, tape->pc->error, 0); return ide_stopped; } -static void idetape_create_read_cmd (idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct bio *bio) +static void idetape_create_read_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh) { - struct bio *p = bio; - struct bio_vec *bv = bio_iovec(p); /* effective page bh */ + struct idetape_bh *p = bh; idetape_init_pc(pc); pc->c[0] = IDETAPE_READ_CMD; put_unaligned(htonl(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; pc->callback = &idetape_rw_callback; - pc->bio = bio; - bv->bv_len = 0; + pc->bh = bh; + atomic_set(&bh->b_count, 0); pc->buffer = NULL; if (tape->onstream) { while (p) { - bv->bv_len = 0; - p = p->bi_next; + atomic_set(&p->b_count, 0); + p = p->b_reqnext; } } if (!tape->onstream) { @@ -2546,10 +2650,10 @@ } } -static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct bio *bio) +static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh) { int size = 32768; - struct bio *p = bio; + struct idetape_bh *p = bh; idetape_init_pc(pc); pc->c[0] = IDETAPE_READ_BUFFER_CMD; @@ -2557,20 +2661,19 @@ pc->c[7] = size >> 8; pc->c[8] = size & 0xff; pc->callback = &idetape_pc_callback; - pc->bio = bio; - atomic_set(&bio->bi_cnt, 0); + pc->bh = bh; + atomic_set(&bh->b_count, 0); pc->buffer = NULL; while (p) { - p->bi_size = 0; - p = p->bi_next; + atomic_set(&p->b_count, 0); + p = p->b_reqnext; } pc->request_transfer = pc->buffer_size = size; } -static void idetape_create_write_cmd (idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct bio *bio) +static void idetape_create_write_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh) { - struct bio *p = bio; - struct bio_vec *bv= bio_iovec(p); + struct idetape_bh *p = bh; idetape_init_pc(pc); pc->c[0] = IDETAPE_WRITE_CMD; @@ -2580,13 +2683,13 @@ set_bit(PC_WRITING, &pc->flags); if (tape->onstream) { while (p) { - bv->bv_len = p->bi_size; - p = p->bi_next; + atomic_set(&p->b_count, p->b_size); + p = p->b_reqnext; } } - pc->bio = bio; - pc->b_data = bio_data(bio); - pc->b_count = bio->bi_size; + pc->bh = bh; + pc->b_data = bh->b_data; + pc->b_count = atomic_read(&bh->b_count); pc->buffer = NULL; if (!tape->onstream) { pc->request_transfer = pc->buffer_size = length * tape->tape_block_size; @@ -2604,7 +2707,8 @@ /* * idetape_do_request is our request handling function. */ -static ide_startstop_t idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block) +static ide_startstop_t idetape_do_request(ide_drive_t *drive, + struct request *rq, sector_t block) { idetape_tape_t *tape = drive->driver_data; idetape_pc_t *pc; @@ -2630,7 +2734,7 @@ */ printk(KERN_NOTICE "ide-tape: %s: Unsupported command in " "request queue (%ld)\n", drive->name, rq->flags); - ide_end_request(drive, 0); + ide_end_request(drive, 0, 0); return ide_stopped; } @@ -2646,7 +2750,7 @@ if (rq != postponed_rq) { printk(KERN_ERR "ide-tape: ide-tape.c bug - " "Two DSC requests were queued\n"); - idetape_end_request(drive, 0); + idetape_end_request(drive, 0, 0); return ide_stopped; } #endif /* IDETAPE_DEBUG_BUGS */ @@ -2718,7 +2822,8 @@ tape->name, tape->postpone_cnt); #endif } - if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) && !status.b.dsc) { + if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) && + !status.b.dsc) { if (postponed_rq == NULL) { tape->dsc_polling_start = jiffies; tape->dsc_polling_frequency = tape->best_dsc_rw_frequency; @@ -2752,7 +2857,7 @@ tape->req_buffer_fill = 1; } pc = idetape_next_pc_storage(drive); - idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, rq->bio); + idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); break; case IDETAPE_WRITE_RQ: tape->buffer_head++; @@ -2769,16 +2874,16 @@ calculate_speeds(drive); } pc = idetape_next_pc_storage(drive); - idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, rq->bio); + idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); break; case IDETAPE_READ_BUFFER_RQ: tape->postpone_cnt = 0; pc = idetape_next_pc_storage(drive); - idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, rq->bio); + idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); break; case IDETAPE_ABORTED_WRITE_RQ: rq->flags = IDETAPE_WRITE_RQ; - idetape_end_request(drive, IDETAPE_ERROR_EOD); + idetape_end_request(drive, IDETAPE_ERROR_EOD, 0); return ide_stopped; case IDETAPE_ABORTED_READ_RQ: #if IDETAPE_DEBUG_LOG @@ -2786,7 +2891,7 @@ printk(KERN_INFO "ide-tape: %s: detected aborted read rq\n", tape->name); #endif rq->flags = IDETAPE_READ_RQ; - idetape_end_request(drive, IDETAPE_ERROR_EOD); + idetape_end_request(drive, IDETAPE_ERROR_EOD, 0); return ide_stopped; case IDETAPE_PC_RQ1: pc = (idetape_pc_t *) rq->buffer; @@ -2797,7 +2902,7 @@ return ide_stopped; default: printk(KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n"); - idetape_end_request(drive, 0); + idetape_end_request(drive, 0, 0); return ide_stopped; } return idetape_issue_packet_command(drive, pc); @@ -2830,67 +2935,59 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full, int clear) { idetape_stage_t *stage; - struct bio *prev_bio, *bio; + struct idetape_bh *prev_bh, *bh; int pages = tape->pages_per_stage; char *b_data = NULL; - struct bio_vec *bv; if ((stage = (idetape_stage_t *) kmalloc (sizeof (idetape_stage_t),GFP_KERNEL)) == NULL) return NULL; stage->next = NULL; - bio = stage->bio = bio_alloc(GFP_KERNEL,1); - bv = bio_iovec(bio); - bv->bv_len = 0; - if (bio == NULL) + bh = stage->bh = (struct idetape_bh *)kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); + if (bh == NULL) goto abort; - bio->bi_next = NULL; - if ((bio->bi_io_vec[0].bv_page = alloc_page(GFP_KERNEL)) == NULL) + bh->b_reqnext = NULL; + if ((bh->b_data = (char *) __get_free_page (GFP_KERNEL)) == NULL) goto abort; if (clear) - memset(bio_data(bio), 0, PAGE_SIZE); - bio->bi_size = PAGE_SIZE; - if (bv->bv_len == full) - bv->bv_len = bio->bi_size; - -// set_bit(BH_Lock, &bio->bi_flags); + memset(bh->b_data, 0, PAGE_SIZE); + bh->b_size = PAGE_SIZE; + atomic_set(&bh->b_count, full ? bh->b_size : 0); while (--pages) { - if ((bio->bi_io_vec[pages].bv_page = alloc_page(GFP_KERNEL)) == NULL) + if ((b_data = (char *) __get_free_page (GFP_KERNEL)) == NULL) goto abort; if (clear) - memset(bio_data(bio), 0, PAGE_SIZE); - if (bio->bi_size == bv->bv_len + PAGE_SIZE) { - bio->bi_size += PAGE_SIZE; - bv->bv_len += PAGE_SIZE; - bv->bv_offset -= PAGE_SIZE; + memset(b_data, 0, PAGE_SIZE); + if (bh->b_data == b_data + PAGE_SIZE) { + bh->b_size += PAGE_SIZE; + bh->b_data -= PAGE_SIZE; if (full) - bio->bi_size += PAGE_SIZE; + atomic_add(PAGE_SIZE, &bh->b_count); continue; } - if (b_data == bio_data(bio) + bio->bi_size) { - bio->bi_size += PAGE_SIZE; + if (b_data == bh->b_data + bh->b_size) { + bh->b_size += PAGE_SIZE; if (full) - bio->bi_size += PAGE_SIZE; + atomic_add(PAGE_SIZE, &bh->b_count); continue; } - prev_bio = bio; - if ((bio = bio_alloc(GFP_KERNEL,1)) == NULL) { - free_page((unsigned long) bio_data(bio)); + prev_bh = bh; + if ((bh = (struct idetape_bh *)kmalloc(sizeof(struct idetape_bh), GFP_KERNEL)) == NULL) { + free_page((unsigned long) b_data); goto abort; } - bio->bi_next = NULL; - //bio->bi_io_vec[0].bv_offset = b_data; - bio->bi_size = PAGE_SIZE; - atomic_set(&bio->bi_cnt, full ? bio->bi_size : 0); -// set_bit(BH_Lock, &bio->bi_flags); - prev_bio->bi_next = bio; + bh->b_reqnext = NULL; + bh->b_data = b_data; + bh->b_size = PAGE_SIZE; + atomic_set(&bh->b_count, full ? bh->b_size : 0); + prev_bh->b_reqnext = bh; } - bio->bi_size -= tape->excess_bh_size; + bh->b_size -= tape->excess_bh_size; if (full) - atomic_sub(tape->excess_bh_size, &bio->bi_cnt); + atomic_sub(tape->excess_bh_size, &bh->b_count); if (tape->onstream) - stage->aux = (os_aux_t *) (bio_data(bio) + bio->bi_size - OS_AUX_SIZE); + stage->aux = (os_aux_t *) (bh->b_data + bh->b_size - OS_AUX_SIZE); return stage; abort: __idetape_kfree_stage(stage); @@ -2917,40 +3014,40 @@ static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char *buf, int n) { - struct bio *bio = tape->bio; + struct idetape_bh *bh = tape->bh; int count; while (n) { #if IDETAPE_DEBUG_BUGS - if (bio == NULL) { - printk(KERN_ERR "ide-tape: bio == NULL in " + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_copy_stage_from_user\n"); return; } #endif /* IDETAPE_DEBUG_BUGS */ - count = min((unsigned long) (bio->bi_size - tape->b_count), (unsigned long) n); - copy_from_user(bio_data(bio) + tape->b_count, buf, count); + count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), (unsigned int)n); + copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, count); n -= count; - bio->bi_size += count; + atomic_add(count, &bh->b_count); buf += count; - if (tape->b_count == bio->bi_size) { - bio = bio->bi_next; - if (bio) - tape->b_count = 0; + if (atomic_read(&bh->b_count) == bh->b_size) { + bh = bh->b_reqnext; + if (bh) + atomic_set(&bh->b_count, 0); } } - tape->bio = bio; + tape->bh = bh; } static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape_stage_t *stage, int n) { - struct bio *bio = tape->bio; + struct idetape_bh *bh = tape->bh; int count; while (n) { #if IDETAPE_DEBUG_BUGS - if (bio == NULL) { - printk(KERN_ERR "ide-tape: bio == NULL in " + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_copy_stage_to_user\n"); return; } @@ -2962,10 +3059,10 @@ tape->b_count -= count; buf += count; if (!tape->b_count) { - tape->bio = bio = bio->bi_next; - if (bio) { - tape->b_data = bio_data(bio); - tape->b_count = bio->bi_size; + tape->bh = bh = bh->b_reqnext; + if (bh) { + tape->b_data = bh->b_data; + tape->b_count = atomic_read(&bh->b_count); } } } @@ -2973,26 +3070,27 @@ static void idetape_init_merge_stage (idetape_tape_t *tape) { - struct bio *bio = tape->merge_stage->bio; + struct idetape_bh *bh = tape->merge_stage->bh; - tape->bio = bio; + tape->bh = bh; if (tape->chrdev_direction == idetape_direction_write) - atomic_set(&bio->bi_cnt, 0); + atomic_set(&bh->b_count, 0); else { - tape->b_data = bio_data(bio); - tape->b_count = atomic_read(&bio->bi_cnt); + tape->b_data = bh->b_data; + tape->b_count = atomic_read(&bh->b_count); } } static void idetape_switch_buffers (idetape_tape_t *tape, idetape_stage_t *stage) { - struct bio *tmp; + struct idetape_bh *tmp; os_aux_t *tmp_aux; - tmp = stage->bio; tmp_aux = stage->aux; - stage->bio = tape->merge_stage->bio; + tmp = stage->bh; + tmp_aux = stage->aux; + stage->bh = tape->merge_stage->bh; stage->aux = tape->merge_stage->aux; - tape->merge_stage->bio = tmp; + tape->merge_stage->bh = tmp; tape->merge_stage->aux = tmp_aux; idetape_init_merge_stage(tape); } @@ -3010,7 +3108,7 @@ printk (KERN_INFO "ide-tape: Reached idetape_add_stage_tail\n"); #endif /* IDETAPE_DEBUG_LOG */ spin_lock_irqsave(&tape->spinlock, flags); - stage->next=NULL; + stage->next = NULL; if (tape->last_stage != NULL) tape->last_stage->next=stage; else @@ -3076,10 +3174,13 @@ else dat->dat_list[0].flags = OS_DAT_FLAGS_DATA; dat->dat_list[0].reserved = 0; - } - aux->filemark_cnt = ntohl(tape->filemark_cnt); /* shouldn't this be htonl ?? */ - aux->phys_fm = ntohl(0xffffffff); /* shouldn't this be htonl ?? */ - aux->last_mark_addr = ntohl(tape->last_mark_addr); /* shouldn't this be htonl ?? */ + } + /* shouldn't this be htonl ?? */ + aux->filemark_cnt = ntohl(tape->filemark_cnt); + /* shouldn't this be htonl ?? */ + aux->phys_fm = ntohl(0xffffffff); + /* shouldn't this be htonl ?? */ + aux->last_mark_addr = ntohl(tape->last_mark_addr); } /* @@ -3130,7 +3231,7 @@ if (result->bpu) { printk(KERN_INFO "ide-tape: Block location is unknown to the tape\n"); clear_bit(IDETAPE_ADDRESS_VALID, &tape->flags); - idetape_end_request(drive, 0); + idetape_end_request(drive, 0, 0); } else { #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 2) @@ -3141,10 +3242,10 @@ tape->last_frame_position = ntohl(result->last_block); tape->blocks_in_buffer = result->blocks_in_buffer[2]; set_bit(IDETAPE_ADDRESS_VALID, &tape->flags); - idetape_end_request(drive, 1); + idetape_end_request(drive, 1, 0); } } else { - idetape_end_request(drive, 0); + idetape_end_request(drive, 0, 0); } return ide_stopped; } @@ -3183,8 +3284,8 @@ * ide_do_drive_cmd from ide.c * cdrom_queue_request and cdrom_queue_packet_command from ide-cd.c * - * We add a special packet command request to the tail of the request queue, - * and wait for it to be serviced. + * We add a special packet command request to the tail of the request + * queue, and wait for it to be serviced. * * This is not to be called from within the request handling part * of the driver ! We allocate here data in the stack, and it is valid @@ -3223,7 +3324,7 @@ pc->callback = &idetape_pc_callback; } -static int idetape_wait_ready (ide_drive_t *drive, unsigned long long timeout) +static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) { idetape_tape_t *tape = drive->driver_data; idetape_pc_t pc; @@ -3462,7 +3563,7 @@ * idetape_queue_rw_tail generates a read/write request for the block * device interface and wait for it to be serviced. */ -static int idetape_queue_rw_tail (ide_drive_t *drive, int cmd, int blocks, struct bio *bio) +static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct idetape_bh *bh) { idetape_tape_t *tape = drive->driver_data; struct request rq; @@ -3479,7 +3580,7 @@ #endif /* IDETAPE_DEBUG_BUGS */ ide_init_drive_cmd(&rq); - rq.bio = bio; + rq.special = (void *)bh; rq.flags = cmd; rq.sector = tape->first_frame_position; rq.nr_sectors = rq.current_nr_sectors = blocks; @@ -3521,8 +3622,8 @@ if (!first) first = stage; aux = stage->aux; - p = bio_data(stage->bio); - idetape_queue_rw_tail(drive, IDETAPE_READ_BUFFER_RQ, tape->capabilities.ctl, stage->bio); + p = stage->bh->b_data; + idetape_queue_rw_tail(drive, IDETAPE_READ_BUFFER_RQ, tape->capabilities.ctl, stage->bh); #if ONSTREAM_DEBUG if (tape->debug_level >= 2) printk(KERN_INFO "ide-tape: %s: read back logical block %d, data %x %x %x %x\n", tape->name, logical_blk_num, *p++, *p++, *p++, *p++); @@ -3678,18 +3779,18 @@ os_aux_t *aux = stage->aux; os_partition_t *par = &aux->partition; struct request *rq = &stage->rq; - struct bio *bio; + struct idetape_bh *bh; if (!tape->onstream) return 1; if (tape->raw) { if (rq->errors) { - bio = stage->bio; - while (bio) { - memset(bio_data(bio), 0, bio->bi_size); - bio = bio->bi_next; + bh = stage->bh; + while (bh) { + memset(bh->b_data, 0, bh->b_size); + bh = bh->b_reqnext; } - strcpy(bio_data(stage->bio), "READ ERROR ON FRAME"); + strcpy(stage->bh->b_data, "READ ERROR ON FRAME"); } return 1; } @@ -3799,13 +3900,14 @@ * Linux is short on memory. Fallback to * non-pipelined operation mode for this request. */ - return idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, blocks, tape->merge_stage->bio); + return idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, blocks, tape->merge_stage->bh); } } rq = &new_stage->rq; ide_init_drive_cmd(rq); rq->flags = IDETAPE_WRITE_RQ; - rq->sector = tape->first_frame_position; /* Doesn't actually matter - We always assume sequential access */ + /* Doesn't actually matter - We always assume sequential access */ + rq->sector = tape->first_frame_position; rq->nr_sectors = rq->current_nr_sectors = blocks; idetape_switch_buffers(tape, new_stage); @@ -3848,7 +3950,8 @@ idetape_insert_pipeline_into_queue(drive); } } - if (test_and_clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) /* Return a deferred error */ + if (test_and_clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) + /* Return a deferred error */ return -EIO; return blocks; } @@ -3875,7 +3978,7 @@ { idetape_tape_t *tape = drive->driver_data; int blocks, min; - struct bio *bio; + struct idetape_bh *bh; #if IDETAPE_DEBUG_BUGS if (tape->chrdev_direction != idetape_direction_write) { @@ -3894,22 +3997,23 @@ blocks++; i = tape->tape_block_size - tape->merge_stage_size % tape->tape_block_size; - bio = tape->bio->bi_next; - while (bio) { - atomic_set(&bio->bi_cnt, 0); - bio = bio->bi_next; + bh = tape->bh->b_reqnext; + while (bh) { + atomic_set(&bh->b_count, 0); + bh = bh->b_reqnext; } - bio = tape->bio; + bh = tape->bh; while (i) { - if (bio == NULL) { - printk(KERN_INFO "ide-tape: bug, bio NULL\n"); + if (bh == NULL) { + + printk(KERN_INFO "ide-tape: bug, bh NULL\n"); break; } - min = min(i, bio->bi_size - atomic_read(&bio->bi_cnt)); - memset(bio_data(bio) + bio->bi_size, 0, min); - atomic_add(min, &bio->bi_cnt); + min = min(i, (unsigned int)(bh->b_size - atomic_read(&bh->b_count))); + memset(bh->b_data + atomic_read(&bh->b_count), 0, min); + atomic_add(min, &bh->b_count); i -= min; - bio = bio->bi_next; + bh = bh->b_reqnext; } } (void) idetape_add_chrdev_write_request(drive, blocks); @@ -3967,10 +4071,11 @@ int bytes_read; int blocks = tape->capabilities.ctl; - if (tape->chrdev_direction != idetape_direction_read) { /* Initialize read operation */ + /* Initialize read operation */ + if (tape->chrdev_direction != idetape_direction_read) { if (tape->chrdev_direction == idetape_direction_write) { - idetape_empty_write_pipeline (drive); - idetape_flush_tape_buffers (drive); + idetape_empty_write_pipeline(drive); + idetape_flush_tape_buffers(drive); } #if IDETAPE_DEBUG_BUGS if (tape->merge_stage || tape->merge_stage_size) { @@ -3988,7 +4093,7 @@ * is switched from completion mode to buffer available * mode. */ - bytes_read = idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 0, tape->merge_stage->bio); + bytes_read = idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 0, tape->merge_stage->bh); if (bytes_read < 0) { __idetape_kfree_stage(tape->merge_stage); tape->merge_stage = NULL; @@ -4054,19 +4159,27 @@ position = idetape_read_position(drive); printk(KERN_INFO "ide-tape: %s: blank block detected at %d\n", tape->name, position); if (position >= 3000 && position < 3080) - position += 32; /* Why is this check and number ??? MM */ - if (position >= OS_DATA_ENDFRAME1 && position < 3000) + /* Why is this check and number ??? MM */ + position += 32; + if (position >= OS_DATA_ENDFRAME1 && + position < 3000) position = 3000; else /* - * compensate for write errors that generally skip 80 frames, - * expect around 20 read errors in a row... + * compensate for write errors that + * generally skip 80 frames, expect + * around 20 read errors in a row... */ position += 60; - if (position >= OS_DATA_ENDFRAME1 && position < 3000) + if (position >= OS_DATA_ENDFRAME1 && + position < 3000) position = 3000; printk(KERN_INFO "ide-tape: %s: positioning tape to block %d\n", tape->name, position); - if (position == 3000) /* seems to be needed to correctly position at block 3000 MM */ + + /* seems to be needed to correctly position + * at block 3000 MM + */ + if (position == 3000) idetape_position_tape(drive, 0, 0, 0); idetape_position_tape(drive, position, 0, 0); cnt += 40; @@ -4129,7 +4242,7 @@ } if (test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) return 0; - return idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, blocks, tape->merge_stage->bio); + return idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, blocks, tape->merge_stage->bh); } rq_ptr = &tape->first_stage->rq; bytes_read = tape->tape_block_size * (rq_ptr->nr_sectors - rq_ptr->current_nr_sectors); @@ -4168,9 +4281,9 @@ calculate_speeds(drive); } #if IDETAPE_DEBUG_BUGS - if (bytes_read > blocks*tape->tape_block_size) { + if (bytes_read > blocks * tape->tape_block_size) { printk(KERN_ERR "ide-tape: bug: trying to return more bytes than requested\n"); - bytes_read = blocks*tape->tape_block_size; + bytes_read = blocks * tape->tape_block_size; } #endif /* IDETAPE_DEBUG_BUGS */ return (bytes_read); @@ -4179,23 +4292,23 @@ static void idetape_pad_zeros (ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; - struct bio *bio; + struct idetape_bh *bh; int blocks; while (bcount) { unsigned int count; - bio = tape->merge_stage->bio; + bh = tape->merge_stage->bh; count = min(tape->stage_size, bcount); bcount -= count; blocks = count / tape->tape_block_size; while (count) { - atomic_set(&bio->bi_cnt, min(count, bio->bi_size)); - memset(bio_data(bio), 0, bio->bi_size); - count -= atomic_read(&bio->bi_cnt); - bio = bio->bi_next; + atomic_set(&bh->b_count, min(count, (unsigned int)bh->b_size)); + memset(bh->b_data, 0, atomic_read(&bh->b_count)); + count -= atomic_read(&bh->b_count); + bh = bh->b_reqnext; } - idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, blocks, tape->merge_stage->bio); + idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, blocks, tape->merge_stage->bh); } } @@ -4578,7 +4691,6 @@ static ssize_t idetape_chrdev_read (struct file *file, char *buf, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; ide_drive_t *drive = file->private_data; idetape_tape_t *tape = drive->driver_data; ssize_t bytes_read,temp, actually_read = 0, rc; @@ -4598,7 +4710,8 @@ if (tape->chrdev_direction != idetape_direction_read) { if (test_bit(IDETAPE_DETECT_BS, &tape->flags)) - if (count > tape->tape_block_size && (count % tape->tape_block_size) == 0) + if (count > tape->tape_block_size && + (count % tape->tape_block_size) == 0) tape->user_bs_factor = count / tape->tape_block_size; } if ((rc = idetape_initiate_read(drive, tape->max_stages)) < 0) @@ -4606,7 +4719,7 @@ if (count == 0) return (0); if (tape->merge_stage_size) { - actually_read = min((unsigned long) (tape->merge_stage_size), (unsigned long) count); + actually_read = min((unsigned int)(tape->merge_stage_size), (unsigned int)count); idetape_copy_stage_to_user(tape, buf, tape->merge_stage, actually_read); buf += actually_read; tape->merge_stage_size -= actually_read; @@ -4625,7 +4738,7 @@ bytes_read = idetape_add_chrdev_read_request(drive, tape->capabilities.ctl); if (bytes_read <= 0) goto finish; - temp = min((unsigned long) count, (unsigned long) bytes_read); + temp = min((unsigned long)count, (unsigned long)bytes_read); idetape_copy_stage_to_user(tape, buf, tape->merge_stage, temp); actually_read += temp; tape->merge_stage_size = bytes_read-temp; @@ -4675,7 +4788,7 @@ "tape block %d\n", tape->last_frame_position); #endif idetape_position_tape(drive, last_mark_addr, 0, 0); - if (!idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 1, stage->bio)) { + if (!idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 1, stage->bh)) { printk(KERN_INFO "ide-tape: %s: couldn't read last marker\n", tape->name); __idetape_kfree_stage(stage); @@ -4696,7 +4809,7 @@ #endif aux->next_mark_addr = htonl(next_mark_addr); idetape_position_tape(drive, last_mark_addr, 0, 0); - if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bio)) { + if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bh)) { printk(KERN_INFO "ide-tape: %s: couldn't write back marker " "frame at %d\n", tape->name, last_mark_addr); __idetape_kfree_stage(stage); @@ -4730,9 +4843,9 @@ /* don't write fillers if we cannot position the tape. */ return; - strcpy(bio_data(stage->bio), "Filler"); + strcpy(stage->bh->b_data, "Filler"); while (cnt--) { - if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bio)) { + if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bh)) { printk(KERN_INFO "ide-tape: %s: write_filler: " "couldn't write header frame\n", tape->name); __idetape_kfree_stage(stage); @@ -4765,9 +4878,9 @@ header.partition.last_frame_addr = htonl(tape->capacity); header.partition.wrt_pass_cntr = htons(tape->wrt_pass_cntr); header.partition.eod_frame_addr = htonl(tape->eod_frame_addr); - memcpy(bio_data(stage->bio), &header, sizeof(header)); + memcpy(stage->bh->b_data, &header, sizeof(header)); while (cnt--) { - if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bio)) { + if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bh)) { printk(KERN_INFO "ide-tape: %s: couldn't write " "header frame\n", tape->name); __idetape_kfree_stage(stage); @@ -4832,8 +4945,8 @@ return -EINVAL; } /* - * Check if we reach the end of the tape. Just assume the - * whole pipeline is filled with write requests! + * Check if we reach the end of the tape. Just assume the whole + * pipeline is filled with write requests! */ if (tape->first_frame_position + tape->nr_stages >= tape->capacity - OS_EW) { #if ONSTREAM_DEBUG @@ -4846,8 +4959,8 @@ } } + /* Initialize write operation */ if (tape->chrdev_direction != idetape_direction_write) { - /* Initialize write operation */ if (tape->chrdev_direction == idetape_direction_read) idetape_discard_read_pipeline(drive, 1); #if IDETAPE_DEBUG_BUGS @@ -4900,7 +5013,7 @@ * is switched from completion mode to buffer available * mode. */ - retval = idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 0, tape->merge_stage->bio); + retval = idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 0, tape->merge_stage->bh); if (retval < 0) { __idetape_kfree_stage(tape->merge_stage); tape->merge_stage = NULL; @@ -4924,7 +5037,7 @@ tape->merge_stage_size = 0; } #endif /* IDETAPE_DEBUG_BUGS */ - actually_written = min((unsigned long) (tape->stage_size - tape->merge_stage_size), (unsigned long) count); + actually_written = min((unsigned int)(tape->stage_size - tape->merge_stage_size), (unsigned int)count); idetape_copy_stage_from_user(tape, tape->merge_stage, buf, actually_written); buf += actually_written; tape->merge_stage_size += actually_written; @@ -4934,7 +5047,7 @@ tape->merge_stage_size = 0; retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl); if (retval <= 0) - return(retval); + return (retval); } } while (count >= tape->stage_size) { @@ -4944,7 +5057,7 @@ retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl); actually_written += tape->stage_size; if (retval <= 0) - return(retval); + return (retval); } if (count) { actually_written += count; @@ -4961,7 +5074,8 @@ idetape_pc_t pc; if (!tape->onstream) { - idetape_create_write_filemark_cmd(drive, &pc, 1); /* Write a filemark */ + /* Write a filemark */ + idetape_create_write_filemark_cmd(drive, &pc, 1); if (idetape_queue_pc_tail(drive, &pc)) { printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); return -EIO; @@ -5373,13 +5487,13 @@ printk(KERN_INFO "ide-tape: %s: reading header\n", tape->name); #endif idetape_position_tape(drive, block, 0, 0); - if (!idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 1, stage->bio)) { + if (!idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 1, stage->bh)) { printk(KERN_INFO "ide-tape: %s: couldn't read header frame\n", tape->name); __idetape_kfree_stage(stage); return 0; } - header = (os_header_t *) bio_data(stage->bio); + header = (os_header_t *) stage->bh->b_data; aux = stage->aux; if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0) { printk(KERN_INFO "ide-tape: %s: invalid header identification string\n", tape->name); @@ -5532,7 +5646,7 @@ */ static int idetape_chrdev_release (struct inode *inode, struct file *filp) { - ide_drive_t *drive = file->private_data; + ide_drive_t *drive = filp->private_data; idetape_tape_t *tape; idetape_pc_t pc; unsigned int minor = minor(inode->i_rdev); @@ -5891,17 +6005,19 @@ idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); if (idetape_queue_pc_tail(drive, &pc)) { printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming some default values\n"); - tape->tape_block_size = 512; tape->capabilities.ctl = 52; - tape->capabilities.speed = 450; tape->capabilities.buffer_size = 6 * 52; + tape->tape_block_size = 512; + tape->capabilities.ctl = 52; + tape->capabilities.speed = 450; + tape->capabilities.buffer_size = 6 * 52; return; } header = (idetape_mode_parameter_header_t *) pc.buffer; capabilities = (idetape_capabilities_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl); - capabilities->max_speed = ntohs (capabilities->max_speed); - capabilities->ctl = ntohs (capabilities->ctl); - capabilities->speed = ntohs (capabilities->speed); - capabilities->buffer_size = ntohs (capabilities->buffer_size); + capabilities->max_speed = ntohs(capabilities->max_speed); + capabilities->ctl = ntohs(capabilities->ctl); + capabilities->speed = ntohs(capabilities->speed); + capabilities->buffer_size = ntohs(capabilities->buffer_size); if (!capabilities->speed) { printk(KERN_INFO "ide-tape: %s: overriding capabilities->speed (assuming 650KB/sec)\n", drive->name); @@ -6037,7 +6153,8 @@ memset(tape, 0, sizeof (idetape_tape_t)); spin_lock_init(&tape->spinlock); drive->driver_data = tape; - drive->ready_stat = 0; /* An ATAPI device ignores DRDY */ + /* An ATAPI device ignores DRDY */ + drive->ready_stat = 0; if (strstr(drive->id->model, "OnStream DI-")) tape->onstream = 1; drive->dsc_overlap = 1; @@ -6056,7 +6173,9 @@ #endif /* CONFIG_BLK_DEV_IDEPCI */ tape->drive = drive; tape->minor = minor; - tape->name[0] = 'h'; tape->name[1] = 't'; tape->name[2] = '0' + minor; + tape->name[0] = 'h'; + tape->name[1] = 't'; + tape->name[2] = '0' + minor; tape->chrdev_direction = idetape_direction_none; tape->pc = tape->pc_stack; tape->max_insert_speed = 10000; @@ -6143,7 +6262,7 @@ unsigned long flags; spin_lock_irqsave(&ide_lock, flags); - if (test_bit (IDETAPE_BUSY, &tape->flags) || drive->usage || + if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage || tape->first_stage != NULL || tape->merge_stage_size) { spin_unlock_irqrestore(&ide_lock, flags); return 1; @@ -6290,7 +6409,7 @@ idetape_setup(drive, tape, minor); idetape_chrdevs[minor].drive = drive; - devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor) + devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor), S_IFCHR | S_IRUGO | S_IWUGO, "%s/mt", drive->devfs_name); devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor + 128), diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c --- a/drivers/ide/ide.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ide/ide.c Mon Aug 18 22:21:02 2003 @@ -778,6 +778,17 @@ /* More messed up locking ... */ spin_unlock_irq(&ide_lock); device_unregister(&hwif->gendev); + + /* + * Remove us from the kernel's knowledge + */ + blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<drives[i].disk; + hwif->drives[i].disk = NULL; + put_disk(disk); + } + unregister_blkdev(hwif->major, hwif->name); spin_lock_irq(&ide_lock); #if !defined(CONFIG_DMA_NONPCI) @@ -793,22 +804,12 @@ hwif->dma_prdtable = 0; } #endif /* !(CONFIG_DMA_NONPCI) */ - - /* - * Remove us from the kernel's knowledge - */ - blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<drives[i].disk; - hwif->drives[i].disk = NULL; - put_disk(disk); - } - unregister_blkdev(hwif->major, hwif->name); - old_hwif = *hwif; init_hwif_data(index); /* restore hwif data to pristine status */ hwif->hwgroup = old_hwif.hwgroup; + hwif->gendev.parent = old_hwif.gendev.parent; + hwif->proc = old_hwif.proc; hwif->major = old_hwif.major; @@ -904,7 +905,7 @@ hwif->mmio = old_hwif.mmio; hwif->rqsize = old_hwif.rqsize; - hwif->addressing = old_hwif.addressing; + hwif->no_lba48 = old_hwif.no_lba48; #ifndef CONFIG_BLK_DEV_IDECS hwif->irq = old_hwif.irq; #endif /* CONFIG_BLK_DEV_IDECS */ @@ -1614,18 +1615,6 @@ if (put_user(drive->bios_head, (u8 *) &loc->heads)) return -EFAULT; if (put_user(drive->bios_sect, (u8 *) &loc->sectors)) return -EFAULT; if (put_user(bios_cyl, (u16 *) &loc->cylinders)) return -EFAULT; - if (put_user((unsigned)get_start_sect(bdev), - (unsigned long *) &loc->start)) return -EFAULT; - return 0; - } - - case HDIO_GETGEO_BIG_RAW: - { - struct hd_big_geometry *loc = (struct hd_big_geometry *) arg; - if (!loc || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL; - if (put_user(drive->head, (u8 *) &loc->heads)) return -EFAULT; - if (put_user(drive->sect, (u8 *) &loc->sectors)) return -EFAULT; - if (put_user(drive->cyl, (unsigned int *) &loc->cylinders)) return -EFAULT; if (put_user((unsigned)get_start_sect(bdev), (unsigned long *) &loc->start)) return -EFAULT; return 0; diff -Nru a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c --- a/drivers/ide/legacy/ali14xx.c Mon Aug 18 22:21:01 2003 +++ b/drivers/ide/legacy/ali14xx.c Mon Aug 18 22:21:01 2003 @@ -269,7 +269,7 @@ MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets"); MODULE_LICENSE("GPL"); -int __init ali14xx_mod_init(void) +static int __init ali14xx_mod_init(void) { /* auto-detect IDE controller port */ if (findPort()) @@ -287,7 +287,7 @@ } module_init(ali14xx_mod_init); -void __init ali14xx_mod_exit(void) +static void __exit ali14xx_mod_exit(void) { ali14xx_release(); } diff -Nru a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c --- a/drivers/ide/legacy/dtc2278.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ide/legacy/dtc2278.c Mon Aug 18 22:21:02 2003 @@ -173,7 +173,7 @@ MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets"); MODULE_LICENSE("GPL"); -int __init dtc2278_mod_init(void) +static int __init dtc2278_mod_init(void) { probe_dtc2278(); if (ide_hwifs[0].chipset != ide_dtc2278 && @@ -185,7 +185,7 @@ } module_init(dtc2278_mod_init); -void __init dtc2278_mod_exit(void) +static void __exit dtc2278_mod_exit(void) { dtc2278_release(); } diff -Nru a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c --- a/drivers/ide/legacy/hd.c Mon Aug 18 22:21:00 2003 +++ b/drivers/ide/legacy/hd.c Mon Aug 18 22:21:00 2003 @@ -715,7 +715,7 @@ hd_queue = blk_init_queue(do_hd_request, &hd_lock); if (!hd_queue) { - unegister_blkdev(MAJOR_NR,"hd"); + unregister_blkdev(MAJOR_NR,"hd"); return -ENOMEM; } diff -Nru a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c --- a/drivers/ide/legacy/ht6560b.c Mon Aug 18 22:21:05 2003 +++ b/drivers/ide/legacy/ht6560b.c Mon Aug 18 22:21:05 2003 @@ -330,7 +330,7 @@ release_region(HT_CONFIG_PORT, 1); } -int __init ht6560b_mod_init(void) +static int __init ht6560b_mod_init(void) { int t; @@ -391,7 +391,7 @@ MODULE_LICENSE("GPL"); #ifdef MODULE -void __init ht6560b_mod_exit(void) +static void __exit ht6560b_mod_exit(void) { ht6560b_release(); } diff -Nru a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c --- a/drivers/ide/legacy/ide-cs.c Mon Aug 18 22:21:04 2003 +++ b/drivers/ide/legacy/ide-cs.c Mon Aug 18 22:21:04 2003 @@ -92,7 +92,7 @@ int hd; } ide_info_t; -static void ide_release(u_long arg); +static void ide_release(dev_link_t *); static int ide_event(event_t event, int priority, event_callback_args_t *args); @@ -126,9 +126,6 @@ memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; - init_timer(&link->release); - link->release.function = &ide_release; - link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; @@ -187,9 +184,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) - ide_release((u_long)link); + ide_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -383,7 +379,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); failed: - ide_release((u_long)link); + ide_release(link); link->state &= ~DEV_CONFIG_PENDING; } /* ide_config */ @@ -396,9 +392,8 @@ ======================================================================*/ -void ide_release(u_long arg) +void ide_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; ide_info_t *info = link->priv; DEBUG(0, "ide_release(0x%p)\n", link); @@ -446,7 +441,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + ide_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -Nru a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c --- a/drivers/ide/legacy/pdc4030.c Mon Aug 18 22:21:03 2003 +++ b/drivers/ide/legacy/pdc4030.c Mon Aug 18 22:21:03 2003 @@ -227,7 +227,7 @@ hwif2->mate = hwif; hwif2->channel = 1; hwif->rqsize = hwif2->rqsize = 127; - hwif->addressing = hwif2->addressing = 1; + hwif->no_lba48 = hwif2->no_lba48 = 1; hwif->selectproc = hwif2->selectproc = &promise_selectproc; hwif->serialized = hwif2->serialized = 1; /* DC4030 hosted drives need their own identify... */ @@ -326,7 +326,7 @@ #endif } -void __init release_pdc4030(ide_hwif_t *hwif, ide_hwif_t *mate) +static void __exit release_pdc4030(ide_hwif_t *hwif, ide_hwif_t *mate) { hwif->chipset = ide_unknown; hwif->selectproc = NULL; @@ -369,7 +369,7 @@ MODULE_DESCRIPTION("Support of Promise 4030 VLB series IDE chipsets"); MODULE_LICENSE("GPL"); -int __init pdc4030_mod_init(void) +static int __init pdc4030_mod_init(void) { if (enable_promise_support == 0) enable_promise_support = 1; @@ -380,7 +380,7 @@ } module_init(pdc4030_mod_init); -void __init pdc4030_mod_exit(void) +static void __exit pdc4030_mod_exit(void) { unsigned int index; ide_hwif_t *hwif; diff -Nru a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c --- a/drivers/ide/legacy/qd65xx.c Mon Aug 18 22:21:01 2003 +++ b/drivers/ide/legacy/qd65xx.c Mon Aug 18 22:21:01 2003 @@ -360,7 +360,7 @@ * * called to unsetup an ata channel : back to default values, unlinks tuning */ -void __init qd_unsetup (int unit) +static void __exit qd_unsetup (int unit) { ide_hwif_t *hwif = &ide_hwifs[unit]; u8 config = hwif->config_data; @@ -495,7 +495,7 @@ MODULE_DESCRIPTION("support of qd65xx vlb ide chipset"); MODULE_LICENSE("GPL"); -int __init qd65xx_mod_init(void) +static int __init qd65xx_mod_init(void) { if (qd_probe(0x30)) qd_probe(0xb0); if (ide_hwifs[0].chipset != ide_qd65xx && @@ -505,7 +505,7 @@ } module_init(qd65xx_mod_init); -void __init qd65xx_mod_exit(void) +static void __exit qd65xx_mod_exit(void) { qd_unsetup(0); qd_unsetup(1); diff -Nru a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c --- a/drivers/ide/legacy/umc8672.c Mon Aug 18 22:21:01 2003 +++ b/drivers/ide/legacy/umc8672.c Mon Aug 18 22:21:01 2003 @@ -207,7 +207,7 @@ MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset"); MODULE_LICENSE("GPL"); -int __init umc8672_mod_init(void) +static int __init umc8672_mod_init(void) { if (probe_umc8672()) return -ENODEV; @@ -220,7 +220,7 @@ } module_init(umc8672_mod_init); -void __init umc8672_mod_exit(void) +static void __exit umc8672_mod_exit(void) { umc8672_release(); } diff -Nru a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c --- a/drivers/ide/pci/alim15x3.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ide/pci/alim15x3.c Mon Aug 18 22:21:02 2003 @@ -745,7 +745,7 @@ hwif->speedproc = &ali15x3_tune_chipset; /* Don't use LBA48 on ALi devices before rev 0xC5 */ - hwif->addressing = (m5229_revision <= 0xC4) ? 1 : 0; + hwif->no_lba48 = (m5229_revision <= 0xC4) ? 1 : 0; if (!hwif->dma_base) { hwif->drives[0].autotune = 1; @@ -860,7 +860,7 @@ { ide_pci_device_t *d = &ali15x3_chipsets[id->driver_data]; - if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_IGP, NULL)) + if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL)) printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n"); #if defined(CONFIG_SPARC64) diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c --- a/drivers/ide/pci/amd74xx.c Mon Aug 18 22:21:06 2003 +++ b/drivers/ide/pci/amd74xx.c Mon Aug 18 22:21:06 2003 @@ -104,7 +104,7 @@ amd_print("----------AMD BusMastering IDE Configuration----------------"); amd_print("Driver Version: 2.9"); - amd_print("South Bridge: %s", bmide_dev->dev.name); + amd_print("South Bridge: %s", pci_name(bmide_dev)); pci_read_config_byte(dev, PCI_REVISION_ID, &t); amd_print("Revision: IDE %#x", t); @@ -365,7 +365,7 @@ pci_read_config_byte(dev, PCI_REVISION_ID, &t); printk(KERN_INFO "AMD_IDE: %s (rev %02x) %s controller on pci%s\n", - dev->dev.name, t, amd_dma[amd_config->flags & AMD_UDMA], pci_name(dev)); + pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA], pci_name(dev)); /* * Register /proc/ide/amd74xx entry diff -Nru a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c --- a/drivers/ide/pci/hpt366.c Mon Aug 18 22:21:04 2003 +++ b/drivers/ide/pci/hpt366.c Mon Aug 18 22:21:04 2003 @@ -440,7 +440,7 @@ static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); + pio = ide_get_best_pio_mode(drive, 255, pio, NULL); (void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio)); } diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c --- a/drivers/ide/pci/pdc202xx_old.c Mon Aug 18 22:21:06 2003 +++ b/drivers/ide/pci/pdc202xx_old.c Mon Aug 18 22:21:06 2003 @@ -750,7 +750,7 @@ hwif->quirkproc = &pdc202xx_quirkproc; if (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) - hwif->addressing = (hwif->channel) ? 0 : 1; + hwif->no_lba48 = (hwif->channel) ? 0 : 1; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { hwif->busproc = &pdc202xx_tristate; diff -Nru a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c --- a/drivers/ide/pci/siimage.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ide/pci/siimage.c Mon Aug 18 22:21:02 2003 @@ -724,7 +724,7 @@ } #ifdef SIIMAGE_BUFFERED_TASKFILE - hwif->addressing = 1; + hwif->no_lba48 = 1; #endif /* SIIMAGE_BUFFERED_TASKFILE */ hwif->irq = hw.irq; hwif->hwif_data = pci_get_drvdata(hwif->pci_dev); diff -Nru a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c --- a/drivers/ide/pci/trm290.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ide/pci/trm290.c Mon Aug 18 22:21:02 2003 @@ -309,7 +309,7 @@ u8 reg = 0; struct pci_dev *dev = hwif->pci_dev; - hwif->addressing = 1; + hwif->no_lba48 = 1; hwif->chipset = ide_trm290; cfgbase = pci_resource_start(dev, 4); if ((dev->class & 5) && cfgbase) { diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c --- a/drivers/ide/ppc/pmac.c Mon Aug 18 22:21:01 2003 +++ b/drivers/ide/ppc/pmac.c Mon Aug 18 22:21:01 2003 @@ -971,7 +971,7 @@ if (sector_count > 127) { memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); - sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; + sg[nents].offset = offset_in_page(virt_addr); sg[nents].length = 127 * SECTOR_SIZE; nents++; virt_addr = virt_addr + (127 * SECTOR_SIZE); @@ -979,7 +979,7 @@ } memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); - sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; + sg[nents].offset = offset_in_page(virt_addr); sg[nents].length = sector_count * SECTOR_SIZE; nents++; diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c --- a/drivers/ieee1394/nodemgr.c Mon Aug 18 22:21:04 2003 +++ b/drivers/ieee1394/nodemgr.c Mon Aug 18 22:21:04 2003 @@ -460,21 +460,6 @@ } -static void nodemgr_update_ud_names(struct host_info *hi, struct node_entry *ne) -{ - struct list_head *lh; - - list_for_each(lh, &ne->device.children) { - struct unit_directory *ud; - ud = container_of(list_to_dev(lh), struct unit_directory, device); - - snprintf(ud->device.name, DEVICE_NAME_SIZE, - "IEEE-1394 unit directory " NODE_BUS_FMT "-%u", - NODE_BUS_ARGS(hi->host, ne->nodeid), ud->id); - } -} - - static void nodemgr_remove_ne(struct node_entry *ne) { struct device *dev = &ne->device; @@ -720,9 +705,6 @@ ne->device.parent = &host->device; snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", (unsigned long long)(ne->guid)); - snprintf(ne->device.name, DEVICE_NAME_SIZE, - "IEEE-1394 device " NODE_BUS_FMT, - NODE_BUS_ARGS(host, ne->nodeid)); device_register(&ne->device); @@ -732,8 +714,6 @@ nodemgr_process_config_rom (hi, ne, busoptions); - nodemgr_update_ud_names(hi, ne); - HPSB_DEBUG("%s added: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", (host->node_id == nodeid) ? "Host" : "Node", NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); @@ -1312,18 +1292,11 @@ struct host_info *hi, nodeid_t nodeid, unsigned int generation) { - int update_ud_names = 0; - if (ne->nodeid != nodeid) { - snprintf(ne->device.name, DEVICE_NAME_SIZE, - "IEEE-1394 device " NODE_BUS_FMT, - NODE_BUS_ARGS(hi->host, ne->nodeid)); HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, NODE_BUS_ARGS(ne->host, ne->nodeid), NODE_BUS_ARGS(ne->host, nodeid)); ne->nodeid = nodeid; - - update_ud_names++; } if (ne->busopt.generation != ((busoptions >> 4) & 0xf)) { @@ -1333,13 +1306,8 @@ /* This will re-register our unitdir's */ nodemgr_process_config_rom (hi, ne, busoptions); - - update_ud_names++; } - if (update_ud_names) - nodemgr_update_ud_names(hi, ne); - /* Since that's done, we can declare this record current */ ne->generation = generation; @@ -1772,8 +1740,6 @@ sizeof(host->device)); host->device.parent = &host->pdev->dev; snprintf(host->device.bus_id, BUS_ID_SIZE, "fw-host%d", host->id); - snprintf(host->device.name, DEVICE_NAME_SIZE, "IEEE-1394 Host %s-%d", - host->driver->name, host->id); sprintf(hi->daemon_name, "knodemgrd_%d", host->id); diff -Nru a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c --- a/drivers/ieee1394/pcilynx.c Mon Aug 18 22:21:02 2003 +++ b/drivers/ieee1394/pcilynx.c Mon Aug 18 22:21:02 2003 @@ -144,9 +144,7 @@ .id = 0xAA, //FIXME: probably we should get an id in i2c-id.h .client_register = bit_reg, .client_unregister = bit_unreg, - .dev = { - .name = "PCILynx I2C", - }, + .name = "PCILynx I2C", }; diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c --- a/drivers/ieee1394/sbp2.c Mon Aug 18 22:21:01 2003 +++ b/drivers/ieee1394/sbp2.c Mon Aug 18 22:21:01 2003 @@ -1002,8 +1002,9 @@ sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); /* Remove it from the scsi layer now */ - if (sdev && scsi_remove_device(sdev)) - SBP2_ERR("scsi_remove_device failed"); + if (sdev) { + scsi_remove_device(sdev); + } sbp2util_remove_command_orb_pool(scsi_id); @@ -2890,7 +2891,6 @@ .cmd_per_lun = SBP2_MAX_CMDS_PER_LUN, .can_queue = SBP2_MAX_SCSI_QUEUE, .emulated = 1, - .highmem_io = 1, }; static int sbp2_module_init(void) diff -Nru a/drivers/input/evdev.c b/drivers/input/evdev.c --- a/drivers/input/evdev.c Mon Aug 18 22:21:04 2003 +++ b/drivers/input/evdev.c Mon Aug 18 22:21:04 2003 @@ -218,7 +218,7 @@ return put_user(EV_VERSION, (int *) arg); case EVIOCGID: - return copy_to_user((void *) arg, &dev->id, sizeof(struct input_id)); + return copy_to_user((void *) arg, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0; case EVIOCGREP: if (put_user(dev->rep[0], ((int *) arg) + 0)) return -EFAULT; diff -Nru a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c --- a/drivers/input/gameport/emu10k1-gp.c Mon Aug 18 22:21:04 2003 +++ b/drivers/input/gameport/emu10k1-gp.c Mon Aug 18 22:21:04 2003 @@ -84,7 +84,7 @@ emu->dev = pdev; emu->gameport.io = ioport; - emu->gameport.name = pdev->dev.name; + emu->gameport.name = pci_name(pdev); emu->gameport.phys = emu->phys; emu->gameport.id.bustype = BUS_PCI; emu->gameport.id.vendor = pdev->vendor; @@ -94,8 +94,8 @@ gameport_register_port(&emu->gameport); - printk(KERN_INFO "gameport: %s at pci%s speed %d kHz\n", - pdev->dev.name, pci_name(pdev), emu->gameport.speed); + printk(KERN_INFO "gameport: pci%s speed %d kHz\n", + pci_name(pdev), emu->gameport.speed); return 0; } diff -Nru a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c --- a/drivers/input/gameport/fm801-gp.c Mon Aug 18 22:21:04 2003 +++ b/drivers/input/gameport/fm801-gp.c Mon Aug 18 22:21:04 2003 @@ -115,8 +115,8 @@ gameport_register_port(&gp->gameport); - printk(KERN_INFO "gameport: %s at pci%s speed %d kHz\n", - pci->dev.name, pci_name(pci), gp->gameport.speed); + printk(KERN_INFO "gameport: at pci%s speed %d kHz\n", + pci_name(pci), gp->gameport.speed); return 0; } diff -Nru a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c --- a/drivers/input/gameport/lightning.c Mon Aug 18 22:21:02 2003 +++ b/drivers/input/gameport/lightning.c Mon Aug 18 22:21:02 2003 @@ -209,7 +209,7 @@ return 0; } -int __init l4_init(void) +static int __init l4_init(void) { int cal[4] = {255,255,255,255}; int i, j, rev, cards = 0; @@ -286,7 +286,7 @@ return 0; } -void __init l4_exit(void) +static void __exit l4_exit(void) { int i; int cal[4] = {59, 59, 59, 59}; diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c --- a/drivers/input/gameport/ns558.c Mon Aug 18 22:21:05 2003 +++ b/drivers/input/gameport/ns558.c Mon Aug 18 22:21:05 2003 @@ -222,7 +222,7 @@ port->gameport.id.version = 0x100; sprintf(port->phys, "pnp%s/gameport0", dev->dev.bus_id); - sprintf(port->name, "%s", dev->dev.name[0] ? dev->dev.name : "NS558 PnP Gameport"); + sprintf(port->name, "%s", "NS558 PnP Gameport"); gameport_register_port(&port->gameport); diff -Nru a/drivers/input/gameport/vortex.c b/drivers/input/gameport/vortex.c --- a/drivers/input/gameport/vortex.c Mon Aug 18 22:21:05 2003 +++ b/drivers/input/gameport/vortex.c Mon Aug 18 22:21:05 2003 @@ -127,7 +127,7 @@ vortex->gameport.cooked_read = vortex_cooked_read; vortex->gameport.open = vortex_open; - vortex->gameport.name = dev->dev.name; + vortex->gameport.name = pci_name(dev); vortex->gameport.phys = vortex->phys; vortex->gameport.id.bustype = BUS_PCI; vortex->gameport.id.vendor = dev->vendor; @@ -145,8 +145,8 @@ gameport_register_port(&vortex->gameport); - printk(KERN_INFO "gameport: %s at pci%s speed %d kHz\n", - dev->dev.name, pci_name(dev), vortex->gameport.speed); + printk(KERN_INFO "gameport at pci%s speed %d kHz\n", + pci_name(dev), vortex->gameport.speed); return 0; } diff -Nru a/drivers/input/input.c b/drivers/input/input.c --- a/drivers/input/input.c Mon Aug 18 22:21:03 2003 +++ b/drivers/input/input.c Mon Aug 18 22:21:03 2003 @@ -685,25 +685,47 @@ static int __init input_init(void) { struct proc_dir_entry *entry; + int retval = -ENOMEM; class_register(&input_class); #ifdef CONFIG_PROC_FS proc_bus_input_dir = proc_mkdir("input", proc_bus); + if (proc_bus_input_dir == NULL) + return -ENOMEM; proc_bus_input_dir->owner = THIS_MODULE; entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); + if (entry == NULL) { + remove_proc_entry("input", proc_bus); + return -ENOMEM; + } entry->owner = THIS_MODULE; entry->proc_fops->poll = input_devices_poll; entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); + if (entry == NULL) { + remove_proc_entry("devices", proc_bus_input_dir); + remove_proc_entry("input", proc_bus); + return -ENOMEM; + } entry->owner = THIS_MODULE; #endif - if (register_chrdev(INPUT_MAJOR, "input", &input_fops)) { + retval = register_chrdev(INPUT_MAJOR, "input", &input_fops); + if (retval) { printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); - return -EBUSY; + remove_proc_entry("devices", proc_bus_input_dir); + remove_proc_entry("handlers", proc_bus_input_dir); + remove_proc_entry("input", proc_bus); + return retval; } - devfs_mk_dir("input"); - return 0; + retval = devfs_mk_dir("input"); + if (retval) { + remove_proc_entry("devices", proc_bus_input_dir); + remove_proc_entry("handlers", proc_bus_input_dir); + remove_proc_entry("input", proc_bus); + unregister_chrdev(INPUT_MAJOR, "input"); + } + return retval; } static void __exit input_exit(void) @@ -714,8 +736,7 @@ remove_proc_entry("input", proc_bus); #endif devfs_remove("input"); - if (unregister_chrdev(INPUT_MAJOR, "input")) - printk(KERN_ERR "input: can't unregister char major %d", INPUT_MAJOR); + unregister_chrdev(INPUT_MAJOR, "input"); class_unregister(&input_class); } diff -Nru a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c --- a/drivers/input/joystick/joydump.c Mon Aug 18 22:21:05 2003 +++ b/drivers/input/joystick/joydump.c Mon Aug 18 22:21:05 2003 @@ -81,8 +81,7 @@ t = 0; i = 1; - save_flags(flags); - cli(); + local_irq_save(flags); u = gameport_read(gameport); @@ -103,7 +102,7 @@ t++; } - restore_flags(flags); + local_irq_restore(flags); /* * Dump data. diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c --- a/drivers/input/misc/uinput.c Mon Aug 18 22:21:05 2003 +++ b/drivers/input/misc/uinput.c Mon Aug 18 22:21:05 2003 @@ -226,7 +226,7 @@ return retval; } -static int uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct uinput_device *udev = file->private_data; @@ -323,36 +323,67 @@ retval = uinput_destroy_device(udev); break; - case UI_SET_EVBIT: + if (arg > EV_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->evbit); break; case UI_SET_KEYBIT: + if (arg > KEY_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->keybit); break; case UI_SET_RELBIT: + if (arg > REL_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->relbit); break; case UI_SET_ABSBIT: + if (arg > ABS_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->absbit); break; case UI_SET_MSCBIT: + if (arg > MSC_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->mscbit); break; case UI_SET_LEDBIT: + if (arg > LED_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->ledbit); break; case UI_SET_SNDBIT: + if (arg > SND_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->sndbit); break; case UI_SET_FFBIT: + if (arg > FF_MAX) { + retval = -EINVAL; + break; + } set_bit(arg, udev->dev->ffbit); break; diff -Nru a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h --- a/drivers/input/serio/i8042.h Mon Aug 18 22:21:05 2003 +++ b/drivers/input/serio/i8042.h Mon Aug 18 22:21:05 2003 @@ -103,11 +103,11 @@ #ifdef DEBUG static unsigned long i8042_start; -#define dbg_init() do { i8042_start = jiffies; } while (0); +#define dbg_init() do { i8042_start = jiffies; } while (0) #define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" ,\ ## arg, (int) (jiffies - i8042_start)) #else -#define dbg_init() do { } while (0); +#define dbg_init() do { } while (0) #define dbg(format, arg...) do {} while (0) #endif diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c --- a/drivers/input/serio/pcips2.c Mon Aug 18 22:21:01 2003 +++ b/drivers/input/serio/pcips2.c Mon Aug 18 22:21:01 2003 @@ -153,7 +153,7 @@ ps2if->io.write = pcips2_write; ps2if->io.open = pcips2_open; ps2if->io.close = pcips2_close; - ps2if->io.name = dev->dev.name; + ps2if->io.name = pci_name(dev); ps2if->io.phys = dev->dev.bus_id; ps2if->io.driver = ps2if; ps2if->dev = dev; diff -Nru a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c --- a/drivers/isdn/hardware/avm/avm_cs.c Mon Aug 18 22:21:00 2003 +++ b/drivers/isdn/hardware/avm/avm_cs.c Mon Aug 18 22:21:00 2003 @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -64,7 +63,7 @@ */ static void avmcs_config(dev_link_t *link); -static void avmcs_release(u_long arg); +static void avmcs_release(dev_link_t *link); static int avmcs_event(event_t event, int priority, event_callback_args_t *args); @@ -142,8 +141,6 @@ if (!link) goto err; memset(link, 0, sizeof(struct dev_link_t)); - link->release.function = &avmcs_release; - link->release.data = (u_long)link; /* The io structure describes IO port mapping */ link->io.NumPorts1 = 16; @@ -403,7 +400,7 @@ link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { - avmcs_release((u_long)link); + avmcs_release(link); return; } @@ -417,7 +414,7 @@ if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); - avmcs_release((u_long)link); + avmcs_release(link); return; } dev->node.minor = i; @@ -432,10 +429,8 @@ ======================================================================*/ -static void avmcs_release(u_long arg) +static void avmcs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; - /* If the device is currently in use, we won't release until it is actually closed. @@ -483,10 +478,8 @@ switch (event) { case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - link->release.expires = jiffies + (HZ/20); - add_timer(&link->release); - } + if (link->state & DEV_CONFIG) + avmcs_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; @@ -531,7 +524,7 @@ /* XXX: this really needs to move into generic code.. */ while (dev_list != NULL) { if (dev_list->state & DEV_CONFIG) - avmcs_release((u_long)dev_list); + avmcs_release(dev_list); avmcs_detach(dev_list); } } diff -Nru a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c --- a/drivers/isdn/hisax/avma1_cs.c Mon Aug 18 22:21:04 2003 +++ b/drivers/isdn/hisax/avma1_cs.c Mon Aug 18 22:21:04 2003 @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -76,7 +75,7 @@ */ static void avma1cs_config(dev_link_t *link); -static void avma1cs_release(u_long arg); +static void avma1cs_release(dev_link_t *link); static int avma1cs_event(event_t event, int priority, event_callback_args_t *args); @@ -156,8 +155,6 @@ if (!link) return NULL; memset(link, 0, sizeof(struct dev_link_t)); - link->release.function = &avma1cs_release; - link->release.data = (u_long)link; /* The io structure describes IO port mapping */ link->io.NumPorts1 = 16; @@ -407,7 +404,7 @@ link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { - avma1cs_release((u_long)link); + avma1cs_release(link); return; } @@ -435,9 +432,8 @@ ======================================================================*/ -static void avma1cs_release(u_long arg) +static void avma1cs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; local_info_t *local = link->priv; DEBUG(0, "avma1cs_release(0x%p)\n", link); @@ -494,10 +490,8 @@ switch (event) { case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - link->release.expires = jiffies + HZ/20; - add_timer(&link->release); - } + if (link->state & DEV_CONFIG) + avma1cs_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; @@ -542,7 +536,7 @@ /* XXX: this really needs to move into generic code.. */ while (dev_list != NULL) { if (dev_list->state & DEV_CONFIG) - avma1cs_release((u_long)dev_list); + avma1cs_release(dev_list); avma1cs_detach(dev_list); } } diff -Nru a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c --- a/drivers/isdn/hisax/elsa_cs.c Mon Aug 18 22:21:03 2003 +++ b/drivers/isdn/hisax/elsa_cs.c Mon Aug 18 22:21:03 2003 @@ -107,7 +107,7 @@ */ static void elsa_cs_config(dev_link_t *link); -static void elsa_cs_release(u_long arg); +static void elsa_cs_release(dev_link_t *link); static int elsa_cs_event(event_t event, int priority, event_callback_args_t *args); @@ -198,10 +198,6 @@ memset(local, 0, sizeof(local_info_t)); link = &local->link; link->priv = local; - /* Initialize the dev_link_t structure */ - link->release.function = &elsa_cs_release; - link->release.data = (u_long)link; - /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID|IRQ_SHARE_ID; @@ -272,9 +268,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) - elsa_cs_release((u_long)link); + elsa_cs_release(link); /* If the device is currently configured and active, we won't @@ -431,7 +426,7 @@ return; cs_failed: cs_error(link->handle, last_fn, i); - elsa_cs_release((u_long)link); + elsa_cs_release(link); } /* elsa_cs_config */ /*====================================================================== @@ -442,9 +437,8 @@ ======================================================================*/ -static void elsa_cs_release(u_long arg) +static void elsa_cs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; DEBUG(0, "elsa_cs_release(0x%p)\n", link); @@ -503,7 +497,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { ((local_info_t*)link->priv)->busy = 1; - mod_timer(&link->release, jiffies + HZ/20); + elsa_cs_release(link); } break; case CS_EVENT_CARD_INSERTION: diff -Nru a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c --- a/drivers/isdn/hisax/sedlbauer_cs.c Mon Aug 18 22:21:02 2003 +++ b/drivers/isdn/hisax/sedlbauer_cs.c Mon Aug 18 22:21:02 2003 @@ -107,7 +107,7 @@ */ static void sedlbauer_config(dev_link_t *link); -static void sedlbauer_release(u_long arg); +static void sedlbauer_release(dev_link_t *link); static int sedlbauer_event(event_t event, int priority, event_callback_args_t *args); @@ -205,10 +205,6 @@ memset(local, 0, sizeof(local_info_t)); link = &local->link; link->priv = local; - /* Initialize the dev_link_t structure */ - link->release.function = &sedlbauer_release; - link->release.data = (u_long)link; - /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; @@ -523,7 +519,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); - sedlbauer_release((u_long)link); + sedlbauer_release(link); } /* sedlbauer_config */ @@ -535,10 +531,8 @@ ======================================================================*/ -static void sedlbauer_release(u_long arg) +static void sedlbauer_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; - DEBUG(0, "sedlbauer_release(0x%p)\n", link); /* @@ -601,7 +595,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { ((local_info_t *)link->priv)->stop = 1; - mod_timer(&link->release, jiffies + HZ/20); + sedlbauer_release(link); } break; case CS_EVENT_CARD_INSERTION: @@ -655,7 +649,7 @@ while (dev_list != NULL) { del_timer(&dev_list->release); if (dev_list->state & DEV_CONFIG) - sedlbauer_release((u_long)dev_list); + sedlbauer_release(dev_list); sedlbauer_detach(dev_list); } } diff -Nru a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c --- a/drivers/isdn/hisax/st5481_b.c Mon Aug 18 22:21:02 2003 +++ b/drivers/isdn/hisax/st5481_b.c Mon Aug 18 22:21:02 2003 @@ -254,7 +254,7 @@ DBG(4,""); - altsetting = &(dev->config->interface[0].altsetting[3]); + altsetting = &(dev->config->interface[0]->altsetting[3]); // Allocate URBs and buffers for the B channel out endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2]; diff -Nru a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c --- a/drivers/isdn/hisax/st5481_d.c Mon Aug 18 22:21:03 2003 +++ b/drivers/isdn/hisax/st5481_d.c Mon Aug 18 22:21:03 2003 @@ -658,7 +658,7 @@ DBG(2,""); - altsetting = &(dev->config->interface[0].altsetting[3]); + altsetting = &(dev->config->interface[0]->altsetting[3]); // Allocate URBs and buffers for the D channel out endpoint = &altsetting->endpoint[EP_D_OUT-1]; diff -Nru a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c --- a/drivers/isdn/hisax/st5481_usb.c Mon Aug 18 22:21:04 2003 +++ b/drivers/isdn/hisax/st5481_usb.c Mon Aug 18 22:21:04 2003 @@ -252,13 +252,13 @@ DBG(1,""); - if ((status = usb_set_configuration (dev,dev->config[0].desc.bConfigurationValue)) < 0) { - WARN("set_configuration failed,status=%d",status); + if ((status = usb_reset_configuration (dev)) < 0) { + WARN("reset_configuration failed,status=%d",status); return status; } - altsetting = &(dev->config->interface[0].altsetting[3]); + altsetting = &(dev->config->interface[0]->altsetting[3]); // Check if the config is sane if ( altsetting->desc.bNumEndpoints != 7 ) { diff -Nru a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile --- a/drivers/macintosh/Makefile Mon Aug 18 22:21:05 2003 +++ b/drivers/macintosh/Makefile Mon Aug 18 22:21:05 2003 @@ -4,6 +4,8 @@ # Each configuration option enables a list of files. +obj-$(CONFIG_PPC_PMAC) += macio_asic.o + obj-$(CONFIG_PMAC_PBOOK) += mediabay.o obj-$(CONFIG_MAC_SERIAL) += macserial.o ifneq ($(CONFIG_MAC),y) diff -Nru a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/macintosh/macio_asic.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,355 @@ +/* + * Bus & driver management routines for devices within + * a MacIO ASIC. Interface to new driver model mostly + * stolen from the PCI version. + * + * TODO: + * + * - Don't probe below media bay by default, but instead provide + * some hooks for media bay to dynamically add/remove it's own + * sub-devices. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +macio_bus_match(struct device *dev, struct device_driver *drv) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * macio_drv = to_macio_driver(drv); + const struct of_match * matches = macio_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, &macio_dev->ofdev) != NULL; +} + +struct bus_type macio_bus_type = { + name: "macio", + match: macio_bus_match, +}; + +static int __init +macio_bus_driver_init(void) +{ + return bus_register(&macio_bus_type); +} + +postcore_initcall(macio_bus_driver_init); + +static int +macio_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct macio_driver *drv; + struct macio_dev *macio_dev; + const struct of_match *match; + + drv = to_macio_driver(dev->driver); + macio_dev = to_macio_device(dev); + + if (!drv->probe) + return error; + +/* if (!try_module_get(driver->owner)) { + printk(KERN_ERR "Can't get a module reference for %s\n", driver->name); + return error; + } +*/ + match = of_match_device(drv->match_table, &macio_dev->ofdev); + if (match) + error = drv->probe(macio_dev, match); +/* + module_put(driver->owner); +*/ + return error; +} + +static int +macio_device_remove(struct device *dev) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + + if (drv && drv->remove) + drv->remove(macio_dev); + return 0; +} + +static int +macio_device_suspend(struct device *dev, u32 state, u32 level) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + int error = 0; + + if (drv && drv->suspend) + error = drv->suspend(macio_dev, state, level); + return error; +} + +static int +macio_device_resume(struct device * dev, u32 level) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + int error = 0; + + if (drv && drv->resume) + error = drv->resume(macio_dev, level); + return error; +} + +/** + * macio_add_one_device - Add one device from OF node to the device tree + * @chip: pointer to the macio_chip holding the device + * @np: pointer to the device node in the OF tree + * @in_bay: set to 1 if device is part of a media-bay + * + * When media-bay is changed to hotswap drivers, this function will + * be exposed to the bay driver some way... + */ +static struct macio_dev * +macio_add_one_device(struct macio_chip *chip, struct device *parent, + struct device_node *np, struct macio_dev *in_bay) +{ + struct macio_dev *dev; + u32 *reg; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); + + dev->bus = &chip->lbus; + dev->media_bay = in_bay; + dev->ofdev.node = np; + dev->ofdev.dma_mask = 0xffffffffUL; + dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; + dev->ofdev.dev.parent = parent; + dev->ofdev.dev.bus = &macio_bus_type; + + /* MacIO itself has a different reg, we use it's PCI base */ + if (np == chip->of_node) { + sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.8s", chip->lbus.index, +#ifdef CONFIG_PCI + pci_resource_start(chip->lbus.pdev, 0), +#else + 0, /* NuBus may want to do something better here */ +#endif + np->name); + } else { + reg = (u32 *)get_property(np, "reg", NULL); + sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.8s", chip->lbus.index, + reg ? *reg : 0, np->name); + } + + if (of_device_register(&dev->ofdev) != 0) { + kfree(dev); + return NULL; + } + + return dev; +} + +static int +macio_skip_device(struct device_node *np) +{ + if (strncmp(np->name, "battery", 7) == 0) + return 1; + if (strncmp(np->name, "escc-legacy", 11) == 0) + return 1; + return 0; +} + +/** + * macio_pci_add_devices - Adds sub-devices of mac-io to the device tree + * @chip: pointer to the macio_chip holding the devices + * + * This function will do the job of extracting devices from the + * Open Firmware device tree, build macio_dev structures and add + * them to the Linux device tree. + * + * For now, childs of media-bay are added now as well. This will + * change rsn though. + */ +static void +macio_pci_add_devices(struct macio_chip *chip) +{ + struct device_node *np; + struct macio_dev *rdev, *mdev, *mbdev = NULL, *sdev = NULL; + struct device *parent = NULL; + + /* Add a node for the macio bus itself */ +#ifdef CONFIG_PCI + if (chip->lbus.pdev) + parent = &chip->lbus.pdev->dev; +#endif + rdev = macio_add_one_device(chip, parent, chip->of_node, NULL); + if (rdev == NULL) + return; + + /* First scan 1st level */ + for (np = chip->of_node->child; np != NULL; np = np->sibling) { + if (!macio_skip_device(np)) { + mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL); + if (strncmp(np->name, "media-bay", 9) == 0) + mbdev = mdev; + else if (strncmp(np->name, "escc", 4) == 0) + sdev = mdev; + } + } + + /* Add media bay devices if any */ + if (mbdev) { + for (np = mbdev->ofdev.node->child; np != NULL; np = np->sibling) + if (!macio_skip_device(np)) + macio_add_one_device(chip, &mbdev->ofdev.dev, np, mbdev); + } + /* Add serial ports if any */ + if (sdev) { + for (np = sdev->ofdev.node->child; np != NULL; np = np->sibling) + if (!macio_skip_device(np)) + macio_add_one_device(chip, &sdev->ofdev.dev, np, NULL); + } +} + + +/** + * macio_register_driver - Registers a new MacIO device driver + * @drv: pointer to the driver definition structure + */ +int +macio_register_driver(struct macio_driver *drv) +{ + int count = 0; + + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &macio_bus_type; + drv->driver.probe = macio_device_probe; + drv->driver.resume = macio_device_resume; + drv->driver.suspend = macio_device_suspend; + drv->driver.remove = macio_device_remove; + + /* register with core */ + count = driver_register(&drv->driver); + return count ? count : 1; +} + +/** + * macio_unregister_driver - Unregisters a new MacIO device driver + * @drv: pointer to the driver definition structure + */ +void +macio_unregister_driver(struct macio_driver *drv) +{ + driver_unregister(&drv->driver); +} + +#ifdef CONFIG_PCI + +static int __devinit +macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct device_node* np; + struct macio_chip* chip; + + if (ent->vendor != PCI_VENDOR_ID_APPLE) + return -ENODEV; + + np = pci_device_to_OF_node(pdev); + if (np == NULL) + return -ENODEV; + + chip = macio_find(np, macio_unknown); + if (chip == NULL) + return -ENODEV; + + /* XXX Need locking */ + if (chip->lbus.pdev == NULL) { + chip->lbus.pdev = pdev; + chip->lbus.chip = chip; +// INIT_LIST_HEAD(&chip->lbus.devices); + pci_set_drvdata(pdev, &chip->lbus); + pci_set_master(pdev); + } + + printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n", + chip->name); + + macio_pci_add_devices(chip); + + return 0; +} + +static void __devexit +macio_pci_remove(struct pci_dev* pdev) +{ + panic("removing of macio-asic not supported !\n"); +} + +/* + * MacIO is matched against any Apple ID, it's probe() function + * will then decide wether it applies or not + */ +static const struct pci_device_id __devinitdata pci_ids [] = { { + .vendor = PCI_VENDOR_ID_APPLE, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + + }, { /* end: all zeroes */ } +}; +MODULE_DEVICE_TABLE (pci, pci_ids); + +/* pci driver glue; this is a "new style" PCI driver module */ +static struct pci_driver macio_pci_driver = { + .name = (char *) "macio", + .id_table = pci_ids, + + .probe = macio_pci_probe, + .remove = macio_pci_remove, +}; + +#endif /* CONFIG_PCI */ + +static int __init +macio_module_init (void) +{ +#ifdef CONFIG_PCI + int rc; + + rc = pci_module_init(&macio_pci_driver); + if (rc) + return rc; +#endif /* CONFIG_PCI */ + return 0; +} + +/* +static void __exit +macio_module_cleanup (void) +{ +#ifdef CONFIG_PCI + pci_unregister_driver(&macio_pci_driver); +#endif +} +module_exit(macio_module_cleanup); +*/ +module_init(macio_module_init); + +EXPORT_SYMBOL(macio_register_driver); +EXPORT_SYMBOL(macio_unregister_driver); diff -Nru a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c --- a/drivers/mca/mca-bus.c Mon Aug 18 22:21:01 2003 +++ b/drivers/mca/mca-bus.c Mon Aug 18 22:21:01 2003 @@ -134,7 +134,7 @@ return NULL; memset(mca_bus, 0, sizeof(struct mca_bus)); sprintf(mca_bus->dev.bus_id,"mca%d",bus); - sprintf(mca_bus->dev.name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); + sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); device_register(&mca_bus->dev); mca_root_busses[bus] = mca_bus; diff -Nru a/drivers/mca/mca-device.c b/drivers/mca/mca-device.c --- a/drivers/mca/mca-device.c Mon Aug 18 22:21:01 2003 +++ b/drivers/mca/mca-device.c Mon Aug 18 22:21:01 2003 @@ -200,3 +200,18 @@ { return mca_dev->status; } +EXPORT_SYMBOL(mca_device_status); + +/** + * mca_device_set_name - set the name of the device + * @mca_device: device to set the name of + * @name: name to set + */ +void mca_device_set_name(struct mca_device *mca_dev, const char *name) +{ + if(!mca_dev) + return; + + strlcpy(mca_dev->name, name, sizeof(mca_dev->name)); +} +EXPORT_SYMBOL(mca_device_set_name); diff -Nru a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c --- a/drivers/mca/mca-legacy.c Mon Aug 18 22:21:06 2003 +++ b/drivers/mca/mca-legacy.c Mon Aug 18 22:21:06 2003 @@ -278,7 +278,7 @@ if(!mca_dev) return; - strlcpy(mca_dev->dev.name, name, sizeof(mca_dev->dev.name)); + mca_device_set_name(mca_dev, name); } EXPORT_SYMBOL(mca_set_adapter_name); @@ -297,7 +297,7 @@ if(!mca_dev) return NULL; - return mca_dev->dev.name; + return mca_device_get_name(mca_dev); } EXPORT_SYMBOL(mca_get_adapter_name); diff -Nru a/drivers/mca/mca-proc.c b/drivers/mca/mca-proc.c --- a/drivers/mca/mca-proc.c Mon Aug 18 22:21:04 2003 +++ b/drivers/mca/mca-proc.c Mon Aug 18 22:21:04 2003 @@ -39,7 +39,7 @@ for(j=0; j<8; j++) len += sprintf(page+len, "%02x ", mca_dev ? mca_dev->pos[j] : 0xff); - len += sprintf(page+len, " %s\n", mca_dev ? mca_dev->dev.name : ""); + len += sprintf(page+len, " %s\n", mca_dev ? mca_dev->name : ""); return len; } @@ -108,12 +108,12 @@ } else if(slot == MCA_MOTHERBOARD) { len += sprintf(buf+len, "Motherboard\n"); } - if(mca_dev->dev.name[0]) { + if (mca_dev->name[0]) { /* Drivers might register a name without /proc handler... */ len += sprintf(buf+len, "Adapter Name: %s\n", - mca_dev->dev.name); + mca_dev->name); } else { len += sprintf(buf+len, "Adapter Name: Unknown\n"); } diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c --- a/drivers/md/linear.c Mon Aug 18 22:21:03 2003 +++ b/drivers/md/linear.c Mon Aug 18 22:21:03 2003 @@ -114,6 +114,8 @@ } disk->rdev = rdev; + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); disk->size = rdev->size; mddev->array_size += rdev->size; diff -Nru a/drivers/md/multipath.c b/drivers/md/multipath.c --- a/drivers/md/multipath.c Mon Aug 18 22:21:03 2003 +++ b/drivers/md/multipath.c Mon Aug 18 22:21:03 2003 @@ -272,6 +272,8 @@ for (path=0; pathraid_disks; path++) if ((p=conf->multipaths+path)->rdev == NULL) { p->rdev = rdev; + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); conf->working_disks++; rdev->raid_disk = path; rdev->in_sync = 1; @@ -409,6 +411,8 @@ disk = conf->multipaths + disk_idx; disk->rdev = rdev; + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); if (!rdev->faulty) conf->working_disks++; } diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c --- a/drivers/md/raid0.c Mon Aug 18 22:21:03 2003 +++ b/drivers/md/raid0.c Mon Aug 18 22:21:03 2003 @@ -113,6 +113,8 @@ goto abort; } zone->dev[j] = rdev1; + blk_queue_stack_limits(mddev->queue, + rdev1->bdev->bd_disk->queue); if (!smallest || (rdev1->size size)) smallest = rdev1; cnt++; @@ -293,7 +295,6 @@ conf->hash_spacing++; } - blk_queue_max_sectors(mddev->queue, mddev->chunk_size >> 9); blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec); return 0; diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c --- a/drivers/md/raid1.c Mon Aug 18 22:21:03 2003 +++ b/drivers/md/raid1.c Mon Aug 18 22:21:03 2003 @@ -678,6 +678,8 @@ for (mirror=0; mirror < mddev->raid_disks; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { p->rdev = rdev; + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); p->head_position = 0; rdev->raid_disk = mirror; found = 1; @@ -1076,6 +1078,8 @@ disk = conf->mirrors + disk_idx; disk->rdev = rdev; + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); disk->head_position = 0; if (!rdev->faulty && rdev->in_sync) conf->working_disks++; diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c --- a/drivers/md/raid5.c Mon Aug 18 22:21:01 2003 +++ b/drivers/md/raid5.c Mon Aug 18 22:21:01 2003 @@ -1326,7 +1326,7 @@ (unsigned long long)new_sector, (unsigned long long)logical_sector); - sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK)); + sh = get_active_stripe(conf, new_sector, pd_idx, 0/*(bi->bi_rw&RWA_MASK)*/); if (sh) { add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK)); diff -Nru a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c --- a/drivers/media/dvb/dvb-core/dvbdev.c Mon Aug 18 22:21:01 2003 +++ b/drivers/media/dvb/dvb-core/dvbdev.c Mon Aug 18 22:21:01 2003 @@ -299,14 +299,14 @@ static int __init init_dvbdev(void) { + int retval; devfs_mk_dir("dvb"); - if(register_chrdev(DVB_MAJOR,"DVB", &dvb_device_fops)) { + retval = register_chrdev(DVB_MAJOR,"DVB", &dvb_device_fops); + if (retval) printk("video_dev: unable to get major %d\n", DVB_MAJOR); - return -EIO; - } - return 0; + return retval; } diff -Nru a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Mon Aug 18 22:21:06 2003 +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Mon Aug 18 22:21:06 2003 @@ -1017,7 +1017,7 @@ static int ttusb_setup_interfaces(struct ttusb *ttusb) { - usb_set_configuration(ttusb->dev, 1); + usb_reset_configuration(ttusb->dev); usb_set_interface(ttusb->dev, 1, 1); ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1); diff -Nru a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c Mon Aug 18 22:21:05 2003 +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c Mon Aug 18 22:21:05 2003 @@ -413,7 +413,7 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if (dec->iso_stream_count) - usb_submit_urb(urb, GFP_KERNEL); + usb_submit_urb(urb, GFP_ATOMIC); #endif } diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c --- a/drivers/media/video/bttv-cards.c Mon Aug 18 22:21:03 2003 +++ b/drivers/media/video/bttv-cards.c Mon Aug 18 22:21:03 2003 @@ -1211,7 +1211,7 @@ .tuner_type = -1, .pll = PLL_28, .muxsel = { 2 }, - gpiomask: 0 + .gpiomask = 0 },{ /* Tomasz Pyra */ .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", @@ -1298,7 +1298,7 @@ },{ .name = "Powercolor MTV878/ MTV878R/ MTV878F", .video_inputs = 3, - audio_inputs: 2, + .audio_inputs = 2, .tuner = 0, .svhs = 2, .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset @@ -1338,7 +1338,7 @@ },{ .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", .video_inputs = 4, - audio_inputs: 3, + .audio_inputs = 3, .tuner = 0, .svhs = 2, .gpiomask = 7, diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c --- a/drivers/media/video/bttv-driver.c Mon Aug 18 22:21:05 2003 +++ b/drivers/media/video/bttv-driver.c Mon Aug 18 22:21:05 2003 @@ -2873,8 +2873,8 @@ static struct video_device bttv_video_template = { .name = "UNSET", - type: VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| - VID_TYPE_CLIPPING|VID_TYPE_SCALES, + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| + VID_TYPE_CLIPPING|VID_TYPE_SCALES, .hardware = VID_HARDWARE_BT848, .fops = &bttv_fops, .minor = -1, diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c --- a/drivers/media/video/bttv-if.c Mon Aug 18 22:21:01 2003 +++ b/drivers/media/video/bttv-if.c Mon Aug 18 22:21:01 2003 @@ -315,7 +315,7 @@ memcpy(&btv->i2c_client, &bttv_i2c_client_template, sizeof(struct i2c_client)); - sprintf(btv->i2c_adap.dev.name, "bt848 #%d", btv->nr); + sprintf(btv->i2c_adap.name, "bt848 #%d", btv->nr); btv->i2c_adap.dev.parent = &btv->dev->dev; btv->i2c_algo.data = btv; diff -Nru a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h --- a/drivers/media/video/bttvp.h Mon Aug 18 22:21:02 2003 +++ b/drivers/media/video/bttvp.h Mon Aug 18 22:21:02 2003 @@ -24,7 +24,7 @@ #ifndef _BTTVP_H_ #define _BTTVP_H_ -#include + #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,11) #include diff -Nru a/drivers/media/video/planb.c b/drivers/media/video/planb.c --- a/drivers/media/video/planb.c Mon Aug 18 22:21:05 2003 +++ b/drivers/media/video/planb.c Mon Aug 18 22:21:05 2003 @@ -2030,7 +2030,6 @@ { unsigned char saa_rev; int i, result; - unsigned long flags; memset ((void *) &pb->win, 0, sizeof (struct planb_window)); /* Simple sanity check */ @@ -2096,7 +2095,6 @@ /* clear interrupt mask */ pb->intr_mask = PLANB_CLR_IRQ; - save_flags(flags); cli(); result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb); if (result < 0) { if (result==-EINVAL) @@ -2105,11 +2103,9 @@ else if (result==-EBUSY) printk(KERN_ERR "PlanB: I don't know why, " "but IRQ %d is busy\n", (int)pb->irq); - restore_flags(flags); return result; } disable_irq(pb->irq); - restore_flags(flags); /* Now add the template and register the device unit. */ memcpy(&pb->video_dev,&planb_template,sizeof(planb_template)); diff -Nru a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c --- a/drivers/message/fusion/mptbase.c Mon Aug 18 22:21:02 2003 +++ b/drivers/message/fusion/mptbase.c Mon Aug 18 22:21:02 2003 @@ -1279,7 +1279,7 @@ u32 psize; int ii; int r = -ENODEV; - u64 mask = 0xffffffffffffffff; + u64 mask = 0xffffffffffffffffULL; if (pci_enable_device(pdev)) return r; diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Mon Aug 18 22:21:02 2003 +++ b/drivers/message/fusion/mptscsih.c Mon Aug 18 22:21:02 2003 @@ -1458,7 +1458,6 @@ sh->max_lun = MPT_LAST_LUN + 1; sh->max_sectors = MPT_SCSI_MAX_SECTORS; - sh->highmem_io = 1; sh->this_id = this->pfacts[portnum].PortSCSIID; /* Required entry. diff -Nru a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig --- a/drivers/mtd/devices/Kconfig Mon Aug 18 22:21:03 2003 +++ b/drivers/mtd/devices/Kconfig Mon Aug 18 22:21:03 2003 @@ -102,7 +102,7 @@ config MTD_BLKMTD tristate "MTD emulation using block device" - depends on MTD + depends on MTD && BROKEN help This driver allows a block device to appear as an MTD. It would generally be used in the following cases: diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c --- a/drivers/mtd/devices/blkmtd.c Mon Aug 18 22:21:01 2003 +++ b/drivers/mtd/devices/blkmtd.c Mon Aug 18 22:21:01 2003 @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -287,12 +288,9 @@ return 0; } - static struct address_space_operations blkmtd_aops = { - writepage: blkmtd_writepage, - readpage: NULL, + .writepage = blkmtd_writepage, }; - /* This is the kernel thread that empties the write queue to disk */ static int write_queue_task(void *data) diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig --- a/drivers/mtd/maps/Kconfig Mon Aug 18 22:21:06 2003 +++ b/drivers/mtd/maps/Kconfig Mon Aug 18 22:21:06 2003 @@ -468,7 +468,7 @@ config MTD_PCMCIA tristate "PCMCIA MTD driver" - depends on MTD && PCMCIA && MTD_COMPLEX_MAPPINGS + depends on MTD && PCMCIA && MTD_COMPLEX_MAPPINGS && BROKEN help Map driver for accessing PCMCIA linear flash memory cards. These cards are usually around 4-16MiB in size. This does not include diff -Nru a/drivers/net/3c505.c b/drivers/net/3c505.c --- a/drivers/net/3c505.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/3c505.c Mon Aug 18 22:21:06 2003 @@ -449,18 +449,18 @@ case ASF_PCB_ACK: adapter->send_pcb_semaphore = 0; return TRUE; - break; + case ASF_PCB_NAK: #ifdef ELP_DEBUG printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name); #endif goto abort; - break; } } if (elp_debug >= 1) printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr)); + goto abort; sti_abort: spin_unlock_irqrestore(&adapter->lock, flags); diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c --- a/drivers/net/8139cp.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/8139cp.c Mon Aug 18 22:21:03 2003 @@ -468,7 +468,7 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) { - vlan_hwaccel_rx(skb, cp->vlgrp, desc->opts2 & 0xffff); + vlan_hwaccel_rx(skb, cp->vlgrp, be16_to_cpu(desc->opts2 & 0xffff)); } else #endif netif_rx(skb); @@ -776,7 +776,7 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && vlan_tx_tag_present(skb)) - vlan_tag = TxVlanTag | vlan_tx_tag_get(skb); + vlan_tag = TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb)); #endif entry = cp->tx_head; diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Mon Aug 18 22:21:00 2003 +++ b/drivers/net/8139too.c Mon Aug 18 22:21:00 2003 @@ -566,6 +566,7 @@ void *mmio_addr; int drv_flags; struct pci_dev *pci_dev; + u32 pci_state[16]; struct net_device_stats stats; unsigned char *rx_ring; unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ @@ -2570,6 +2571,9 @@ tp->stats.rx_missed_errors += RTL_R32 (RxMissed); RTL_W32 (RxMissed, 0); + pci_set_power_state (pdev, 3); + pci_save_state (pdev, tp->pci_state); + spin_unlock_irqrestore (&tp->lock, flags); return 0; } @@ -2578,11 +2582,15 @@ static int rtl8139_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); + struct rtl8139_private *tp = dev->priv; if (!netif_running (dev)) return 0; - netif_device_attach (dev); + pci_restore_state (pdev, tp->pci_state); + pci_set_power_state (pdev, 0); + rtl8139_init_ring (dev); rtl8139_hw_start (dev); + netif_device_attach (dev); return 0; } diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig Mon Aug 18 22:21:05 2003 +++ b/drivers/net/Kconfig Mon Aug 18 22:21:05 2003 @@ -1160,7 +1160,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. + called seeq8005. config SK_G16 tristate "SK_G16 support (OBSOLETE)" @@ -2041,6 +2041,17 @@ 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. + +config SIS190 + tristate "SiS190 gigabit ethernet support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL + ---help--- + Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter. + + 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 sis190. config SK98LIN tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support" diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Mon Aug 18 22:21:02 2003 +++ b/drivers/net/Makefile Mon Aug 18 22:21:02 2003 @@ -41,6 +41,7 @@ obj-$(CONFIG_EEPRO100) += eepro100.o mii.o obj-$(CONFIG_TLAN) += tlan.o obj-$(CONFIG_EPIC100) += epic100.o mii.o +obj-$(CONFIG_SIS190) += sis190.o obj-$(CONFIG_SIS900) += sis900.o obj-$(CONFIG_YELLOWFIN) += yellowfin.o obj-$(CONFIG_ACENIC) += acenic.o diff -Nru a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib --- a/drivers/net/Makefile.lib Mon Aug 18 22:21:05 2003 +++ b/drivers/net/Makefile.lib Mon Aug 18 22:21:05 2003 @@ -25,6 +25,7 @@ obj-$(CONFIG_PCMCIA_XIRTULIP) += crc32.o obj-$(CONFIG_PCNET32) += crc32.o obj-$(CONFIG_SGI_IOC3_ETH) += crc32.o +obj-$(CONFIG_SIS190) += crc32.o obj-$(CONFIG_SIS900) += crc32.o obj-$(CONFIG_SMC9194) += crc32.o obj-$(CONFIG_ADAPTEC_STARFIRE) += crc32.o diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c --- a/drivers/net/acenic.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/acenic.c Mon Aug 18 22:21:03 2003 @@ -1960,7 +1960,7 @@ */ skb_reserve(skb, 2 + 16); mapping = pci_map_page(ap->pdev, virt_to_page(skb->data), - ((unsigned long)skb->data & ~PAGE_MASK), + offset_in_page(skb->data), ACE_STD_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); ap->skb->rx_std_skbuff[idx].skb = skb; @@ -2026,7 +2026,7 @@ */ skb_reserve(skb, 2 + 16); mapping = pci_map_page(ap->pdev, virt_to_page(skb->data), - ((unsigned long)skb->data & ~PAGE_MASK), + offset_in_page(skb->data), ACE_MINI_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); ap->skb->rx_mini_skbuff[idx].skb = skb; @@ -2087,7 +2087,7 @@ */ skb_reserve(skb, 2 + 16); mapping = pci_map_page(ap->pdev, virt_to_page(skb->data), - ((unsigned long)skb->data & ~PAGE_MASK), + offset_in_page(skb->data), ACE_JUMBO_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); ap->skb->rx_jumbo_skbuff[idx].skb = skb; @@ -2743,7 +2743,7 @@ struct tx_ring_info *info; mapping = pci_map_page(ap->pdev, virt_to_page(skb->data), - ((unsigned long) skb->data & ~PAGE_MASK), + offset_in_page(skb->data), skb->len, PCI_DMA_TODEVICE); info = ap->skb->tx_skbuff + idx; diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c --- a/drivers/net/amd8111e.c Mon Aug 18 22:21:04 2003 +++ b/drivers/net/amd8111e.c Mon Aug 18 22:21:04 2003 @@ -1940,12 +1940,12 @@ } static struct pci_driver amd8111e_driver = { - name: MODULE_NAME, - id_table: amd8111e_pci_tbl, - probe: amd8111e_probe_one, - remove: __devexit_p(amd8111e_remove_one), - suspend: amd8111e_suspend, - resume: amd8111e_resume + .name = MODULE_NAME, + .id_table = amd8111e_pci_tbl, + .probe = amd8111e_probe_one, + .remove = __devexit_p(amd8111e_remove_one), + .suspend = amd8111e_suspend, + .resume = amd8111e_resume }; static int __init amd8111e_init(void) diff -Nru a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c --- a/drivers/net/arcnet/arc-rimi.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/arcnet/arc-rimi.c Mon Aug 18 22:21:01 2003 @@ -132,9 +132,9 @@ u_long first_mirror, last_mirror, shmem; int mirror_size; - /* reserve the irq */ { - if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) - BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); + /* reserve the irq */ + if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) { + BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); return -ENODEV; } diff -Nru a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c --- a/drivers/net/arcnet/com20020-pci.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/arcnet/com20020-pci.c Mon Aug 18 22:21:01 2003 @@ -97,7 +97,7 @@ dev->base_addr = ioaddr; dev->irq = pdev->irq; dev->dev_addr[0] = node; - lp->card_name = pdev->dev.name; + lp->card_name = "PCI COM20020"; lp->card_flags = id->driver_data; lp->backplane = backplane; lp->clockp = clockp & 7; @@ -105,7 +105,7 @@ lp->timeout = timeout; lp->hw.owner = THIS_MODULE; - if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) { + if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) { BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n", ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); err = -EBUSY; @@ -121,6 +121,8 @@ err = -EIO; goto out_priv; } + + release_region(ioaddr, ARCNET_TOTAL_SIZE); if ((err = com20020_found(dev, SA_SHIRQ)) != 0) goto out_priv; diff -Nru a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c --- a/drivers/net/arcnet/com20020.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/arcnet/com20020.c Mon Aug 18 22:21:02 2003 @@ -55,7 +55,7 @@ static void com20020_copy_from_card(struct net_device *dev, int bufnum, int offset, void *buf, int count); static void com20020_set_mc_list(struct net_device *dev); -static void com20020_close(struct net_device *, bool); +static void com20020_close(struct net_device *); static void com20020_copy_from_card(struct net_device *dev, int bufnum, int offset, void *buf, int count) @@ -86,7 +86,7 @@ /* Reset the card and check some basic stuff during the detection stage. */ -int __devinit com20020_check(struct net_device *dev) +int com20020_check(struct net_device *dev) { int ioaddr = dev->base_addr, status; struct arcnet_local *lp = dev->priv; @@ -152,7 +152,7 @@ /* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __devinit com20020_found(struct net_device *dev, int shared) +int com20020_found(struct net_device *dev, int shared) { struct arcnet_local *lp; int ioaddr = dev->base_addr; @@ -180,6 +180,10 @@ if (!dev->dev_addr[0]) dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */ + /* reserve the I/O region */ + if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) + return -EBUSY; + SET_SUBADR(SUB_SETUP1); outb(lp->setup, _XREG); @@ -203,13 +207,10 @@ if (request_irq(dev->irq, &arcnet_interrupt, shared, "arcnet (COM20020)", dev)) { BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq); + release_region(ioaddr, ARCNET_TOTAL_SIZE); return -ENODEV; } - /* reserve the I/O region */ - if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) { - free_irq(dev->irq, dev); - return -EBUSY; - } + dev->base_addr = ioaddr; BUGMSG(D_NORMAL, "%s: station %02Xh found at %03lXh, IRQ %d.\n", @@ -226,8 +227,8 @@ clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]); if (!dev->init && register_netdev(dev)) { - free_irq(dev->irq, dev); release_region(ioaddr, ARCNET_TOTAL_SIZE); + free_irq(dev->irq, dev); return -EIO; } return 0; @@ -298,16 +299,14 @@ return ASTATUS(); } -static void com20020_close(struct net_device *dev, bool open) +static void com20020_close(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int ioaddr = dev->base_addr; - if (!open) { - /* disable transmitter */ - lp->config &= ~TXENcfg; - SETCONF; - } + /* disable transmitter */ + lp->config &= ~TXENcfg; + SETCONF; } /* Set or clear the multicast filter for this adaptor. @@ -339,7 +338,7 @@ } } -void __devexit com20020_remove(struct net_device *dev) +void com20020_remove(struct net_device *dev) { unregister_netdev(dev); free_irq(dev->irq, dev); diff -Nru a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c --- a/drivers/net/arcnet/com90io.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/arcnet/com90io.c Mon Aug 18 22:21:02 2003 @@ -158,14 +158,14 @@ "must specify the base address!\n"); return -ENODEV; } - if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) { + if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) { BUGMSG(D_INIT_REASONS, "IO check_region %x-%x failed.\n", ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } if (ASTATUS() == 0xFF) { BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr); - return -ENODEV; + goto err_out; } inb(_RESET); mdelay(RESETtime); @@ -174,7 +174,7 @@ if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) { BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status); - return -ENODEV; + goto err_out; } BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status); @@ -186,7 +186,7 @@ if (status & RESETflag) { BUGMSG(D_INIT_REASONS, "Eternal reset (status=%Xh)\n", status); - return -ENODEV; + goto err_out; } outb((0x16 | IOMAPflag) & ~ENABLE16flag, _CONFIG); @@ -198,7 +198,7 @@ if ((status = inb(_MEMDATA)) != 0xd1) { BUGMSG(D_INIT_REASONS, "Signature byte not found" " (%Xh instead).\n", status); - return -ENODEV; + goto err_out; } if (!dev->irq) { /* @@ -215,10 +215,15 @@ if (dev->irq <= 0) { BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed\n"); - return -ENODEV; + goto err_out; } } + release_region(ioaddr, ARCNET_TOTAL_SIZE); /* end of probing */ return com90io_found(dev); + +err_out: + release_region(ioaddr, ARCNET_TOTAL_SIZE); + return -ENODEV; } diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c --- a/drivers/net/eexpress.c Mon Aug 18 22:21:00 2003 +++ b/drivers/net/eexpress.c Mon Aug 18 22:21:00 2003 @@ -650,7 +650,7 @@ buf = skb_padto(buf, ETH_ZLEN); if (buf == NULL) return 0; - length = buf->len; + length = ETH_ZLEN; } disable_irq(dev->irq); diff -Nru a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c --- a/drivers/net/hamradio/bpqether.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/hamradio/bpqether.c Mon Aug 18 22:21:03 2003 @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -99,7 +100,7 @@ static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *); static int bpq_device_event(struct notifier_block *, unsigned long, void *); -static char *bpq_print_ethaddr(unsigned char *); +static const char *bpq_print_ethaddr(const unsigned char *); static struct packet_type bpq_packet_type = { .type = __constant_htons(ETH_P_BPQ), @@ -113,15 +114,16 @@ #define MAXBPQDEV 100 -static struct bpqdev { - struct bpqdev *next; - char ethname[14]; /* ether device name */ - struct net_device *ethdev; /* link to ethernet device */ - struct net_device axdev; /* bpq device (bpq#) */ +struct bpqdev { + struct list_head bpq_list; /* list of bpq devices chain */ + struct net_device *ethdev; /* link to ethernet device */ + struct net_device *axdev; /* bpq device (bpq#) */ struct net_device_stats stats; /* some statistics */ char dest_addr[6]; /* ether destination address */ char acpt_addr[6]; /* accept ether frames from this address only */ -} *bpq_devices; +}; + +static LIST_HEAD(bpq_devices); /* ------------------------------------------------------------------------ */ @@ -144,10 +146,10 @@ { struct bpqdev *bpq; - for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) + list_for_each_entry(bpq, &bpq_devices, bpq_list) { if (bpq->ethdev == dev) - return &bpq->axdev; - + return bpq->axdev; + } return NULL; } @@ -159,50 +161,6 @@ ); } -static spinlock_t bpq_lock = SPIN_LOCK_UNLOCKED; - -/* - * Sanity check: remove all devices that ceased to exists and - * return '1' if the given BPQ device was affected. - */ -static int bpq_check_devices(struct net_device *dev) -{ - struct bpqdev *bpq, *bpq_prev, *bpq_next; - int result = 0; - unsigned long flags; - - spin_lock_irqsave(&bpq_lock, flags); - - bpq_prev = NULL; - - for (bpq = bpq_devices; bpq != NULL; bpq = bpq_next) { - bpq_next = bpq->next; - if (!dev_get(bpq->ethname)) { - if (bpq_prev) - bpq_prev->next = bpq->next; - else - bpq_devices = bpq->next; - - if (&bpq->axdev == dev) - result = 1; - - /* We should be locked, call - * unregister_netdevice directly - */ - - unregister_netdevice(&bpq->axdev); - kfree(bpq); - } - else - bpq_prev = bpq; - } - - spin_unlock_irqrestore(&bpq_lock, flags); - - return result; -} - - /* ------------------------------------------------------------------------ */ @@ -218,12 +176,11 @@ skb->sk = NULL; /* Initially we don't know who it's for */ + rcu_read_lock(); dev = bpq_get_ax25_dev(dev); - if (dev == NULL || !netif_running(dev)) { - kfree_skb(skb); - return 0; - } + if (dev == NULL || !netif_running(dev)) + goto drop; /* * if we want to accept frames from just one ethernet device @@ -234,8 +191,7 @@ if (!(bpq->acpt_addr[0] & 0x01) && memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN)) { printk(KERN_DEBUG "bpqether: wrong dest %s\n", bpq_print_ethaddr(eth->h_source)); - kfree_skb(skb); - return 0; + goto drop; } len = skb->data[0] + skb->data[1] * 256 - 5; @@ -256,8 +212,15 @@ netif_rx(skb); dev->last_rx = jiffies; + unlock: + + rcu_read_unlock(); return 0; + drop: + kfree_skb(skb); + goto unlock; + } /* @@ -275,7 +238,6 @@ * is down, the ethernet device may have gone. */ if (!netif_running(dev)) { - bpq_check_devices(dev); kfree_skb(skb); return -ENODEV; } @@ -400,11 +362,6 @@ */ static int bpq_open(struct net_device *dev) { - if (bpq_check_devices(dev)) - return -ENODEV; /* oops, it's gone */ - - MOD_INC_USE_COUNT; - netif_start_queue(dev); return 0; } @@ -412,15 +369,6 @@ static int bpq_close(struct net_device *dev) { netif_stop_queue(dev); - MOD_DEC_USE_COUNT; - return 0; -} - -/* - * currently unused - */ -static int bpq_dev_init(struct net_device *dev) -{ return 0; } @@ -431,7 +379,7 @@ /* * Proc filesystem */ -static char * bpq_print_ethaddr(unsigned char *e) +static const char * bpq_print_ethaddr(const unsigned char *e) { static char buf[18]; @@ -441,98 +389,92 @@ return buf; } -static int bpq_get_info(char *buffer, char **start, off_t offset, int length) +#define BPQ_PROC_START ((void *)1) + +static void *bpq_seq_start(struct seq_file *seq, loff_t *pos) { + int i = 1; struct bpqdev *bpqdev; - int len = 0; - off_t pos = 0; - off_t begin = 0; - unsigned long flags; - - spin_lock_irqsave(&bpq_lock, flags); - - len += sprintf(buffer, "dev ether destination accept from\n"); - - for (bpqdev = bpq_devices; bpqdev != NULL; bpqdev = bpqdev->next) { - len += sprintf(buffer + len, "%-5s %-10s %s ", - bpqdev->axdev.name, bpqdev->ethname, - bpq_print_ethaddr(bpqdev->dest_addr)); - - len += sprintf(buffer + len, "%s\n", - (bpqdev->acpt_addr[0] & 0x01) ? "*" : bpq_print_ethaddr(bpqdev->acpt_addr)); - pos = begin + len; + rcu_read_lock(); - if (pos < offset) { - len = 0; - begin = pos; - } - - if (pos > offset + length) - break; + if (*pos == 0) + return BPQ_PROC_START; + + list_for_each_entry(bpqdev, &bpq_devices, bpq_list) { + if (i == *pos) + return bpqdev; } + return NULL; +} - spin_unlock_irqrestore(&bpq_lock, flags); +static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct list_head *p; - *start = buffer + (offset - begin); - len -= (offset - begin); + ++*pos; - if (len > length) len = length; + if (v == BPQ_PROC_START) + p = bpq_devices.next; + else + p = ((struct bpqdev *)v)->bpq_list.next; - return len; + return (p == &bpq_devices) ? NULL + : list_entry(p, struct bpqdev, bpq_list); } - -/* ------------------------------------------------------------------------ */ - - -/* - * Setup a new device. - */ -static int bpq_new_device(struct net_device *dev) +static void bpq_seq_stop(struct seq_file *seq, void *v) { - int k; - struct bpqdev *bpq, *bpq2; - unsigned long flags; + rcu_read_unlock(); +} - if ((bpq = kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL) - return -ENOMEM; - memset(bpq, 0, sizeof(struct bpqdev)); +static int bpq_seq_show(struct seq_file *seq, void *v) +{ + if (v == BPQ_PROC_START) + seq_puts(seq, + "dev ether destination accept from\n"); + else { + const struct bpqdev *bpqdev = v; - bpq->ethdev = dev; + seq_printf(seq, "%-5s %-10s %s ", + bpqdev->axdev->name, bpqdev->ethdev->name, + bpq_print_ethaddr(bpqdev->dest_addr)); - bpq->ethname[sizeof(bpq->ethname)-1] = '\0'; - strncpy(bpq->ethname, dev->name, sizeof(bpq->ethname)-1); + seq_printf(seq, "%s\n", + (bpqdev->acpt_addr[0] & 0x01) ? "*" + : bpq_print_ethaddr(bpqdev->acpt_addr)); - memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr)); - memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr)); - - dev = &bpq->axdev; + } + return 0; +} - for (k = 0; k < MAXBPQDEV; k++) { - struct net_device *odev; +static struct seq_operations bpq_seqops = { + .start = bpq_seq_start, + .next = bpq_seq_next, + .stop = bpq_seq_stop, + .show = bpq_seq_show, +}; - sprintf(dev->name, "bpq%d", k); +static int bpq_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &bpq_seqops); +} - if ((odev = __dev_get_by_name(dev->name)) == NULL || bpq_check_devices(odev)) - break; - } +static struct file_operations bpq_info_fops = { + .owner = THIS_MODULE, + .open = bpq_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - if (k == MAXBPQDEV) { - kfree(bpq); - return -ENODEV; - } - dev->priv = (void *)bpq; /* pointer back */ - dev->init = bpq_dev_init; +/* ------------------------------------------------------------------------ */ - /* We should be locked, call register_netdevice() directly. */ - if (register_netdevice(dev) != 0) { - kfree(bpq); - return -EIO; - } +static void bpq_setup(struct net_device *dev) +{ dev->hard_start_xmit = bpq_xmit; dev->open = bpq_open; @@ -540,6 +482,7 @@ dev->set_mac_address = bpq_set_mac_address; dev->get_stats = bpq_get_stats; dev->do_ioctl = bpq_ioctl; + dev->destructor = (void (*)(struct net_device *)) kfree; memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); memcpy(dev->dev_addr, ax25_defaddr, AX25_ADDR_LEN); @@ -556,20 +499,59 @@ dev->mtu = AX25_DEF_PACLEN; dev->addr_len = AX25_ADDR_LEN; - spin_lock_irqsave(&bpq_lock, flags); +} - if (bpq_devices == NULL) { - bpq_devices = bpq; - } else { - for (bpq2 = bpq_devices; bpq2->next != NULL; bpq2 = bpq2->next); - bpq2->next = bpq; - } +/* + * Setup a new device. + */ +static int bpq_new_device(struct net_device *edev) +{ + int err; + struct net_device *ndev; + struct bpqdev *bpq; + + ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", + bpq_setup); + if (!ndev) + return -ENOMEM; - spin_unlock_irqrestore(&bpq_lock, flags); + + bpq = ndev->priv; + dev_hold(edev); + bpq->ethdev = edev; + bpq->axdev = ndev; + memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr)); + memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr)); + + err = dev_alloc_name(ndev, ndev->name); + if (err < 0) + goto error; + + err = register_netdevice(ndev); + if (err) + goto error; + + /* List protected by RTNL */ + list_add_rcu(&bpq->bpq_list, &bpq_devices); return 0; + + error: + dev_put(edev); + kfree(ndev); + return err; + } +static void bpq_free_device(struct net_device *ndev) +{ + struct bpqdev *bpq = ndev->priv; + + dev_put(bpq->ethdev); + list_del_rcu(&bpq->bpq_list); + + unregister_netdevice(ndev); +} /* * Handle device status changes. @@ -581,22 +563,27 @@ if (!dev_is_ethdev(dev)) return NOTIFY_DONE; - bpq_check_devices(NULL); + rcu_read_lock(); switch (event) { - case NETDEV_UP: /* new ethernet device -> new BPQ interface */ - if (bpq_get_ax25_dev(dev) == NULL) - bpq_new_device(dev); - break; - - case NETDEV_DOWN: /* ethernet device closed -> close BPQ interface */ - if ((dev = bpq_get_ax25_dev(dev)) != NULL) - dev_close(dev); - break; + case NETDEV_UP: /* new ethernet device -> new BPQ interface */ + if (bpq_get_ax25_dev(dev) == NULL) + bpq_new_device(dev); + break; - default: - break; + case NETDEV_DOWN: /* ethernet device closed -> close BPQ interface */ + if ((dev = bpq_get_ax25_dev(dev)) != NULL) + dev_close(dev); + break; + + case NETDEV_UNREGISTER: /* ethernet device removed -> free BPQ interface */ + if ((dev = bpq_get_ax25_dev(dev)) != NULL) + bpq_free_device(dev); + break; + default: + break; } + rcu_read_unlock(); return NOTIFY_DONE; } @@ -618,7 +605,7 @@ printk(banner); - if (!proc_net_create("bpqether", 0, bpq_get_info)) { + if (!proc_net_fops_create("bpqether", S_IRUGO, &bpq_info_fops)) { printk(KERN_ERR "bpq: cannot create /proc/net/bpqether entry.\n"); unregister_netdevice_notifier(&bpq_dev_notifier); @@ -626,15 +613,15 @@ return -ENOENT; } - read_lock_bh(&dev_base_lock); + rtnl_lock(); for (dev = dev_base; dev != NULL; dev = dev->next) { - if (dev_is_ethdev(dev)) { - read_unlock_bh(&dev_base_lock); - bpq_new_device(dev); - read_lock_bh(&dev_base_lock); + if (dev_is_ethdev(dev) && bpq_new_device(dev)) { + printk(KERN_ERR + "bpq: cannot setup dev for '%s'\n", + dev->name); } } - read_unlock_bh(&dev_base_lock); + rtnl_unlock(); return 0; } @@ -648,8 +635,12 @@ proc_net_remove("bpqether"); - for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) - unregister_netdev(&bpq->axdev); + rtnl_lock(); + while (!list_empty(&bpq_devices)) { + bpq = list_entry(bpq_devices.next, struct bpqdev, bpq_list); + bpq_free_device(bpq->axdev); + } + rtnl_unlock(); } MODULE_AUTHOR("Joerg Reuter DL1BKE "); diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c --- a/drivers/net/hamradio/yam.c Mon Aug 18 22:21:04 2003 +++ b/drivers/net/hamradio/yam.c Mon Aug 18 22:21:04 2003 @@ -72,6 +72,7 @@ #include #include +#include #include #include @@ -120,7 +121,7 @@ int irq; int dupmode; - struct net_device dev; + struct net_device *dev; /* Stats section */ @@ -161,7 +162,7 @@ struct yam_mcs *next; }; -static struct yam_port yam_ports[NR_PORTS]; +static struct net_device *yam_devs[NR_PORTS]; static struct yam_mcs *yam_data; @@ -628,8 +629,8 @@ int i; for (i = 0; i < NR_PORTS; i++) { - struct net_device *dev = &yam_ports[i].dev; - if (netif_running(dev)) + struct net_device *dev = yam_devs[i]; + if (dev && netif_running(dev)) yam_arbitrate(dev); } yam_timer.expires = jiffies + HZ / 100; @@ -724,8 +725,8 @@ int handled = 0; for (i = 0; i < NR_PORTS; i++) { - yp = &yam_ports[i]; - dev = &yp->dev; + dev = yam_devs[i]; + yp = dev->priv; if (!netif_running(dev)) continue; @@ -765,56 +766,73 @@ return IRQ_RETVAL(handled); } -static int yam_net_get_info(char *buffer, char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS + +static void *yam_seq_start(struct seq_file *seq, loff_t *pos) { - int len = 0; - int i; - off_t pos = 0; - off_t begin = 0; + return (*pos < NR_PORTS) ? yam_devs[*pos] : NULL; +} +static void *yam_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + return (*pos < NR_PORTS) ? yam_devs[*pos] : NULL; +} - for (i = 0; i < NR_PORTS; i++) { - if (yam_ports[i].iobase == 0 || yam_ports[i].irq == 0) - continue; - len += sprintf(buffer + len, "Device yam%d\n", i); - len += sprintf(buffer + len, " Up %d\n", netif_running(&yam_ports[i].dev)); - len += sprintf(buffer + len, " Speed %u\n", yam_ports[i].bitrate); - len += sprintf(buffer + len, " IoBase 0x%x\n", yam_ports[i].iobase); - len += sprintf(buffer + len, " BaudRate %u\n", yam_ports[i].baudrate); - len += sprintf(buffer + len, " IRQ %u\n", yam_ports[i].irq); - len += sprintf(buffer + len, " TxState %u\n", yam_ports[i].tx_state); - len += sprintf(buffer + len, " Duplex %u\n", yam_ports[i].dupmode); - len += sprintf(buffer + len, " HoldDly %u\n", yam_ports[i].holdd); - len += sprintf(buffer + len, " TxDelay %u\n", yam_ports[i].txd); - len += sprintf(buffer + len, " TxTail %u\n", yam_ports[i].txtail); - len += sprintf(buffer + len, " SlotTime %u\n", yam_ports[i].slot); - len += sprintf(buffer + len, " Persist %u\n", yam_ports[i].pers); - len += sprintf(buffer + len, " TxFrames %lu\n", yam_ports[i].stats.tx_packets); - len += sprintf(buffer + len, " RxFrames %lu\n", yam_ports[i].stats.rx_packets); - len += sprintf(buffer + len, " TxInt %u\n", yam_ports[i].nb_mdint); - len += sprintf(buffer + len, " RxInt %u\n", yam_ports[i].nb_rxint); - len += sprintf(buffer + len, " RxOver %lu\n", yam_ports[i].stats.rx_fifo_errors); - len += sprintf(buffer + len, "\n"); - - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - break; - } +static void yam_seq_stop(struct seq_file *seq, void *v) +{ +} - *start = buffer + (offset - begin); - len -= (offset - begin); +static int yam_seq_show(struct seq_file *seq, void *v) +{ + const struct net_device *dev = v; + const struct yam_port *yp = dev->priv; - if (len > length) - len = length; + seq_printf(seq, "Device %s\n", dev->name); + seq_printf(seq, " Up %d\n", netif_running(dev)); + seq_printf(seq, " Speed %u\n", yp->bitrate); + seq_printf(seq, " IoBase 0x%x\n", yp->iobase); + seq_printf(seq, " BaudRate %u\n", yp->baudrate); + seq_printf(seq, " IRQ %u\n", yp->irq); + seq_printf(seq, " TxState %u\n", yp->tx_state); + seq_printf(seq, " Duplex %u\n", yp->dupmode); + seq_printf(seq, " HoldDly %u\n", yp->holdd); + seq_printf(seq, " TxDelay %u\n", yp->txd); + seq_printf(seq, " TxTail %u\n", yp->txtail); + seq_printf(seq, " SlotTime %u\n", yp->slot); + seq_printf(seq, " Persist %u\n", yp->pers); + seq_printf(seq, " TxFrames %lu\n", yp->stats.tx_packets); + seq_printf(seq, " RxFrames %lu\n", yp->stats.rx_packets); + seq_printf(seq, " TxInt %u\n", yp->nb_mdint); + seq_printf(seq, " RxInt %u\n", yp->nb_rxint); + seq_printf(seq, " RxOver %lu\n", yp->stats.rx_fifo_errors); + seq_printf(seq, "\n"); - return len; } +static struct seq_operations yam_seqops = { + .start = yam_seq_start, + .next = yam_seq_next, + .stop = yam_seq_stop, + .show = yam_seq_show, +}; + +static int yam_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &yam_seqops); +} + +static struct file_operations yam_info_fops = { + .owner = THIS_MODULE, + .open = yam_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#endif + + /* --------------------------------------------------------------------- */ static struct net_device_stats *yam_get_stats(struct net_device *dev) @@ -882,8 +900,10 @@ /* Reset overruns for all ports - FPGA programming makes overruns */ for (i = 0; i < NR_PORTS; i++) { - inb(LSR(yam_ports[i].dev.base_addr)); - yam_ports[i].stats.rx_fifo_errors = 0; + struct net_device *dev = yam_devs[i]; + struct yam_port *yp = dev->priv; + inb(LSR(dev->base_addr)); + yp->stats.rx_fifo_errors = 0; } printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq, @@ -1070,14 +1090,26 @@ /* --------------------------------------------------------------------- */ -static int yam_probe(struct net_device *dev) +static void yam_setup(struct net_device *dev) { - struct yam_port *yp; - - if (!dev) - return -ENXIO; + struct yam_port *yp = dev->priv; - yp = (struct yam_port *) dev->priv; + yp->magic = YAM_MAGIC; + yp->bitrate = DEFAULT_BITRATE; + yp->baudrate = DEFAULT_BITRATE * 2; + yp->iobase = 0; + yp->irq = 0; + yp->dupmode = 0; + yp->holdd = DEFAULT_HOLDD; + yp->txd = DEFAULT_TXD; + yp->txtail = DEFAULT_TXTAIL; + yp->slot = DEFAULT_SLOT; + yp->pers = DEFAULT_PERS; + yp->dev = dev; + + dev->base_addr = yp->iobase; + dev->irq = yp->irq; + SET_MODULE_OWNER(dev); dev->open = yam_open; dev->stop = yam_close; @@ -1104,58 +1136,49 @@ memcpy(dev->broadcast, ax25_bcast, 7); memcpy(dev->dev_addr, ax25_test, 7); - /* New style flags */ - dev->flags = 0; - - return 0; } -/* --------------------------------------------------------------------- */ - static int __init yam_init_driver(void) { struct net_device *dev; - int i; + int i, err; + char name[IFNAMSIZ]; printk(yam_drvinfo); for (i = 0; i < NR_PORTS; i++) { - sprintf(yam_ports[i].dev.name, "yam%d", i); - yam_ports[i].magic = YAM_MAGIC; - yam_ports[i].bitrate = DEFAULT_BITRATE; - yam_ports[i].baudrate = DEFAULT_BITRATE * 2; - yam_ports[i].iobase = 0; - yam_ports[i].irq = 0; - yam_ports[i].dupmode = 0; - yam_ports[i].holdd = DEFAULT_HOLDD; - yam_ports[i].txd = DEFAULT_TXD; - yam_ports[i].txtail = DEFAULT_TXTAIL; - yam_ports[i].slot = DEFAULT_SLOT; - yam_ports[i].pers = DEFAULT_PERS; - - dev = &yam_ports[i].dev; - - dev->priv = &yam_ports[i]; - dev->base_addr = yam_ports[i].iobase; - dev->irq = yam_ports[i].irq; - dev->init = yam_probe; - dev->if_port = 0; - - if (register_netdev(dev)) { + sprintf(name, "yam%d", i); + + dev = alloc_netdev(sizeof(struct yam_port), name, + yam_setup); + if (!dev) { + printk(KERN_ERR "yam: cannot allocate net device %s\n", + dev->name); + err = -ENOMEM; + goto error; + } + + err = register_netdev(dev); + if (err) { printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name); - dev->priv = NULL; - return -ENXIO; + goto error; } + yam_devs[i] = dev; - SET_MODULE_OWNER(dev); } yam_timer.function = yam_dotimer; yam_timer.expires = jiffies + HZ / 100; add_timer(&yam_timer); - proc_net_create("yam", 0, yam_net_get_info); + proc_net_fops_create("yam", S_IRUGO, &yam_info_fops); return 0; + error: + while (--i >= 0) { + unregister_netdev(yam_devs[i]); + kfree(yam_devs[i]); + } + return err; } /* --------------------------------------------------------------------- */ @@ -1167,12 +1190,11 @@ del_timer(&yam_timer); for (i = 0; i < NR_PORTS; i++) { - struct net_device *dev = &yam_ports[i].dev; - if (!dev->priv) - continue; - if (netif_running(dev)) - yam_close(dev); - unregister_netdev(dev); + struct net_device *dev = yam_devs[i]; + if (dev) { + unregister_netdev(dev); + kfree(dev); + } } while (yam_data) { diff -Nru a/drivers/net/hydra.c b/drivers/net/hydra.c --- a/drivers/net/hydra.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/hydra.c Mon Aug 18 22:21:03 2003 @@ -33,20 +33,8 @@ #include "8390.h" -#define NE_BASE (dev->base_addr) -#define NE_CMD (0x00*2) - -#define NE_EN0_ISR (0x07*2) #define NE_EN0_DCFG (0x0e*2) -#define NE_EN0_RSARLO (0x08*2) -#define NE_EN0_RSARHI (0x09*2) -#define NE_EN0_RCNTLO (0x0a*2) -#define NE_EN0_RXCR (0x0c*2) -#define NE_EN0_TXCR (0x0d*2) -#define NE_EN0_RCNTHI (0x0b*2) -#define NE_EN0_IMR (0x0f*2) - #define NESM_START_PG 0x0 /* First page of TX buffer */ #define NESM_STOP_PG 0x40 /* Last page +1 of RX ring */ @@ -56,12 +44,10 @@ #define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) -#ifdef MODULE static struct net_device *root_hydra_dev; -#endif static int __init hydra_probe(void); -static int hydra_init(unsigned long board); +static int __init hydra_init(unsigned long board); static int hydra_open(struct net_device *dev); static int hydra_close(struct net_device *dev); static void hydra_reset_8390(struct net_device *dev); @@ -96,11 +82,11 @@ return err; } -int __init hydra_init(unsigned long board) +static int __init hydra_init(unsigned long board) { struct net_device *dev; unsigned long ioaddr = board+HYDRA_NIC_BASE; - const char *name = NULL; + const char name[] = "NE2000"; int start_page, stop_page; int j; @@ -136,8 +122,6 @@ return -ENOMEM; } - name = "NE2000"; - printk("%s: hydra at 0x%08lx, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", dev->name, ZTWO_PADDR(board), dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); @@ -235,7 +219,6 @@ static void __exit hydra_cleanup(void) { -#ifdef MODULE struct net_device *dev, *next; while ((dev = root_hydra_dev)) { @@ -246,7 +229,6 @@ kfree(dev); root_hydra_dev = next; } -#endif } module_init(hydra_probe); diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c --- a/drivers/net/irda/irda-usb.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/irda/irda-usb.c Mon Aug 18 22:21:03 2003 @@ -1482,9 +1482,9 @@ goto err_out_2; } - /* Is this really necessary? */ - if (usb_set_configuration (dev, dev->config[0].desc.bConfigurationValue) < 0) { - err("set_configuration failed"); + /* Is this really necessary? (no, except maybe for broken devices) */ + if (usb_reset_configuration (dev) < 0) { + err("reset_configuration failed"); ret = -EIO; goto err_out_3; } diff -Nru a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c --- a/drivers/net/irda/irtty.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/irda/irtty.c Mon Aug 18 22:21:02 2003 @@ -39,9 +39,6 @@ #include #include -static hashbin_t *irtty = NULL; -static struct tty_ldisc irda_ldisc; - static int qos_mtt_bits = 0x03; /* 5 ms or more */ /* Network device fuction prototypes */ @@ -55,7 +52,8 @@ /* Line discipline function prototypes */ static int irtty_open(struct tty_struct *tty); static void irtty_close(struct tty_struct *tty); -static int irtty_ioctl(struct tty_struct *, void *, int, void *); +static int irtty_ioctl(struct tty_struct *, struct file *, + unsigned int, unsigned long); static int irtty_receive_room(struct tty_struct *tty); static void irtty_write_wakeup(struct tty_struct *tty); static void irtty_receive_buf(struct tty_struct *, const unsigned char *, @@ -69,37 +67,22 @@ static int irtty_set_mode(struct net_device *dev, int mode); static int irtty_change_speed(struct irda_task *task); -char *driver_name = "irtty"; +static struct tty_ldisc irda_ldisc = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = "irda", + .open = irtty_open, + .close = irtty_close, + .ioctl = irtty_ioctl, + .receive_buf = irtty_receive_buf, + .receive_room = irtty_receive_room, + .write_wakeup = irtty_write_wakeup, +}; int __init irtty_init(void) { int status; - /* Probably no need to lock here because all operations done in - * open()/close() which are already safe - Jean II */ - irtty = hashbin_new( HB_NOLOCK); - if ( irtty == NULL) { - printk( KERN_WARNING "IrDA: Can't allocate irtty hashbin!\n"); - return -ENOMEM; - } - - /* Fill in our line protocol discipline, and register it */ - memset(&irda_ldisc, 0, sizeof( irda_ldisc)); - - irda_ldisc.magic = TTY_LDISC_MAGIC; - irda_ldisc.name = "irda"; - irda_ldisc.flags = 0; - irda_ldisc.open = irtty_open; - irda_ldisc.close = irtty_close; - irda_ldisc.read = NULL; - irda_ldisc.write = NULL; - irda_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *, - unsigned int, unsigned long)) irtty_ioctl; - irda_ldisc.poll = NULL; - irda_ldisc.receive_buf = irtty_receive_buf; - irda_ldisc.receive_room = irtty_receive_room; - irda_ldisc.write_wakeup = irtty_write_wakeup; - if ((status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) { ERROR("IrDA: can't register line discipline (err = %d)\n", status); @@ -124,12 +107,6 @@ __FUNCTION__, ret); } - /* - * The TTY should care of deallocating the instances by using the - * callback to irtty_close(), therefore we do give any deallocation - * function to hashbin_destroy(). - */ - hashbin_delete(irtty, NULL); } /* @@ -172,8 +149,6 @@ /* Give self a name */ strcpy(name, tty->name); - hashbin_insert(irtty, (irda_queue_t *) self, (int) self, NULL); - if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); @@ -251,8 +226,6 @@ MESSAGE("IrDA: Registered device %s\n", dev->name); - MOD_INC_USE_COUNT; - return 0; } @@ -285,8 +258,6 @@ if (self->netdev) unregister_netdev(self->netdev); - self = hashbin_remove(irtty, (int) self, NULL); - /* Protect access to self->task and self->?x_buff - Jean II */ spin_lock_irqsave(&self->lock, flags); @@ -305,8 +276,6 @@ spin_unlock_irqrestore(&self->lock, flags); kfree(self); - - MOD_DEC_USE_COUNT; } /* @@ -487,7 +456,8 @@ * The Swiss army knife of system calls :-) * */ -static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) +static int irtty_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { dongle_t *dongle; struct irtty_info info; @@ -511,8 +481,7 @@ case TCGETS: case TCGETA: /* Unsure about locking here, to check - Jean II */ - return n_tty_ioctl(tty, (struct file *) file, cmd, - (unsigned long) arg); + return n_tty_ioctl(tty, (struct file *) file, cmd, arg); break; case IRTTY_IOCTDONGLE: /* Initialize dongle */ @@ -543,7 +512,7 @@ memset(&info, 0, sizeof(struct irtty_info)); strncpy(info.name, self->netdev->name, 5); - if (copy_to_user(arg, &info, sizeof(struct irtty_info))) + if (copy_to_user((void *) arg, &info, sizeof(struct irtty_info))) return -EFAULT; break; default: @@ -938,7 +907,6 @@ { struct irtty_cb *self = (struct irtty_cb *) dev->priv; struct tty_struct *tty = self->tty; - char hwname[16]; ASSERT(self != NULL, return -1;); ASSERT(self->magic == IRTTY_MAGIC, return -1;); @@ -951,16 +919,11 @@ /* Make sure we can receive more data */ irtty_stop_receiver(self, FALSE); - /* Give self a hardware name */ - sprintf(hwname, "%s", tty->name); - /* * Open new IrLAP layer instance, now that everything should be * initialized properly */ - self->irlap = irlap_open(dev, &self->qos, hwname); - - MOD_INC_USE_COUNT; + self->irlap = irlap_open(dev, &self->qos, tty->name); return 0; } @@ -982,8 +945,6 @@ if (self->irlap) irlap_close(self->irlap); self->irlap = NULL; - - MOD_DEC_USE_COUNT; return 0; } diff -Nru a/drivers/net/loopback.c b/drivers/net/loopback.c --- a/drivers/net/loopback.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/loopback.c Mon Aug 18 22:21:01 2003 @@ -128,17 +128,13 @@ * instead are lobbed from tx queue to rx queue */ - if(atomic_read(&skb->users) != 1) - { + if (skb_shared(skb)) { struct sk_buff *skb2=skb; skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */ - if(skb==NULL) { - kfree_skb(skb2); + kfree_skb(skb2); + if (unlikely(skb==NULL)) return 0; - } - kfree_skb(skb2); - } - else + } else skb_orphan(skb); skb->protocol=eth_type_trans(skb,dev); @@ -148,12 +144,8 @@ #endif if (skb_shinfo(skb)->tso_size) { - struct iphdr *iph = skb->nh.iph; - - if (skb->protocol != htons(ETH_P_IP)) - BUG(); - if (iph->protocol != IPPROTO_TCP) - BUG(); + BUG_ON(skb->protocol != htons(ETH_P_IP)); + BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); emulate_large_send_offload(skb); return 0; diff -Nru a/drivers/net/meth.c b/drivers/net/meth.c --- a/drivers/net/meth.c Mon Aug 18 22:21:05 2003 +++ b/drivers/net/meth.c Mon Aug 18 22:21:05 2003 @@ -844,9 +844,6 @@ printk("meth: error %i registering device \"%s\"\n", result, meth_devs->name); else device_present++; -#ifndef METH_DEBUG - EXPORT_NO_SYMBOLS; -#endif return device_present ? 0 : -ENODEV; } diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/ppp_generic.c Mon Aug 18 22:21:06 2003 @@ -2073,7 +2073,8 @@ case CCP_CONFACK: if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN) break; - if (!pskb_may_pull(skb, len = CCP_LENGTH(dp)) + 2) + len = CCP_LENGTH(dp); + if (!pskb_may_pull(skb, len + 2)) return; /* too short */ dp += CCP_HDRLEN; len -= CCP_HDRLEN; diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c --- a/drivers/net/rrunner.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/rrunner.c Mon Aug 18 22:21:02 2003 @@ -1641,13 +1641,13 @@ spin_lock_irqsave(&rrpriv->lock, flags); i = rr_read_eeprom(rrpriv, 0, image, EEPROM_BYTES); + spin_unlock_irqrestore(&rrpriv->lock, flags); if (i != EEPROM_BYTES){ printk(KERN_ERR "%s: Error reading EEPROM\n", dev->name); error = -EFAULT; goto gf_out; } - spin_unlock_irqrestore(&rrpriv->lock, flags); error = copy_to_user(rq->ifr_data, image, EEPROM_BYTES); if (error) error = -EFAULT; diff -Nru a/drivers/net/sis190.c b/drivers/net/sis190.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/sis190.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,1208 @@ +/* SiS190.c: A Linux PCI Ethernet driver for the SiS190 chips. */ +/* +========================================================================= + SiS190.c: A SiS190 Gigabit Ethernet driver for Linux kernel 2.6.x. + -------------------------------------------------------------------- + + drivers/net/SiS190.c + + Maintained by K.M. Liu + + Modified from the driver which is originally written by Donald Becker. + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. + + History: +========================================================================= + VERSION 1.0 <2003/8/7> K.M. Liu, Test 100bps Full in 2.6.0 O.K. + 1.1 <2003/8/8> K.M. Liu, Add mode detection. + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SiS190_VERSION "1.1" +#define MODULENAME "SiS190" +#define SiS190_DRIVER_NAME MODULENAME " Gigabit Ethernet driver " SiS190_VERSION +#define PFX MODULENAME ": " + +#ifdef SiS190_DEBUG +#define assert(expr) \ + if(unlikely(!(expr))) { \ + printk( "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + } +#else +#define assert(expr) do {} while (0) +#endif + +/* media options */ +#define MAX_UNITS 8 + +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int max_interrupt_work = 20; + +/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + The chips use a 64 element hash table based on the Ethernet CRC. */ +static int multicast_filter_limit = 32; + +/* MAC address length*/ +#define MAC_ADDR_LEN 6 + +/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/ +#define MAX_ETH_FRAME_SIZE 1536 + +#define TX_FIFO_THRESH 256 /* In bytes */ + +#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ +#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ +#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ +#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ +#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */ +#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ + +#define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ +#define NUM_RX_DESC 64 /* Number of Rx descriptor registers */ +#define RX_BUF_SIZE 1536 /* Rx Buffer size */ + +#define SiS190_MIN_IO_SIZE 0x80 +#define TX_TIMEOUT (6*HZ) + +/* enhanced PHY access register bit definitions */ +#define EhnMIIread 0x0000 +#define EhnMIIwrite 0x0020 +#define EhnMIIdataShift 16 +#define EhnMIIpmdShift 6 /* 7016 only */ +#define EhnMIIregShift 11 +#define EhnMIIreq 0x0010 +#define EhnMIInotDone 0x0010 + +//------------------------------------------------------------------------- +// Bit Mask definitions +//------------------------------------------------------------------------- +#define BIT_0 0x0001 +#define BIT_1 0x0002 +#define BIT_2 0x0004 +#define BIT_3 0x0008 +#define BIT_4 0x0010 +#define BIT_5 0x0020 +#define BIT_6 0x0040 +#define BIT_7 0x0080 +#define BIT_8 0x0100 +#define BIT_9 0x0200 +#define BIT_10 0x0400 +#define BIT_11 0x0800 +#define BIT_12 0x1000 +#define BIT_13 0x2000 +#define BIT_14 0x4000 +#define BIT_15 0x8000 +#define BIT_16 0x10000 +#define BIT_17 0x20000 +#define BIT_18 0x40000 +#define BIT_19 0x80000 +#define BIT_20 0x100000 +#define BIT_21 0x200000 +#define BIT_22 0x400000 +#define BIT_23 0x800000 +#define BIT_24 0x1000000 +#define BIT_25 0x2000000 +#define BIT_26 0x04000000 +#define BIT_27 0x08000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + +/* write/read MMIO register */ +#define SiS_W8(reg, val8) writeb ((val8), ioaddr + (reg)) +#define SiS_W16(reg, val16) writew ((val16), ioaddr + (reg)) +#define SiS_W32(reg, val32) writel ((val32), ioaddr + (reg)) +#define SiS_R8(reg) readb (ioaddr + (reg)) +#define SiS_R16(reg) readw (ioaddr + (reg)) +#define SiS_R32(reg) ((unsigned long) readl (ioaddr + (reg))) + +static struct { + const char *name; +} board_info[] __devinitdata = { + { "SiS190 Gigabit Ethernet" }, +}; + +static struct pci_device_id sis190_pci_tbl[] __devinitdata = { + { 0x1039, 0x0190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0,}, +}; + +MODULE_DEVICE_TABLE(pci, sis190_pci_tbl); + +enum SiS190_registers { + TxControl = 0x0, + TxDescStartAddr = 0x4, + TxNextDescAddr = 0x0c, + RxControl = 0x10, + RxDescStartAddr = 0x14, + RxNextDescAddr = 0x1c, + IntrStatus = 0x20, + IntrMask = 0x24, + IntrControl = 0x28, + IntrTimer = 0x2c, + PMControl = 0x30, + ROMControl = 0x38, + ROMInterface = 0x3c, + StationControl = 0x40, + GMIIControl = 0x44, + TxMacControl = 0x50, + RxMacControl = 0x60, + RxMacAddr = 0x62, + RxHashTable = 0x68, + RxWakeOnLan = 0x70, + RxMPSControl = 0x78, +}; + +enum sis190_register_content { + /*InterruptStatusBits */ + + SoftInt = 0x40000000, + Timeup = 0x20000000, + PauseFrame = 0x80000, + MagicPacket = 0x40000, + WakeupFrame = 0x20000, + LinkChange = 0x10000, + RxQEmpty = 0x80, + RxQInt = 0x40, + TxQ1Empty = 0x20, + TxQ1Int = 0x10, + TxQ0Empty = 0x08, + TxQ0Int = 0x04, + RxHalt = 0x02, + TxHalt = 0x01, + + /*RxStatusDesc */ + RxRES = 0x00200000, + RxCRC = 0x00080000, + RxRUNT = 0x00100000, + RxRWT = 0x00400000, + + /*ChipCmdBits */ + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x01, + RxBufEmpty = 0x01, + + /*Cfg9346Bits */ + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xC0, + + /*rx_mode_bits */ + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x0800, + AcceptMulticast = 0x0400, + AcceptMyPhys = 0x0200, + AcceptAllPhys = 0x0100, + + /*RxConfigBits */ + RxCfgFIFOShift = 13, + RxCfgDMAShift = 8, + + /*TxConfigBits */ + TxInterFrameGapShift = 24, + TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ + + /*_PHYstatus */ + TBI_Enable = 0x80, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + + _1000bpsF = 0x1c, + _1000bpsH = 0x0c, + _100bpsF = 0x18, + _100bpsH = 0x08, + _10bpsF = 0x14, + _10bpsH = 0x04, + + LinkStatus = 0x02, + FullDup = 0x01, + + /*GIGABIT_PHY_registers */ + PHY_CTRL_REG = 0, + PHY_STAT_REG = 1, + PHY_AUTO_NEGO_REG = 4, + PHY_1000_CTRL_REG = 9, + + /*GIGABIT_PHY_REG_BIT */ + PHY_Restart_Auto_Nego = 0x0200, + PHY_Enable_Auto_Nego = 0x1000, + + //PHY_STAT_REG = 1; + PHY_Auto_Neco_Comp = 0x0020, + + //PHY_AUTO_NEGO_REG = 4; + PHY_Cap_10_Half = 0x0020, + PHY_Cap_10_Full = 0x0040, + PHY_Cap_100_Half = 0x0080, + PHY_Cap_100_Full = 0x0100, + + //PHY_1000_CTRL_REG = 9; + PHY_Cap_1000_Full = 0x0200, + + PHY_Cap_Null = 0x0, + + /*_MediaType*/ + _10_Half = 0x01, + _10_Full = 0x02, + _100_Half = 0x04, + _100_Full = 0x08, + _1000_Full = 0x10, + + /*_TBICSRBit*/ + TBILinkOK = 0x02000000, +}; + +const static struct { + const char *name; + u8 version; /* depend on docs */ + u32 RxConfigMask; /* should clear the bits supported by this chip */ +} sis_chip_info[] = { + { "SiS-0190", 0x00, 0xff7e1880,}, +}; + +enum _DescStatusBit { + OWNbit = 0x80000000, + INTbit = 0x40000000, + DEFbit = 0x200000, + CRCbit = 0x20000, + PADbit = 0x10000, + ENDbit = 0x80000000, +}; + +struct TxDesc { + u32 PSize; + u32 status; + u32 buf_addr; + u32 buf_Len; +}; + +struct RxDesc { + u32 PSize; + u32 status; + u32 buf_addr; + u32 buf_Len; +}; + +struct sis190_private { + void *mmio_addr; /* memory map physical address */ + struct pci_dev *pci_dev; /* Index of PCI device */ + struct net_device_stats stats; /* statistics of net device */ + spinlock_t lock; /* spin lock flag */ + int chipset; + unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + unsigned long dirty_tx; + void *tx_desc_raw; /* Tx descriptor buffer */ + dma_addr_t tx_dma_raw; + dma_addr_t tx_dma_aligned; + void *rx_desc_raw; /* Rx descriptor buffer */ + dma_addr_t rx_dma_raw; + dma_addr_t rx_dma_aligned; + struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ + struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ + unsigned char *RxBufferRings; /* Index of Rx Buffer */ + unsigned char *RxBufferRing[NUM_RX_DESC]; /* Index of Rx Buffer array */ + struct sk_buff *Tx_skbuff[NUM_TX_DESC]; /* Index of Transmit data buffer */ +}; + +MODULE_AUTHOR("K.M. Liu "); +MODULE_DESCRIPTION("SiS SiS190 Gigabit Ethernet driver"); +MODULE_LICENSE("GPL"); +MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i"); + +static int SiS190_open(struct net_device *dev); +static int SiS190_start_xmit(struct sk_buff *skb, struct net_device *dev); +static irqreturn_t SiS190_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); +static void SiS190_init_ring(struct net_device *dev); +static void SiS190_hw_start(struct net_device *dev); +static int SiS190_close(struct net_device *dev); +static void SiS190_set_rx_mode(struct net_device *dev); +static void SiS190_tx_timeout(struct net_device *dev); +static struct net_device_stats *SiS190_get_stats(struct net_device *netdev); + +static const u32 sis190_intr_mask = + RxQEmpty | RxQInt | TxQ1Empty | TxQ1Int | TxQ0Empty | TxQ0Int | RxHalt | + TxHalt; + +void +smdio_write(void *ioaddr, int RegAddr, int value) +{ + + u32 l; + u16 i; + u32 pmd; + + pmd = 1; + + l = 0; + l = EhnMIIwrite | (((u32) RegAddr) << EhnMIIregShift) | EhnMIIreq | + (((u32) value) << EhnMIIdataShift) | (((u32) pmd) << + EhnMIIpmdShift); + + SiS_W32(GMIIControl, l); + + udelay(1000); + + for (i = 0; i < 1000; i++) { + if (SiS_R32(GMIIControl) & EhnMIInotDone) { + udelay(100); + } else { + break; + } + } + + if (i > 999) + printk(KERN_ERR PFX "Phy write Error!!!\n"); + +} + +int +smdio_read(void *ioaddr, int RegAddr) +{ + + u32 l; + u16 i; + u32 pmd; + + pmd = 1; + l = 0; + l = EhnMIIread | EhnMIIreq | (((u32) RegAddr) << EhnMIIregShift) | + (((u32) pmd) << EhnMIIpmdShift); + + SiS_W32(GMIIControl, l); + + udelay(1000); + + for (i = 0; i < 1000; i++) { + if ((l == SiS_R32(GMIIControl)) & EhnMIInotDone) { + udelay(100); + } else { + break; + } + + if (i > 999) + printk(KERN_ERR PFX "Phy Read Error!!!\n"); + } + l = SiS_R32(GMIIControl); + + return ((u16) (l >> EhnMIIdataShift)); + +} + +int +ReadEEprom(void *ioaddr, u32 RegAddr) +{ + u16 data; + u32 i; + u32 ulValue; + + if (!(SiS_R32(ROMControl) & BIT_1)) { + return 0; + } + + ulValue = (BIT_7 | (0x2 << 8) | (RegAddr << 10)); + + SiS_W32(ROMInterface, ulValue); + + for (i = 0; i < 200; i++) { + + if (!(SiS_R32(ROMInterface) & BIT_7)) + break; + + udelay(1000); + } + + data = (u16) ((SiS_R32(ROMInterface) & 0xffff0000) >> 16); + + return data; +} + +static int __devinit +SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out, + void **ioaddr_out) +{ + void *ioaddr = NULL; + struct net_device *dev; + struct sis190_private *tp; + u16 rc; + unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; + + assert(pdev != NULL); + assert(ioaddr_out != NULL); + + *ioaddr_out = NULL; + *dev_out = NULL; + + // dev zeroed in init_etherdev + + dev = alloc_etherdev(sizeof (*tp)); + if (dev == NULL) { + printk(KERN_ERR PFX "unable to alloc new ethernet\n"); + return -ENOMEM; + } + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + tp = dev->priv; + + // enable device (incl. PCI PM wakeup and hotplug setup) + rc = pci_enable_device(pdev); + if (rc) + goto err_out; + + mmio_start = pci_resource_start(pdev, 0); + mmio_end = pci_resource_end(pdev, 0); + mmio_flags = pci_resource_flags(pdev, 0); + mmio_len = pci_resource_len(pdev, 0); + + // make sure PCI base addr 0 is MMIO + if (!(mmio_flags & IORESOURCE_MEM)) { + printk(KERN_ERR PFX + "region #0 not an MMIO resource, aborting\n"); + rc = -ENODEV; + goto err_out; + } + // check for weird/broken PCI region reporting + if (mmio_len < SiS190_MIN_IO_SIZE) { + printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); + rc = -ENODEV; + goto err_out; + } + + rc = pci_request_regions(pdev, dev->name); + if (rc) + goto err_out; + + // enable PCI bus-mastering + pci_set_master(pdev); + + // ioremap MMIO region + ioaddr = ioremap(mmio_start, mmio_len); + if (ioaddr == NULL) { + printk(KERN_ERR PFX "cannot remap MMIO, aborting\n"); + rc = -EIO; + goto err_out_free_res; + } + // Soft reset the chip. + SiS_W32(IntrControl, 0x8000); + udelay(1000); + SiS_W32(IntrControl, 0x0); + + SiS_W32(TxControl, 0x1a00); + SiS_W32(RxControl, 0x1a00); + udelay(1000); + + *ioaddr_out = ioaddr; + *dev_out = dev; + return 0; + +err_out_free_res: + pci_release_regions(pdev); + +err_out: + pci_disable_device(pdev); + unregister_netdev(dev); + kfree(dev); + return rc; +} + +static int __devinit +SiS190_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *dev = NULL; + struct sis190_private *tp = NULL; + void *ioaddr = NULL; + static int board_idx = -1; + static int printed_version = 0; + int i, rc; + u16 reg31; + + assert(pdev != NULL); + assert(ent != NULL); + + board_idx++; + + if (!printed_version) { + printk(KERN_INFO SiS190_DRIVER_NAME " loaded\n"); + printed_version = 1; + } + + i = SiS190_init_board(pdev, &dev, &ioaddr); + if (i < 0) { + return i; + } + + tp = dev->priv; + assert(ioaddr != NULL); + assert(dev != NULL); + assert(tp != NULL); + + // Get MAC address // + // Read node address from the EEPROM + + if (SiS_R32(ROMControl) & 0x2) { + + for (i = 0; i < 6; i += 2) { + SiS_W16(RxMacAddr + i, ReadEEprom(ioaddr, 3 + (i / 2))); + } + + } else { + + SiS_W32(RxMacAddr, 0x11111100); //If 9346 does not exist + SiS_W32(RxMacAddr + 2, 0x00111111); + } + + for (i = 0; i < MAC_ADDR_LEN; i++) { + dev->dev_addr[i] = SiS_R8(RxMacAddr + i); + printk("SiS_R8(RxMacAddr+%x)= %x ", i, SiS_R8(RxMacAddr + i)); + } + + dev->open = SiS190_open; + dev->hard_start_xmit = SiS190_start_xmit; + dev->get_stats = SiS190_get_stats; + dev->stop = SiS190_close; + dev->tx_timeout = SiS190_tx_timeout; + dev->set_multicast_list = SiS190_set_rx_mode; + dev->watchdog_timeo = TX_TIMEOUT; + dev->irq = pdev->irq; + dev->base_addr = (unsigned long) ioaddr; +// dev->do_ioctl = mii_ioctl; + + tp = dev->priv; // private data // + tp->pci_dev = pdev; + tp->mmio_addr = ioaddr; + + printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name, + sis_chip_info[tp->chipset].name); + + spin_lock_init(&tp->lock); + rc = register_netdev(dev); + if (rc) { + iounmap(ioaddr); + pci_release_regions(pdev); + pci_disable_device(pdev); + kfree(dev); + return rc; + } + + printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name, + sis_chip_info[tp->chipset].name); + + pci_set_drvdata(pdev, dev); + + printk(KERN_INFO "%s: %s at 0x%lx, " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " + "IRQ %d\n", + dev->name, + board_info[ent->driver_data].name, + dev->base_addr, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], dev->irq); + + int val = smdio_read(ioaddr, PHY_AUTO_NEGO_REG); + + printk(KERN_INFO "%s: Auto-negotiation Enabled.\n", dev->name); + + // enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged + smdio_write(ioaddr, PHY_AUTO_NEGO_REG, + PHY_Cap_10_Half | PHY_Cap_10_Full | + PHY_Cap_100_Half | PHY_Cap_100_Full | (val & 0x1F)); + + // enable 1000 Full Mode + smdio_write(ioaddr, PHY_1000_CTRL_REG, PHY_Cap_1000_Full); + + // Enable auto-negotiation and restart auto-nigotiation + smdio_write(ioaddr, PHY_CTRL_REG, + PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego); + udelay(100); + + // wait for auto-negotiation process + for (i = 10000; i > 0; i--) { + //check if auto-negotiation complete + if (smdio_read(ioaddr, PHY_STAT_REG) & PHY_Auto_Neco_Comp) { + udelay(100); + reg31 = smdio_read(ioaddr, 31); + reg31 &= 0x1c; //bit 4:2 + switch (reg31) { + case _1000bpsF: + SiS_W16(0x40, 0x1c01); + printk + ("SiS190 Link on 1000 bps Full Duplex mode. \n"); + break; + case _1000bpsH: + SiS_W16(0x40, 0x0c01); + printk + ("SiS190 Link on 1000 bps Half Duplex mode. \n"); + break; + case _100bpsF: + SiS_W16(0x40, 0x1801); + printk + ("SiS190 Link on 100 bps Full Duplex mode. \n"); + break; + case _100bpsH: + SiS_W16(0x40, 0x0801); + printk + ("SiS190 Link on 100 bps Half Duplex mode. \n"); + break; + case _10bpsF: + SiS_W16(0x40, 0x1401); + printk + ("SiS190 Link on 10 bps Full Duplex mode. \n"); + break; + case _10bpsH: + SiS_W16(0x40, 0x0401); + printk + ("SiS190 Link on 10 bps Half Duplex mode. \n"); + break; + default: + printk(KERN_ERR PFX + "Error! SiS190 Can not detect mode !!! \n"); + break; + } + + break; + } else { + udelay(100); + } + } // end for-loop to wait for auto-negotiation process + return 0; +} + +static void __devexit +SiS190_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct sis190_private *tp = (struct sis190_private *) (dev->priv); + + assert(dev != NULL); + assert(tp != NULL); + + unregister_netdev(dev); + iounmap(tp->mmio_addr); + pci_release_regions(pdev); + + // poison memory before freeing + memset(dev, 0xBC, + sizeof (struct net_device) + sizeof (struct sis190_private)); + + kfree(dev); + pci_set_drvdata(pdev, NULL); +} + +static int +SiS190_open(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + int retval; + u8 diff; + int rc; + + retval = + request_irq(dev->irq, SiS190_interrupt, SA_SHIRQ, dev->name, dev); + if (retval) { + return retval; + } + + tp->tx_desc_raw = pci_alloc_consistent(tp->pci_dev, + (NUM_TX_DESC * sizeof (struct TxDesc)) + 256, + &tp->tx_dma_raw); + if (!tp->tx_desc_raw) { + rc = -ENOMEM; + goto err_out; + } + // Tx Desscriptor needs 256 bytes alignment; + diff = 256 - (tp->tx_dma_raw - ((tp->tx_dma_raw >> 8) << 8)); + tp->tx_dma_aligned = tp->tx_dma_raw + diff; + tp->TxDescArray = (struct TxDesc *) (tp->tx_desc_raw + diff); + + tp->rx_desc_raw = pci_alloc_consistent(tp->pci_dev, + (NUM_RX_DESC * sizeof (struct RxDesc)) + 256, + &tp->rx_dma_raw); + if (!tp->rx_desc_raw) { + rc = -ENOMEM; + goto err_out_free_tx; + } + // Rx Desscriptor needs 256 bytes alignment; + diff = 256 - (tp->rx_dma_raw - ((tp->rx_dma_raw >> 8) << 8)); + tp->rx_dma_aligned = tp->rx_dma_raw + diff; + tp->RxDescArray = (struct RxDesc *) (tp->rx_desc_raw + diff); + + tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL); + if (tp->RxBufferRings == NULL) { + printk(KERN_INFO "Allocate RxBufferRing failed\n"); + } + + SiS190_init_ring(dev); + SiS190_hw_start(dev); + + return 0; + +err_out_free_tx: + pci_free_consistent(tp->pci_dev, + (NUM_TX_DESC * sizeof (struct TxDesc)) + 256, + tp->tx_desc_raw, tp->tx_dma_raw); +err_out: + free_irq(dev->irq, dev); + return rc; +} + +static void +SiS190_hw_start(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + void *ioaddr = tp->mmio_addr; + + /* Soft reset the chip. */ + + SiS_W32(IntrControl, 0x8000); + udelay(1000); + SiS_W32(IntrControl, 0x0); + + SiS_W32(0x0, 0x01a00); + SiS_W32(0x4, tp->tx_dma_aligned); + + SiS_W32(0x10, 0x1a00); + SiS_W32(0x14, tp->rx_dma_aligned); + + SiS_W32(0x20, 0xffffffff); + SiS_W32(0x24, 0x0); + SiS_W16(0x40, 0x1901); //default is 100Mbps + SiS_W32(0x44, 0x0); + SiS_W32(0x50, 0x60); + SiS_W16(0x60, 0x02); + SiS_W32(0x68, 0x0); + SiS_W32(0x6c, 0x0); + SiS_W32(0x70, 0x0); + SiS_W32(0x74, 0x0); + + // Set Rx Config register + + tp->cur_rx = 0; + + udelay(10); + + SiS190_set_rx_mode(dev); + + /* Enable all known interrupts by setting the interrupt mask. */ + SiS_W32(IntrMask, sis190_intr_mask); + + SiS_W32(0x0, 0x1a01); + SiS_W32(0x10, 0x1a1d); + + netif_start_queue(dev); + +} + +static void +SiS190_init_ring(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + int i; + + tp->cur_rx = 0; + tp->cur_tx = 0; + tp->dirty_tx = 0; + memset(tp->TxDescArray, 0x0, NUM_TX_DESC * sizeof (struct TxDesc)); + memset(tp->RxDescArray, 0x0, NUM_RX_DESC * sizeof (struct RxDesc)); + + for (i = 0; i < NUM_TX_DESC; i++) { + tp->Tx_skbuff[i] = NULL; + } + for (i = 0; i < NUM_RX_DESC; i++) { + + tp->RxDescArray[i].PSize = 0x0; + + if (i == (NUM_RX_DESC - 1)) + tp->RxDescArray[i].buf_Len = BIT_31 + RX_BUF_SIZE; //bit 31 is End bit + else + tp->RxDescArray[i].buf_Len = RX_BUF_SIZE; + +#warning Replace virt_to_bus with DMA mapping + tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]); + tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]); + tp->RxDescArray[i].status = OWNbit | INTbit; + + } + +} + +static void +SiS190_tx_clear(struct sis190_private *tp) +{ + int i; + + tp->cur_tx = 0; + for (i = 0; i < NUM_TX_DESC; i++) { + if (tp->Tx_skbuff[i] != NULL) { + dev_kfree_skb(tp->Tx_skbuff[i]); + tp->Tx_skbuff[i] = NULL; + tp->stats.tx_dropped++; + } + } +} + +static void +SiS190_tx_timeout(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + void *ioaddr = tp->mmio_addr; + u8 tmp8; + + /* disable Tx, if not already */ + tmp8 = SiS_R8(TxControl); + if (tmp8 & CmdTxEnb) + SiS_W8(TxControl, tmp8 & ~CmdTxEnb); + + /* Disable interrupts by clearing the interrupt mask. */ + SiS_W32(IntrMask, 0x0000); + + /* Stop a shared interrupt from scavenging while we are. */ + spin_lock_irq(&tp->lock); + SiS190_tx_clear(tp); + spin_unlock_irq(&tp->lock); + + /* ...and finally, reset everything */ + SiS190_hw_start(dev); + + netif_wake_queue(dev); +} + +static int +SiS190_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + void *ioaddr = tp->mmio_addr; + int entry = tp->cur_tx % NUM_TX_DESC; + + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; + } + + spin_lock_irq(&tp->lock); + + if ((tp->TxDescArray[entry].status & OWNbit) == 0) { +#warning Replace virt_to_bus with DMA mapping + tp->Tx_skbuff[entry] = skb; + tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data); + tp->TxDescArray[entry].PSize = + ((skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN); + + if (entry != (NUM_TX_DESC - 1)) { + tp->TxDescArray[entry].buf_Len = + tp->TxDescArray[entry].PSize; + } else { + tp->TxDescArray[entry].buf_Len = + tp->TxDescArray[entry].PSize | ENDbit; + } + + tp->TxDescArray[entry].status |= + (OWNbit | INTbit | DEFbit | CRCbit | PADbit); + + SiS_W32(TxControl, 0x1a11); //Start Send + + dev->trans_start = jiffies; + + tp->cur_tx++; + } + + spin_unlock_irq(&tp->lock); + + if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) { + netif_stop_queue(dev); + } + + return 0; +} + +static void +SiS190_tx_interrupt(struct net_device *dev, struct sis190_private *tp, + void *ioaddr) +{ + unsigned long dirty_tx, tx_left = 0; + int entry = tp->cur_tx % NUM_TX_DESC; + + assert(dev != NULL); + assert(tp != NULL); + assert(ioaddr != NULL); + + dirty_tx = tp->dirty_tx; + tx_left = tp->cur_tx - dirty_tx; + + while (tx_left > 0) { + if ((tp->TxDescArray[entry].status & OWNbit) == 0) { + dev_kfree_skb_irq(tp-> + Tx_skbuff[dirty_tx % NUM_TX_DESC]); + tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL; + tp->stats.tx_packets++; + dirty_tx++; + tx_left--; + entry++; + } + } + + if (tp->dirty_tx != dirty_tx) { + tp->dirty_tx = dirty_tx; + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); + } +} + +static void +SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp, + void *ioaddr) +{ + int cur_rx; + struct sk_buff *skb; + int pkt_size = 0; + + assert(dev != NULL); + assert(tp != NULL); + assert(ioaddr != NULL); + + cur_rx = tp->cur_rx; + while ((tp->RxDescArray[cur_rx].status & OWNbit) == 0) { + + if (tp->RxDescArray[cur_rx].PSize & 0x0080000) { + printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); + tp->stats.rx_errors++; + tp->stats.rx_length_errors++; + } else if (!(tp->RxDescArray[cur_rx].PSize & 0x0010000)) { + printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); + tp->stats.rx_errors++; + tp->stats.rx_crc_errors++; + } else { + pkt_size = + (int) (tp->RxDescArray[cur_rx]. + PSize & 0x0000FFFF) - 4; + skb = dev_alloc_skb(pkt_size + 2); + if (skb != NULL) { + skb->dev = dev; + skb_reserve(skb, 2); // 16 byte align the IP fields. // + eth_copy_and_sum(skb, tp->RxBufferRing[cur_rx], + pkt_size, 0); + skb_put(skb, pkt_size); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + + tp->RxDescArray[cur_rx].PSize = 0x0; + + if (cur_rx == (NUM_RX_DESC - 1)) + tp->RxDescArray[cur_rx].buf_Len = + ENDbit + RX_BUF_SIZE; + else + tp->RxDescArray[cur_rx].buf_Len = + RX_BUF_SIZE; + +#warning Replace virt_to_bus with DMA mapping + tp->RxDescArray[cur_rx].buf_addr = + virt_to_bus(tp->RxBufferRing[cur_rx]); + dev->last_rx = jiffies; + tp->stats.rx_bytes += pkt_size; + tp->stats.rx_packets++; + + tp->RxDescArray[cur_rx].status = + OWNbit | INTbit; + } else { + printk(KERN_WARNING + "%s: Memory squeeze, deferring packet.\n", + dev->name); + /* We should check that some rx space is free. + If not, free one and mark stats->rx_dropped++. */ + tp->stats.rx_dropped++; + } + } + + cur_rx = (cur_rx + 1) % NUM_RX_DESC; + + } + + tp->cur_rx = cur_rx; +} + +/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ +static irqreturn_t +SiS190_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) dev_instance; + struct sis190_private *tp = dev->priv; + int boguscnt = max_interrupt_work; + void *ioaddr = tp->mmio_addr; + unsigned long status = 0; + int handled = 0; + + do { + status = SiS_R32(IntrStatus); + + /* h/w no longer present (hotplug?) or major error, bail */ + + SiS_W32(IntrStatus, status); + + if ((status & (TxQ0Int | RxQInt)) == 0) + break; + + // Rx interrupt + if (status & (RxQInt)) { + SiS190_rx_interrupt(dev, tp, ioaddr); + } + // Tx interrupt + if (status & (TxQ0Int)) { + spin_lock(&tp->lock); + SiS190_tx_interrupt(dev, tp, ioaddr); + spin_unlock(&tp->lock); + } + + boguscnt--; + } while (boguscnt > 0); + + if (boguscnt <= 0) { + printk(KERN_WARNING "%s: Too much work at interrupt!\n", + dev->name); + /* Clear all interrupt sources. */ + SiS_W32(IntrStatus, 0xffffffff); + } + + return IRQ_RETVAL(handled); +} + +static int +SiS190_close(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + void *ioaddr = tp->mmio_addr; + int i; + + netif_stop_queue(dev); + + spin_lock_irq(&tp->lock); + + /* Stop the chip's Tx and Rx DMA processes. */ + + SiS_W32(TxControl, 0x1a00); + SiS_W32(RxControl, 0x1a00); + + /* Disable interrupts by clearing the interrupt mask. */ + SiS_W32(IntrMask, 0x0000); + + /* Update the error counts. */ + //tp->stats.rx_missed_errors += _R32(RxMissed); + + spin_unlock_irq(&tp->lock); + + synchronize_irq(); + free_irq(dev->irq, dev); + + SiS190_tx_clear(tp); + pci_free_consistent(tp->pci_dev, + (NUM_TX_DESC * sizeof (struct TxDesc)) + 256, + tp->tx_desc_raw, tp->tx_dma_raw); + pci_free_consistent(tp->pci_dev, + (NUM_RX_DESC * sizeof (struct RxDesc)) + 256, + tp->rx_desc_raw, tp->rx_dma_raw); + tp->TxDescArray = NULL; + tp->RxDescArray = NULL; + kfree(tp->RxBufferRings); + for (i = 0; i < NUM_RX_DESC; i++) { + tp->RxBufferRing[i] = NULL; + } + + return 0; +} + +static void +SiS190_set_rx_mode(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + void *ioaddr = tp->mmio_addr; + unsigned long flags; + u32 mc_filter[2]; /* Multicast hash filter */ + int i, rx_mode; + u32 tmp = 0; + + if (dev->flags & IFF_PROMISC) { + /* Unconditionally log net taps. */ + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", + dev->name); + rx_mode = + AcceptBroadcast | AcceptMulticast | AcceptMyPhys | + AcceptAllPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else if ((dev->mc_count > multicast_filter_limit) + || (dev->flags & IFF_ALLMULTI)) { + /* Too many to filter perfectly -- accept all multicasts. */ + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else { + struct dev_mc_list *mclist; + rx_mode = AcceptBroadcast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0; + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + int bit_nr = + ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + rx_mode |= AcceptMulticast; + } + } + + spin_lock_irqsave(&tp->lock, flags); + + tmp = rx_mode | 0x2; + + SiS_W16(RxMacControl, tmp); + SiS_W32(RxHashTable, mc_filter[0]); + SiS_W32(RxHashTable + 4, mc_filter[1]); + + spin_unlock_irqrestore(&tp->lock, flags); +} + +struct net_device_stats * +SiS190_get_stats(struct net_device *dev) +{ + struct sis190_private *tp = dev->priv; + return &tp->stats; +} + +static struct pci_driver sis190_pci_driver = { + .name = MODULENAME, + .id_table = sis190_pci_tbl, + .probe = SiS190_init_one, + .remove = SiS190_remove_one, +}; + +static int __init +SiS190_init_module(void) +{ + return pci_module_init(&sis190_pci_driver); +} + +static void __exit +SiS190_cleanup_module(void) +{ + pci_unregister_driver(&sis190_pci_driver); +} + +module_init(SiS190_init_module); +module_exit(SiS190_cleanup_module); diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c --- a/drivers/net/sk98lin/skge.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/sk98lin/skge.c Mon Aug 18 22:21:01 2003 @@ -2142,7 +2142,7 @@ */ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, virt_to_page(pMessage->data), - ((unsigned long) pMessage->data & ~PAGE_MASK), + offset_in_page(pMessage->data), pMessage->len, PCI_DMA_TODEVICE); pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); @@ -2259,7 +2259,7 @@ */ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, virt_to_page(pMessage->data), - ((unsigned long) pMessage->data & ~PAGE_MASK), + offset_in_page(pMessage->data), skb_headlen(pMessage), PCI_DMA_TODEVICE); @@ -2518,8 +2518,7 @@ Length = pAC->RxBufSize; PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, virt_to_page(pMsgBlock->data), - ((unsigned long) pMsgBlock->data & - ~PAGE_MASK), + offset_in_page(pMsgBlock->data), pAC->RxBufSize - 2, PCI_DMA_FROMDEVICE); diff -Nru a/drivers/net/slip.c b/drivers/net/slip.c --- a/drivers/net/slip.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/slip.c Mon Aug 18 22:21:06 2003 @@ -1369,6 +1369,7 @@ /* Fill in our line protocol discipline, and register it */ if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); + kfree(slip_devs); } return status; } diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c --- a/drivers/net/smc-mca.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/smc-mca.c Mon Aug 18 22:21:01 2003 @@ -215,7 +215,7 @@ printk(KERN_INFO "%s: %s found in slot %d\n", dev->name, smc_mca_adapter_names[adapter], slot + 1); - strncpy(gen_dev->name, smc_mca_adapter_names[adapter], sizeof(gen_dev->name)); + mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]); mca_device_set_claim(mca_dev, 1); ultra_found++; diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c --- a/drivers/net/sungem.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/sungem.c Mon Aug 18 22:21:06 2003 @@ -725,8 +725,7 @@ skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET)); rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev, virt_to_page(new_skb->data), - ((unsigned long) new_skb->data & - ~PAGE_MASK), + offset_in_page(new_skb->data), RX_BUF_ALLOC_SIZE(gp), PCI_DMA_FROMDEVICE)); skb_reserve(new_skb, RX_OFFSET); @@ -873,8 +872,7 @@ len = skb->len; mapping = pci_map_page(gp->pdev, virt_to_page(skb->data), - ((unsigned long) skb->data & - ~PAGE_MASK), + offset_in_page(skb->data), len, PCI_DMA_TODEVICE); ctrl |= TXDCTRL_SOF | TXDCTRL_EOF | len; if (gem_intme(entry)) @@ -898,7 +896,7 @@ */ first_len = skb_headlen(skb); first_mapping = pci_map_page(gp->pdev, virt_to_page(skb->data), - ((unsigned long) skb->data & ~PAGE_MASK), + offset_in_page(skb->data), first_len, PCI_DMA_TODEVICE); entry = NEXT_TX(entry); @@ -1464,8 +1462,7 @@ skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET)); dma_addr = pci_map_page(gp->pdev, virt_to_page(skb->data), - ((unsigned long) skb->data & - ~PAGE_MASK), + offset_in_page(skb->data), RX_BUF_ALLOC_SIZE(gp), PCI_DMA_FROMDEVICE); rxd->buffer = cpu_to_le64(dma_addr); diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/tg3.c Mon Aug 18 22:21:03 2003 @@ -5051,16 +5051,20 @@ #define TG3_REGDUMP_LEN (32 * 1024) -static u8 *tg3_get_regs(struct tg3 *tp) +static int tg3_get_regs_len(struct net_device *dev) { - u8 *orig_p = kmalloc(TG3_REGDUMP_LEN, GFP_KERNEL); - u8 *p; + return TG3_REGDUMP_LEN; +} + +static void tg3_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) +{ + struct tg3 *tp = dev->priv; + u8 *orig_p = p; int i; - if (orig_p == NULL) - return NULL; + regs->version = 0; - memset(orig_p, 0, TG3_REGDUMP_LEN); + memset(p, 0, TG3_REGDUMP_LEN); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -5114,388 +5118,263 @@ spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - - return orig_p; } -static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) +static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tg3 *tp = dev->priv; + + if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || + tp->link_config.phy_is_low_power) + return -EAGAIN; + + cmd->supported = (SUPPORTED_Autoneg); + + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) + cmd->supported |= (SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); + + if (tp->phy_id != PHY_ID_SERDES) + cmd->supported |= (SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_MII); + else + cmd->supported |= SUPPORTED_FIBRE; + + cmd->advertising = tp->link_config.advertising; + cmd->speed = tp->link_config.active_speed; + cmd->duplex = tp->link_config.active_duplex; + cmd->port = 0; + cmd->phy_address = PHY_ADDR; + cmd->transceiver = 0; + cmd->autoneg = tp->link_config.autoneg; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + return 0; +} + +static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct tg3 *tp = dev->priv; - struct pci_dev *pci_dev = tp->pdev; - u32 ethcmd; - - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO:{ - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_MODULE_NAME); - strcpy (info.version, DRV_MODULE_VERSION); - memset(&info.fw_version, 0, sizeof(info.fw_version)); - strcpy (info.bus_info, pci_name(pci_dev)); - info.eedump_len = 0; - info.regdump_len = TG3_REGDUMP_LEN; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - case ETHTOOL_GSET: { - struct ethtool_cmd cmd = { ETHTOOL_GSET }; - - if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || - tp->link_config.phy_is_low_power) - return -EAGAIN; - cmd.supported = (SUPPORTED_Autoneg); - - if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) - cmd.supported |= (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); - - if (tp->phy_id != PHY_ID_SERDES) - cmd.supported |= (SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_MII); - else - cmd.supported |= SUPPORTED_FIBRE; - - cmd.advertising = tp->link_config.advertising; - cmd.speed = tp->link_config.active_speed; - cmd.duplex = tp->link_config.active_duplex; - cmd.port = 0; - cmd.phy_address = PHY_ADDR; - cmd.transceiver = 0; - cmd.autoneg = tp->link_config.autoneg; - cmd.maxtxpkt = 0; - cmd.maxrxpkt = 0; - if (copy_to_user(useraddr, &cmd, sizeof(cmd))) - return -EFAULT; - return 0; - } - case ETHTOOL_SSET: { - struct ethtool_cmd cmd; - - if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || - tp->link_config.phy_is_low_power) - return -EAGAIN; - - if (copy_from_user(&cmd, useraddr, sizeof(cmd))) - return -EFAULT; - - /* Fiber PHY only supports 1000 full/half */ - if (cmd.autoneg == AUTONEG_ENABLE) { - if (tp->phy_id == PHY_ID_SERDES && - (cmd.advertising & - (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full))) - return -EINVAL; - if ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) && - (cmd.advertising & - (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full))) - return -EINVAL; - } else { - if (tp->phy_id == PHY_ID_SERDES && - (cmd.speed == SPEED_10 || - cmd.speed == SPEED_100)) - return -EINVAL; - if ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) && - (cmd.speed == SPEED_10 || - cmd.speed == SPEED_100)) - return -EINVAL; - } - - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - - tp->link_config.autoneg = cmd.autoneg; - if (cmd.autoneg == AUTONEG_ENABLE) { - tp->link_config.advertising = cmd.advertising; - tp->link_config.speed = SPEED_INVALID; - tp->link_config.duplex = DUPLEX_INVALID; - } else { - tp->link_config.speed = cmd.speed; - tp->link_config.duplex = cmd.duplex; - } - - tg3_setup_phy(tp); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - - return 0; - } - - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u8 *regbuf; - int ret; - - if (copy_from_user(®s, useraddr, sizeof(regs))) - return -EFAULT; - if (regs.len > TG3_REGDUMP_LEN) - regs.len = TG3_REGDUMP_LEN; - regs.version = 0; - if (copy_to_user(useraddr, ®s, sizeof(regs))) - return -EFAULT; - - regbuf = tg3_get_regs(tp); - if (!regbuf) - return -ENOMEM; - - useraddr += offsetof(struct ethtool_regs, data); - ret = 0; - if (copy_to_user(useraddr, regbuf, regs.len)) - ret = -EFAULT; - kfree(regbuf); - return ret; - } - case ETHTOOL_GWOL: { - struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; - - wol.supported = WAKE_MAGIC; - wol.wolopts = 0; - if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) - wol.wolopts = WAKE_MAGIC; - memset(&wol.sopass, 0, sizeof(wol.sopass)); - if (copy_to_user(useraddr, &wol, sizeof(wol))) - return -EFAULT; - return 0; + + if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || + tp->link_config.phy_is_low_power) + return -EAGAIN; + + if (cmd->autoneg == AUTONEG_ENABLE) { + tp->link_config.advertising = cmd->advertising; + tp->link_config.speed = SPEED_INVALID; + tp->link_config.duplex = DUPLEX_INVALID; + } else { + tp->link_config.speed = cmd->speed; + tp->link_config.duplex = cmd->duplex; + } + + tg3_setup_phy(tp); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + + return 0; +} + +static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct tg3 *tp = dev->priv; + + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); + strcpy(info->bus_info, pci_name(tp->pdev)); +} + +static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct tg3 *tp = dev->priv; + + wol->supported = WAKE_MAGIC; + wol->wolopts = 0; + if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) + wol->wolopts = WAKE_MAGIC; + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct tg3 *tp = dev->priv; + + if (wol->wolopts & ~WAKE_MAGIC) + return -EINVAL; + if ((wol->wolopts & WAKE_MAGIC) && + tp->phy_id == PHY_ID_SERDES && + !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) + return -EINVAL; + + spin_lock_irq(&tp->lock); + if (wol->wolopts & WAKE_MAGIC) + tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; + else + tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; + spin_unlock_irq(&tp->lock); + + return 0; +} + +static u32 tg3_get_msglevel(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + return tp->msg_enable; +} + +static void tg3_set_msglevel(struct net_device *dev, u32 value) +{ + struct tg3 *tp = dev->priv; + tp->msg_enable = value; +} + +static int tg3_nway_reset(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + u32 bmcr; + int r; + + spin_lock_irq(&tp->lock); + tg3_readphy(tp, MII_BMCR, &bmcr); + tg3_readphy(tp, MII_BMCR, &bmcr); + r = -EINVAL; + if (bmcr & BMCR_ANENABLE) { + tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); + r = 0; } - case ETHTOOL_SWOL: { - struct ethtool_wolinfo wol; - - if (copy_from_user(&wol, useraddr, sizeof(wol))) - return -EFAULT; - if (wol.wolopts & ~WAKE_MAGIC) - return -EINVAL; - if ((wol.wolopts & WAKE_MAGIC) && - tp->phy_id == PHY_ID_SERDES && - !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) + spin_unlock_irq(&tp->lock); + + return r; +} + +static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct tg3 *tp = dev->priv; + + ering->rx_max_pending = TG3_RX_RING_SIZE - 1; + ering->rx_mini_max_pending = 0; + ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; + + ering->rx_pending = tp->rx_pending; + ering->rx_mini_pending = 0; + ering->rx_jumbo_pending = tp->rx_jumbo_pending; + ering->tx_pending = tp->tx_pending; +} + +static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct tg3 *tp = dev->priv; + + if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || + (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || + (ering->tx_pending > TG3_TX_RING_SIZE - 1)) + return -EINVAL; + + tg3_netif_stop(tp); + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + + tp->rx_pending = ering->rx_pending; + tp->rx_jumbo_pending = ering->rx_jumbo_pending; + tp->tx_pending = ering->tx_pending; + + tg3_halt(tp); + tg3_init_rings(tp); + tg3_init_hw(tp); + netif_wake_queue(tp->dev); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); + + return 0; +} + +static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) +{ + struct tg3 *tp = dev->priv; + + epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; + epause->rx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0; + epause->tx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0; +} + +static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) +{ + struct tg3 *tp = dev->priv; + + tg3_netif_stop(tp); + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + if (epause->autoneg) + tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; + else + tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; + if (epause->rx_pause) + tp->tg3_flags |= TG3_FLAG_PAUSE_RX; + else + tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX; + if (epause->tx_pause) + tp->tg3_flags |= TG3_FLAG_PAUSE_TX; + else + tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; + tg3_halt(tp); + tg3_init_rings(tp); + tg3_init_hw(tp); + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); + + return 0; +} + +static u32 tg3_get_rx_csum(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + return (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0; +} + +static int tg3_set_rx_csum(struct net_device *dev, u32 data) +{ + struct tg3 *tp = dev->priv; + + if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { + if (data != 0) return -EINVAL; - - spin_lock_irq(&tp->lock); - if (wol.wolopts & WAKE_MAGIC) - tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; - else - tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; - spin_unlock_irq(&tp->lock); - - return 0; - } - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = { ETHTOOL_GMSGLVL }; - edata.data = tp->msg_enable; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - tp->msg_enable = edata.data; - return 0; - } - case ETHTOOL_NWAY_RST: { - u32 bmcr; - int r; - - spin_lock_irq(&tp->lock); - tg3_readphy(tp, MII_BMCR, &bmcr); - tg3_readphy(tp, MII_BMCR, &bmcr); - r = -EINVAL; - if (bmcr & BMCR_ANENABLE) { - tg3_writephy(tp, MII_BMCR, - bmcr | BMCR_ANRESTART); - r = 0; - } - spin_unlock_irq(&tp->lock); - - return r; - } - case ETHTOOL_GLINK: { - struct ethtool_value edata = { ETHTOOL_GLINK }; - edata.data = netif_carrier_ok(tp->dev) ? 1 : 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_GRINGPARAM: { - struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM }; - - ering.rx_max_pending = TG3_RX_RING_SIZE - 1; - ering.rx_mini_max_pending = 0; - ering.rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; - - ering.rx_pending = tp->rx_pending; - ering.rx_mini_pending = 0; - ering.rx_jumbo_pending = tp->rx_jumbo_pending; - ering.tx_pending = tp->tx_pending; - - if (copy_to_user(useraddr, &ering, sizeof(ering))) - return -EFAULT; - return 0; - } - case ETHTOOL_SRINGPARAM: { - struct ethtool_ringparam ering; - - if (copy_from_user(&ering, useraddr, sizeof(ering))) - return -EFAULT; - - if ((ering.rx_pending > TG3_RX_RING_SIZE - 1) || - (ering.rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || - (ering.tx_pending > TG3_TX_RING_SIZE - 1)) + return 0; + } + + spin_lock_irq(&tp->lock); + if (data) + tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; + else + tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; + spin_unlock_irq(&tp->lock); + + return 0; +} + +static int tg3_set_tx_csum(struct net_device *dev, u32 data) +{ + struct tg3 *tp = dev->priv; + + if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { + if (data != 0) return -EINVAL; + return 0; + } + + if (data) + dev->features |= NETIF_F_IP_CSUM; + else + dev->features &= ~NETIF_F_IP_CSUM; - tg3_netif_stop(tp); - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - - tp->rx_pending = ering.rx_pending; - tp->rx_jumbo_pending = ering.rx_jumbo_pending; - tp->tx_pending = ering.tx_pending; - - tg3_halt(tp); - tg3_init_hw(tp); - netif_wake_queue(tp->dev); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); - - return 0; - } - case ETHTOOL_GPAUSEPARAM: { - struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM }; - - epause.autoneg = - (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; - epause.rx_pause = - (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0; - epause.tx_pause = - (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0; - if (copy_to_user(useraddr, &epause, sizeof(epause))) - return -EFAULT; - return 0; - } - case ETHTOOL_SPAUSEPARAM: { - struct ethtool_pauseparam epause; - - if (copy_from_user(&epause, useraddr, sizeof(epause))) - return -EFAULT; - - tg3_netif_stop(tp); - spin_lock_irq(&tp->lock); - spin_lock(&tp->tx_lock); - if (epause.autoneg) - tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; - if (epause.rx_pause) - tp->tg3_flags |= TG3_FLAG_PAUSE_RX; - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX; - if (epause.tx_pause) - tp->tg3_flags |= TG3_FLAG_PAUSE_TX; - else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; - tg3_halt(tp); - tg3_init_hw(tp); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); - - return 0; - } - case ETHTOOL_GRXCSUM: { - struct ethtool_value edata = { ETHTOOL_GRXCSUM }; - - edata.data = - (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SRXCSUM: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - - if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { - if (edata.data != 0) - return -EINVAL; - return 0; - } - - spin_lock_irq(&tp->lock); - if (edata.data) - tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; - else - tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; - spin_unlock_irq(&tp->lock); - - return 0; - } - case ETHTOOL_GTXCSUM: { - struct ethtool_value edata = { ETHTOOL_GTXCSUM }; - - edata.data = - (tp->dev->features & NETIF_F_IP_CSUM) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_STXCSUM: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - - if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { - if (edata.data != 0) - return -EINVAL; - return 0; - } - - if (edata.data) - tp->dev->features |= NETIF_F_IP_CSUM; - else - tp->dev->features &= ~NETIF_F_IP_CSUM; - - return 0; - } - case ETHTOOL_GSG: { - struct ethtool_value edata = { ETHTOOL_GSG }; - - edata.data = - (tp->dev->features & NETIF_F_SG) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SSG: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - - if (edata.data) - tp->dev->features |= NETIF_F_SG; - else - tp->dev->features &= ~NETIF_F_SG; - - return 0; - } - }; - - return -EOPNOTSUPP; + return 0; } - + static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; @@ -5503,8 +5382,6 @@ int err; switch(cmd) { - case SIOCETHTOOL: - return tg3_ethtool_ioctl(dev, (void *) ifr->ifr_data); case SIOCGMIIPHY: data->phy_id = PHY_ADDR; @@ -5568,6 +5445,30 @@ } #endif +static struct ethtool_ops tg3_ethtool_ops = { + .get_settings = tg3_get_settings, + .set_settings = tg3_set_settings, + .get_drvinfo = tg3_get_drvinfo, + .get_regs_len = tg3_get_regs_len, + .get_regs = tg3_get_regs, + .get_wol = tg3_get_wol, + .set_wol = tg3_set_wol, + .get_msglevel = tg3_get_msglevel, + .set_msglevel = tg3_set_msglevel, + .nway_reset = tg3_nway_reset, + .get_link = ethtool_op_get_link, + .get_ringparam = tg3_get_ringparam, + .set_ringparam = tg3_set_ringparam, + .get_pauseparam = tg3_get_pauseparam, + .set_pauseparam = tg3_set_pauseparam, + .get_rx_csum = tg3_get_rx_csum, + .set_rx_csum = tg3_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = tg3_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +}; + /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { @@ -6880,6 +6781,7 @@ dev->do_ioctl = tg3_ioctl; dev->tx_timeout = tg3_tx_timeout; dev->poll = tg3_poll; + dev->ethtool_ops = &tg3_ethtool_ops; dev->weight = 64; dev->watchdog_timeo = TG3_TX_TIMEOUT; dev->change_mtu = tg3_change_mtu; diff -Nru a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c --- a/drivers/net/tokenring/3c359.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/tokenring/3c359.c Mon Aug 18 22:21:06 2003 @@ -315,7 +315,7 @@ dev->irq=pdev->irq; dev->base_addr=pci_resource_start(pdev,0) ; dev->init=NULL ; /* Must be null with new api, otherwise get called twice */ - xl_priv->xl_card_name = (char *)pdev->dev.name ; + xl_priv->xl_card_name = pci_name(pdev); xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE); xl_priv->pdev = pdev ; diff -Nru a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c --- a/drivers/net/tokenring/ibmtr.c Mon Aug 18 22:21:04 2003 +++ b/drivers/net/tokenring/ibmtr.c Mon Aug 18 22:21:04 2003 @@ -876,7 +876,6 @@ if (i==0) break; if (ti->open_status == OPEN && ti->sap_status==OPEN) { netif_start_queue(dev); - MOD_INC_USE_COUNT; DPRINTK("Adapter is up and running\n"); return 0; } @@ -1041,7 +1040,6 @@ netif_stop_queue(dev); DPRINTK("Adapter is closed.\n"); - MOD_DEC_USE_COUNT; return 0; } @@ -1918,7 +1916,7 @@ MODULE_PARM(irq, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i"); MODULE_PARM(mem, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i"); -int init_module(void) +static int __init ibmtr_init(void) { int i; int count=0; @@ -1948,21 +1946,24 @@ if (count) return 0; printk("ibmtr: register_netdev() returned non-zero.\n"); return -EIO; -} /*init_module */ +} +module_init(ibmtr_init); -void cleanup_module(void) +static void __exit ibmtr_cleanup(void) { - int i,j; + int i; for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){ if (!dev_ibmtr[i]) continue; if (dev_ibmtr[i]->base_addr) { outb(0,dev_ibmtr[i]->base_addr+ADAPTRESET); - for(j=jiffies+TR_RST_TIME; - time_before_eq(jiffies,j);) ; + + schedule_timeout(TR_RST_TIME); /* wait 50ms */ + outb(0,dev_ibmtr[i]->base_addr+ADAPTRESETREL); } + unregister_netdev(dev_ibmtr[i]); free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]); release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT); @@ -1978,4 +1979,5 @@ dev_ibmtr[i] = NULL; } } -#endif /* MODULE */ +module_exit(ibmtr_cleanup); +#endif diff -Nru a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c --- a/drivers/net/tokenring/olympic.c Mon Aug 18 22:21:05 2003 +++ b/drivers/net/tokenring/olympic.c Mon Aug 18 22:21:05 2003 @@ -230,9 +230,10 @@ dev->irq=pdev->irq; dev->base_addr=pci_resource_start(pdev, 0); dev->init=NULL; /* Must be NULL otherwise we get called twice */ - olympic_priv->olympic_card_name = (char *)pdev->dev.name ; + olympic_priv->olympic_card_name = pci_name(pdev); olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256); olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048); +#warning check ioremap return value olympic_priv->pdev = pdev ; if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) diff -Nru a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig --- a/drivers/net/tulip/Kconfig Mon Aug 18 22:21:05 2003 +++ b/drivers/net/tulip/Kconfig Mon Aug 18 22:21:05 2003 @@ -19,15 +19,13 @@ 21040 (Tulip series) chips. Some LinkSys PCI cards are of this type. (If your card is NOT SMC EtherPower 10/100 PCI (smc9332dst), you can also try the driver for "Generic DECchip" - cards, above. However, most people with a network card of this type + cards, below. However, most people with a network card of this type will say Y here.) Do read the Ethernet-HOWTO, available from - . More specific - information is contained in - . + . 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. If you want to compile it as a + The module will be called de2104x. If you want to compile it as a module, say M here and read as well as . diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c --- a/drivers/net/tulip/tulip_core.c Mon Aug 18 22:21:04 2003 +++ b/drivers/net/tulip/tulip_core.c Mon Aug 18 22:21:04 2003 @@ -226,6 +226,7 @@ { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, /* ALi 1563 integrated ethernet */ + { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c --- a/drivers/net/tun.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/tun.c Mon Aug 18 22:21:03 2003 @@ -51,6 +51,8 @@ /* Network device part of the driver */ +static LIST_HEAD(tun_dev_list); + /* Net device open. */ static int tun_net_open(struct net_device *dev) { @@ -70,7 +72,7 @@ { struct tun_struct *tun = (struct tun_struct *)dev->priv; - DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->name, skb->len); + DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len); /* Drop packet if interface is not attached */ if (!tun->attached) @@ -120,7 +122,7 @@ { struct tun_struct *tun = (struct tun_struct *)dev->priv; - DBG(KERN_INFO "%s: tun_net_init\n", tun->name); + DBG(KERN_INFO "%s: tun_net_init\n", tun->dev->name); switch (tun->flags & TUN_TYPE_MASK) { case TUN_TUN_DEV: @@ -161,7 +163,7 @@ if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_poll\n", tun->name); + DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); poll_wait(file, &tun->read_wait, wait); @@ -226,7 +228,7 @@ if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count); + DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); for (i = 0, len = 0; i < count; i++) { if (verify_area(VERIFY_READ, iv[i].iov_base, iv[i].iov_len)) @@ -290,7 +292,7 @@ if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_read\n", tun->name); + DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name); for (i = 0, len = 0; i < count; i++) { if (verify_area(VERIFY_WRITE, iv[i].iov_base, iv[i].iov_len)) @@ -350,7 +352,7 @@ tun->owner = -1; dev->init = tun_net_init; - tun->name = dev->name; + SET_MODULE_OWNER(dev); dev->open = tun_net_open; dev->hard_start_xmit = tun_net_xmit; @@ -359,27 +361,40 @@ dev->destructor = (void (*)(struct net_device *))kfree; } +static struct tun_struct *tun_get_by_name(const char *name) +{ + struct tun_struct *tun; + + ASSERT_RTNL(); + list_for_each_entry(tun, &tun_dev_list, list) { + if (!strncmp(tun->dev->name, name, IFNAMSIZ)) + return tun; + } + + return NULL; +} + static int tun_set_iff(struct file *file, struct ifreq *ifr) { struct tun_struct *tun; - struct net_device *dev; int err; - dev = __dev_get_by_name(ifr->ifr_name); - if (dev) { - /* Device exist */ - tun = dev->priv; - - if (dev->init != tun_net_init || tun->attached) + tun = tun_get_by_name(ifr->ifr_name); + if (tun) { + if (tun->attached) return -EBUSY; /* Check permissions */ - if (tun->owner != -1) - if (current->euid != tun->owner && !capable(CAP_NET_ADMIN)) - return -EPERM; - } else { + if (tun->owner != -1 && + current->euid != tun->owner && !capable(CAP_NET_ADMIN)) + return -EPERM; + } + else if (__dev_get_by_name(ifr->ifr_name)) + return -EINVAL; + else { char *name; unsigned long flags = 0; + struct net_device *dev; err = -EINVAL; @@ -420,9 +435,10 @@ goto failed; } + list_add(&tun->list, &tun_dev_list); } - DBG(KERN_INFO "%s: tun_set_iff\n", tun->name); + DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name); if (ifr->ifr_flags & IFF_NO_PI) tun->flags |= TUN_NO_PI; @@ -433,7 +449,7 @@ file->private_data = tun; tun->attached = 1; - strcpy(ifr->ifr_name, tun->name); + strcpy(ifr->ifr_name, tun->dev->name); return 0; failed: return err; @@ -459,14 +475,15 @@ if (err) return err; - copy_to_user((void *)arg, &ifr, sizeof(ifr)); + if (copy_to_user((void *)arg, &ifr, sizeof(ifr))) + return -EFAULT; return 0; } if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->name, cmd); + DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); switch (cmd) { case TUNSETNOCSUM: @@ -477,7 +494,7 @@ tun->flags &= ~TUN_NOCHECKSUM; DBG(KERN_INFO "%s: checksum %s\n", - tun->name, arg ? "disabled" : "enabled"); + tun->dev->name, arg ? "disabled" : "enabled"); break; case TUNSETPERSIST: @@ -488,14 +505,14 @@ tun->flags &= ~TUN_PERSIST; DBG(KERN_INFO "%s: persist %s\n", - tun->name, arg ? "disabled" : "enabled"); + tun->dev->name, arg ? "disabled" : "enabled"); break; case TUNSETOWNER: /* Set owner of the device */ tun->owner = (uid_t) arg; - DBG(KERN_INFO "%s: owner set to %d\n", tun->owner); + DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner); break; #ifdef TUN_DEBUG @@ -519,7 +536,7 @@ if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->name, on); + DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on); if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0) return ret; @@ -549,7 +566,7 @@ if (!tun) return 0; - DBG(KERN_INFO "%s: tun_chr_close\n", tun->name); + DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); tun_chr_fasync(-1, file, 0); @@ -562,8 +579,10 @@ /* Drop read queue */ skb_queue_purge(&tun->readq); - if (!(tun->flags & TUN_PERSIST)) + if (!(tun->flags & TUN_PERSIST)) { + list_del(&tun->list); unregister_netdevice(tun->dev); + } rtnl_unlock(); @@ -605,7 +624,17 @@ void tun_cleanup(void) { + struct tun_struct *tun, *nxt; + misc_deregister(&tun_miscdev); + + rtnl_lock(); + list_for_each_entry_safe(tun, nxt, &tun_dev_list, list) { + DBG(KERN_INFO "%s cleaned up\n", tun->dev->name); + unregister_netdevice(tun->dev); + } + rtnl_unlock(); + } module_init(tun_init); diff -Nru a/drivers/net/wan/comx-hw-locomx.c b/drivers/net/wan/comx-hw-locomx.c --- a/drivers/net/wan/comx-hw-locomx.c Mon Aug 18 22:21:04 2003 +++ b/drivers/net/wan/comx-hw-locomx.c Mon Aug 18 22:21:04 2003 @@ -339,7 +339,10 @@ return -ENOMEM; } - copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE)); + if (copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE))) { + free_page((unsigned long)page); + return -EBADF; + } if (*(page + count - 1) == '\n') { *(page + count - 1) = 0; } diff -Nru a/drivers/net/wan/comx-hw-mixcom.c b/drivers/net/wan/comx-hw-mixcom.c --- a/drivers/net/wan/comx-hw-mixcom.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/wan/comx-hw-mixcom.c Mon Aug 18 22:21:06 2003 @@ -763,7 +763,10 @@ return -ENOMEM; } - copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE)); + if (copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE))) { + free_page((unsigned long)page); + return -EFAULT; + } if (*(page + count - 1) == '\n') { *(page + count - 1) = 0; } diff -Nru a/drivers/net/wan/comx-hw-munich.c b/drivers/net/wan/comx-hw-munich.c --- a/drivers/net/wan/comx-hw-munich.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/wan/comx-hw-munich.c Mon Aug 18 22:21:02 2003 @@ -2414,7 +2414,10 @@ return -ENOMEM; /* Copy user data and cut trailing \n */ - copy_from_user(page, buffer, count = min(count, PAGE_SIZE)); + if (copy_from_user(page, buffer, count = min(count, PAGE_SIZE))) { + free_page((unsigned long)page); + return -EFAULT; + } if (*(page + count - 1) == '\n') *(page + count - 1) = 0; *(page + PAGE_SIZE - 1) = 0; diff -Nru a/drivers/net/wan/comx-proto-fr.c b/drivers/net/wan/comx-proto-fr.c --- a/drivers/net/wan/comx-proto-fr.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/wan/comx-proto-fr.c Mon Aug 18 22:21:02 2003 @@ -657,7 +657,10 @@ return -ENOMEM; } - copy_from_user(page, buffer, count); + if (copy_from_user(page, buffer, count)) { + free_page((unsigned long)page); + return -EFAULT; + } if (*(page + count - 1) == '\n') { *(page + count - 1) = 0; } diff -Nru a/drivers/net/wan/comx-proto-lapb.c b/drivers/net/wan/comx-proto-lapb.c --- a/drivers/net/wan/comx-proto-lapb.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/wan/comx-proto-lapb.c Mon Aug 18 22:21:01 2003 @@ -232,7 +232,10 @@ return -ENOMEM; } - copy_from_user(page, buffer, count); + if (copy_from_user(page, buffer, count)) { + free_page((unsigned long)page); + return -EFAULT; + } if (*(page + count - 1) == '\n') { *(page + count - 1) = 0; } diff -Nru a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c --- a/drivers/net/wan/lapbether.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/wan/lapbether.c Mon Aug 18 22:21:02 2003 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -52,50 +51,27 @@ struct lapbethdev { struct list_head node; - char ethname[14]; /* ether device name */ struct net_device *ethdev; /* link to ethernet device */ - struct net_device axdev; /* lapbeth device (lapb#) */ + struct net_device *axdev; /* lapbeth device (lapb#) */ struct net_device_stats stats; /* some statistics */ - atomic_t refcnt; }; static struct list_head lapbeth_devices = LIST_HEAD_INIT(lapbeth_devices); -static rwlock_t lapbeth_devices_lock = RW_LOCK_UNLOCKED; -static __inline__ void lapbeth_hold(struct lapbethdev *lapbeth) -{ - atomic_inc(&lapbeth->refcnt); -} - -static __inline__ void lapbeth_put(struct lapbethdev *lapbeth) -{ - if (atomic_dec_and_test(&lapbeth->refcnt)) - kfree(lapbeth); -} /* ------------------------------------------------------------------------ */ /* * Get the LAPB device for the ethernet device */ -static __inline__ struct lapbethdev *lapbeth_get_x25_dev(struct net_device *dev) +static struct lapbethdev *lapbeth_get_x25_dev(struct net_device *dev) { - struct list_head *entry; - struct lapbethdev *lapbeth, *use = NULL; - - read_lock(&lapbeth_devices_lock); + struct lapbethdev *lapbeth; - list_for_each(entry, &lapbeth_devices) { - lapbeth = list_entry(entry, struct lapbethdev, node); - if (lapbeth->ethdev == dev) { - use = lapbeth; - break; - } + list_for_each_entry_rcu(lapbeth, &lapbeth_devices, node) { + if (lapbeth->ethdev == dev) + return lapbeth; } - if (use) - lapbeth_hold(use); - - read_unlock(&lapbeth_devices_lock); - return use; + return NULL; } static __inline__ int dev_is_ethdev(struct net_device *dev) @@ -103,36 +79,6 @@ return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5); } -/* - * Sanity check: remove all devices that ceased to exists and - * return '1' if the given LAPB device was affected. - */ -static int lapbeth_check_devices(struct net_device *dev) -{ - struct lapbethdev *lapbeth; - struct list_head *entry, *tmp; - int result = 0; - - write_lock(&lapbeth_devices_lock); - - list_for_each_safe(entry, tmp, &lapbeth_devices) { - lapbeth = list_entry(entry, struct lapbethdev, node); - - if (!dev_get(lapbeth->ethname)) { - if (&lapbeth->axdev == dev) - result = 1; - - unregister_netdev(&lapbeth->axdev); - dev_put(lapbeth->ethdev); - list_del(&lapbeth->node); - lapbeth_put(lapbeth); - } - } - write_unlock(&lapbeth_devices_lock); - - return result; -} - /* ------------------------------------------------------------------------ */ /* @@ -145,29 +91,28 @@ skb->sk = NULL; /* Initially we don't know who it's for */ + rcu_read_lock(); lapbeth = lapbeth_get_x25_dev(dev); - if (!lapbeth) goto drop; - if (!netif_running(&lapbeth->axdev)) - goto put_drop; + if (!netif_running(lapbeth->axdev)) + goto drop; lapbeth->stats.rx_packets++; len = skb->data[0] + skb->data[1] * 256; + lapbeth->stats.rx_bytes += len; skb_pull(skb, 2); /* Remove the length bytes */ skb_trim(skb, len); /* Set the length of the data */ if ((err = lapb_data_received(lapbeth, skb)) != LAPB_OK) { printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err); - goto put_drop; + goto drop; } - lapbeth_put(lapbeth); out: + rcu_read_unlock(); return 0; -put_drop: - lapbeth_put(lapbeth); drop: kfree_skb(skb); goto out; @@ -181,7 +126,7 @@ ptr = skb_push(skb, 1); *ptr = 0x00; - skb->dev = &lapbeth->axdev; + skb->dev = lapbeth->axdev; skb->protocol = htons(ETH_P_X25); skb->mac.raw = skb->data; skb->pkt_type = PACKET_HOST; @@ -203,7 +148,6 @@ * is down, the ethernet device may have gone. */ if (!netif_running(dev)) { - lapbeth_check_devices(dev); goto drop; } @@ -257,6 +201,7 @@ *ptr++ = size / 256; lapbeth->stats.tx_packets++; + lapbeth->stats.tx_bytes += size; skb->dev = dev = lapbeth->ethdev; @@ -279,7 +224,7 @@ ptr = skb_put(skb, 1); *ptr = 0x01; - skb->dev = &lapbeth->axdev; + skb->dev = lapbeth->axdev; skb->protocol = htons(ETH_P_X25); skb->mac.raw = skb->data; skb->pkt_type = PACKET_HOST; @@ -302,7 +247,7 @@ ptr = skb_put(skb, 1); *ptr = 0x02; - skb->dev = &lapbeth->axdev; + skb->dev = lapbeth->axdev; skb->protocol = htons(ETH_P_X25); skb->mac.raw = skb->data; skb->pkt_type = PACKET_HOST; @@ -330,27 +275,26 @@ return 0; } + +static struct lapb_register_struct lapbeth_callbacks = { + .connect_confirmation = lapbeth_connected, + .connect_indication = lapbeth_connected, + .disconnect_confirmation = lapbeth_disconnected, + .disconnect_indication = lapbeth_disconnected, + .data_indication = lapbeth_data_indication, + .data_transmit = lapbeth_data_transmit, + +}; + /* * open/close a device */ static int lapbeth_open(struct net_device *dev) { - struct lapb_register_struct lapbeth_callbacks; struct lapbethdev *lapbeth; int err; - if (lapbeth_check_devices(dev)) - return -ENODEV; /* oops, it's gone */ - lapbeth = (struct lapbethdev *)dev->priv; - - lapbeth_callbacks.connect_confirmation = lapbeth_connected; - lapbeth_callbacks.connect_indication = lapbeth_connected; - lapbeth_callbacks.disconnect_confirmation = lapbeth_disconnected; - lapbeth_callbacks.disconnect_indication = lapbeth_disconnected; - lapbeth_callbacks.data_indication = lapbeth_data_indication; - lapbeth_callbacks.data_transmit = lapbeth_data_transmit; - if ((err = lapb_register(lapbeth, &lapbeth_callbacks)) != LAPB_OK) { printk(KERN_ERR "lapbeth: lapb_register error - %d\n", err); return -ENODEV; @@ -375,65 +319,52 @@ /* ------------------------------------------------------------------------ */ +static void lapbeth_setup(struct net_device *dev) +{ + dev->hard_start_xmit = lapbeth_xmit; + dev->open = lapbeth_open; + dev->stop = lapbeth_close; + dev->destructor = (void (*)(struct net_device *))kfree; + dev->set_mac_address = lapbeth_set_mac_address; + dev->get_stats = lapbeth_get_stats; + dev->type = ARPHRD_X25; + dev->hard_header_len = 3; + dev->mtu = 1000; + dev->addr_len = 0; + SET_MODULE_OWNER(dev); +} + /* * Setup a new device. */ static int lapbeth_new_device(struct net_device *dev) { - unsigned char buf[14]; + struct net_device *ndev; struct lapbethdev *lapbeth; - int k, rc = -ENOMEM; + int rc = -ENOMEM; - if ((lapbeth = kmalloc(sizeof(struct lapbethdev), GFP_ATOMIC)) == NULL) + ASSERT_RTNL(); + + ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", + lapbeth_setup); + if (!ndev) goto out; - memset(lapbeth, 0, sizeof(struct lapbethdev)); + lapbeth = ndev->priv; + lapbeth->axdev = ndev; dev_hold(dev); lapbeth->ethdev = dev; - strncpy(lapbeth->ethname, dev->name, sizeof(lapbeth->ethname) - 1); - lapbeth->ethname[sizeof(lapbeth->ethname) - 1] = '\0'; - atomic_set(&lapbeth->refcnt, 1); - - dev = &lapbeth->axdev; - SET_MODULE_OWNER(dev); - - for (k = 0; k < MAXLAPBDEV; k++) { - struct net_device *odev; - - sprintf(buf, "lapb%d", k); - - if ((odev = __dev_get_by_name(buf)) == NULL || - lapbeth_check_devices(odev)) - break; - } - - rc = -ENODEV; - if (k == MAXLAPBDEV) + rc = dev_alloc_name(ndev, ndev->name); + if (rc < 0) goto fail; - dev->priv = (void *)lapbeth; /* pointer back */ - strcpy(dev->name, buf); - rc = -EIO; - if (register_netdev(dev)) + if (register_netdevice(ndev)) goto fail; - dev->hard_start_xmit = lapbeth_xmit; - dev->open = lapbeth_open; - dev->stop = lapbeth_close; - dev->set_mac_address = lapbeth_set_mac_address; - dev->get_stats = lapbeth_get_stats; - dev->type = ARPHRD_X25; - dev->hard_header_len = 3; - dev->mtu = 1000; - dev->addr_len = 0; - - write_lock(&lapbeth_devices_lock); - list_add(&lapbeth->node, &lapbeth_devices); - lapbeth_hold(lapbeth); - write_unlock(&lapbeth_devices_lock); + list_add_rcu(&lapbeth->node, &lapbeth_devices); rc = 0; out: return rc; @@ -444,6 +375,16 @@ } /* + * Free a lapb network device. + */ +static void lapbeth_free_device(struct lapbethdev *lapbeth) +{ + dev_put(lapbeth->ethdev); + list_del_rcu(&lapbeth->node); + unregister_netdevice(lapbeth->axdev); +} + +/* * Handle device status changes. */ static int lapbeth_device_event(struct notifier_block *this, @@ -455,30 +396,27 @@ if (!dev_is_ethdev(dev)) return NOTIFY_DONE; - lapbeth_check_devices(NULL); - + rcu_read_lock(); switch (event) { case NETDEV_UP: - /* - * New ethernet device -> new LAPB interface - */ - lapbeth = lapbeth_get_x25_dev(dev); - - if (lapbeth) - lapbeth_put(lapbeth); - else + /* New ethernet device -> new LAPB interface */ + if (lapbeth_get_x25_dev(dev) == NULL) lapbeth_new_device(dev); break; - case NETDEV_GOING_DOWN: - case NETDEV_DOWN: /* ethernet device closed -> close LAPB interface */ + case NETDEV_DOWN: + /* ethernet device closed -> close LAPB interface */ lapbeth = lapbeth_get_x25_dev(dev); - - if (lapbeth) { - dev_close(lapbeth->ethdev); - lapbeth_put(lapbeth); - } + if (lapbeth) + dev_close(lapbeth->axdev); + break; + case NETDEV_UNREGISTER: + /* ethernet device disappears -> remove LAPB interface */ + lapbeth = lapbeth_get_x25_dev(dev); + if (lapbeth) + lapbeth_free_device(lapbeth); break; } + rcu_read_unlock(); return NOTIFY_DONE; } @@ -506,15 +444,13 @@ printk(banner); - read_lock_bh(&dev_base_lock); + rtnl_lock(); for (dev = dev_base; dev; dev = dev->next) { if (dev_is_ethdev(dev)) { - read_unlock_bh(&dev_base_lock); lapbeth_new_device(dev); - read_lock_bh(&dev_base_lock); } } - read_unlock_bh(&dev_base_lock); + rtnl_unlock(); return 0; } @@ -528,16 +464,13 @@ dev_remove_pack(&lapbeth_packet_type); unregister_netdevice_notifier(&lapbeth_dev_notifier); - write_lock(&lapbeth_devices_lock); - + rtnl_lock(); list_for_each_safe(entry, tmp, &lapbeth_devices) { lapbeth = list_entry(entry, struct lapbethdev, node); - unregister_netdev(&lapbeth->axdev); - list_del(&lapbeth->node); - lapbeth_put(lapbeth); - } - write_unlock(&lapbeth_devices_lock); + unregister_netdevice(lapbeth->axdev); + } + rtnl_unlock(); } module_exit(lapbeth_cleanup_driver); diff -Nru a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c --- a/drivers/net/wan/pc300_drv.c Mon Aug 18 22:21:06 2003 +++ b/drivers/net/wan/pc300_drv.c Mon Aug 18 22:21:06 2003 @@ -2623,7 +2623,8 @@ sizeof(struct net_device_stats)); if (card->hw.type == PC300_TE) memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); - copy_to_user(arg, &pc300stats, sizeof(pc300stats_t)); + if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t))) + return -EFAULT; } return 0; } diff -Nru a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c --- a/drivers/net/wan/sbni.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/wan/sbni.c Mon Aug 18 22:21:02 2003 @@ -1287,8 +1287,9 @@ error = verify_area( VERIFY_WRITE, ifr->ifr_data, sizeof(struct sbni_in_stats) ); if( !error ) - copy_to_user( ifr->ifr_data, &nl->in_stats, - sizeof(struct sbni_in_stats) ); + if (copy_to_user( ifr->ifr_data, &nl->in_stats, + sizeof(struct sbni_in_stats) )) + return -EFAULT; break; case SIOCDEVRESINSTATS : @@ -1307,7 +1308,8 @@ error = verify_area( VERIFY_WRITE, ifr->ifr_data, sizeof flags ); if( !error ) - copy_to_user( ifr->ifr_data, &flags, sizeof flags ); + if (copy_to_user( ifr->ifr_data, &flags, sizeof flags )) + return -EFAULT; break; case SIOCDEVSHWSTATE : @@ -1339,7 +1341,8 @@ sizeof slave_name )) != 0 ) return error; - copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ); + if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name )) + return -EFAULT; slave_dev = dev_get_by_name( slave_name ); if( !slave_dev || !(slave_dev->flags & IFF_UP) ) { printk( KERN_ERR "%s: trying to enslave non-active " diff -Nru a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c --- a/drivers/net/wan/z85230.c Mon Aug 18 22:21:00 2003 +++ b/drivers/net/wan/z85230.c Mon Aug 18 22:21:00 2003 @@ -890,12 +890,12 @@ if(c->mtu > PAGE_SIZE/2) return -EMSGSIZE; - c->rx_buf[0]=(void *)get_free_page(GFP_KERNEL|GFP_DMA); + c->rx_buf[0]=(void *)get_zeroed_page(GFP_KERNEL|GFP_DMA); if(c->rx_buf[0]==NULL) return -ENOBUFS; c->rx_buf[1]=c->rx_buf[0]+PAGE_SIZE/2; - c->tx_dma_buf[0]=(void *)get_free_page(GFP_KERNEL|GFP_DMA); + c->tx_dma_buf[0]=(void *)get_zeroed_page(GFP_KERNEL|GFP_DMA); if(c->tx_dma_buf[0]==NULL) { free_page((unsigned long)c->rx_buf[0]); @@ -1080,7 +1080,7 @@ if(c->mtu > PAGE_SIZE/2) return -EMSGSIZE; - c->tx_dma_buf[0]=(void *)get_free_page(GFP_KERNEL|GFP_DMA); + c->tx_dma_buf[0]=(void *)get_zeroed_page(GFP_KERNEL|GFP_DMA); if(c->tx_dma_buf[0]==NULL) return -ENOBUFS; diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig --- a/drivers/net/wireless/Kconfig Mon Aug 18 22:21:02 2003 +++ b/drivers/net/wireless/Kconfig Mon Aug 18 22:21:02 2003 @@ -284,6 +284,8 @@ config PCMCIA_ATMEL tristate "Atmel at76c502/at76c504 PCMCIA cards" depends on NET_RADIO && EXPERIMENTAL && PCMCIA + enable FW_LOADER + enable CRC32 ---help--- A driver for PCMCIA 802.11 wireless cards based on the Atmel fast-vnet chips. This driver supports standard diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Mon Aug 18 22:21:01 2003 +++ b/drivers/net/wireless/airo.c Mon Aug 18 22:21:01 2003 @@ -31,8 +31,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -959,8 +959,6 @@ static void enable_interrupts(struct airo_info*); static void disable_interrupts(struct airo_info*); static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp); -static u16 sendcommand(struct airo_info *ai, Cmd *pCmd); -static void completecommand(struct airo_info *ai, Resp *pRsp); static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap); static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); @@ -980,6 +978,8 @@ static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs *regs); +static int airo_thread(void *data); +static void timer_func( struct net_device *dev ); static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef WIRELESS_EXT struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); @@ -990,8 +990,8 @@ int flashcard(struct net_device *dev, aironet_ioctl *comp); #endif /* CISCO_EXT */ #ifdef MICSUPPORT -static void micinit(struct airo_info *ai, MICRid *micr); -static void micsetup(struct airo_info *ai); +static void micinit(struct airo_info *ai); +static int micsetup(struct airo_info *ai); static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); #endif @@ -1009,40 +1009,50 @@ int need_commit; // Need to set config char keyindex; // Used with auto wep char defindex; // Used with auto wep - struct timer_list timer; struct proc_dir_entry *proc_entry; struct airo_info *next; spinlock_t aux_lock; unsigned long flags; -#define FLAG_PROMISC IFF_PROMISC /* 0x100 - include/linux/if.h */ -#define FLAG_RADIO_OFF 0x02 /* User disabling of MAC */ -#define FLAG_RADIO_DOWN 0x08 /* ifup/ifdown disabling of MAC */ -#define FLAG_FLASHING 0x10 -#define FLAG_ADHOC 0x01 /* Needed by MIC */ -#define FLAG_MIC_CAPABLE 0x20 -#define FLAG_UPDATE_MULTI 0x40 -#define FLAG_UPDATE_UNI 0x80 -#define FLAG_802_11 0x200 -#define FLAG_PENDING_XMIT 0x400 -#define FLAG_PENDING_XMIT11 0x800 +#define FLAG_PROMISC 8 /* IFF_PROMISC 0x100 - include/linux/if.h */ +#define FLAG_RADIO_OFF 0 /* User disabling of MAC */ +#define FLAG_RADIO_DOWN 1 /* ifup/ifdown disabling of MAC */ +#define FLAG_RADIO_MASK 0x03 +#define FLAG_FLASHING 2 +#define FLAG_ADHOC 3 /* Needed by MIC */ +#define FLAG_MIC_CAPABLE 4 +#define FLAG_UPDATE_MULTI 5 +#define FLAG_UPDATE_UNI 6 +#define FLAG_802_11 7 +#define FLAG_PENDING_XMIT 9 +#define FLAG_PENDING_XMIT11 10 +#define FLAG_PCI 11 +#define JOB_MASK 0xff0000 +#define JOB_DIE 16 +#define JOB_XMIT 17 +#define JOB_XMIT11 18 +#define JOB_STATS 19 +#define JOB_PROMISC 20 +#define JOB_MIC 21 +#define JOB_EVENT 22 +#define JOB_AUTOWEP 23 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); unsigned short *flash; tdsRssiEntry *rssi; - struct semaphore sem; struct task_struct *task; - struct work_struct stats_task; - struct work_struct promisc_task; + struct semaphore sem; + pid_t thr_pid; + wait_queue_head_t thr_wait; + struct completion thr_exited; + unsigned long expires; struct { struct sk_buff *skb; int fid; - struct work_struct task; } xmit, xmit11; struct net_device *wifidev; #ifdef WIRELESS_EXT struct iw_statistics wstats; // wireless stats unsigned long scan_timestamp; /* Time started to scan */ - struct work_struct event_task; #if WIRELESS_EXT > 15 struct iw_spy_data spy_data; #else /* WIRELESS_EXT > 15 */ @@ -1056,7 +1066,6 @@ /* MIC stuff */ mic_module mod[2]; mic_statistics micstats; - struct work_struct mic_task; }; static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, @@ -1206,9 +1215,9 @@ cfgr = ai->config; if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS) - ai->flags |= FLAG_ADHOC; + set_bit(FLAG_ADHOC, &ai->flags); else - ai->flags &= ~FLAG_ADHOC; + clear_bit(FLAG_ADHOC, &ai->flags); for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s); @@ -1272,7 +1281,7 @@ struct airo_info *info = dev->priv; Resp rsp; - if (info->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &info->flags)) return -EIO; /* Make sure the card is configured. @@ -1286,7 +1295,7 @@ if (info->wifidev != dev) { /* Power on the MAC controller (which may have been disabled) */ - info->flags &= ~FLAG_RADIO_DOWN; + clear_bit(FLAG_RADIO_DOWN, &info->flags); enable_interrupts(info); } enable_MAC(info, &rsp, 1); @@ -1344,7 +1353,7 @@ } } -static void airo_do_xmit(struct net_device *dev) { +static void airo_end_xmit(struct net_device *dev) { u16 status; int i; struct airo_info *priv = dev->priv; @@ -1352,17 +1361,10 @@ int fid = priv->xmit.fid; u32 *fids = priv->fids; - if (down_trylock(&priv->sem) != 0) { - priv->flags |= FLAG_PENDING_XMIT; - netif_stop_queue(dev); - priv->xmit.task.func = (void (*)(void *))airo_do_xmit; - priv->xmit.task.data = (void *)dev; - schedule_work(&priv->xmit.task); - return; - } + clear_bit(JOB_XMIT, &priv->flags); + clear_bit(FLAG_PENDING_XMIT, &priv->flags); status = transmit_802_3_packet (priv, fids[fid], skb->data); up(&priv->sem); - priv->flags &= ~FLAG_PENDING_XMIT; i = 0; if ( status == SUCCESS ) { @@ -1406,11 +1408,17 @@ fids[i] |= (len << 16); priv->xmit.skb = skb; priv->xmit.fid = i; - airo_do_xmit(dev); + if (down_trylock(&priv->sem) != 0) { + set_bit(FLAG_PENDING_XMIT, &priv->flags); + netif_stop_queue(dev); + set_bit(JOB_XMIT, &priv->flags); + wake_up_interruptible(&priv->thr_wait); + } else + airo_end_xmit(dev); return 0; } -static void airo_do_xmit11(struct net_device *dev) { +static void airo_end_xmit11(struct net_device *dev) { u16 status; int i; struct airo_info *priv = dev->priv; @@ -1418,17 +1426,10 @@ int fid = priv->xmit11.fid; u32 *fids = priv->fids; - if (down_trylock(&priv->sem) != 0) { - priv->flags |= FLAG_PENDING_XMIT11; - netif_stop_queue(dev); - priv->xmit11.task.func = (void (*)(void *))airo_do_xmit11; - priv->xmit11.task.data = (void *)dev; - schedule_work(&priv->xmit11.task); - return; - } + clear_bit(JOB_XMIT11, &priv->flags); + clear_bit(FLAG_PENDING_XMIT11, &priv->flags); status = transmit_802_11_packet (priv, fids[fid], skb->data); up(&priv->sem); - priv->flags &= ~FLAG_PENDING_XMIT11; i = MAX_FIDS / 2; if ( status == SUCCESS ) { @@ -1472,7 +1473,13 @@ fids[i] |= (len << 16); priv->xmit11.skb = skb; priv->xmit11.fid = i; - airo_do_xmit11(dev); + if (down_trylock(&priv->sem) != 0) { + set_bit(FLAG_PENDING_XMIT11, &priv->flags); + netif_stop_queue(dev); + set_bit(JOB_XMIT11, &priv->flags); + wake_up_interruptible(&priv->thr_wait); + } else + airo_end_xmit11(dev); return 0; } @@ -1480,29 +1487,24 @@ StatsRid stats_rid; u32 *vals = stats_rid.vals; - if (down_trylock(&ai->sem) == 0) { - readStatsRid(ai, &stats_rid, RID_STATS, 0); - up(&ai->sem); + clear_bit(JOB_STATS, &ai->flags); + readStatsRid(ai, &stats_rid, RID_STATS, 0); + up(&ai->sem); - ai->stats.rx_packets = vals[43] + vals[44] + vals[45]; - ai->stats.tx_packets = vals[39] + vals[40] + vals[41]; - ai->stats.rx_bytes = vals[92]; - ai->stats.tx_bytes = vals[91]; - ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; - ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors; - ai->stats.multicast = vals[43]; - ai->stats.collisions = vals[89]; - - /* detailed rx_errors: */ - ai->stats.rx_length_errors = vals[3]; - ai->stats.rx_crc_errors = vals[4]; - ai->stats.rx_frame_errors = vals[2]; - ai->stats.rx_fifo_errors = vals[0]; - } else { - ai->stats_task.func = (void (*)(void *))airo_read_stats; - ai->stats_task.data = (void *)ai; - schedule_work(&ai->stats_task); - } + ai->stats.rx_packets = vals[43] + vals[44] + vals[45]; + ai->stats.tx_packets = vals[39] + vals[40] + vals[41]; + ai->stats.rx_bytes = vals[92]; + ai->stats.tx_bytes = vals[91]; + ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; + ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors; + ai->stats.multicast = vals[43]; + ai->stats.collisions = vals[89]; + + /* detailed rx_errors: */ + ai->stats.rx_length_errors = vals[3]; + ai->stats.rx_crc_errors = vals[4]; + ai->stats.rx_frame_errors = vals[2]; + ai->stats.rx_fifo_errors = vals[0]; } struct net_device_stats *airo_get_stats(struct net_device *dev) @@ -1510,46 +1512,37 @@ struct airo_info *local = dev->priv; /* Get stats out of the card if available */ - airo_read_stats(local); + if (down_trylock(&local->sem) != 0) { + set_bit(JOB_STATS, &local->flags); + wake_up_interruptible(&local->thr_wait); + } else + airo_read_stats(local); return &local->stats; } -static void airo_end_promisc(struct airo_info *ai) { - Resp rsp; - - if ((IN4500(ai, EVSTAT) & EV_CMD) != 0) { - completecommand(ai, &rsp); - up(&ai->sem); - } else { - ai->promisc_task.func = (void (*)(void *))airo_end_promisc; - ai->promisc_task.data = (void *)ai; - schedule_work(&ai->promisc_task); - } -} - static void airo_set_promisc(struct airo_info *ai) { Cmd cmd; + Resp rsp; - if (down_trylock(&ai->sem) == 0) { - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd=CMD_SETMODE; - cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; - sendcommand(ai, &cmd); - airo_end_promisc(ai); - } else { - ai->promisc_task.func = (void (*)(void *))airo_set_promisc; - ai->promisc_task.data = (void *)ai; - schedule_work(&ai->promisc_task); - } + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd=CMD_SETMODE; + clear_bit(JOB_PROMISC, &ai->flags); + cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; + issuecommand(ai, &cmd, &rsp); + up(&ai->sem); } static void airo_set_multicast_list(struct net_device *dev) { struct airo_info *ai = dev->priv; if ((dev->flags ^ ai->flags) & IFF_PROMISC) { - ai->flags ^= IFF_PROMISC; - airo_set_promisc(ai); + change_bit(FLAG_PROMISC, &ai->flags); + if (down_trylock(&ai->sem) != 0) { + set_bit(JOB_PROMISC, &ai->flags); + wake_up_interruptible(&ai->thr_wait); + } else + airo_set_promisc(ai); } if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) { @@ -1595,7 +1588,7 @@ * That's the method that is most friendly towards the network * stack (i.e. the network stack won't try to broadcast * anything on the interface and routes are gone. Jean II */ - ai->flags |= FLAG_RADIO_DOWN; + set_bit(FLAG_RADIO_DOWN, &ai->flags); disable_MAC(ai, 1); #endif disable_interrupts( ai ); @@ -1610,8 +1603,6 @@ struct airo_info *ai = dev->priv; disable_interrupts(ai); free_irq( dev->irq, dev ); - if (auto_wep) - del_timer_sync(&ai->timer); takedown_proc_entry( dev, ai ); if (ai->registered) { unregister_netdev( dev ); @@ -1622,7 +1613,9 @@ } ai->registered = 0; } - flush_scheduled_work(); + set_bit(JOB_DIE, &ai->flags); + kill_proc(ai->thr_pid, SIGTERM, 1); + wait_for_completion(&ai->thr_exited); if (ai->flash) kfree(ai->flash); if (ai->rssi) @@ -1727,9 +1720,14 @@ sema_init(&ai->sem, 1); ai->need_commit = 0; ai->config.len = 0; + init_waitqueue_head (&ai->thr_wait); + init_completion (&ai->thr_exited); + ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); + if (ai->thr_pid < 0) + goto err_out_free; rc = add_airo_dev( dev ); if (rc) - goto err_out_free; + goto err_out_thr; /* The Airo-specific entries in the device structure. */ dev->hard_start_xmit = &airo_start_xmit; @@ -1769,7 +1767,7 @@ } } else { ai->bap_read = fast_bap_read; - ai->flags |= FLAG_FLASHING; + set_bit(FLAG_FLASHING, &ai->flags); } rc = register_netdev(dev); @@ -1800,6 +1798,10 @@ free_irq(dev->irq, dev); err_out_unlink: del_airo_dev(dev); +err_out_thr: + set_bit(JOB_DIE, &ai->flags); + kill_proc(ai->thr_pid, SIGTERM, 1); + wait_for_completion(&ai->thr_exited); err_out_free: kfree(dev); return NULL; @@ -1863,38 +1865,102 @@ union iwreq_data wrqu; StatusRid status_rid; - if (down_trylock(&ai->sem) == 0) { - PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); - up(&ai->sem); - wrqu.data.length = 0; - wrqu.data.flags = 0; - memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; + clear_bit(JOB_EVENT, &ai->flags); + PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); + up(&ai->sem); + wrqu.data.length = 0; + wrqu.data.flags = 0; + memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; - /* Send event to user space */ - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - } else { - ai->event_task.func = (void (*)(void *))airo_send_event; - ai->event_task.data = (void *)dev; - schedule_work(&ai->event_task); - } + /* Send event to user space */ + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); } #endif -static void airo_read_mic(struct airo_info *ai) { - MICRid mic_rid; +static int airo_thread(void *data) { + struct net_device *dev = data; + struct airo_info *ai = dev->priv; + int locked; + + daemonize("%s", dev->name); + allow_signal(SIGTERM); + + while(1) { + if (signal_pending(current)) + flush_signals(current); + + /* make swsusp happy with our thread */ + if (current->flags & PF_FREEZE) + refrigerator(PF_IOTHREAD); - if (down_trylock(&ai->sem) == 0) { - PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); - up(&ai->sem); + if (test_bit(JOB_DIE, &ai->flags)) + break; + + if (ai->flags & JOB_MASK) { + locked = down_interruptible(&ai->sem); + } else { + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); + add_wait_queue(&ai->thr_wait, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (ai->flags & JOB_MASK) + break; + if (ai->expires) { + if (time_after_eq(jiffies,ai->expires)){ + set_bit(JOB_AUTOWEP,&ai->flags); + break; + } + if (!signal_pending(current)) { + schedule_timeout(ai->expires - jiffies); + continue; + } + } else if (!signal_pending(current)) { + schedule(); + continue; + } + break; + } + current->state = TASK_RUNNING; + remove_wait_queue(&ai->thr_wait, &wait); + locked = 1; + } + + if (locked) + continue; + + if (test_bit(JOB_DIE, &ai->flags)) { + up(&ai->sem); + break; + } + + if (test_bit(FLAG_FLASHING, &ai->flags)) { + up(&ai->sem); + continue; + } + + if (test_bit(JOB_XMIT, &ai->flags)) + airo_end_xmit(dev); + else if (test_bit(JOB_XMIT11, &ai->flags)) + airo_end_xmit11(dev); + else if (test_bit(JOB_STATS, &ai->flags)) + airo_read_stats(ai); + else if (test_bit(JOB_PROMISC, &ai->flags)) + airo_set_promisc(ai); #ifdef MICSUPPORT - micinit (ai, &mic_rid); + else if (test_bit(JOB_MIC, &ai->flags)) + micinit(ai); #endif - } else { - ai->mic_task.func = (void (*)(void *))airo_read_mic; - ai->mic_task.data = (void *)ai; - schedule_work(&ai->mic_task); +#if WIRELESS_EXT > 13 + else if (test_bit(JOB_EVENT, &ai->flags)) + airo_send_event(dev); +#endif + else if (test_bit(JOB_AUTOWEP, &ai->flags)) + timer_func(dev); } + complete_and_exit (&ai->thr_exited, 0); } static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { @@ -1926,8 +1992,15 @@ if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); - if (apriv->flags & FLAG_MIC_CAPABLE) - airo_read_mic( apriv ); +#ifdef MICSUPPORT + if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { + if (down_trylock(&apriv->sem) != 0) { + set_bit(JOB_MIC, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); + } else + micinit (apriv); + } +#endif } if ( status & EV_LINK ) { #if WIRELESS_EXT > 13 @@ -1969,15 +2042,18 @@ #define RC_NOAUTH 9 /* Station requesting (Re)Association is not Authenticated with the responding station */ if (newStatus != ASSOCIATED) { - if (auto_wep && !timer_pending(&apriv->timer)) { - apriv->timer.expires = RUN_AT(HZ*3); - add_timer(&apriv->timer); + if (auto_wep && !apriv->expires) { + apriv->expires = RUN_AT(3*HZ); + wake_up_interruptible(&apriv->thr_wait); } } else { struct task_struct *task = apriv->task; + if (auto_wep) + apriv->expires = 0; if (task) wake_up_process (task); - apriv->flags|=FLAG_UPDATE_UNI|FLAG_UPDATE_MULTI; + set_bit(FLAG_UPDATE_UNI, &apriv->flags); + set_bit(FLAG_UPDATE_MULTI, &apriv->flags); } #if WIRELESS_EXT > 13 /* Question : is ASSOCIATED the only status @@ -1998,7 +2074,11 @@ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); apriv->scan_timestamp = 0; } - airo_send_event(dev); + if (down_trylock(&apriv->sem) != 0) { + set_bit(JOB_EVENT, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); + } else + airo_send_event(dev); } else { memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -2029,7 +2109,7 @@ fid = IN4500( apriv, RXFID ); /* Get the packet length */ - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { bap_setup (apriv, fid, 4, BAP0); bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0); /* Bad CRC. Ignore packet */ @@ -2048,7 +2128,7 @@ len = 0; } if (len) { - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0); fc = le16_to_cpu(fc); switch (fc & 0xc) { @@ -2077,7 +2157,7 @@ } if (len) { buffer = (u16*)skb_put (skb, len + hdrlen); - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { buffer[0] = fc; bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); if (hdrlen == 24) @@ -2124,11 +2204,12 @@ char *sa; struct iw_quality wstats; /* Prepare spy data : addr + qual */ - sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6); - if (!(apriv->flags & FLAG_802_11)) { + if (!test_bit(FLAG_802_11, &apriv->flags)) { + sa = (char*)buffer + 6; bap_setup (apriv, fid, 8, BAP0); bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); - } + } else + sa = (char*)buffer + 10; wstats.qual = hdr.rssi[0]; if (apriv->rssi) wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; @@ -2145,12 +2226,12 @@ int i; char *sa; - sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6); + sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6); for (i=0; ispy_number; i++) if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN)) { - if (!(apriv->flags & FLAG_802_11)) { + if (!test_bit(FLAG_802_11, &apriv->flags)) { bap_setup (apriv, fid, 8, BAP0); bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); } @@ -2168,7 +2249,7 @@ #endif /* WIRELESS_EXT > 15 */ OUT4500( apriv, EVACK, EV_RX); - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { skb->mac.raw = skb->data; skb->pkt_type = PACKET_OTHERHOST; skb->dev = apriv->wifidev; @@ -2206,10 +2287,10 @@ /* Set up to be used again */ apriv->fids[index] &= 0xffff; if (index < MAX_FIDS / 2) { - if (!(apriv->flags & FLAG_PENDING_XMIT)) + if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags)) netif_wake_queue(dev); } else { - if (!(apriv->flags & FLAG_PENDING_XMIT11)) + if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags)) netif_wake_queue(apriv->wifidev); } } else { @@ -2269,7 +2350,7 @@ * instead of this flag, but I don't trust it *within* the * open/close functions, and testing both flags together is * "cheaper" - Jean II */ - if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS; + if (ai->flags & FLAG_RADIO_MASK) return SUCCESS; memset(&cmd, 0, sizeof(cmd)); cmd.cmd = MAC_ENABLE; if (!lock) @@ -2390,10 +2471,10 @@ ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS; #ifdef MICSUPPORT - if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1)) { + if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) && + (micsetup(ai) == SUCCESS)) { ai->config.opmode |= MODE_MIC; - ai->flags |= FLAG_MIC_CAPABLE; - micsetup(ai); + set_bit(FLAG_MIC_CAPABLE, &ai->flags); } #endif @@ -2459,34 +2540,15 @@ rc = readWepKeyRid(ai, &wkr, 0); } while(lastindex != wkr.kindex); - if (auto_wep && !timer_pending(&ai->timer)) { - ai->timer.expires = RUN_AT(HZ*3); - add_timer(&ai->timer); + if (auto_wep) { + ai->expires = RUN_AT(3*HZ); + wake_up_interruptible(&ai->thr_wait); } - return SUCCESS; -} -static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { - // Im really paranoid about letting it run forever! - int max_tries = 600000; - - if (sendcommand(ai, pCmd) == (u16)ERROR) - return ERROR; - - while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) { - if (!in_interrupt() && (max_tries & 255) == 0) - schedule(); - } - if ( max_tries == -1 ) { - printk( KERN_ERR - "airo: Max tries exceeded waiting for command\n" ); - return ERROR; - } - completecommand(ai, pRsp); return SUCCESS; } -static u16 sendcommand(struct airo_info *ai, Cmd *pCmd) { +static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { // Im really paranoid about letting it run forever! int max_tries = 600000; u16 cmd; @@ -2505,10 +2567,16 @@ "airo: Max tries exceeded when issueing command\n" ); return ERROR; } - return SUCCESS; -} -static void completecommand(struct airo_info *ai, Resp *pRsp) { + while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) { + if (!in_atomic() && (max_tries & 255) == 0) + schedule(); + } + if ( max_tries == -1 ) { + printk( KERN_ERR + "airo: Max tries exceeded waiting for command\n" ); + return ERROR; + } // command completed pRsp->status = IN4500(ai, STATUS); pRsp->rsp0 = IN4500(ai, RESP0); @@ -2521,6 +2589,8 @@ } // acknowledge processing the status/response OUT4500(ai, EVACK, EV_CMD); + + return SUCCESS; } /* Sets up the bap to start exchange data. whichbap should @@ -2807,7 +2877,7 @@ len -= ETH_ALEN * 2; #ifdef MICSUPPORT - if ((ai->flags & FLAG_MIC_CAPABLE) && ai->micstats.enabled && + if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && (ntohs(((u16 *)pPacket)[6]) != 0x888E)) { if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS) return ERROR; @@ -3315,7 +3385,7 @@ if ((ai->config.rmode & 0xff) >= RXMODE_RFMON) ai->need_commit = 2; ai->config.rmode &= 0xfe00; - ai->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &ai->flags); ai->config.opmode &= 0xFF00; ai->config.scanMode = SCANMODE_ACTIVE; if ( line[0] == 'a' ) { @@ -3325,11 +3395,11 @@ if ( line[0] == 'r' ) { ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; ai->config.scanMode = SCANMODE_PASSIVE; - ai->flags |= FLAG_802_11; + set_bit (FLAG_802_11, &ai->flags); } else if ( line[0] == 'y' ) { ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER; ai->config.scanMode = SCANMODE_PASSIVE; - ai->flags |= FLAG_802_11; + set_bit (FLAG_802_11, &ai->flags); } else if ( line[0] == 'l' ) ai->config.rmode |= RXMODE_LANMON; } @@ -3340,9 +3410,9 @@ else if (!strncmp(line,"Radio: ", 7)) { line += 7; if (!strncmp(line,"off",3)) { - ai->flags |= FLAG_RADIO_OFF; + set_bit (FLAG_RADIO_OFF, &ai->flags); } else { - ai->flags &= ~FLAG_RADIO_OFF; + clear_bit (FLAG_RADIO_OFF, &ai->flags); } } /*** NodeName processing */ @@ -3544,7 +3614,7 @@ (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode): (ai->config.opmode & 0xFF) == 2 ? "AP" : (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error", - ai->flags&FLAG_RADIO_OFF ? "off" : "on", + test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on", ai->config.nodeName, ai->config.powerSaveMode == 0 ? "CAM" : ai->config.powerSaveMode == 1 ? "PSP" : @@ -4002,23 +4072,14 @@ will switch WEP modes to see if that will help. If the card is associated we will check every minute to see if anything has changed. */ -static void timer_func( u_long data ) { - struct net_device *dev = (struct net_device*)data; +static void timer_func( struct net_device *dev ) { struct airo_info *apriv = dev->priv; - u16 linkstat = IN4500(apriv, LINKSTAT); Resp rsp; - if (!(apriv->flags & FLAG_FLASHING) && (linkstat != 0x400)) { /* We don't have a link so try changing the authtype */ - if (down_trylock(&apriv->sem) != 0) { - apriv->timer.expires = RUN_AT(1); - add_timer(&apriv->timer); - return; - } - - readConfigRid(apriv, 0); - disable_MAC(apriv, 0); - switch(apriv->config.authType) { + readConfigRid(apriv, 0); + disable_MAC(apriv, 0); + switch(apriv->config.authType) { case AUTH_ENCRYPT: /* So drop to OPEN */ apriv->config.authType = AUTH_OPEN; @@ -4037,16 +4098,15 @@ break; default: /* We'll escalate to SHAREDKEY */ apriv->config.authType = AUTH_SHAREDKEY; - } - apriv->need_commit = 1; - writeConfigRid(apriv, 0); - enable_MAC(apriv, &rsp, 0); - up(&apriv->sem); + } + apriv->need_commit = 1; + writeConfigRid(apriv, 0); + enable_MAC(apriv, &rsp, 0); + up(&apriv->sem); /* Schedule check to see if the change worked */ - apriv->timer.expires = RUN_AT(HZ*3); - add_timer(&apriv->timer); - } + clear_bit(JOB_AUTOWEP, &apriv->flags); + apriv->expires = RUN_AT(HZ*3); } static int add_airo_dev( struct net_device *dev ) { @@ -4054,15 +4114,6 @@ if ( !node ) return -ENOMEM; - if ( auto_wep ) { - struct airo_info *apriv=dev->priv; - struct timer_list *timer = &apriv->timer; - - timer->function = timer_func; - timer->data = (u_long)dev; - init_timer(timer); - } - node->dev = dev; node->next = airo_devices; airo_devices = node; @@ -4093,6 +4144,7 @@ return -ENODEV; pci_set_drvdata(pdev, dev); + clear_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags); return 0; } @@ -4134,11 +4186,19 @@ static void __exit airo_cleanup_module( void ) { + int is_pci = 0; while( airo_devices ) { printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); +#ifdef CONFIG_PCI + if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags)) + is_pci = 1; +#endif stop_airo_card( airo_devices->dev, 1 ); } remove_proc_entry("aironet", proc_root_driver); + + if (is_pci) + pci_unregister_driver(&airo_driver); } #ifdef WIRELESS_EXT @@ -4604,28 +4664,28 @@ local->config.opmode |= MODE_STA_IBSS; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_INFRA: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_STA_ESS; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_MASTER: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_REPEAT: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP_RPTR; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_MONITOR: local->config.opmode &= 0xFF00; @@ -4633,7 +4693,7 @@ local->config.rmode &= 0xfe00; local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; local->config.scanMode = SCANMODE_PASSIVE; - local->flags |= FLAG_802_11; + set_bit (FLAG_802_11, &local->flags); break; default: return -EINVAL; @@ -4822,14 +4882,14 @@ readCapabilityRid(local, &cap_rid); if (vwrq->disabled) { - local->flags |= FLAG_RADIO_OFF; + set_bit (FLAG_RADIO_OFF, &local->flags); local->need_commit = 1; return -EINPROGRESS; /* Call commit handler */ } if (vwrq->flags != IW_TXPOW_MWATT) { return -EINVAL; } - local->flags &= ~FLAG_RADIO_OFF; + clear_bit (FLAG_RADIO_OFF, &local->flags); for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) if ((vwrq->value==cap_rid.txPowerLevels[i])) { local->config.txPower = vwrq->value; @@ -4853,7 +4913,7 @@ vwrq->value = local->config.txPower; vwrq->fixed = 1; /* No power control */ - vwrq->disabled = (local->flags & FLAG_RADIO_OFF); + vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags); vwrq->flags = IW_TXPOW_MWATT; return 0; @@ -5503,10 +5563,14 @@ writeSsidRid(local, &SSID_rid); writeAPListRid(local, &APList_rid); } - writeConfigRid(local, 1); - enable_MAC(local, &rsp, 1); + if (down_interruptible(&local->sem)) + return -ERESTARTSYS; + writeConfigRid(local, 0); + enable_MAC(local, &rsp, 0); if (local->need_commit > 1) airo_set_promisc(local); + else + up(&local->sem); return 0; } @@ -5612,7 +5676,7 @@ .standard = (iw_handler *) airo_handler, .private = (iw_handler *) airo_private_handler, .private_args = (struct iw_priv_args *) airo_private_args, -#if 0 && WIRELESS_EXT > 15 +#if WIRELESS_EXT > 15 .spy_offset = ((void *) (&((struct airo_info *) NULL)->spy_data) - (void *) NULL), #endif /* WIRELESS_EXT > 15 */ @@ -6045,7 +6109,7 @@ unsigned char *iobuf; struct airo_info *ai = dev->priv; - if (ai->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; switch(comp->command) @@ -6113,7 +6177,7 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (ai->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; ridcode = 0; @@ -6187,13 +6251,13 @@ if (comp->command == AIROPCFG) { ConfigRid *cfg = (ConfigRid *)iobuf; - if (ai->flags & FLAG_MIC_CAPABLE) + if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) cfg->opmode |= MODE_MIC; if ((cfg->opmode & 0xFF) == MODE_STA_IBSS) - ai->flags |= FLAG_ADHOC; + set_bit (FLAG_ADHOC, &ai->flags); else - ai->flags &= ~FLAG_ADHOC; + clear_bit (FLAG_ADHOC, &ai->flags); } if((*writer)(ai, ridcode, iobuf,comp->len,1)) { @@ -6304,7 +6368,7 @@ */ int setflashmode (struct airo_info *ai) { - ai->flags |= FLAG_FLASHING; + set_bit (FLAG_FLASHING, &ai->flags); OUT4500(ai, SWS0, FLASH_COMMAND); OUT4500(ai, SWS1, FLASH_COMMAND); @@ -6320,7 +6384,7 @@ schedule_timeout (HZ/2); /* 500ms delay */ if(!waitbusy(ai)) { - ai->flags &= ~FLAG_FLASHING; + clear_bit (FLAG_FLASHING, &ai->flags); printk(KERN_INFO "Waitbusy hang after setflash mode\n"); return -EIO; } @@ -6426,7 +6490,7 @@ set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (HZ); /* Added 12/7/00 */ - ai->flags &= ~FLAG_FLASHING; + clear_bit (FLAG_FLASHING, &ai->flags); status = setup_card(ai, dev->dev_addr); for( i = 0; i < MAX_FIDS; i++ ) { diff -Nru a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c --- a/drivers/net/wireless/atmel.c Mon Aug 18 22:21:02 2003 +++ b/drivers/net/wireless/atmel.c Mon Aug 18 22:21:02 2003 @@ -64,13 +64,11 @@ #include #include #include -#ifdef CONFIG_FW_LOADER #include -#endif #include "ieee802_11.h" #define DRIVER_MAJOR 0 -#define DRIVER_MINOR 7 +#define DRIVER_MINOR 8 MODULE_AUTHOR("Simon Kelley"); MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); @@ -2057,12 +2055,13 @@ range->num_channels = 0; for (j = 0; j < sizeof(channel_table)/sizeof(channel_table[0]); j++) if (priv->reg_domain == channel_table[j].reg_domain) { - range->num_channels = channel_table[j].max - channel_table[j].min + 1; + range->num_channels = channel_table[j].max - channel_table[j].min + 1; + break; } if (range->num_channels != 0) { for(k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) { - range->freq[k].i = i + 1; /* List index */ - range->freq[k].m = frequency_list[i] * 100000; + range->freq[k].i = i; /* List index */ + range->freq[k].m = frequency_list[i-1] * 100000; range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ } range->num_frequency = k; @@ -3337,13 +3336,10 @@ if (priv->card_type == CARD_TYPE_EEPROM) { /* copy in firmware if needed */ -#ifdef CONFIG_FW_LOADER const struct firmware *fw_entry = NULL; -#endif unsigned char *fw; int len = priv->firmware_length; if (!(fw = priv->firmware)) { -#ifdef CONFIG_FW_LOADER if (strlen(priv->firmware_id) == 0) { printk(KERN_INFO "%s: card type is unknown: assuming at76c502 firmware is OK.\n", @@ -3361,11 +3357,6 @@ } fw = fw_entry->data; len = fw_entry->size; -#else - printk(KERN_ALERT - "%s: no firmware supplied, cannot start.\n", dev->name); - return 0; -#endif } if (len <= 0x6000) { @@ -3381,10 +3372,8 @@ atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000); } -#ifdef CONFIG_FW_LOADER if (fw_entry) release_firmware(fw_entry); -#endif } if (!atmel_wakeup_firmware(priv)) diff -Nru a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c --- a/drivers/net/wireless/atmel_cs.c Mon Aug 18 22:21:03 2003 +++ b/drivers/net/wireless/atmel_cs.c Mon Aug 18 22:21:03 2003 @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -108,7 +107,7 @@ int reset_atmel_card( struct net_device * ); static void atmel_config(dev_link_t *link); -static void atmel_release(u_long arg); +static void atmel_release(dev_link_t *link); static int atmel_event(event_t event, int priority, event_callback_args_t *args); @@ -222,9 +221,6 @@ return NULL; } memset(link, 0, sizeof(struct dev_link_t)); - init_timer(&link->release); - link->release.function = &atmel_release; - link->release.data = (u_long)link; /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -300,9 +296,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if ( link->state & DEV_CONFIG ) { - atmel_release( (int)link ); + atmel_release(link); if ( link->state & DEV_STALE_CONFIG ) { link->state |= DEV_STALE_LINK; return; @@ -375,11 +370,11 @@ { 0, 0, "SMC/2632W", "atmel_at76c502d.bin", "SMC 2632W-V3" }, { 0xd601, 0x0007, NULL, "atmel_at76c502.bin", "Sitecom WLAN-011"}, /* suspect - from a usenet posting. */ { 0x01bf, 0x3302, NULL, "atmel_at76c502d.bin", "Belkin F5D6060u"}, /* " " " " " */ + { 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502.bin", "BT Voyager 1020"} }; /* This is strictly temporary, until PCMCIA devices get integrated into the device model. */ static struct device atmel_device = { - .name = "Atmel at76c50x wireless", .bus_id = "pcmcia", }; @@ -606,9 +601,8 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); - atmel_release((u_long)link); - -} /* atmel_config */ + atmel_release(link); +} /*====================================================================== @@ -618,9 +612,8 @@ ======================================================================*/ -static void atmel_release(u_long arg) +static void atmel_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; DEBUG(0, "atmel_release(0x%p)\n", link); @@ -639,8 +632,7 @@ if (link->irq.AssignedIRQ) CardServices(ReleaseIRQ, link->handle, &link->irq); link->state &= ~DEV_CONFIG; - -} /* atmel_release */ +} /*====================================================================== @@ -667,7 +659,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { netif_device_detach(local->eth_dev); - mod_timer(&link->release, jiffies + HZ/20); + atmel_release(link); } break; case CS_EVENT_CARD_INSERTION: @@ -719,7 +711,7 @@ /* XXX: this really needs to move into generic code.. */ while (dev_list != NULL) { if (dev_list->state & DEV_CONFIG) - atmel_release((u_long)dev_list); + atmel_release(dev_list); atmel_detach(dev_list); } } diff -Nru a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c --- a/drivers/parport/parport_cs.c Mon Aug 18 22:21:06 2003 +++ b/drivers/parport/parport_cs.c Mon Aug 18 22:21:06 2003 @@ -96,7 +96,7 @@ static dev_link_t *parport_attach(void); static void parport_detach(dev_link_t *); static void parport_config(dev_link_t *link); -static void parport_cs_release(u_long arg); +static void parport_cs_release(dev_link_t *); static int parport_event(event_t event, int priority, event_callback_args_t *args); @@ -126,9 +126,6 @@ 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; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -186,9 +183,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); if (link->state & DEV_CONFIG) - parport_cs_release((u_long)link); + parport_cs_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -308,7 +304,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); failed: - parport_cs_release((u_long)link); + parport_cs_release(link); link->state &= ~DEV_CONFIG_PENDING; } /* parport_config */ @@ -321,9 +317,8 @@ ======================================================================*/ -void parport_cs_release(u_long arg) +void parport_cs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; parport_info_t *info = link->priv; DEBUG(0, "parport_release(0x%p)\n", link); @@ -366,7 +361,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + parport_cs_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c --- a/drivers/pci/pci-sysfs.c Mon Aug 18 22:21:03 2003 +++ b/drivers/pci/pci-sysfs.c Mon Aug 18 22:21:03 2003 @@ -67,6 +67,7 @@ { struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); unsigned int size = 64; + loff_t init_off = off; /* Several chips lock up trying to read undefined config space */ if (capable(CAP_SYS_ADMIN)) { @@ -87,7 +88,7 @@ while (off & 3) { unsigned char val; pci_read_config_byte(dev, off, &val); - buf[off] = val; + buf[off - init_off] = val; off++; if (--size == 0) break; @@ -96,10 +97,10 @@ while (size > 3) { unsigned int val; pci_read_config_dword(dev, off, &val); - buf[off] = val & 0xff; - buf[off + 1] = (val >> 8) & 0xff; - buf[off + 2] = (val >> 16) & 0xff; - buf[off + 3] = (val >> 24) & 0xff; + buf[off - init_off] = val & 0xff; + buf[off - init_off + 1] = (val >> 8) & 0xff; + buf[off - init_off + 2] = (val >> 16) & 0xff; + buf[off - init_off + 3] = (val >> 24) & 0xff; off += 4; size -= 4; } @@ -107,7 +108,7 @@ while (size > 0) { unsigned char val; pci_read_config_byte(dev, off, &val); - buf[off] = val; + buf[off - init_off] = val; off++; --size; } @@ -120,6 +121,7 @@ { struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); unsigned int size = count; + loff_t init_off = off; if (off > 256) return 0; @@ -129,24 +131,24 @@ } while (off & 3) { - pci_write_config_byte(dev, off, buf[off]); + pci_write_config_byte(dev, off, buf[off - init_off]); off++; if (--size == 0) break; } while (size > 3) { - unsigned int val = buf[off]; - val |= (unsigned int) buf[off + 1] << 8; - val |= (unsigned int) buf[off + 2] << 16; - val |= (unsigned int) buf[off + 3] << 24; + unsigned int val = buf[off - init_off]; + val |= (unsigned int) buf[off - init_off + 1] << 8; + val |= (unsigned int) buf[off - init_off + 2] << 16; + val |= (unsigned int) buf[off - init_off + 3] << 24; pci_write_config_dword(dev, off, val); off += 4; size -= 4; } while (size > 0) { - pci_write_config_byte(dev, off, buf[off]); + pci_write_config_byte(dev, off, buf[off - init_off]); off++; --size; } diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c --- a/drivers/pci/quirks.c Mon Aug 18 22:21:00 2003 +++ b/drivers/pci/quirks.c Mon Aug 18 22:21:00 2003 @@ -822,7 +822,7 @@ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_IGP, quirk_ati_exploding_mce }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_exploding_mce }, /* * i82380FB mobile docking controller: its PCI-to-PCI bridge * is subtractive decoding (transparent), and does indicate this diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c --- a/drivers/pci/setup-bus.c Mon Aug 18 22:21:06 2003 +++ b/drivers/pci/setup-bus.c Mon Aug 18 22:21:06 2003 @@ -203,6 +203,11 @@ Enable ISA in either case (FIXME!). */ l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04; pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l); + + /* Make sure the bridge COMMAND register has the appropriate + bits set, just in case... + */ + pcibios_enable_device(bridge, 0xfff); } /* Check whether the bridge supports optional I/O and diff -Nru a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c --- a/drivers/pci/setup-res.c Mon Aug 18 22:21:05 2003 +++ b/drivers/pci/setup-res.c Mon Aug 18 22:21:05 2003 @@ -42,9 +42,10 @@ pcibios_resource_to_bus(dev, ®ion, res); - DBGC((KERN_ERR " got res [%lx:%lx] bus [%lx:%lx] for " - "resource %d of %s\n", res->start, res->end, - region.start, region.end, resno, dev->dev.name)); + DBGC((KERN_ERR " got res [%lx:%lx] bus [%lx:%lx] flags %lx for " + "BAR %d of %s\n", res->start, res->end, + region.start, region.end, res->flags, + resno, dev->dev.name)); new = region.start | (res->flags & PCI_REGION_FLAG_MASK); if (res->flags & IORESOURCE_IO) diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c --- a/drivers/pcmcia/ds.c Mon Aug 18 22:21:05 2003 +++ b/drivers/pcmcia/ds.c Mon Aug 18 22:21:05 2003 @@ -689,7 +689,7 @@ err = ret = 0; - if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size); + if (cmd & IOC_IN) __copy_from_user((char *)&buf, (char *)arg, size); switch (cmd) { case DS_ADJUST_RESOURCE_INFO: @@ -803,9 +803,9 @@ err = -EIO; break; } } - - if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size); - + + if (cmd & IOC_OUT) __copy_to_user((char *)arg, (char *)&buf, size); + return err; } /* ds_ioctl */ diff -Nru a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c --- a/drivers/pcmcia/i82365.c Mon Aug 18 22:21:05 2003 +++ b/drivers/pcmcia/i82365.c Mon Aug 18 22:21:05 2003 @@ -1361,9 +1361,6 @@ static struct platform_device i82365_device = { .name = "i82365", .id = 0, - .dev = { - .name = "i82365", - }, }; static int __init init_i82365(void) diff -Nru a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c --- a/drivers/pcmcia/tcic.c Mon Aug 18 22:21:04 2003 +++ b/drivers/pcmcia/tcic.c Mon Aug 18 22:21:04 2003 @@ -372,9 +372,6 @@ static struct platform_device tcic_device = { .name = "tcic-pcmcia", .id = 0, - .dev = { - .name = "tcic-pcmcia", - }, }; diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c --- a/drivers/pcmcia/yenta_socket.c Mon Aug 18 22:21:04 2003 +++ b/drivers/pcmcia/yenta_socket.c Mon Aug 18 22:21:04 2003 @@ -899,7 +899,7 @@ /* We must finish initialization here */ - if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) { + if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, pci_name(socket->dev), socket)) { /* No IRQ or request_irq failed. Poll */ socket->cb_irq = 0; /* But zero is a valid IRQ number. */ init_timer(&socket->poll_timer); diff -Nru a/drivers/pnp/core.c b/drivers/pnp/core.c --- a/drivers/pnp/core.c Mon Aug 18 22:21:01 2003 +++ b/drivers/pnp/core.c Mon Aug 18 22:21:01 2003 @@ -69,7 +69,6 @@ protocol->number = nodenum; sprintf(protocol->dev.bus_id, "pnp%d", nodenum); - strlcpy(protocol->dev.name,protocol->name,DEVICE_NAME_SIZE); return device_register(&protocol->dev); } diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c --- a/drivers/pnp/isapnp/core.c Mon Aug 18 22:21:03 2003 +++ b/drivers/pnp/isapnp/core.c Mon Aug 18 22:21:03 2003 @@ -743,7 +743,7 @@ size = 0; break; case _LTAG_ANSISTR: - isapnp_parse_name(dev->dev.name, sizeof(dev->dev.name), &size); + isapnp_parse_name(dev->name, sizeof(dev->name), &size); break; case _LTAG_UNICODESTR: /* silently ignore */ @@ -808,7 +808,7 @@ case _STAG_VENDOR: break; case _LTAG_ANSISTR: - isapnp_parse_name(card->dev.name, sizeof(card->dev.name), &size); + isapnp_parse_name(card->name, sizeof(card->name), &size); break; case _LTAG_UNICODESTR: /* silently ignore */ @@ -1144,11 +1144,11 @@ protocol_for_each_card(&isapnp_protocol,card) { cards++; if (isapnp_verbose) { - printk(KERN_INFO "isapnp: Card '%s'\n", card->dev.name[0]?card->dev.name:"Unknown"); + printk(KERN_INFO "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown"); if (isapnp_verbose < 2) continue; card_for_each_dev(card,dev) { - printk(KERN_INFO "isapnp: Device '%s'\n", dev->dev.name[0]?dev->dev.name:"Unknown"); + printk(KERN_INFO "isapnp: Device '%s'\n", dev->name[0]?dev->name:"Unknown"); } } } diff -Nru a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c --- a/drivers/s390/char/sclp.c Mon Aug 18 22:21:04 2003 +++ b/drivers/s390/char/sclp.c Mon Aug 18 22:21:04 2003 @@ -468,17 +468,17 @@ * SCLP quiesce event handler */ #ifdef CONFIG_SMP -static volatile unsigned long cpu_quiesce_map; +static cpumask_t cpu_quiesce_map; static void do_load_quiesce_psw(void * __unused) { psw_t quiesce_psw; - clear_bit(smp_processor_id(), &cpu_quiesce_map); + cpu_clear(smp_processor_id(), cpu_quiesce_map); if (smp_processor_id() == 0) { /* Wait for all other cpus to enter do_load_quiesce_psw */ - while (cpu_quiesce_map != 0); + while (!cpus_empty(cpu_quiesce_map)); /* Quiesce the last cpu with the special psw */ quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; quiesce_psw.addr = 0xfff; diff -Nru a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c --- a/drivers/sbus/char/riowatchdog.c Mon Aug 18 22:21:03 2003 +++ b/drivers/sbus/char/riowatchdog.c Mon Aug 18 22:21:03 2003 @@ -194,17 +194,11 @@ return 0; } -static ssize_t riowd_read(struct file *file, char *buffer, size_t count, loff_t *ppos) -{ - return -EINVAL; -} - static struct file_operations riowd_fops = { .owner = THIS_MODULE, .ioctl = riowd_ioctl, .open = riowd_open, .write = riowd_write, - .read = riowd_read, .release = riowd_release, }; diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- a/drivers/scsi/3w-xxxx.c Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/3w-xxxx.c Mon Aug 18 22:21:06 2003 @@ -2112,7 +2112,7 @@ if (cmd->request_bufflen == 0) return 0; - mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), ((unsigned long)cmd->request_buffer & ~PAGE_MASK), cmd->request_bufflen, dma_dir); + mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), offset_in_page(cmd->request_buffer), cmd->request_bufflen, dma_dir); if (mapping == 0) { printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n"); @@ -3451,7 +3451,6 @@ .cmd_per_lun = TW_MAX_CMDS_PER_LUN, .use_clustering = ENABLE_CLUSTERING, .emulated = 1, - .highmem_io = 1, }; #include "scsi_module.c" diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c --- a/drivers/scsi/53c700.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/53c700.c Mon Aug 18 22:21:01 2003 @@ -282,7 +282,6 @@ tpnt->slave_configure = NCR_700_slave_configure; tpnt->slave_destroy = NCR_700_slave_destroy; tpnt->use_blk_tcq = 1; - tpnt->highmem_io = 1; if(tpnt->name == NULL) tpnt->name = "53c700"; diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c --- a/drivers/scsi/NCR53c406a.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/NCR53c406a.c Mon Aug 18 22:21:03 2003 @@ -450,6 +450,7 @@ static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt) { + int present = 0; struct Scsi_Host *shpnt = NULL; #ifndef PORT_BASE int i; @@ -522,7 +523,7 @@ DEB(printk("NCR53c406a: using port_base 0x%x\n", port_base)); - tpnt->present = 1; + present = 1; tpnt->proc_name = "NCR53c406a"; shpnt = scsi_register(tpnt, 0); @@ -576,7 +577,7 @@ sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ? "fast" : "slow"); #endif - return (tpnt->present); + return (present); #if USE_DMA err_free_irq: diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c --- a/drivers/scsi/NCR_D700.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/NCR_D700.c Mon Aug 18 22:21:01 2003 @@ -335,7 +335,7 @@ } mca_device_set_claim(mca_dev, 1); - strlcpy(dev->name, "NCR_D700", sizeof(dev->name)); + mca_device_set_name(mca_dev, "NCR_D700"); dev_set_drvdata(dev, p); return 0; } diff -Nru a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c --- a/drivers/scsi/NCR_Q720.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/NCR_Q720.c Mon Aug 18 22:21:01 2003 @@ -291,7 +291,7 @@ } mca_device_set_claim(mca_dev, 1); - strlcpy(dev->name, "NCR_Q720", sizeof(dev->name)); + mca_device_set_name(mca_dev, "NCR_Q720"); dev_set_drvdata(dev, p); return 0; diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c --- a/drivers/scsi/aacraid/linit.c Mon Aug 18 22:21:02 2003 +++ b/drivers/scsi/aacraid/linit.c Mon Aug 18 22:21:02 2003 @@ -295,7 +295,6 @@ printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n"); } - template->present = aac_count; /* # of cards of this type found */ return aac_count; } diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c --- a/drivers/scsi/aha152x.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/aha152x.c Mon Aug 18 22:21:01 2003 @@ -1868,11 +1868,30 @@ static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *shpnt = lookup_irq(irqno); + unsigned char rev, dmacntrl0; if (!shpnt) { printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno); return IRQ_NONE; } + + /* + * Read a couple of registers that are known to not be all 1's. If + * we read all 1's (-1), that means that either: + * + * a. The host adapter chip has gone bad, and we cannot control it, + * OR + * b. The host adapter is a PCMCIA card that has been ejected + * + * In either case, we cannot do anything with the host adapter at + * this point in time. So just ignore the interrupt and return. + * In the latter case, the interrupt might actually be meant for + * someone else sharing this IRQ, and that driver will handle it. + */ + rev = GETPORT(REV); + dmacntrl0 = GETPORT(DMACNTRL0); + if ((rev == 0xFF) && (dmacntrl0 == 0xFF)) + return IRQ_NONE; /* no more interrupts from the controller, while we're busy. INTEN is restored by the BH handler */ diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c --- a/drivers/scsi/aic7xxx/aic79xx_osm.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c Mon Aug 18 22:21:03 2003 @@ -1681,33 +1681,9 @@ .this_id = -1, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - /* - * We can only map 16MB per-SG - * so create a sector limit of - * "16MB" in 2K sectors. - */ - .max_sectors = 8192, -#endif -#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) -/* Assume RedHat Distribution with its different HIGHIO conventions. */ - .can_dma_32 = 1, - .single_sg_okay = 1, -#else - .highmem_io = 1, -#endif -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) .slave_alloc = ahd_linux_slave_alloc, .slave_configure = ahd_linux_slave_configure, .slave_destroy = ahd_linux_slave_destroy, -#else - .detect = ahd_linux_detect, - .release = ahd_linux_release, - .select_queue_depths = ahd_linux_select_queue_depth, - .use_new_eh_code = 1, -#endif }; /**************************** Tasklet Handler *********************************/ diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c Mon Aug 18 22:21:01 2003 @@ -1307,33 +1307,9 @@ .this_id = -1, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - /* - * We can only map 16MB per-SG - * so create a sector limit of - * "16MB" in 2K sectors. - */ - .max_sectors = 8192, -#endif -#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) -/* Assume RedHat Distribution with its different HIGHIO conventions. */ - .can_dma_32 = 1, - .single_sg_okay = 1, -#else - .highmem_io = 1, -#endif -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) .slave_alloc = ahc_linux_slave_alloc, .slave_configure = ahc_linux_slave_configure, .slave_destroy = ahc_linux_slave_destroy, -#else - .detect = ahc_linux_detect, - .release = ahc_linux_release, - .select_queue_depths = ahc_linux_select_queue_depth, - .use_new_eh_code = 1, -#endif }; /**************************** Tasklet Handler *********************************/ diff -Nru a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h --- a/drivers/scsi/arm/scsi.h Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/arm/scsi.h Mon Aug 18 22:21:01 2003 @@ -23,7 +23,7 @@ BUG_ON(bufs + 1 > max); sg->page = virt_to_page(SCp->ptr); - sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK; + sg->offset = offset_in_page(SCp->ptr); sg->length = SCp->this_residual; if (bufs) diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c --- a/drivers/scsi/cpqfcTSinit.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/cpqfcTSinit.c Mon Aug 18 22:21:01 2003 @@ -549,14 +549,14 @@ hba->private_data_bits+(i/BITS_PER_LONG)); } -int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg) +int cpqfcTS_ioctl( struct scsi_device *ScsiDev, int Cmnd, void *arg) { int result = 0; struct Scsi_Host *HostAdapter = ScsiDev->host; CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; PTACHYON fcChip = &cpqfcHBAdata->fcChip; PFC_LOGGEDIN_PORT pLoggedInPort = NULL; - Scsi_Cmnd DumCmnd; + struct scsi_cmnd *DumCmnd; int i, j; VENDOR_IOCTL_REQ ioc; cpqfc_passthru_t *vendor_cmd; @@ -723,13 +723,16 @@ /* DumCmnd.target = ScsiDev->id; */ /* DumCmnd.lun = ScsiDev->lun; */ - DumCmnd.device = ScsiDev; + DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL); + if (!DumCmnd) + return -ENOMEM; pLoggedInPort = fcFindLoggedInPort( fcChip, - &DumCmnd, // search Scsi Nexus + DumCmnd, // search Scsi Nexus 0, // DON'T search linked list for FC port id NULL, // DON'T search linked list for FC WWN NULL); // DON'T care about end of list + scsi_put_command (DumCmnd); if (pLoggedInPort == NULL) { result = -ENXIO; break; @@ -918,7 +921,8 @@ int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) { - Scsi_Cmnd DumCmnd; + struct scsi_cmnd *DumCmnd; + struct scsi_device *ScsiDev; int Chan, Targ, i; struct info_str info; CPQFCHBA *cpqfcHBA; @@ -946,13 +950,21 @@ #define DISPLAY_WWN_INFO #ifdef DISPLAY_WWN_INFO + ScsiDev = scsi_get_host_dev (host); + if (!ScsiDev) + return -ENOMEM; + DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL); + if (!DumCmnd) { + scsi_free_host_dev (ScsiDev); + return -ENOMEM; + } copy_info(&info, "WWN database: (\"port_id: 000000\" means disconnected)\n"); for ( Chan=0; Chan <= host->max_channel; Chan++) { - DumCmnd.channel = Chan; + DumCmnd->device->channel = Chan; for (Targ=0; Targ <= host->max_id; Targ++) { - DumCmnd.target = Targ; + DumCmnd->device->id = Targ; if ((pLoggedInPort = fcFindLoggedInPort( fcChip, - &DumCmnd, // search Scsi Nexus + DumCmnd, // search Scsi Nexus 0, // DON'T search list for FC port id NULL, // DON'T search list for FC WWN NULL))){ // DON'T care about end of list @@ -966,6 +978,9 @@ } } } + + scsi_put_command (DumCmnd); + scsi_free_host_dev (ScsiDev); #endif @@ -1578,7 +1593,7 @@ // Scsi_Request, etc. // For now, so people don't fall into a hole... return -ENOTSUPP; - +/* // printk(" ENTERING cpqfcTS_TargetDeviceReset() - flag=%d \n",reset_flags); if (ScsiDev->host->eh_active) return FAILED; @@ -1600,7 +1615,7 @@ SCpnt->request->CPQFC_WAITING = NULL; } -/* + if(driver_byte(SCpnt->result) != 0) switch(SCpnt->sense_buffer[2] & 0xf) { case ILLEGAL_REQUEST: diff -Nru a/drivers/scsi/cpqfcTSstructs.h b/drivers/scsi/cpqfcTSstructs.h --- a/drivers/scsi/cpqfcTSstructs.h Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/cpqfcTSstructs.h Mon Aug 18 22:21:03 2003 @@ -696,7 +696,6 @@ ULONG port_id; // a FC 24-bit address of port (lower 8 bits = al_pa) - Scsi_Cmnd ScsiCmnd; // command buffer for Report Luns #define REPORT_LUNS_PL 256 UCHAR ReportLunsPayload[REPORT_LUNS_PL]; diff -Nru a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c --- a/drivers/scsi/cpqfcTSworker.c Mon Aug 18 22:21:05 2003 +++ b/drivers/scsi/cpqfcTSworker.c Mon Aug 18 22:21:05 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #define __KERNEL_SYSCALLS__ @@ -1196,9 +1197,9 @@ // have to terminate by SCSI target, NOT port_id. if( Exchanges->fcExchange[x_ID].Cmnd) // Cmnd in progress? { - if( (Exchanges->fcExchange[x_ID].Cmnd->target == ScsiNexus->target) + if( (Exchanges->fcExchange[x_ID].Cmnd->device->id == ScsiNexus->target) && - (Exchanges->fcExchange[x_ID].Cmnd->channel == ScsiNexus->channel)) + (Exchanges->fcExchange[x_ID].Cmnd->device->channel == ScsiNexus->channel)) { Exchanges->fcExchange[x_ID].status = TerminateStatus; cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID ); // timed-out @@ -2681,7 +2682,7 @@ // D. Deming, 1994, pg 7-19 (ISBN 1-879936-08-9) static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd) { - struct Scsi_Host *HostAdapter = Cmnd->host; + struct Scsi_Host *HostAdapter = Cmnd->device->host; CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; PTACHYON fcChip = &cpqfcHBAdata->fcChip; FC_EXCHANGES *Exchanges = fcChip->Exchanges; @@ -2887,11 +2888,11 @@ call_scsi_done(Scsi_Cmnd *Cmnd) { CPQFCHBA *hba; - hba = (CPQFCHBA *) Cmnd->host->hostdata; + hba = (CPQFCHBA *) Cmnd->device->host->hostdata; // Was this command a cpqfc passthru ioctl ? - if (Cmnd->sc_request != NULL && Cmnd->host != NULL && - Cmnd->host->hostdata != NULL && - is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->host->hostdata, + if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL && + Cmnd->device->host->hostdata != NULL && + is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata, Cmnd->sc_request->upper_private_data)) { cpqfc_free_private_data(hba, Cmnd->sc_request->upper_private_data); @@ -2918,7 +2919,8 @@ { PTACHYON fcChip = &cpqfcHBAdata->fcChip; PFC_LOGGEDIN_PORT pLoggedInPort; - Scsi_Cmnd *Cmnd; + struct scsi_cmnd *Cmnd = NULL; + struct scsi_device *ScsiDev = NULL; LONG x_ID; ULONG ulStatus; UCHAR *ucBuff; @@ -2942,17 +2944,20 @@ if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) ) goto Done; // forget it - FC device not a "target" - // now use the port's Scsi Command buffer for the - // Report Luns Command - Cmnd = &pLoggedInPort->ScsiCmnd; + ScsiDev = scsi_get_host_dev (cpqfcHBAdata->HostAdapter); + if (!ScsiDev) + goto Done; + + Cmnd = scsi_get_command (ScsiDev, GFP_KERNEL); + if (!Cmnd) + goto Done; + ucBuff = pLoggedInPort->ReportLunsPayload; - memset( Cmnd, 0, sizeof(Scsi_Cmnd)); memset( ucBuff, 0, REPORT_LUNS_PL); Cmnd->scsi_done = ScsiReportLunsDone; - Cmnd->host = cpqfcHBAdata->HostAdapter; Cmnd->request_buffer = pLoggedInPort->ReportLunsPayload; Cmnd->request_bufflen = REPORT_LUNS_PL; @@ -2962,8 +2967,8 @@ Cmnd->cmnd[9] = (UCHAR)REPORT_LUNS_PL; Cmnd->cmd_len = 12; - Cmnd->channel = pLoggedInPort->ScsiNexus.channel; - Cmnd->target = pLoggedInPort->ScsiNexus.target; + Cmnd->device->channel = pLoggedInPort->ScsiNexus.channel; + Cmnd->device->id = pLoggedInPort->ScsiNexus.target; ulStatus = cpqfcTSBuildExchange( @@ -3003,6 +3008,10 @@ Done: + if (Cmnd) + scsi_put_command (Cmnd); + if (ScsiDev) + scsi_free_host_dev (ScsiDev); } @@ -3361,22 +3370,22 @@ { // check Linux Scsi Cmnd for channel/target Nexus match // (all luns are accessed through matching "pLoggedInPort") - if( (pLoggedInPort->ScsiNexus.target == Cmnd->target) + if( (pLoggedInPort->ScsiNexus.target == Cmnd->device->id) && - (pLoggedInPort->ScsiNexus.channel == Cmnd->channel)) + (pLoggedInPort->ScsiNexus.channel == Cmnd->device->channel)) { // For "passthru" modes, the IOCTL caller is responsible // for setting the FCP-LUN addressing - if (Cmnd->sc_request != NULL && Cmnd->host != NULL && - Cmnd->host->hostdata != NULL && - is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->host->hostdata, + if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL && + Cmnd->device->host->hostdata != NULL && + is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata, Cmnd->sc_request->upper_private_data)) { /* This is a passthru... */ cpqfc_passthru_private_t *pd; pd = Cmnd->sc_request->upper_private_data; Cmnd->SCp.phase = pd->bus; // Cmnd->SCp.have_data_in = pd->pdrive; - Cmnd->SCp.have_data_in = Cmnd->lun; + Cmnd->SCp.have_data_in = Cmnd->device->lun; } else { /* This is not a passthru... */ @@ -3391,17 +3400,17 @@ // Report Luns command if( pLoggedInPort->ScsiNexus.LunMasking == 1) { - if (Cmnd->lun > sizeof(pLoggedInPort->ScsiNexus.lun)) + if (Cmnd->device->lun > sizeof(pLoggedInPort->ScsiNexus.lun)) return NULL; // we KNOW all the valid LUNs... 0xFF is invalid! - Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->lun]; - if (pLoggedInPort->ScsiNexus.lun[Cmnd->lun] == 0xFF) + Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun]; + if (pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun] == 0xFF) return NULL; // printk("xlating lun %d to 0x%02x\n", Cmnd->lun, // pLoggedInPort->ScsiNexus.lun[Cmnd->lun]); } else - Cmnd->SCp.have_data_in = Cmnd->lun; // Linux & target luns match + Cmnd->SCp.have_data_in = Cmnd->device->lun; // Linux & target luns match } break; // found it! } @@ -3507,9 +3516,9 @@ // Are there any Q'd commands for this target? - if( (Cmnd->target == pLoggedInPort->ScsiNexus.target) + if( (Cmnd->device->id == pLoggedInPort->ScsiNexus.target) && - (Cmnd->channel == pLoggedInPort->ScsiNexus.channel) ) + (Cmnd->device->channel == pLoggedInPort->ScsiNexus.channel) ) { Cmnd->result = (DID_SOFT_ERROR <<16); // force retry if( Cmnd->scsi_done == NULL) diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c --- a/drivers/scsi/dc395x.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/dc395x.c Mon Aug 18 22:21:01 2003 @@ -60,6 +60,7 @@ #include #include #include +#include /*--------------------------------------------------------------------------- Features @@ -264,11 +265,49 @@ }; +/* + * The SEEPROM structure for TRM_S1040 + */ +struct NVRamTarget { + u8 cfg0; /* Target configuration byte 0 */ + u8 period; /* Target period */ + u8 cfg2; /* Target configuration byte 2 */ + u8 cfg3; /* Target configuration byte 3 */ +}; + + +struct NvRamType { + u8 sub_vendor_id[2]; /* 0,1 Sub Vendor ID */ + u8 sub_sys_id[2]; /* 2,3 Sub System ID */ + u8 sub_class; /* 4 Sub Class */ + u8 vendor_id[2]; /* 5,6 Vendor ID */ + u8 device_id[2]; /* 7,8 Device ID */ + u8 reserved; /* 9 Reserved */ + struct NVRamTarget target[DC395x_MAX_SCSI_ID]; + /** 10,11,12,13 + ** 14,15,16,17 + ** .... + ** .... + ** 70,71,72,73 + */ + u8 scsi_id; /* 74 Host Adapter SCSI ID */ + u8 channel_cfg; /* 75 Channel configuration */ + u8 delay_time; /* 76 Power on delay time */ + u8 max_tag; /* 77 Maximum tags */ + u8 reserved0; /* 78 */ + u8 boot_target; /* 79 */ + u8 boot_lun; /* 80 */ + u8 reserved1; /* 81 */ + u16 reserved2[22]; /* 82,..125 */ + u16 cksum; /* 126,127 */ +}; + + /*----------------------------------------------------------------------- SCSI Request Block -----------------------------------------------------------------------*/ struct ScsiReqBlk { - struct ScsiReqBlk *next; + struct list_head list; /* next/prev ptrs for srb lists */ struct DeviceCtlBlk *dcb; /* HW scatter list (up to 64 entries) */ @@ -312,22 +351,16 @@ Device Control Block -----------------------------------------------------------------------*/ struct DeviceCtlBlk { - struct DeviceCtlBlk *next; + struct list_head list; /* next/prev ptrs for the dcb list */ struct AdapterCtlBlk *acb; - - struct ScsiReqBlk *going_srb; - struct ScsiReqBlk *going_last; - - struct ScsiReqBlk *waiting_srb; - struct ScsiReqBlk *wait_list; + struct list_head srb_going_list; /* head of going srb list */ + struct list_head srb_waiting_list; /* head of waiting srb list */ struct ScsiReqBlk *active_srb; u32 tag_mask; u16 max_command; - u16 going_srb_count; - u16 waiting_srb_count; u8 target_id; /* SCSI Target ID (SCSI Only) */ u8 target_lun; /* SCSI Log. Unit (SCSI Only) */ u8 identify_msg; @@ -349,25 +382,20 @@ -----------------------------------------------------------------------*/ struct AdapterCtlBlk { struct Scsi_Host *scsi_host; - struct AdapterCtlBlk *next_acb; u16 IOPortBase; - struct DeviceCtlBlk *link_dcb; - struct DeviceCtlBlk *last_dcb; + struct list_head dcb_list; /* head of going dcb list */ struct DeviceCtlBlk *dcb_run_robin; - struct DeviceCtlBlk *active_dcb; - struct ScsiReqBlk *free_srb; + struct list_head srb_free_list; /* head of free srb list */ struct ScsiReqBlk *tmp_srb; struct timer_list waiting_timer; struct timer_list selto_timer; u16 srb_count; - u16 adapter_index; /* nth Adapter this driver */ - u8 dcb_count; u8 sel_timeout; u8 irq_level; @@ -389,45 +417,11 @@ struct ScsiReqBlk srb_array[DC395x_MAX_SRB_CNT]; struct ScsiReqBlk srb; -}; - -/* - * The SEEPROM structure for TRM_S1040 - */ -struct NVRamTarget { - u8 cfg0; /* Target configuration byte 0 */ - u8 period; /* Target period */ - u8 cfg2; /* Target configuration byte 2 */ - u8 cfg3; /* Target configuration byte 3 */ + struct NvRamType eeprom; /* eeprom settings for this adapter */ }; -struct NvRamType { - u8 sub_vendor_id[2]; /* 0,1 Sub Vendor ID */ - u8 sub_sys_id[2]; /* 2,3 Sub System ID */ - u8 sub_class; /* 4 Sub Class */ - u8 vendor_id[2]; /* 5,6 Vendor ID */ - u8 device_id[2]; /* 7,8 Device ID */ - u8 reserved; /* 9 Reserved */ - struct NVRamTarget target[DC395x_MAX_SCSI_ID]; - /** 10,11,12,13 - ** 14,15,16,17 - ** .... - ** .... - ** 70,71,72,73 - */ - u8 scsi_id; /* 74 Host Adapter SCSI ID */ - u8 channel_cfg; /* 75 Channel configuration */ - u8 delay_time; /* 76 Power on delay time */ - u8 max_tag; /* 77 Maximum tags */ - u8 reserved0; /* 78 */ - u8 boot_target; /* 79 */ - u8 boot_lun; /* 80 */ - u8 reserved1; /* 81 */ - u16 reserved2[22]; /* 82,..125 */ - u16 cksum; /* 126,127 */ -}; /*--------------------------------------------------------------------------- @@ -512,9 +506,6 @@ /*--------------------------------------------------------------------------- Static Data ---------------------------------------------------------------------------*/ -static struct AdapterCtlBlk *acb_list_head = NULL; -static struct AdapterCtlBlk *acb_list_tail = NULL; -static u16 adapter_count = 0; static u16 current_sync_offset = 0; static char monitor_next_irq = 0; @@ -546,7 +537,6 @@ msgin_phase1, /* phase:7 */ }; -struct NvRamType eeprom_buf[DC395x_MAX_ADAPTER_NUM]; /* *Fast20: 000 50ns, 20.0 MHz * 001 75ns, 13.3 MHz @@ -826,6 +816,60 @@ /*--------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ +/** + * list_size - Returns the size (in number of entries) of the + * supplied list. + * + * @head: The pointer to the head of the list to count the items in. + **/ +unsigned int list_size(struct list_head *head) +{ + unsigned int count = 0; + struct list_head *pos; + list_for_each(pos, head) + count++; + return count; +} + + +/** + * dcb_get_next - Given a dcb return the next dcb in the list of + * dcb's, wrapping back to the start of the dcb list if required. + * Returns the supplied dcb if there is only one dcb in the list. + * + * @head: The pointer to the head of the list to count the items in. + * @pos: The pointer the dcb for which we are searching for the + * following dcb. + **/ +struct DeviceCtlBlk *dcb_get_next( + struct list_head *head, + struct DeviceCtlBlk *pos) +{ + int use_next = 0; + struct DeviceCtlBlk* next = NULL; + struct DeviceCtlBlk* i; + + if (list_empty(head)) + return NULL; + + /* find supplied dcb and then select the next one */ + list_for_each_entry(i, head, list) + if (use_next) { + next = i; + break; + } else if (i == pos) { + use_next = 1; + } + /* if no next one take the head one (ie, wraparound) */ + if (!next) + list_for_each_entry(i, head, list) { + next = i; + break; + } + + return next; +} + /* * Queueing philosphy: @@ -853,200 +897,153 @@ /* Find cmd in SRB list */ inline static -struct ScsiReqBlk *find_cmd(Scsi_Cmnd * cmd, - struct ScsiReqBlk *start) +struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd, + struct list_head *head) { - struct ScsiReqBlk *psrb = start; - if (!start) - return 0; - do { - if (psrb->cmd == cmd) - return psrb; - psrb = psrb->next; - } while (psrb && psrb != start); - return 0; + struct ScsiReqBlk *i; + list_for_each_entry(i, head, list) + if (i->cmd == cmd) + return i; + return NULL; } -/* Return next free SRB */ -static inline -struct ScsiReqBlk *get_srb_free(struct AdapterCtlBlk *acb) +/* + * srb_get_free - Return a free srb from the list of free SRBs that + * is stored with the acb. + */ +static +struct ScsiReqBlk *srb_get_free(struct AdapterCtlBlk *acb) { + struct list_head *head = &acb->srb_free_list; struct ScsiReqBlk *srb; - /*DC395x_Free_integrity (acb); */ - srb = acb->free_srb; - if (!srb) + if (!list_empty(head)) { + srb = list_entry(head->next, struct ScsiReqBlk, list); + list_del(head->next); + dprintkdbg(DBG_0, "srb_get_free: got srb %p\n", srb); + } else { + srb = NULL; dprintkl(KERN_ERR, "Out of Free SRBs :-(\n"); - if (srb) { - acb->free_srb = srb->next; - srb->next = NULL; } - return srb; } -/* Insert SRB oin top of free list */ -static inline -void insert_srb_free(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +/* + * srb_free_insert - Insert an srb to the head of the free list + * stored in the acb. + */ +static +void srb_free_insert(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "Free SRB %p\n", srb); - srb->next = acb->free_srb; - acb->free_srb = srb; + dprintkdbg(DBG_0, "srb_free_insert: put srb %p\n", srb); + list_add_tail(&srb->list, &acb->srb_free_list); } -/* Inserts a SRB to the top of the Waiting list */ -static inline -void insert_srb_waiting(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) +/* + * srb_waiting_insert - Insert an srb to the head of the wiating list + * stored in the dcb. + */ +static +void srb_waiting_insert(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "Insert srb %p cmd %li to Waiting\n", srb, srb->cmd->pid); - srb->next = dcb->waiting_srb; - if (!dcb->waiting_srb) - dcb->wait_list = srb; - dcb->waiting_srb = srb; - dcb->waiting_srb_count++; + dprintkdbg(DBG_0, "srb_waiting_insert: srb %p cmd %li\n", srb, srb->cmd->pid); + list_add(&srb->list, &dcb->srb_waiting_list); } -/* Queue SRB to waiting list */ +/* + * srb_waiting_append - Append an srb to the tail of the waiting list + * stored in the dcb. + */ static inline -void append_srb_waiting(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) +void srb_waiting_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "Append srb %p cmd %li to Waiting\n", srb, srb->cmd->pid); - if (dcb->waiting_srb) - dcb->wait_list->next = srb; - else - dcb->waiting_srb = srb; - - dcb->wait_list = srb; - /* No next one in waiting list */ - srb->next = NULL; - dcb->waiting_srb_count++; + dprintkdbg(DBG_0, "srb_waiting_append: srb %p cmd %li\n", srb, srb->cmd->pid); + list_add_tail(&srb->list, &dcb->srb_waiting_list); } +/* + * srb_going_append - Append an srb to the tail of the going list + * stored in the dcb. + */ static inline -void append_srb_going(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) -{ - dprintkdbg(DBG_0, "Append SRB %p to Going\n", srb); - /* Append to the list of Going commands */ - if (dcb->going_srb) - dcb->going_last->next = srb; - else - dcb->going_srb = srb; - - dcb->going_last = srb; - /* No next one in sent list */ - srb->next = NULL; - dcb->going_srb_count++; -} - - -/* Find predecessor SRB */ -inline static -struct ScsiReqBlk *find_srb_prev(struct ScsiReqBlk *srb, - struct ScsiReqBlk *start) +void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { - struct ScsiReqBlk *p = start; - if (!start) - return 0; - do { - if (p->next == srb) - return p; - p = p->next; - } while (p && p != start); - return 0; + dprintkdbg(DBG_0, "srb_going_append: srb %p\n", srb); + list_add_tail(&srb->list, &dcb->srb_going_list); } -/* Remove SRB from SRB queue */ -inline static -struct ScsiReqBlk *remove_srb(struct ScsiReqBlk *srb, - struct ScsiReqBlk *pre) -{ - if (pre->next != srb) - pre = find_srb_prev(srb, pre); - if (!pre) { - dprintkl(KERN_ERR, "Internal ERROR: SRB to rmv not found in Q!\n"); - return 0; - } - pre->next = srb->next; - /*srb->next = NULL; */ - return pre; -} - -/* Remove SRB from Going queue */ +/* + * srb_going_remove - Remove an srb from the going list stored in the + * dcb. + */ static -void remove_srb_going(struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb, - struct ScsiReqBlk *hint) +void srb_going_remove(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { - struct ScsiReqBlk *pre = NULL; - dprintkdbg(DBG_0, "Remove SRB %p from Going\n", srb); - if (!srb) - dprintkl(KERN_ERR, "Going_remove %p!\n", srb); - if (srb == dcb->going_srb) - dcb->going_srb = srb->next; - else if (hint && hint->next == srb) - pre = remove_srb(srb, hint); - else - pre = remove_srb(srb, dcb->going_srb); - if (srb == dcb->going_last) - dcb->going_last = pre; - dcb->going_srb_count--; + struct ScsiReqBlk *i; + struct ScsiReqBlk *tmp; + dprintkdbg(DBG_0, "srb_going_remove: srb %p\n", srb); + + list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list) + if (i == srb) { + list_del(&srb->list); + break; + } } -/* Remove SRB from Waiting queue */ +/* + * srb_waiting_remove - Remove an srb from the waiting list stored in the + * dcb. + */ static -void remove_srb_waiting(struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb, - struct ScsiReqBlk *hint) +void srb_waiting_remove(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { - struct ScsiReqBlk *pre = NULL; - dprintkdbg(DBG_0, "Remove SRB %p from Waiting\n", srb); - if (!srb) - dprintkl(KERN_ERR, "Waiting_remove %p!\n", srb); - if (srb == dcb->waiting_srb) - dcb->waiting_srb = srb->next; - else if (hint && hint->next == srb) - pre = remove_srb(srb, hint); - else - pre = remove_srb(srb, dcb->waiting_srb); - if (srb == dcb->wait_list) - dcb->wait_list = pre; - dcb->waiting_srb_count--; + struct ScsiReqBlk *i; + struct ScsiReqBlk *tmp; + dprintkdbg(DBG_0, "srb_waiting_remove: srb %p\n", srb); + + list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list) + if (i == srb) { + list_del(&srb->list); + break; + } } -/* Moves SRB from Going list to the top of Waiting list */ +/* + * srb_going_to_waiting_move - Remove an srb from the going list in + * the dcb and insert it at the head of the waiting list in the dcb. + */ static -void move_srb_going_to_waiting(struct DeviceCtlBlk *dcb, +void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "Going_to_Waiting (SRB %p) pid = %li\n", srb, srb->cmd->pid); - /* Remove SRB from Going */ - remove_srb_going(dcb, srb, 0); - TRACEPRINTF("GtW *"); - /* Insert on top of Waiting */ - insert_srb_waiting(dcb, srb); - /* Tag Mask must be freed elsewhere ! (KG, 99/06/18) */ + dprintkdbg(DBG_0, "srb_going_waiting_move: srb %p, pid = %li\n", srb, srb->cmd->pid); + list_move(&srb->list, &dcb->srb_waiting_list); } -/* Moves first SRB from Waiting list to Going list */ -static inline -void move_srb_waiting_to_going(struct DeviceCtlBlk *dcb, +/* + * srb_waiting_to_going_move - Remove an srb from the waiting list in + * the dcb and insert it at the head of the going list in the dcb. + */ +static +void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { /* Remove from waiting list */ - dprintkdbg(DBG_0, "Remove SRB %p from head of Waiting\n", srb); - remove_srb_waiting(dcb, srb, 0); + dprintkdbg(DBG_0, "srb_waiting_to_going: srb %p\n", srb); TRACEPRINTF("WtG *"); - append_srb_going(dcb, srb); + list_move(&srb->list, &dcb->srb_going_list); } @@ -1072,39 +1069,66 @@ static void waiting_process_next(struct AdapterCtlBlk *acb) { - struct DeviceCtlBlk *ptr; - struct DeviceCtlBlk *ptr1; + struct DeviceCtlBlk *start = NULL; + struct DeviceCtlBlk *pos; + struct DeviceCtlBlk *dcb; struct ScsiReqBlk *srb; + struct list_head *dcb_list_head = &acb->dcb_list; if ((acb->active_dcb) || (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV))) return; + if (timer_pending(&acb->waiting_timer)) del_timer(&acb->waiting_timer); - ptr = acb->dcb_run_robin; - if (!ptr) { /* This can happen! */ - ptr = acb->link_dcb; - acb->dcb_run_robin = ptr; - } - ptr1 = ptr; - if (!ptr1) + + if (list_empty(dcb_list_head)) return; + + /* + * Find the starting dcb. Need to find it again in the list + * since the list may have changed since we set the ptr to it + */ + list_for_each_entry(dcb, dcb_list_head, list) + if (dcb == acb->dcb_run_robin) { + start = dcb; + break; + } + if (!start) { + /* This can happen! */ + start = list_entry(dcb_list_head->next, typeof(*start), list); + acb->dcb_run_robin = start; + } + + + /* + * Loop over the dcb, but we start somewhere (potentially) in + * the middle of the loop so we need to manully do this. + */ + pos = start; do { + struct list_head *waiting_list_head = &pos->srb_waiting_list; + /* Make sure, the next another device gets scheduled ... */ - acb->dcb_run_robin = ptr1->next; - if (!(srb = ptr1->waiting_srb) - || (ptr1->max_command <= ptr1->going_srb_count)) - ptr1 = ptr1->next; - else { + acb->dcb_run_robin = dcb_get_next(dcb_list_head, + acb->dcb_run_robin); + + if (list_empty(waiting_list_head) || + pos->max_command <= list_size(&pos->srb_going_list)) { + /* move to next dcb */ + pos = dcb_get_next(dcb_list_head, pos); + } else { + srb = list_entry(waiting_list_head->next, + struct ScsiReqBlk, list); + /* Try to send to the bus */ - if (!start_scsi(acb, ptr1, srb)) - move_srb_waiting_to_going(ptr1, srb); + if (!start_scsi(acb, pos, srb)) + srb_waiting_to_going_move(pos, srb); else - waiting_set_timer(acb, HZ / 50); + waiting_set_timer(acb, HZ/50); break; } - } while (ptr1 != ptr); - return; + } while (pos != start); } @@ -1143,30 +1167,18 @@ struct DeviceCtlBlk *dcb; dcb = srb->dcb; - if ((dcb->max_command <= dcb->going_srb_count) || - (acb->active_dcb) || + if (dcb->max_command <= list_size(&dcb->srb_going_list) || + acb->active_dcb || (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV))) { - append_srb_waiting(dcb, srb); + srb_waiting_append(dcb, srb); waiting_process_next(acb); return; } -#if 0 - if (dcb->waiting_srb) { - append_srb_waiting(dcb, srb); - /* srb = waiting_srb_get(dcb); *//* non-existent */ - srb = dcb->waiting_srb; - /* Remove from waiting list */ - dcb->waiting_srb = srb->next; - srb->next = NULL; - if (!dcb->waiting_srb) - dcb->wait_list = NULL; - } -#endif - if (!start_scsi(acb, dcb, srb)) - append_srb_going(dcb, srb); - else { - insert_srb_waiting(dcb, srb); + if (!start_scsi(acb, dcb, srb)) { + srb_going_append(dcb, srb); + } else { + srb_waiting_insert(dcb, srb); waiting_set_timer(acb, HZ / 50); } } @@ -1393,7 +1405,7 @@ cmd->result = 0; /* get a free SRB */ - srb = get_srb_free(acb); + srb = srb_get_free(acb); if (!srb) { /* @@ -1407,9 +1419,9 @@ /* build srb for the command */ build_srb(cmd, dcb, srb); - if (dcb->waiting_srb) { + if (!list_empty(&dcb->srb_waiting_list)) { /* append to waiting queue */ - append_srb_waiting(dcb, srb); + srb_waiting_append(dcb, srb); waiting_process_next(acb); } else { /* process immediately */ @@ -1612,23 +1624,15 @@ static void reset_dev_param(struct AdapterCtlBlk *acb) { struct DeviceCtlBlk *dcb; - struct DeviceCtlBlk *dcb_temp; - struct NvRamType *eeprom; - u8 period_index; - u16 index; + struct NvRamType *eeprom = &acb->eeprom; dprintkdbg(DBG_0, "reset_dev_param..............\n"); - dcb = acb->link_dcb; - if (dcb == NULL) - return; + list_for_each_entry(dcb, &acb->dcb_list, list) { + u8 period_index; - dcb_temp = dcb; - do { dcb->sync_mode &= ~(SYNC_NEGO_DONE + WIDE_NEGO_DONE); dcb->sync_period = 0; dcb->sync_offset = 0; - index = acb->adapter_index; - eeprom = &eeprom_buf[index]; dcb->dev_mode = eeprom->target[dcb->target_id].cfg0; /*dcb->AdpMode = eeprom->channel_cfg; */ @@ -1637,10 +1641,7 @@ if (!(dcb->dev_mode & NTC_DO_WIDE_NEGO) || !(acb->config & HCC_WIDE_CARD)) dcb->sync_mode &= ~WIDE_NEGO_ENABLE; - - dcb = dcb->next; } - while (dcb_temp != dcb && dcb != NULL); } @@ -1679,7 +1680,7 @@ /* We may be in serious trouble. Wait some seconds */ acb->scsi_host->last_reset = jiffies + 3 * HZ / 2 + - HZ * eeprom_buf[acb->adapter_index].delay_time; + HZ * acb->eeprom.delay_time; /* * re-enable interrupt @@ -1735,18 +1736,18 @@ return FAILED; } - srb = find_cmd(cmd, dcb->waiting_srb); + srb = find_cmd(cmd, &dcb->srb_waiting_list); if (srb) { - remove_srb_waiting(dcb, srb, 0); + srb_waiting_remove(dcb, srb); pci_unmap_srb_sense(acb, srb); pci_unmap_srb(acb, srb); free_tag(dcb, srb); - insert_srb_free(acb, srb); + srb_free_insert(acb, srb); dprintkl(KERN_DEBUG, "abort - command found in waiting commands queue"); cmd->result = DID_ABORT << 16; return SUCCESS; } - srb = find_cmd(cmd, dcb->going_srb); + srb = find_cmd(cmd, &dcb->srb_going_list); if (srb) { dprintkl(KERN_DEBUG, "abort - command currently in progress"); /* XXX: Should abort the command here */ @@ -3328,23 +3329,27 @@ struct DeviceCtlBlk *dcb, u8 tag) { - struct ScsiReqBlk *last_srb = dcb->going_last; - struct ScsiReqBlk *srb = dcb->going_srb; + struct ScsiReqBlk *srb = NULL; + struct ScsiReqBlk *i; + + dprintkdbg(DBG_0, "QTag Msg (SRB %p): %i\n", srb, tag); if (!(dcb->tag_mask & (1 << tag))) dprintkl(KERN_DEBUG, "MsgIn_QTag: tag_mask (%08x) does not reserve tag %i!\n", dcb->tag_mask, tag); - if (!srb) + if (list_empty(&dcb->srb_going_list)) goto mingx0; - while (srb) { - if (srb->tag_number == tag) + list_for_each_entry(i, &dcb->srb_going_list, list) { + if (i->tag_number == tag) { + srb = i; break; - if (srb == last_srb) - goto mingx0; - srb = srb->next; + } } + if (!srb) + goto mingx0; + dprintkdbg(DBG_0, "pid %li (%i-%i)\n", srb->cmd->pid, srb->dcb->target_id, srb->dcb->target_lun); if (dcb->flag & ABORT_DEV_) { @@ -3356,13 +3361,18 @@ goto mingx0; /* Tag found */ - TRACEPRINTF("[%s]*", dcb->active_srb->debugtrace); - TRACEPRINTF("RTag*"); - /* Just for debugging ... */ - last_srb = srb; - srb = dcb->active_srb; - TRACEPRINTF("Found.*"); - srb = last_srb; + { + struct ScsiReqBlk *last_srb; + + TRACEPRINTF("[%s]*", dcb->active_srb->debugtrace); + TRACEPRINTF("RTag*"); + /* Just for debugging ... */ + + last_srb = srb; + srb = dcb->active_srb; + TRACEPRINTF("Found.*"); + srb = last_srb; + } memcpy(srb->msgin_buf, dcb->active_srb->msgin_buf, acb->msg_len); srb->state |= dcb->active_srb->state; @@ -3780,36 +3790,26 @@ static void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) { - u8 bval; - u16 cnt, i; - struct DeviceCtlBlk *dcb_temp; + struct DeviceCtlBlk *i; /* - ** set all lun device's period , offset + * set all lun device's period , offset */ - if (!(dcb->identify_msg & 0x07)) { - if (acb->scan_devices) - current_sync_offset = dcb->sync_offset; - else { - dcb_temp = acb->link_dcb; - cnt = acb->dcb_count; - bval = dcb->target_id; - for (i = 0; i < cnt; i++) { - if (dcb_temp->target_id == bval) { - dcb_temp->sync_period = - dcb->sync_period; - dcb_temp->sync_offset = - dcb->sync_offset; - dcb_temp->sync_mode = - dcb->sync_mode; - dcb_temp->min_nego_period = - dcb->min_nego_period; - } - dcb_temp = dcb_temp->next; - } - } + if (dcb->identify_msg & 0x07) + return; + + if (acb->scan_devices) { + current_sync_offset = dcb->sync_offset; + return; } - return; + + list_for_each_entry(i, &acb->dcb_list, list) + if (i->target_id == dcb->target_id) { + i->sync_period = dcb->sync_period; + i->sync_offset = dcb->sync_offset; + i->sync_mode = dcb->sync_mode; + i->min_nego_period = dcb->min_nego_period; + } } @@ -3832,9 +3832,7 @@ /* Suspend queue for a while */ acb->scsi_host->last_reset = jiffies + HZ / 2 + - HZ * - eeprom_buf[acb->adapter_index]. - delay_time; + HZ * acb->eeprom.delay_time; clear_fifo(acb, "DiscEx"); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT); return; @@ -3890,7 +3888,7 @@ goto disc1; } free_tag(dcb, srb); - move_srb_going_to_waiting(dcb, srb); + srb_going_to_waiting_move(dcb, srb); dprintkdbg(DBG_KG, "Retry pid %li ...\n", srb->cmd->pid); waiting_set_timer(acb, HZ / 20); @@ -3972,7 +3970,7 @@ srb->state = SRB_READY; free_tag(dcb, srb); - move_srb_going_to_waiting(dcb, srb); + srb_going_to_waiting_move(dcb, srb); waiting_set_timer(acb, HZ / 20); /* return; */ @@ -4057,43 +4055,32 @@ static void remove_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) { - struct DeviceCtlBlk *pPrevDCB = acb->link_dcb; + struct DeviceCtlBlk *i; + struct DeviceCtlBlk *tmp; dprintkdbg(DBG_0, "remove_dev\n"); - if (dcb->going_srb_count > 1) { + if (list_size(&dcb->srb_going_list) > 1) { dprintkdbg(DBG_DCB, "Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n", dcb->target_id, dcb->target_lun, (int) dcb, - dcb->going_srb_count); + list_size(&dcb->srb_going_list)); return; } acb->dcb_map[dcb->target_id] &= ~(1 << dcb->target_lun); acb->children[dcb->target_id][dcb->target_lun] = NULL; - /* The first one */ - if (dcb == acb->link_dcb) { - /* The last one */ - if (acb->last_dcb == dcb) { - dcb->next = NULL; - acb->last_dcb = NULL; + list_for_each_entry_safe(i, tmp, &acb->dcb_list, list) { + if (dcb == i) { + list_del(&i->list); + break; } - acb->link_dcb = dcb->next; - } else { - while (pPrevDCB->next != dcb) - pPrevDCB = pPrevDCB->next; - pPrevDCB->next = dcb->next; - if (dcb == acb->last_dcb) - acb->last_dcb = pPrevDCB; - } + } dprintkdbg(DBG_DCB, "Driver about to free DCB (ID %i, LUN %i): %p\n", dcb->target_id, dcb->target_lun, dcb); if (dcb == acb->active_dcb) acb->active_dcb = NULL; - if (dcb == acb->link_dcb) - acb->link_dcb = dcb->next; if (dcb == acb->dcb_run_robin) - acb->dcb_run_robin = dcb->next; - acb->dcb_count--; + acb->dcb_run_robin = dcb_get_next(&acb->dcb_list, dcb); dc395x_kfree(dcb); } @@ -4328,7 +4315,7 @@ request_sense(acb, dcb, srb); return; } else if (status_byte(status) == QUEUE_FULL) { - tempcnt = (u8) dcb->going_srb_count; + tempcnt = (u8)list_size(&dcb->srb_going_list); printk ("\nDC395x: QUEUE_FULL for dev %02i-%i with %i cmnds\n", dcb->target_id, dcb->target_lun, tempcnt); @@ -4336,7 +4323,7 @@ tempcnt--; dcb->max_command = tempcnt; free_tag(dcb, srb); - move_srb_going_to_waiting(dcb, srb); + srb_going_to_waiting_move(dcb, srb); waiting_set_timer(acb, HZ / 20); srb->adapter_status = 0; srb->target_status = 0; @@ -4417,12 +4404,12 @@ cmd->device->lun, srb->total_xfer_length); } - remove_srb_going(dcb, srb, 0); + srb_going_remove(dcb, srb); /* Add to free list */ if (srb == acb->tmp_srb) dprintkl(KERN_ERR, "ERROR! Completed Cmnd with tmp_srb!\n"); else - insert_srb_free(acb, srb); + srb_free_insert(acb, srb); dprintkdbg(DBG_0, "SRBdone: done pid %li\n", cmd->pid); if (debug_enabled(DBG_KG)) { @@ -4452,30 +4439,21 @@ Scsi_Cmnd * cmd, u8 force) { struct DeviceCtlBlk *dcb; - struct ScsiReqBlk *srb; - struct ScsiReqBlk *srb_temp; - u16 cnt; - Scsi_Cmnd *p; - dcb = acb->link_dcb; - if (!dcb) - return; dprintkl(KERN_INFO, "doing_srb_done: pids "); - do { - /* As the ML may queue cmnds again, cache old values */ - struct ScsiReqBlk *waiting_srb = dcb->waiting_srb; - /*struct ScsiReqBlk* wait_list = dcb->wait_list; */ - u16 waiting_srb_count = dcb->waiting_srb_count; - /* Going queue */ - cnt = dcb->going_srb_count; - srb = dcb->going_srb; - while (cnt--) { + list_for_each_entry(dcb, &acb->dcb_list, list) { + struct ScsiReqBlk *srb; + struct ScsiReqBlk *tmp; + Scsi_Cmnd *p; + + list_for_each_entry_safe(srb, tmp, &dcb->srb_going_list, list) { int result; int dir; - srb_temp = srb->next; + p = srb->cmd; dir = scsi_to_pci_dma_dir(p->sc_data_direction); result = MK_RES(0, did_flag, 0, 0); + /*result = MK_RES(0,DID_RESET,0,0); */ TRACEPRINTF("Reset(%li):%08x*", jiffies, result); printk(" (G)"); @@ -4484,12 +4462,10 @@ p->device->id, p->device->lun); #endif TRACEOUT("%s\n", srb->debugtrace); - dcb->going_srb = srb_temp; - dcb->going_srb_count--; - if (!srb_temp) - dcb->going_last = NULL; + + srb_going_remove(dcb, srb); free_tag(dcb, srb); - insert_srb_free(acb, srb); + srb_free_insert(acb, srb); p->result = result; pci_unmap_srb_sense(acb, srb); pci_unmap_srb(acb, srb); @@ -4498,9 +4474,8 @@ * as they all complete or all time out */ p->scsi_done(p); } - srb = srb_temp; } - if (dcb->going_srb) + if (!list_empty(&dcb->srb_going_list)) dprintkl(KERN_DEBUG, "How could the ML send cmnds to the Going queue? (%02i-%i)!!\n", dcb->target_id, dcb->target_lun); @@ -4509,16 +4484,12 @@ "tag_mask for %02i-%i should be empty, is %08x!\n", dcb->target_id, dcb->target_lun, dcb->tag_mask); - /*dcb->going_srb_count = 0;; */ - /*dcb->going_srb = NULL; dcb->going_last = NULL; */ /* Waiting queue */ - cnt = waiting_srb_count; - srb = waiting_srb; - while (cnt--) { + list_for_each_entry_safe(srb, tmp, &dcb->srb_waiting_list, list) { int result; - srb_temp = srb->next; p = srb->cmd; + result = MK_RES(0, did_flag, 0, 0); TRACEPRINTF("Reset(%li):%08x*", jiffies, result); printk(" (W)"); @@ -4527,11 +4498,8 @@ p->device->lun); #endif TRACEOUT("%s\n", srb->debugtrace); - dcb->waiting_srb = srb_temp; - dcb->waiting_srb_count--; - if (!srb_temp) - dcb->wait_list = NULL; - insert_srb_free(acb, srb); + srb_waiting_remove(dcb, srb); + srb_free_insert(acb, srb); p->result = result; pci_unmap_srb_sense(acb, srb); @@ -4540,21 +4508,16 @@ /* For new EH, we normally don't need to give commands back, * as they all complete or all time out */ cmd->scsi_done(cmd); - srb = srb_temp; } } - if (dcb->waiting_srb_count) + if (!list_empty(&dcb->srb_waiting_list)) printk ("\nDC395x: Debug: ML queued %i cmnds again to %02i-%i\n", - dcb->waiting_srb_count, dcb->target_id, + list_size(&dcb->srb_waiting_list), dcb->target_id, dcb->target_lun); - /* The ML could have queued the cmnds again! */ - /*dcb->waiting_srb_count = 0;; */ - /*dcb->waiting_srb = NULL; dcb->wait_list = NULL; */ + dcb->flag &= ~ABORT_DEV_; - dcb = dcb->next; } - while (dcb != acb->link_dcb && dcb); printk("\n"); } @@ -4640,7 +4603,7 @@ /* Maybe we locked up the bus? Then lets wait even longer ... */ acb->scsi_host->last_reset = jiffies + 5 * HZ / 2 + - HZ * eeprom_buf[acb->adapter_index].delay_time; + HZ * acb->eeprom.delay_time; clear_fifo(acb, "RstDet"); set_basic_config(acb); @@ -4711,7 +4674,7 @@ "Request Sense failed for pid %li (%02i-%i)!\n", srb->cmd->pid, dcb->target_id, dcb->target_lun); TRACEPRINTF("?*"); - move_srb_going_to_waiting(dcb, srb); + srb_going_to_waiting_move(dcb, srb); waiting_set_timer(acb, HZ / 100); } TRACEPRINTF(".*"); @@ -4731,9 +4694,8 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb, u8 target, u8 lun) { - struct NvRamType *eeprom; + struct NvRamType *eeprom = &acb->eeprom; u8 period_index; - u16 index; struct DeviceCtlBlk *dcb; struct DeviceCtlBlk *dcb2; @@ -4745,34 +4707,23 @@ if (!dcb) return; - if (acb->dcb_count == 0) { - acb->link_dcb = dcb; + INIT_LIST_HEAD(&dcb->srb_waiting_list); + INIT_LIST_HEAD(&dcb->srb_going_list); + if (list_empty(&acb->dcb_list)) acb->dcb_run_robin = dcb; - } else { - acb->last_dcb->next = dcb; - } - - acb->dcb_count++; - dcb->next = acb->link_dcb; - acb->last_dcb = dcb; + list_add_tail(&dcb->list, &acb->dcb_list); /* $$$$$$$ */ dcb->acb = acb; dcb->target_id = target; dcb->target_lun = lun; /* $$$$$$$ */ - dcb->waiting_srb = NULL; - dcb->going_srb = NULL; - dcb->going_srb_count = 0; - dcb->waiting_srb_count = 0; dcb->active_srb = NULL; /* $$$$$$$ */ dcb->tag_mask = 0; dcb->flag = 0; dcb->max_command = 1; /* $$$$$$$ */ - index = acb->adapter_index; - eeprom = &eeprom_buf[index]; dcb->dev_mode = eeprom->target[target].cfg0; /*dcb->AdpMode = eeprom->channel_cfg; */ dcb->inquiry7 = 0; @@ -4803,9 +4754,10 @@ /* $$$$$$$ */ if (dcb->target_lun != 0) { /* Copy settings */ - struct DeviceCtlBlk *prevDCB = acb->link_dcb; - while (prevDCB->target_id != dcb->target_id) - prevDCB = prevDCB->next; + struct DeviceCtlBlk *prevDCB; + list_for_each_entry(prevDCB, &acb->dcb_list, list) + if (prevDCB->target_id == dcb->target_id) + break; dprintkdbg(DBG_KG, "Copy settings from %02i-%02i to %02i-%02i\n", prevDCB->target_id, prevDCB->target_lun, @@ -4935,9 +4887,7 @@ int i; for (i = 0; i < acb->srb_count - 1; i++) - acb->srb_array[i].next = &acb->srb_array[i + 1]; - acb->srb_array[i].next = NULL; - /*DC395x_Free_integrity (acb); */ + srb_free_insert(acb, &acb->srb_array[i]); } @@ -4951,13 +4901,12 @@ *********************************************************************** */ static -int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq, u16 index) +int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq) { - struct NvRamType *eeprom; - struct AdapterCtlBlk *acb; + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; + struct NvRamType *eeprom = &acb->eeprom; u16 i; - eeprom = &eeprom_buf[index]; host->max_cmd_len = 24; host->can_queue = DC395x_MAX_CMD_QUEUE; host->cmd_per_lun = DC395x_MAX_CMD_PER_LUN; @@ -4969,7 +4918,6 @@ host->irq = irq; host->last_reset = jiffies; - acb = (struct AdapterCtlBlk *) host->hostdata; host->max_id = 16; if (host->max_id - 1 == eeprom->scsi_id) @@ -4987,15 +4935,12 @@ */ acb->scsi_host = host; acb->IOPortBase = (u16) io_port; - acb->link_dcb = NULL; acb->dcb_run_robin = NULL; acb->active_dcb = NULL; acb->srb_count = DC395x_MAX_SRB_CNT; - acb->adapter_index = index; acb->scsi_host->this_id = eeprom->scsi_id; acb->hostid_bit = (1 << acb->scsi_host->this_id); /*acb->scsi_host->this_lun = 0; */ - acb->dcb_count = 0; acb->irq_level = irq; acb->tag_max_num = 1 << eeprom->max_tag; if (acb->tag_max_num > 30) @@ -5020,14 +4965,14 @@ return 1; } #endif + INIT_LIST_HEAD(&acb->dcb_list); + INIT_LIST_HEAD(&acb->srb_free_list); link_srb(acb); - acb->free_srb = acb->srb_array; + /* * temp SRB for Q tag used or abort command used */ acb->tmp_srb = &acb->srb; - acb->srb.dcb = NULL; - acb->srb.next = NULL; init_timer(&acb->waiting_timer); for (i = 0; i < DC395x_MAX_SCSI_ID; i++) @@ -5050,16 +4995,14 @@ * @host: This hosts adapter strcuture * @io_port: The base I/O port * @irq: IRQ - * @index: Card instance number * * Returns 0 if the initialization succeeds, any other value on failure. **/ static -int __init init_adapter(struct Scsi_Host *host, u32 io_port, - u8 irq, u16 index) +int __init init_adapter(struct Scsi_Host *host, u32 io_port, u8 irq) { - struct NvRamType *eeprom = &eeprom_buf[index]; struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; + struct NvRamType *eeprom = &acb->eeprom; if (!request_region(io_port, host->n_io_port, DC395X_NAME)) { dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port); @@ -5106,9 +5049,7 @@ acb->scsi_host->last_reset = jiffies + HZ / 2 + - HZ * - eeprom_buf[acb->adapter_index]. - delay_time; + HZ * acb->eeprom.delay_time; /*spin_lock_irq (&io_request_lock); */ } @@ -5465,22 +5406,22 @@ * print_eeprom_settings - output the eeprom settings * to the kernel log so people can see what they were. * - * @index: Adapter number + * @eeprom: The eeprom data strucutre to show details for. **/ static -void __init print_eeprom_settings(u16 index) +void __init print_eeprom_settings(struct NvRamType *eeprom) { dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n", - eeprom_buf[index].scsi_id, - eeprom_buf[index].target[0].period, - clock_speed[eeprom_buf[index].target[0].period] / 10, - clock_speed[eeprom_buf[index].target[0].period] % 10, - eeprom_buf[index].target[0].cfg0); + eeprom->scsi_id, + eeprom->target[0].period, + clock_speed[eeprom->target[0].period] / 10, + clock_speed[eeprom->target[0].period] % 10, + eeprom->target[0].cfg0); dprintkl(KERN_INFO, " AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n", - eeprom_buf[index].channel_cfg, - eeprom_buf[index].max_tag, - 1 << eeprom_buf[index].max_tag, - eeprom_buf[index].delay_time); + eeprom->channel_cfg, + eeprom->max_tag, + 1 << eeprom->max_tag, + eeprom->delay_time); } @@ -5497,52 +5438,37 @@ */ static struct Scsi_Host *__init host_init(Scsi_Host_Template * host_template, - u32 io_port, u8 irq, - u16 index) + u32 io_port, u8 irq) { struct Scsi_Host *host; struct AdapterCtlBlk *acb; - /* - * Read the eeprom contents info the buffer we supply. Use - * defaults is eeprom checksum is wrong. - */ - check_eeprom(&eeprom_buf[index], (u16) io_port); - - /* - *$$$$$$$$$$$ MEMORY ALLOCATE FOR ADAPTER CONTROL BLOCK $$$$$$$$$$$$ - */ host = scsi_host_alloc(host_template, sizeof(struct AdapterCtlBlk)); if (!host) { - dprintkl(KERN_INFO, "pSH scsi_host_alloc ERROR\n"); - return 0; + dprintkl(KERN_INFO, "scsi_host_alloc failed\n"); + goto failed; } - print_eeprom_settings(index); + acb = (struct AdapterCtlBlk *)host->hostdata; - acb = (struct AdapterCtlBlk *) host->hostdata; - if (init_acb(host, io_port, irq, index)) { - scsi_host_put(host); - return 0; + check_eeprom(&acb->eeprom, (u16)io_port); + print_eeprom_settings(&acb->eeprom); + + if (init_acb(host, io_port, irq)) { + goto failed; } print_config(acb); - /* - *$$$$$$$$$$$$$$$$$ INITIAL ADAPTER $$$$$$$$$$$$$$$$$ - */ - if (!init_adapter(host, io_port, irq, index)) { - if (!acb_list_head) { - acb_list_head = acb; - } else { - acb_list_tail->next_acb = acb; - } - acb_list_tail = acb; - acb->next_acb = NULL; - } else { + if (init_adapter(host, io_port, irq)) { dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n"); - scsi_host_put(host); - host = NULL; + goto failed; } + return host; + +failed: + if (host) + scsi_host_put(host); + return NULL; } #undef SEARCH @@ -5579,24 +5505,15 @@ else SPRINTF(" No ") static -int dc395x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, +int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) { - int dev, spd, spd1; + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; + int spd, spd1; char *pos = buffer; - struct AdapterCtlBlk *acb; struct DeviceCtlBlk *dcb; unsigned long flags; - - acb = acb_list_head; - - while (acb) { - if (acb->scsi_host == shpnt) - break; - acb = acb->next_acb; - } - if (!acb) - return -ESRCH; + int dev; if (inout) /* Has data been written to the file ? */ return -EPERM; @@ -5606,26 +5523,24 @@ DC395x_LOCK_IO(acb->scsi_host, flags); - SPRINTF("SCSI Host Nr %i, ", shpnt->host_no); - SPRINTF("DC395U/UW/F DC315/U %s Adapter Nr %i\n", - (acb->config & HCC_WIDE_CARD) ? "Wide" : "", - acb->adapter_index); + SPRINTF("SCSI Host Nr %i, ", host->host_no); + SPRINTF("DC395U/UW/F DC315/U %s\n", + (acb->config & HCC_WIDE_CARD) ? "Wide" : ""); SPRINTF("IOPortBase 0x%04x, ", acb->IOPortBase); SPRINTF("irq_level 0x%02x, ", acb->irq_level); SPRINTF(" SelTimeout %ims\n", (1638 * acb->sel_timeout) / 1000); - SPRINTF("MaxID %i, MaxLUN %i, ", shpnt->max_id, shpnt->max_lun); - SPRINTF("AdapterID %i\n", shpnt->this_id); + SPRINTF("MaxID %i, MaxLUN %i, ", host->max_id, host->max_lun); + SPRINTF("AdapterID %i\n", host->this_id); SPRINTF("tag_max_num %i", acb->tag_max_num); /*SPRINTF(", DMA_Status %i\n", DC395x_read8(acb, TRM_S1040_DMA_STATUS)); */ SPRINTF(", FilterCfg 0x%02x", DC395x_read8(acb, TRM_S1040_SCSI_CONFIG1)); - SPRINTF(", DelayReset %is\n", - eeprom_buf[acb->adapter_index].delay_time); + SPRINTF(", DelayReset %is\n", acb->eeprom.delay_time); /*SPRINTF("\n"); */ - SPRINTF("Nr of DCBs: %i\n", acb->dcb_count); + SPRINTF("Nr of DCBs: %i\n", list_size(&acb->dcb_list)); SPRINTF ("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n", acb->dcb_map[0], acb->dcb_map[1], acb->dcb_map[2], @@ -5640,8 +5555,8 @@ SPRINTF ("Un ID LUN Prty Sync Wide DsCn SndS TagQ nego_period SyncFreq SyncOffs MaxCmd\n"); - dcb = acb->link_dcb; - for (dev = 0; dev < acb->dcb_count; dev++) { + dev = 0; + list_for_each_entry(dcb, &acb->dcb_list, list) { int nego_period; SPRINTF("%02i %02i %02i ", dev, dcb->target_id, dcb->target_lun); @@ -5651,8 +5566,7 @@ YESNO(dcb->dev_mode & NTC_DO_DISCONNECT); YESNO(dcb->dev_mode & NTC_DO_SEND_START); YESNO(dcb->sync_mode & EN_TAG_QUEUEING); - nego_period = - clock_period[dcb->sync_period & 0x07] << 2; + nego_period = clock_period[dcb->sync_period & 0x07] << 2; if (dcb->sync_offset) SPRINTF(" %03i ns ", nego_period); else @@ -5669,45 +5583,42 @@ /* Add more info ... */ SPRINTF(" %02i\n", dcb->max_command); - dcb = dcb->next; + dev++; } if (timer_pending(&acb->waiting_timer)) SPRINTF("Waiting queue timer running\n"); else SPRINTF("\n"); - dcb = acb->link_dcb; - for (dev = 0; dev < acb->dcb_count; dev++) { + list_for_each_entry(dcb, &acb->dcb_list, list) { struct ScsiReqBlk *srb; - if (dcb->waiting_srb_count) + if (!list_empty(&dcb->srb_waiting_list)) SPRINTF("DCB (%02i-%i): Waiting: %i:", dcb->target_id, dcb->target_lun, - dcb->waiting_srb_count); - for (srb = dcb->waiting_srb; srb; srb = srb->next) + list_size(&dcb->srb_waiting_list)); + list_for_each_entry(srb, &dcb->srb_waiting_list, list) SPRINTF(" %li", srb->cmd->pid); - if (dcb->going_srb_count) + if (!list_empty(&dcb->srb_going_list)) SPRINTF("\nDCB (%02i-%i): Going : %i:", dcb->target_id, dcb->target_lun, - dcb->going_srb_count); - for (srb = dcb->going_srb; srb; srb = srb->next) + list_size(&dcb->srb_going_list)); + list_for_each_entry(srb, &dcb->srb_going_list, list) #if debug_enabled(DBG_TRACE|DBG_TRACEALL) SPRINTF("\n %s", srb->debugtrace); #else SPRINTF(" %li", srb->cmd->pid); #endif - if (dcb->waiting_srb_count || dcb->going_srb_count) + if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list)) SPRINTF("\n"); - dcb = dcb->next; } if (debug_enabled(DBG_DCB)) { SPRINTF("DCB list for ACB %p:\n", acb); - dcb = acb->link_dcb; - SPRINTF("%p", dcb); - for (dev = 0; dev < acb->dcb_count; dev++, dcb = dcb->next) - SPRINTF("->%p", dcb->next); - SPRINTF("\n"); + list_for_each_entry(dcb, &acb->dcb_list, list) { + SPRINTF("%p -> ", dcb); + } + SPRINTF("END\n"); } *start = buffer + offset; @@ -5766,19 +5677,13 @@ void free_dcbs(struct AdapterCtlBlk* acb) { struct DeviceCtlBlk *dcb; - struct DeviceCtlBlk *dcb_next; + struct DeviceCtlBlk *tmp; - dprintkdbg(DBG_DCB, "Free %i DCBs\n", acb->dcb_count); + dprintkdbg(DBG_DCB, "Free %i DCBs\n", list_size(&acb->dcb_list)); - for (dcb = acb->link_dcb; dcb != NULL; dcb = dcb_next) - { - dcb_next = dcb->next; + list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list) { dprintkdbg(DBG_DCB, "Free DCB (ID %i, LUN %i): %p\n", dcb->target_id, dcb->target_lun, dcb); - /* - * Free the DCB. This removes the entry from the - * link_dcb list and decrements the count in dcb_count - */ remove_dev(acb, dcb); } } @@ -5852,6 +5757,7 @@ u8 irq; struct Scsi_Host *scsi_host; static int banner_done = 0; + int error = 0; dprintkdbg(DBG_0, "Init one instance of the dc395x\n"); if (!banner_done) @@ -5871,29 +5777,27 @@ irq = dev->irq; dprintkdbg(DBG_0, "IO_PORT=%04x,IRQ=%x\n", (unsigned int) io_port, irq); - scsi_host = host_init(&dc395x_driver_template, io_port, irq, adapter_count); + scsi_host = host_init(&dc395x_driver_template, io_port, irq); if (!scsi_host) { dprintkdbg(DBG_0, "host_init failed\n"); return -ENOMEM; } - - pci_set_master(dev); - - /* store pci devices in out host data object. */ ((struct AdapterCtlBlk *)(scsi_host->hostdata))->dev = dev; - - /* increment adaptor count */ - adapter_count++; - - /* store ptr to scsi host in the PCI device structure */ + pci_set_master(dev); pci_set_drvdata(dev, scsi_host); /* get the scsi mid level to scan for new devices on the bus */ - scsi_add_host(scsi_host, &dev->dev); /* XXX handle failure */ - scsi_scan_host(scsi_host); - - return 0; + error = scsi_add_host(scsi_host, &dev->dev); + if (error) { + dprintkl(KERN_ERR, "scsi_add_host failed\n"); + error = -ENODEV; + host_release(scsi_host); + scsi_host_put(scsi_host); + } else + scsi_scan_host(scsi_host); + + return error; } @@ -5906,9 +5810,15 @@ static void __devexit dc395x_remove_one(struct pci_dev *dev) { struct Scsi_Host *host = pci_get_drvdata(dev); + dprintkdbg(DBG_0, "Removing instance\n"); + if (!host) { + dprintkl(KERN_ERR, "no host allocated\n"); + return; + } scsi_remove_host(host); host_release(host); + scsi_host_put(host); pci_set_drvdata(dev, NULL); } diff -Nru a/drivers/scsi/dc395x.h b/drivers/scsi/dc395x.h --- a/drivers/scsi/dc395x.h Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/dc395x.h Mon Aug 18 22:21:06 2003 @@ -28,7 +28,6 @@ #define DC395x_MAX_CMD_QUEUE 32 /* #define DC395x_MAX_QTAGS 32 */ #define DC395x_MAX_QTAGS 16 -#define DC395x_MAX_ADAPTER_NUM 4 #define DC395x_MAX_SCSI_ID 16 #define DC395x_MAX_CMD_PER_LUN DC395x_MAX_QTAGS #define DC395x_MAX_SG_TABLESIZE 64 /* HW limitation */ diff -Nru a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c --- a/drivers/scsi/eata_pio.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/eata_pio.c Mon Aug 18 22:21:04 2003 @@ -873,13 +873,13 @@ u32 base, x; while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) { - DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", dev->dev.name)); + DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", pci_name(dev))); if (pci_enable_device(dev)) continue; pci_set_master(dev); base = pci_resource_flags(dev, 0); if (base & IORESOURCE_MEM) { - printk("eata_pio: invalid base address of device %s\n", dev->dev.name); + printk("eata_pio: invalid base address of device %s\n", pci_name(dev)); continue; } base = pci_resource_start(dev, 0); diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c --- a/drivers/scsi/esp.c Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/esp.c Mon Aug 18 22:21:06 2003 @@ -4392,7 +4392,6 @@ .sg_tablesize = SG_ALL, .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, - .highmem_io = 1, }; #include "scsi_module.c" diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c --- a/drivers/scsi/gdth.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/gdth.c Mon Aug 18 22:21:04 2003 @@ -27,6 +27,9 @@ * Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.20 * * * * $Log: gdth.c,v $ + * Revision 1.63 2003/07/12 14:01:00 Daniele Bellucci + * Minor cleanups in gdth_ioctl. + * * Revision 1.62 2003/02/27 15:01:59 achim * Dynamic DMA mapping implemented * New (character device) IOCTL interface added @@ -5433,14 +5436,16 @@ case GDTIOCTL_CTRCNT: { int cnt = gdth_ctr_count; - put_user(cnt, (int *)arg); + if (put_user(cnt, (int *)arg)) + return -EFAULT; break; } case GDTIOCTL_DRVERS: { int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION; - put_user(ver, (int *)arg); + if (put_user(ver, (int *)arg)) + return -EFAULT; break; } @@ -5451,7 +5456,8 @@ osv.version = (unchar)(LINUX_VERSION_CODE >> 16); osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8); osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff); - copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers)); + if (copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers))) + return -EFAULT; break; } diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c --- a/drivers/scsi/hosts.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/hosts.c Mon Aug 18 22:21:01 2003 @@ -39,30 +39,53 @@ static int scsi_host_next_hn; /* host_no for next new host */ + +static void scsi_host_cls_release(struct class_device *class_dev) +{ + put_device(&class_to_shost(class_dev)->shost_gendev); +} + +static struct class shost_class = { + .name = "scsi_host", + .release = scsi_host_cls_release, +}; + /** - * scsi_remove_host - check a scsi host for release and release - * @shost: a pointer to a scsi host to release - * - * Return value: - * 0 on Success / 1 on Failure + * scsi_host_cancel - cancel outstanding IO to this host + * @shost: pointer to struct Scsi_Host + * recovery: recovery requested to run. **/ -int scsi_remove_host(struct Scsi_Host *shost) +void scsi_host_cancel(struct Scsi_Host *shost, int recovery) { - struct scsi_device *sdev; + unsigned long flags; - /* - * FIXME Do ref counting. We force all of the devices offline to - * help prevent race conditions where other hosts/processors could - * try and get in and queue a command. - */ - list_for_each_entry(sdev, &shost->my_devices, siblings) - sdev->online = FALSE; + spin_lock_irqsave(shost->host_lock, flags); + set_bit(SHOST_CANCEL, &shost->shost_state); + spin_unlock_irqrestore(shost->host_lock, flags); + device_for_each_child(&shost->shost_gendev, &recovery, + scsi_device_cancel_cb); + wait_event(shost->host_wait, (!test_bit(SHOST_RECOVERY, + &shost->shost_state))); +} +/** + * scsi_remove_host - remove a scsi host + * @shost: a pointer to a scsi host to remove + **/ +void scsi_remove_host(struct Scsi_Host *shost) +{ + unsigned long flags; + + scsi_host_cancel(shost, 0); scsi_proc_host_rm(shost); scsi_forget_host(shost); - scsi_sysfs_remove_host(shost); - return 0; + spin_lock_irqsave(shost->host_lock, flags); + set_bit(SHOST_DEL, &shost->shost_state); + spin_unlock_irqrestore(shost->host_lock, flags); + + class_device_unregister(&shost->shost_classdev); + device_del(&shost->shost_gendev); } /** @@ -84,21 +107,45 @@ if (!shost->can_queue) { printk(KERN_ERR "%s: can_queue = 0 no longer supported\n", sht->name); - error = -EINVAL; + return -EINVAL; } - error = scsi_sysfs_add_host(shost, dev); - if (!error) - scsi_proc_host_add(shost); + if (!shost->shost_gendev.parent) + shost->shost_gendev.parent = dev ? dev : &legacy_bus; + + error = device_add(&shost->shost_gendev); + if (error) + goto out; + + set_bit(SHOST_ADD, &shost->shost_state); + get_device(shost->shost_gendev.parent); + + error = class_device_add(&shost->shost_classdev); + if (error) + goto out_del_gendev; + + get_device(&shost->shost_gendev); + + error = scsi_sysfs_add_host(shost); + if (error) + goto out_del_classdev; + + scsi_proc_host_add(shost); + return error; + + out_del_classdev: + class_device_del(&shost->shost_classdev); + out_del_gendev: + device_del(&shost->shost_gendev); + out: return error; } -/** - * scsi_free_sdev - free a scsi hosts resources - * @shost: scsi host to free - **/ -void scsi_free_shost(struct Scsi_Host *shost) +static void scsi_host_dev_release(struct device *dev) { + struct Scsi_Host *shost = dev_to_shost(dev); + struct device *parent = dev->parent; + if (shost->ehandler) { DECLARE_COMPLETION(sem); shost->eh_notify = &sem; @@ -108,8 +155,10 @@ shost->eh_notify = NULL; } - shost->hostt->present--; + scsi_proc_hostdir_rm(shost->hostt); scsi_destroy_command_freelist(shost); + + put_device(parent); kfree(shost); } @@ -182,7 +231,6 @@ shost->unchecked_isa_dma = sht->unchecked_isa_dma; shost->use_clustering = sht->use_clustering; shost->use_blk_tcq = sht->use_blk_tcq; - shost->highmem_io = sht->highmem_io; if (sht->max_host_blocked) shost->max_host_blocked = sht->max_host_blocked; @@ -198,18 +246,35 @@ else shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS; + /* + * assume a 4GB boundary, if not set + */ + if (sht->dma_boundary) + shost->dma_boundary = sht->dma_boundary; + else + shost->dma_boundary = 0xffffffff; + rval = scsi_setup_command_freelist(shost); if (rval) goto fail; - scsi_sysfs_init_host(shost); + device_initialize(&shost->shost_gendev); + snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d", + shost->host_no); + shost->shost_gendev.release = scsi_host_dev_release; + + class_device_initialize(&shost->shost_classdev); + shost->shost_classdev.dev = &shost->shost_gendev; + shost->shost_classdev.class = &shost_class; + snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", + shost->host_no); shost->eh_notify = &complete; /* XXX(hch): handle error return */ kernel_thread((int (*)(void *))scsi_error_handler, shost, 0); wait_for_completion(&complete); shost->eh_notify = NULL; - shost->hostt->present++; + scsi_proc_hostdir_add(shost->hostt); return shost; fail: kfree(shost); @@ -249,21 +314,21 @@ { struct class *class = class_get(&shost_class); struct class_device *cdev; - struct Scsi_Host *shost = NULL, *p; + struct Scsi_Host *shost = ERR_PTR(-ENXIO), *p; if (class) { down_read(&class->subsys.rwsem); list_for_each_entry(cdev, &class->children, node) { p = class_to_shost(cdev); if (p->host_no == hostnum) { - scsi_host_get(p); - shost = p; + shost = scsi_host_get(p); break; } } up_read(&class->subsys.rwsem); } + class_put(&shost_class); return shost; } @@ -271,10 +336,12 @@ * *scsi_host_get - inc a Scsi_Host ref count * @shost: Pointer to Scsi_Host to inc. **/ -void scsi_host_get(struct Scsi_Host *shost) +struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost) { - get_device(&shost->shost_gendev); - class_device_get(&shost->shost_classdev); + if (test_bit(SHOST_DEL, &shost->shost_state) || + !get_device(&shost->shost_gendev)) + return NULL; + return shost; } /** @@ -283,6 +350,15 @@ **/ void scsi_host_put(struct Scsi_Host *shost) { - class_device_put(&shost->shost_classdev); put_device(&shost->shost_gendev); +} + +int scsi_init_hosts(void) +{ + return class_register(&shost_class); +} + +void scsi_exit_hosts(void) +{ + class_unregister(&shost_class); } diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c --- a/drivers/scsi/ide-scsi.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/ide-scsi.c Mon Aug 18 22:21:04 2003 @@ -761,8 +761,8 @@ printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10); #endif /* IDESCSI_DEBUG_LOG */ bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer); + bh->bi_io_vec[0].bv_offset = offset_in_page(pc->scsi_cmd->request_buffer); bh->bi_io_vec[0].bv_len = pc->request_transfer; - bh->bi_io_vec[0].bv_offset = (unsigned long) pc->scsi_cmd->request_buffer & ~PAGE_MASK; bh->bi_size = pc->request_transfer; } return first_bh; @@ -872,7 +872,7 @@ continue; } /* no, but is it queued in the ide subsystem? */ - if (elv_queue_empty(&drive->queue)) { + if (elv_queue_empty(drive->queue)) { spin_unlock_irqrestore(&ide_lock, flags); return SUCCESS; } @@ -899,7 +899,7 @@ schedule_timeout(1); } /* now nuke the drive queue */ - while ((req = elv_next_request(&drive->queue))) { + while ((req = elv_next_request(drive->queue))) { blkdev_dequeue_request(req); end_that_request_last(req); } @@ -948,7 +948,6 @@ }; static struct device idescsi_primary = { - .name = "Ide-scsi Parent", .bus_id = "ide-scsi", }; static struct bus_type idescsi_emu_bus = { diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c --- a/drivers/scsi/ips.c Mon Aug 18 22:21:00 2003 +++ b/drivers/scsi/ips.c Mon Aug 18 22:21:00 2003 @@ -5,8 +5,8 @@ /* Jack Hammer, Adaptec, Inc. */ /* David Jeffery, Adaptec, Inc. */ /* */ -/* Copyright (C) 2000 IBM Corporation */ -/* Copyright (C) 2002,2003 Adaptec, Inc. */ +/* Copyright (C) 2000 IBM Corporation */ +/* 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 */ @@ -130,6 +130,7 @@ /* 5.10.15 - remove unused code (sem, macros, etc.) */ /* 5.30.00 - use __devexit_p() */ /* 6.00.00 - Add 6x Adapters and Battery Flash */ +/* 6.10.00 - Remove 1G Addressing Limitations */ /*****************************************************************************/ /* @@ -150,7 +151,7 @@ * nommap - Don't use memory mapped I/O * ioctlsize - Initial size of the IOCTL buffer */ - + #include #include #include @@ -187,34 +188,34 @@ #include #ifdef MODULE - static char *ips = NULL; - MODULE_PARM(ips, "s"); +static char *ips = NULL; +MODULE_PARM(ips, "s"); #endif /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "5.99" -#define IPS_VERSION_LOW ".01-BETA" - +#define IPS_VERSION_HIGH "6.10" +#define IPS_VERSION_LOW ".90-BETA" -#if !defined(__i386__) && !defined(__ia64__) - #error "This driver has only been tested on the x86/ia64 platforms" +#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) +#error "This driver has only been tested on the x86/ia64/x86_64 platforms" #endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) - #include "sd.h" - #define IPS_SG_ADDRESS(sg) ((sg)->address) - #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) - #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) - #ifndef __devexit_p - #define __devexit_p(x) x - #endif +#include +#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) +#ifndef __devexit_p +#define __devexit_p(x) x +#endif #else - #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ +#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ page_address((sg)->page)+(sg)->offset : 0) - #define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0) - #define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0) +#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0) +#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0) #endif #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \ @@ -223,34 +224,35 @@ scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction)) #ifdef IPS_DEBUG - #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n"); - #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n"); - #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v); +#define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n"); +#define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n"); +#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v); #else - #define METHOD_TRACE(s, i) - #define DEBUG(i, s) - #define DEBUG_VAR(i, s, v...) +#define METHOD_TRACE(s, i) +#define DEBUG(i, s) +#define DEBUG_VAR(i, s, v...) #endif /* * global variables */ -static const char ips_name[] = "ips"; -static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */ -static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */ +static const char ips_name[] = "ips"; +static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */ +static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */ static unsigned int ips_next_controller; static unsigned int ips_num_controllers; static unsigned int ips_released_controllers; -static int ips_hotplug; -static int ips_cmd_timeout = 60; -static int ips_reset_timeout = 60 * 5; -static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ -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; /* Booting from Manager CD */ -static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ -static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */ -static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ +static int ips_hotplug; +static int ips_cmd_timeout = 60; +static int ips_reset_timeout = 60 * 5; +static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ +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; /* Booting from Manager CD */ +static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ +static dma_addr_t ips_flashbusaddr; +static long ips_FlashDataInUse; /* 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 = { .detect = ips_detect, .release = ips_release, @@ -258,9 +260,12 @@ .queuecommand = ips_queue, .eh_abort_handler = ips_eh_abort, .eh_host_reset_handler = ips_eh_reset, + .proc_name = "ips", #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + .proc_info = ips_proc_info, .slave_configure = ips_slave_configure, #else + .proc_info = ips_proc24_info, .select_queue_depths = ips_select_queue_depth, #endif .bios_param = ips_biosparam, @@ -268,38 +273,35 @@ .sg_tablesize = IPS_MAX_SG, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) || (defined CONFIG_HIGHIO) - .highmem_io = 1, -#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) .use_new_eh_code = 1, #endif }; -IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ +IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ - /* This table describes all ServeRAID Adapters */ - static struct pci_device_id ips_pci_table[] = { - { 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 all ServeRAID Adapters */ +static struct pci_device_id ips_pci_table[] = { + { 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, } +}; - MODULE_DEVICE_TABLE( pci, ips_pci_table ); +MODULE_DEVICE_TABLE( pci, ips_pci_table ); - static char ips_hot_plug_name[] = "ips"; +static char ips_hot_plug_name[] = "ips"; - static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent); - static void __devexit ips_remove_device(struct pci_dev *pci_dev); +static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent); +static void __devexit ips_remove_device(struct pci_dev *pci_dev); - struct pci_driver ips_pci_driver = { - .name = ips_hot_plug_name, - .id_table = ips_pci_table, - .probe = ips_insert_device, - .remove = __devexit_p(ips_remove_device), - }; +struct pci_driver ips_pci_driver = { + .name = ips_hot_plug_name, + .id_table = ips_pci_table, + .probe = ips_insert_device, + .remove = __devexit_p(ips_remove_device), +}; /* @@ -310,83 +312,82 @@ #define MAX_ADAPTER_NAME 15 static char ips_adapter_name[][30] = { - "ServeRAID", - "ServeRAID II", - "ServeRAID on motherboard", - "ServeRAID on motherboard", - "ServeRAID 3H", - "ServeRAID 3L", - "ServeRAID 4H", - "ServeRAID 4M", - "ServeRAID 4L", - "ServeRAID 4Mx", - "ServeRAID 4Lx", - "ServeRAID 5i", - "ServeRAID 5i", - "ServeRAID 00", - "ServeRAID 00" + "ServeRAID", + "ServeRAID II", + "ServeRAID on motherboard", + "ServeRAID on motherboard", + "ServeRAID 3H", + "ServeRAID 3L", + "ServeRAID 4H", + "ServeRAID 4M", + "ServeRAID 4L", + "ServeRAID 4Mx", + "ServeRAID 4Lx", + "ServeRAID 5i", + "ServeRAID 5i", + "ServeRAID 6M", + "ServeRAID 6i" }; - static struct notifier_block ips_notifier = { - ips_halt, NULL, 0 + ips_halt, NULL, 0 }; /* * Direction table */ static char ips_command_direction[] = { -IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, -IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, -IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT, -IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, -IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN, -IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, -IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, -IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, -IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE, -IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, -IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, -IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT, -IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, -IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, -IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK + IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, + IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, + IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT, + IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, + IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN, + IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, + IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, + IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, + IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE, + IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, + IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, + IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT, + IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, + IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, + IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK }; /* @@ -396,8 +397,8 @@ int ips_release(struct Scsi_Host *); int ips_eh_abort(Scsi_Cmnd *); int ips_eh_reset(Scsi_Cmnd *); -int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *)); -const char * ips_info(struct Scsi_Host *); +int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +const char *ips_info(struct Scsi_Host *); irqreturn_t do_ipsintr(int, void *, struct pt_regs *); static int ips_hainit(ips_ha_t *); static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *); @@ -442,7 +443,7 @@ static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *); -static void ips_free_flash_copperhead(ips_ha_t *ha); +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_chkstatus(ips_ha_t *, IPS_STATUS *); @@ -467,37 +468,42 @@ static uint32_t ips_statupd_copperhead(ips_ha_t *); static uint32_t ips_statupd_copperhead_memio(ips_ha_t *); static uint32_t ips_statupd_morpheus(ips_ha_t *); -static ips_scb_t * ips_getscb(ips_ha_t *); +static ips_scb_t *ips_getscb(ips_ha_t *); static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *); static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *); static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *); static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *); -static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *); -static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *); -static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *); -static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); -static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *); -static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); -static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *); -static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *); +static inline void ips_putq_copp_head(ips_copp_queue_t *, + ips_copp_wait_item_t *); +static inline void ips_putq_copp_tail(ips_copp_queue_t *, + ips_copp_wait_item_t *); +static inline ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *); +static inline ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); +static inline Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *); +static inline Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); +static inline ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *, + ips_copp_wait_item_t *); +static inline ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *); static int ips_is_passthru(Scsi_Cmnd *); 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); +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(struct Scsi_Host *, char *, char **, off_t, int, int); +int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int ips_host_info(ips_ha_t *, char *, off_t, int); static void copy_mem_info(IPS_INFOSTR *, char *, int); 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, int index); -static int ips_init_phase2( int index ); +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, int index); +static int ips_init_phase2(int index); -static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ); +static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr); static int ips_register_scsi(int index); /*--------------------------------------------------------------------------*/ /* Exported Functions */ @@ -513,43 +519,48 @@ /* */ /****************************************************************************/ static int -ips_setup(char *ips_str) { +ips_setup(char *ips_str) +{ - int i; - char *key; - char *value; - IPS_OPTION options[] = { - {"noi2o", &ips_force_i2o, 0}, - {"nommap", &ips_force_memio, 0}, - {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE}, - {"cdboot", &ips_cd_boot, 0}, - {"maxcmds", &MaxLiteCmds, 32}, - }; - - /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ - /* Search for value */ - while ((key = strsep(&ips_str, ",."))) { - if (!*key) - continue; - value = strchr(key, ':'); - if (value) - *value++ = '\0'; - /* - * We now have key/value pairs. - * Update the variables - */ - for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) { - if (strnicmp(key, options[i].option_name, strlen(options[i].option_name)) == 0) { - if (value) - *options[i].option_flag = simple_strtoul(value, NULL, 0); - else - *options[i].option_flag = options[i].option_value; - break; - } - } - } + int i; + char *key; + char *value; + IPS_OPTION options[] = { + {"noi2o", &ips_force_i2o, 0}, + {"nommap", &ips_force_memio, 0}, + {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE}, + {"cdboot", &ips_cd_boot, 0}, + {"maxcmds", &MaxLiteCmds, 32}, + }; + + /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ + /* Search for value */ + while ((key = strsep(&ips_str, ",."))) { + if (!*key) + continue; + value = strchr(key, ':'); + if (value) + *value++ = '\0'; + /* + * We now have key/value pairs. + * Update the variables + */ + for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) { + if (strnicmp + (key, options[i].option_name, + strlen(options[i].option_name)) == 0) { + if (value) + *options[i].option_flag = + simple_strtoul(value, NULL, 0); + else + *options[i].option_flag = + options[i].option_value; + break; + } + } + } - return (1); + return (1); } __setup("ips=", ips_setup); @@ -566,94 +577,83 @@ /* */ /****************************************************************************/ int -ips_detect(Scsi_Host_Template *SHT) { - int i; +ips_detect(Scsi_Host_Template * SHT) +{ + int i; - METHOD_TRACE("ips_detect", 1); + METHOD_TRACE("ips_detect", 1); #ifdef MODULE - if (ips) - ips_setup(ips); + if (ips) + ips_setup(ips); #endif - /* 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( 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" ); - } - } - - SHT->proc_info = ips_proc_info; - SHT->proc_name = "ips"; - - for(i = 0; i < ips_num_controllers; i++){ - if ( ips_register_scsi(i) ) - ips_free(ips_ha[i]); - ips_released_controllers++; - } - ips_hotplug = 1; - return (ips_num_controllers); + for (i = 0; i < ips_num_controllers; i++) { + if (ips_register_scsi(i)) + ips_free(ips_ha[i]); + ips_released_controllers++; + } + ips_hotplug = 1; + return (ips_num_controllers); } - /****************************************************************************/ /* configure the function pointers to use the functions that will work */ /* with the found version of the adapter */ /****************************************************************************/ -static void ips_setup_funclist(ips_ha_t *ha){ +static void +ips_setup_funclist(ips_ha_t * ha) +{ - /* - * Setup Functions - */ - if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { - /* morpheus / marco / sebring */ - ha->func.isintr = ips_isintr_morpheus; - ha->func.isinit = ips_isinit_morpheus; - ha->func.issue = ips_issue_i2o_memio; - ha->func.init = ips_init_morpheus; - ha->func.statupd = ips_statupd_morpheus; - ha->func.reset = ips_reset_morpheus; - ha->func.intr = ips_intr_morpheus; - ha->func.enableint = ips_enable_int_morpheus; - } else if (IPS_USE_MEMIO(ha)) { - /* copperhead w/MEMIO */ - ha->func.isintr = ips_isintr_copperhead_memio; - ha->func.isinit = ips_isinit_copperhead_memio; - ha->func.init = ips_init_copperhead_memio; - ha->func.statupd = ips_statupd_copperhead_memio; - ha->func.statinit = ips_statinit_memio; - ha->func.reset = ips_reset_copperhead_memio; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios_memio; - ha->func.programbios = ips_program_bios_memio; - ha->func.verifybios = ips_verify_bios_memio; - ha->func.enableint = ips_enable_int_copperhead_memio; - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o_memio; - else - ha->func.issue = ips_issue_copperhead_memio; - } else { - /* copperhead */ - ha->func.isintr = ips_isintr_copperhead; - ha->func.isinit = ips_isinit_copperhead; - ha->func.init = ips_init_copperhead; - ha->func.statupd = ips_statupd_copperhead; - ha->func.statinit = ips_statinit; - ha->func.reset = ips_reset_copperhead; - ha->func.intr = ips_intr_copperhead; - ha->func.erasebios = ips_erase_bios; - ha->func.programbios = ips_program_bios; - ha->func.verifybios = ips_verify_bios; - ha->func.enableint = ips_enable_int_copperhead; - - if (IPS_USE_I2O_DELIVER(ha)) - ha->func.issue = ips_issue_i2o; - else - ha->func.issue = ips_issue_copperhead; - } + /* + * Setup Functions + */ + if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { + /* morpheus / marco / sebring */ + ha->func.isintr = ips_isintr_morpheus; + ha->func.isinit = ips_isinit_morpheus; + ha->func.issue = ips_issue_i2o_memio; + ha->func.init = ips_init_morpheus; + ha->func.statupd = ips_statupd_morpheus; + ha->func.reset = ips_reset_morpheus; + ha->func.intr = ips_intr_morpheus; + ha->func.enableint = ips_enable_int_morpheus; + } else if (IPS_USE_MEMIO(ha)) { + /* copperhead w/MEMIO */ + ha->func.isintr = ips_isintr_copperhead_memio; + ha->func.isinit = ips_isinit_copperhead_memio; + ha->func.init = ips_init_copperhead_memio; + ha->func.statupd = ips_statupd_copperhead_memio; + ha->func.statinit = ips_statinit_memio; + ha->func.reset = ips_reset_copperhead_memio; + ha->func.intr = ips_intr_copperhead; + ha->func.erasebios = ips_erase_bios_memio; + ha->func.programbios = ips_program_bios_memio; + ha->func.verifybios = ips_verify_bios_memio; + ha->func.enableint = ips_enable_int_copperhead_memio; + if (IPS_USE_I2O_DELIVER(ha)) + ha->func.issue = ips_issue_i2o_memio; + else + ha->func.issue = ips_issue_copperhead_memio; + } else { + /* copperhead */ + ha->func.isintr = ips_isintr_copperhead; + ha->func.isinit = ips_isinit_copperhead; + ha->func.init = ips_init_copperhead; + ha->func.statupd = ips_statupd_copperhead; + ha->func.statinit = ips_statinit; + ha->func.reset = ips_reset_copperhead; + ha->func.intr = ips_intr_copperhead; + ha->func.erasebios = ips_erase_bios; + ha->func.programbios = ips_program_bios; + ha->func.verifybios = ips_verify_bios; + ha->func.enableint = ips_enable_int_copperhead; + + if (IPS_USE_I2O_DELIVER(ha)) + ha->func.issue = ips_issue_i2o; + else + ha->func.issue = ips_issue_copperhead; + } } /****************************************************************************/ @@ -666,70 +666,71 @@ /* */ /****************************************************************************/ int -ips_release(struct Scsi_Host *sh) { - ips_scb_t *scb; - ips_ha_t *ha; - int i; +ips_release(struct Scsi_Host *sh) +{ + ips_scb_t *scb; + ips_ha_t *ha; + int i; - METHOD_TRACE("ips_release", 1); + METHOD_TRACE("ips_release", 1); - for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++); + for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; - if (i == IPS_MAX_ADAPTERS) { - printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n", - ips_name); - BUG(); - return (FALSE); - } + if (i == IPS_MAX_ADAPTERS) { + printk(KERN_WARNING + "(%s) release, invalid Scsi_Host pointer.\n", ips_name); + BUG(); + return (FALSE); + } - ha = IPS_HA(sh); + ha = IPS_HA(sh); - if (!ha) - return (FALSE); + if (!ha) + return (FALSE); - /* flush the cache on the controller */ - scb = &ha->scbs[ha->max_cmds-1]; + /* flush the cache on the controller */ + scb = &ha->scbs[ha->max_cmds - 1]; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FLUSH; + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FLUSH; - scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; - scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flush_cache.state = IPS_NORM_STATE; - scb->cmd.flush_cache.reserved = 0; - scb->cmd.flush_cache.reserved2 = 0; - scb->cmd.flush_cache.reserved3 = 0; - scb->cmd.flush_cache.reserved4 = 0; + scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; + scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flush_cache.state = IPS_NORM_STATE; + scb->cmd.flush_cache.reserved = 0; + scb->cmd.flush_cache.reserved2 = 0; + scb->cmd.flush_cache.reserved3 = 0; + scb->cmd.flush_cache.reserved4 = 0; - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n"); + IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n"); - /* send command */ - if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n"); + /* send command */ + if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) + IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n"); - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n"); + IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n"); - ips_sh[i] = NULL; - ips_ha[i] = NULL; + ips_sh[i] = NULL; + ips_ha[i] = NULL; - /* free extra memory */ - ips_free(ha); + /* free extra memory */ + ips_free(ha); - /* Free I/O Region */ - if (ha->io_addr) - release_region(ha->io_addr, ha->io_len); + /* Free I/O Region */ + if (ha->io_addr) + release_region(ha->io_addr, ha->io_len); - /* free IRQ */ - free_irq(ha->irq, ha); + /* free IRQ */ + free_irq(ha->irq, ha); - IPS_REMOVE_HOST(sh); - scsi_host_put(sh); + IPS_REMOVE_HOST(sh); + scsi_host_put(sh); - ips_released_controllers++; + ips_released_controllers++; - return (FALSE); + return (FALSE); } /****************************************************************************/ @@ -742,50 +743,54 @@ /* */ /****************************************************************************/ static int -ips_halt(struct notifier_block *nb, ulong event, void *buf) { - ips_scb_t *scb; - ips_ha_t *ha; - int i; - - if ((event != SYS_RESTART) && (event != SYS_HALT) && - (event != SYS_POWER_OFF)) - return (NOTIFY_DONE); - - for (i = 0; i < ips_next_controller; i++) { - ha = (ips_ha_t *) ips_ha[i]; - - if (!ha) - continue; - - if (!ha->active) - continue; - - /* flush the cache on the controller */ - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FLUSH; - - scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; - scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flush_cache.state = IPS_NORM_STATE; - scb->cmd.flush_cache.reserved = 0; - scb->cmd.flush_cache.reserved2 = 0; - scb->cmd.flush_cache.reserved3 = 0; - scb->cmd.flush_cache.reserved4 = 0; - - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n"); - - /* send command */ - if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n"); - else - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n"); - } +ips_halt(struct notifier_block *nb, ulong event, void *buf) +{ + ips_scb_t *scb; + ips_ha_t *ha; + int i; + + if ((event != SYS_RESTART) && (event != SYS_HALT) && + (event != SYS_POWER_OFF)) + return (NOTIFY_DONE); + + for (i = 0; i < ips_next_controller; i++) { + ha = (ips_ha_t *) ips_ha[i]; + + if (!ha) + continue; + + if (!ha->active) + continue; + + /* flush the cache on the controller */ + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FLUSH; + + scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; + scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flush_cache.state = IPS_NORM_STATE; + scb->cmd.flush_cache.reserved = 0; + scb->cmd.flush_cache.reserved2 = 0; + scb->cmd.flush_cache.reserved3 = 0; + scb->cmd.flush_cache.reserved4 = 0; + + IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n"); + + /* send command */ + if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == + IPS_FAILURE) + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Incomplete Flush.\n"); + else + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Flushing Complete.\n"); + } - return (NOTIFY_OK); + return (NOTIFY_OK); } /****************************************************************************/ @@ -798,50 +803,51 @@ /* Note: this routine is called under the io_request_lock */ /****************************************************************************/ int -ips_eh_abort(Scsi_Cmnd *SC) { - ips_ha_t *ha; - ips_copp_wait_item_t *item; - int ret; - - METHOD_TRACE("ips_eh_abort", 1); - - if (!SC) - return (FAILED); - - ha = (ips_ha_t *) SC->device->host->hostdata; - - if (!ha) - return (FAILED); - - if (!ha->active) - return (FAILED); - - if (SC->serial_number != SC->serial_number_at_timeout) { - /* HMM, looks like a bogus command */ - DEBUG(1, "Abort called with bogus scsi command"); - - return (FAILED); - } - - /* See if the command is on the copp queue */ - item = ha->copp_waitlist.head; - while ((item) && (item->scsi_cmd != SC)) - item = item->next; - - if (item) { - /* Found it */ - ips_removeq_copp(&ha->copp_waitlist, item); - ret = (SUCCESS); - - /* See if the command is on the wait queue */ - } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) { - /* command not sent yet */ - ret = (SUCCESS); - } else { - /* command must have already been sent */ - ret = (FAILED); - } - return ret; +ips_eh_abort(Scsi_Cmnd * SC) +{ + ips_ha_t *ha; + ips_copp_wait_item_t *item; + int ret; + + METHOD_TRACE("ips_eh_abort", 1); + + if (!SC) + return (FAILED); + + ha = (ips_ha_t *) SC->device->host->hostdata; + + if (!ha) + return (FAILED); + + if (!ha->active) + return (FAILED); + + if (SC->serial_number != SC->serial_number_at_timeout) { + /* HMM, looks like a bogus command */ + DEBUG(1, "Abort called with bogus scsi command"); + + return (FAILED); + } + + /* See if the command is on the copp queue */ + item = ha->copp_waitlist.head; + while ((item) && (item->scsi_cmd != SC)) + item = item->next; + + if (item) { + /* Found it */ + ips_removeq_copp(&ha->copp_waitlist, item); + ret = (SUCCESS); + + /* See if the command is on the wait queue */ + } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) { + /* command not sent yet */ + ret = (SUCCESS); + } else { + /* command must have already been sent */ + ret = (FAILED); + } + return ret; } /****************************************************************************/ @@ -856,188 +862,190 @@ /* */ /****************************************************************************/ int -ips_eh_reset(Scsi_Cmnd *SC) { - int ret; - int i; - ips_ha_t *ha; - ips_scb_t *scb; - ips_copp_wait_item_t *item; +ips_eh_reset(Scsi_Cmnd * SC) +{ + int ret; + int i; + ips_ha_t *ha; + ips_scb_t *scb; + ips_copp_wait_item_t *item; - METHOD_TRACE("ips_eh_reset", 1); + METHOD_TRACE("ips_eh_reset", 1); #ifdef NO_IPS_RESET - return (FAILED); + return (FAILED); #else - if (!SC) { - DEBUG(1, "Reset called with NULL scsi command"); + if (!SC) { + DEBUG(1, "Reset called with NULL scsi command"); + + return (FAILED); + } + + ha = (ips_ha_t *) SC->device->host->hostdata; + + if (!ha) { + DEBUG(1, "Reset called with NULL ha struct"); + + return (FAILED); + } + + if (!ha->active) + return (FAILED); + + /* See if the command is on the copp queue */ + item = ha->copp_waitlist.head; + while ((item) && (item->scsi_cmd != SC)) + item = item->next; + + if (item) { + /* Found it */ + ips_removeq_copp(&ha->copp_waitlist, item); + return (SUCCESS); + } + + /* See if the command is on the wait queue */ + if (ips_removeq_wait(&ha->scb_waitlist, SC)) { + /* command not sent yet */ + return (SUCCESS); + } + + /* An explanation for the casual observer: */ + /* Part of the function of a RAID controller is automatic error */ + /* detection and recovery. As such, the only problem that physically */ + /* resetting an adapter will ever fix is when, for some reason, */ + /* the driver is not successfully communicating with the adapter. */ + /* Therefore, we will attempt to flush this adapter. If that succeeds, */ + /* then there's no real purpose in a physical reset. This will complete */ + /* much faster and avoids any problems that might be caused by a */ + /* physical reset ( such as having to fail all the outstanding I/O's ). */ + + if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */ + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FLUSH; + + scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; + scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flush_cache.state = IPS_NORM_STATE; + scb->cmd.flush_cache.reserved = 0; + scb->cmd.flush_cache.reserved2 = 0; + scb->cmd.flush_cache.reserved3 = 0; + scb->cmd.flush_cache.reserved4 = 0; + + /* Attempt the flush command */ + ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); + if (ret == IPS_SUCCESS) { + IPS_PRINTK(KERN_NOTICE, ha->pcidev, + "Reset Request - Flushed Cache\n"); + return (SUCCESS); + } + } + + /* Either we can't communicate with the adapter or it's an IOCTL request */ + /* from a utility. A physical reset is needed at this point. */ + + ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ + + /* + * command must have already been sent + * reset the controller + */ + IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n"); + ret = (*ha->func.reset) (ha); + + if (!ret) { + Scsi_Cmnd *scsi_cmd; + + IPS_PRINTK(KERN_NOTICE, ha->pcidev, + "Controller reset failed - controller now offline.\n"); + + /* Now fail all of the active commands */ + DEBUG_VAR(1, "(%s%d) Failing active commands", + ips_name, ha->host_num); + + while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + ips_freescb(ha, scb); + } + + /* Now fail all of the pending commands */ + DEBUG_VAR(1, "(%s%d) Failing pending commands", + ips_name, ha->host_num); + + while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { + scsi_cmd->result = DID_ERROR; + scsi_cmd->scsi_done(scsi_cmd); + } + + ha->active = FALSE; + return (FAILED); + } + + if (!ips_clear_adapter(ha, IPS_INTR_IORL)) { + Scsi_Cmnd *scsi_cmd; + + IPS_PRINTK(KERN_NOTICE, ha->pcidev, + "Controller reset failed - controller now offline.\n"); + + /* Now fail all of the active commands */ + DEBUG_VAR(1, "(%s%d) Failing active commands", + ips_name, ha->host_num); + + while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + ips_freescb(ha, scb); + } + + /* Now fail all of the pending commands */ + DEBUG_VAR(1, "(%s%d) Failing pending commands", + ips_name, ha->host_num); + + while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { + scsi_cmd->result = DID_ERROR << 16; + scsi_cmd->scsi_done(scsi_cmd); + } - return (FAILED); - } + ha->active = FALSE; + return (FAILED); + } - ha = (ips_ha_t *) SC->device->host->hostdata; + /* FFDC */ + if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) { + struct timeval tv; + + do_gettimeofday(&tv); + ha->last_ffdc = tv.tv_sec; + ha->reset_count++; + ips_ffdc_reset(ha, IPS_INTR_IORL); + } - if (!ha) { - DEBUG(1, "Reset called with NULL ha struct"); - - return (FAILED); - } - - if (!ha->active) - return (FAILED); - - /* See if the command is on the copp queue */ - item = ha->copp_waitlist.head; - while ((item) && (item->scsi_cmd != SC)) - item = item->next; - - if (item) { - /* Found it */ - ips_removeq_copp(&ha->copp_waitlist, item); - return (SUCCESS); - } - - /* See if the command is on the wait queue */ - if (ips_removeq_wait(&ha->scb_waitlist, SC)) { - /* command not sent yet */ - return (SUCCESS); - } - - /* An explanation for the casual observer: */ - /* Part of the function of a RAID controller is automatic error */ - /* detection and recovery. As such, the only problem that physically */ - /* resetting an adapter will ever fix is when, for some reason, */ - /* the driver is not successfully communicating with the adapter. */ - /* Therefore, we will attempt to flush this adapter. If that succeeds, */ - /* then there's no real purpose in a physical reset. This will complete */ - /* much faster and avoids any problems that might be caused by a */ - /* physical reset ( such as having to fail all the outstanding I/O's ). */ - - if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */ - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FLUSH; - - scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; - scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flush_cache.state = IPS_NORM_STATE; - scb->cmd.flush_cache.reserved = 0; - scb->cmd.flush_cache.reserved2 = 0; - scb->cmd.flush_cache.reserved3 = 0; - scb->cmd.flush_cache.reserved4 = 0; - - /* Attempt the flush command */ - ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); - if (ret == IPS_SUCCESS) { - IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Reset Request - Flushed Cache\n"); - return (SUCCESS); - } - } - - /* Either we can't communicate with the adapter or it's an IOCTL request */ - /* from a utility. A physical reset is needed at this point. */ - - ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ - - /* - * command must have already been sent - * reset the controller - */ - IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n"); - ret = (*ha->func.reset)(ha); - - if (!ret) { - Scsi_Cmnd *scsi_cmd; - - IPS_PRINTK(KERN_NOTICE, ha->pcidev, - "Controller reset failed - controller now offline.\n"); - - /* Now fail all of the active commands */ - DEBUG_VAR(1, "(%s%d) Failing active commands", - ips_name, ha->host_num); - - while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); - } - - /* Now fail all of the pending commands */ - DEBUG_VAR(1, "(%s%d) Failing pending commands", - ips_name, ha->host_num); - - while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { - scsi_cmd->result = DID_ERROR; - scsi_cmd->scsi_done(scsi_cmd); - } - - ha->active = FALSE; - return (FAILED); - } - - if (!ips_clear_adapter(ha, IPS_INTR_IORL)) { - Scsi_Cmnd *scsi_cmd; - - IPS_PRINTK(KERN_NOTICE, ha->pcidev, - "Controller reset failed - controller now offline.\n"); - - /* Now fail all of the active commands */ - DEBUG_VAR(1, "(%s%d) Failing active commands", - ips_name, ha->host_num); - - while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); - } - - /* Now fail all of the pending commands */ - DEBUG_VAR(1, "(%s%d) Failing pending commands", - ips_name, ha->host_num); - - while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { - scsi_cmd->result = DID_ERROR << 16; - scsi_cmd->scsi_done(scsi_cmd); - } - - ha->active = FALSE; - return (FAILED); - } - - /* FFDC */ - if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) { - struct timeval tv; - - do_gettimeofday(&tv); - ha->last_ffdc = tv.tv_sec; - ha->reset_count++; - ips_ffdc_reset(ha, IPS_INTR_IORL); - } - - /* Now fail all of the active commands */ - DEBUG_VAR(1, "(%s%d) Failing active commands", - ips_name, ha->host_num); - - while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { - scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24); - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - ips_freescb(ha, scb); - } - - /* Reset DCDB active command bits */ - for (i = 1; i < ha->nbus; i++) - ha->dcdb_active[i-1] = 0; + /* Now fail all of the active commands */ + DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num); - /* Reset the number of active IOCTLs */ - ha->num_ioctl = 0; + while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { + scb->scsi_cmd->result = + (DID_RESET << 16) | (SUGGEST_RETRY << 24); + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + ips_freescb(ha, scb); + } - ips_next(ha, IPS_INTR_IORL); + /* Reset DCDB active command bits */ + for (i = 1; i < ha->nbus; i++) + ha->dcdb_active[i - 1] = 0; - return (SUCCESS); -#endif /* NO_IPS_RESET */ + /* Reset the number of active IOCTLs */ + ha->num_ioctl = 0; + + ips_next(ha, IPS_INTR_IORL); + + return (SUCCESS); +#endif /* NO_IPS_RESET */ } @@ -1054,96 +1062,95 @@ /* */ /****************************************************************************/ int -ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { - ips_ha_t *ha; - ips_passthru_t *pt; - - METHOD_TRACE("ips_queue", 1); - - ha = (ips_ha_t *) SC->device->host->hostdata; - - if (!ha) - return (1); - - if (!ha->active) - return (DID_ERROR); - - if (ips_is_passthru(SC)) { - if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { - SC->result = DID_BUS_BUSY << 16; - done(SC); - - return (0); - } - } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { - SC->result = DID_BUS_BUSY << 16; - done(SC); - - return (0); - } - - SC->scsi_done = done; - - DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)", - ips_name, - ha->host_num, - SC->cmnd[0], - SC->device->channel, - SC->device->id, - SC->device->lun); - - /* Check for command to initiator IDs */ - if ((SC->device->channel > 0) && (SC->device->id == ha->ha_id[SC->device->channel])) { - SC->result = DID_NO_CONNECT << 16; - done(SC); - - return (0); - } - - if (ips_is_passthru(SC)) { - - ips_copp_wait_item_t *scratch; - - /* A Reset IOCTL is only sent by the ServeRAID boot CD in extreme cases. */ - /* There can never be any system activity ( network or disk ), but check */ - /* anyway just as a good practice. */ - pt = (ips_passthru_t *) SC->request_buffer; - if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) && - (pt->CoppCP.cmd.reset.adapter_flag == 1)) { - if (ha->scb_activelist.count != 0) { - SC->result = DID_BUS_BUSY << 16; - done(SC); - return (0); - } - ha->ioctl_reset = 1; /* This reset request is from an IOCTL */ - ips_eh_reset(SC); - SC->result = DID_OK << 16; - SC->scsi_done(SC); - return (0); - } - - /* allocate space for the scribble */ - scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC); - - if (!scratch) { - SC->result = DID_ERROR << 16; - done(SC); - - return (0); - } - - scratch->scsi_cmd = SC; - scratch->next = NULL; - - ips_putq_copp_tail(&ha->copp_waitlist, scratch); - } - else { - ips_putq_wait_tail(&ha->scb_waitlist, SC); - } +ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *)) +{ + ips_ha_t *ha; + ips_passthru_t *pt; - ips_next(ha, IPS_INTR_IORL); - - return (0); + METHOD_TRACE("ips_queue", 1); + + ha = (ips_ha_t *) SC->device->host->hostdata; + + if (!ha) + return (1); + + if (!ha->active) + return (DID_ERROR); + + if (ips_is_passthru(SC)) { + if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + + return (0); + } + } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + + return (0); + } + + SC->scsi_done = done; + + DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)", + ips_name, + ha->host_num, + SC->cmnd[0], + SC->device->channel, SC->device->id, SC->device->lun); + + /* Check for command to initiator IDs */ + if ((SC->device->channel > 0) + && (SC->device->id == ha->ha_id[SC->device->channel])) { + SC->result = DID_NO_CONNECT << 16; + done(SC); + + return (0); + } + + if (ips_is_passthru(SC)) { + + ips_copp_wait_item_t *scratch; + + /* A Reset IOCTL is only sent by the boot CD in extreme cases. */ + /* There can never be any system activity ( network or disk ), but check */ + /* anyway just as a good practice. */ + pt = (ips_passthru_t *) SC->request_buffer; + if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) && + (pt->CoppCP.cmd.reset.adapter_flag == 1)) { + if (ha->scb_activelist.count != 0) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + return (0); + } + ha->ioctl_reset = 1; /* This reset request is from an IOCTL */ + ips_eh_reset(SC); + SC->result = DID_OK << 16; + SC->scsi_done(SC); + return (0); + } + + /* allocate space for the scribble */ + scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC); + + if (!scratch) { + SC->result = DID_ERROR << 16; + done(SC); + + return (0); + } + + scratch->scsi_cmd = SC; + scratch->next = NULL; + + ips_putq_copp_tail(&ha->copp_waitlist, scratch); + } else { + ips_putq_wait_tail(&ha->scb_waitlist, SC); + } + + ips_next(ha, IPS_INTR_IORL); + + return (0); } /****************************************************************************/ @@ -1157,52 +1164,72 @@ /****************************************************************************/ static int #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -ips_biosparam(Disk *disk, kdev_t dev, int geom[]) { - ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata; - unsigned long capacity = disk->capacity; +ips_biosparam(Disk * disk, kdev_t dev, int geom[]) +{ + ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata; + unsigned long capacity = disk->capacity; #else ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int geom[]) { - ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata; + sector_t capacity, int geom[]) +{ + ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata; #endif - int heads; - int sectors; - int cylinders; - - METHOD_TRACE("ips_biosparam", 1); - - if (!ha) - /* ?!?! host adater info invalid */ - return (0); - - if (!ha->active) - return (0); - - if (!ips_read_adapter_status(ha, IPS_INTR_ON)) - /* ?!?! Enquiry command failed */ - return (0); - - if ((capacity > 0x400000) && - ((ha->enq->ucMiscFlag & 0x8) == 0)) { - heads = IPS_NORM_HEADS; - sectors = IPS_NORM_SECTORS; - } else { - heads = IPS_COMP_HEADS; - sectors = IPS_COMP_SECTORS; - } - - cylinders = (unsigned long)capacity / (heads * sectors); - - DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d", - heads, sectors, cylinders); - - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; + int heads; + int sectors; + int cylinders; + + METHOD_TRACE("ips_biosparam", 1); + + if (!ha) + /* ?!?! host adater info invalid */ + return (0); + + if (!ha->active) + return (0); + + if (!ips_read_adapter_status(ha, IPS_INTR_ON)) + /* ?!?! Enquiry command failed */ + return (0); + + if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) { + heads = IPS_NORM_HEADS; + sectors = IPS_NORM_SECTORS; + } else { + heads = IPS_COMP_HEADS; + sectors = IPS_COMP_SECTORS; + } + + cylinders = (unsigned long) capacity / (heads * sectors); + + DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d", + heads, sectors, cylinders); - return (0); + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + + return (0); } + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + +/* ips_proc24_info is a wrapper around ips_proc_info * + * for compatibility with the 2.4 scsi parameters */ +static int +ips_proc24_info(char *buffer, char **start, off_t offset, int length, + int hostno, int func) +{ + int i; + + for (i = 0; i < ips_next_controller; i++) { + if (ips_sh[i] && ips_sh[i]->host_no == hostno) { + return ips_proc_info(ips_sh[i], buffer, start, + offset, length, func); + } + } + return -EINVAL; +} + /****************************************************************************/ /* */ /* Routine Name: ips_select_queue_depth */ @@ -1213,37 +1240,38 @@ /* */ /****************************************************************************/ static void -ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) { - Scsi_Device *device; - ips_ha_t *ha; - int count = 0; - int min; - - ha = IPS_HA(host); - min = ha->max_cmds / 4; - - for (device = scsi_devs; device; device = device->next) { - if (device->host == host) { - if ((device->channel == 0) && (device->type == 0)) - count++; - } - } - - for (device = scsi_devs; device; device = device->next) { - if (device->host == host) { - if ((device->channel == 0) && (device->type == 0)) { - device->queue_depth = ( ha->max_cmds - 1 ) / count; - if (device->queue_depth < min) - device->queue_depth = min; - } - else { - device->queue_depth = 2; - } - - if (device->queue_depth < 2) - device->queue_depth = 2; - } - } +ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + ips_ha_t *ha; + int count = 0; + int min; + + ha = IPS_HA(host); + min = ha->max_cmds / 4; + + for (device = scsi_devs; device; device = device->next) { + if (device->host == host) { + if ((device->channel == 0) && (device->type == 0)) + count++; + } + } + + for (device = scsi_devs; device; device = device->next) { + if (device->host == host) { + if ((device->channel == 0) && (device->type == 0)) { + device->queue_depth = + (ha->max_cmds - 1) / count; + if (device->queue_depth < min) + device->queue_depth = min; + } else { + device->queue_depth = 2; + } + + if (device->queue_depth < 2) + device->queue_depth = 2; + } + } } #else @@ -1257,19 +1285,19 @@ /* */ /****************************************************************************/ int -ips_slave_configure(Scsi_Device *SDptr) +ips_slave_configure(Scsi_Device * SDptr) { - ips_ha_t *ha; - int min; + ips_ha_t *ha; + int min; - ha = IPS_HA(SDptr->host); - if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) { - min = ha->max_cmds / 2; - if (ha->enq->ucLogDriveCount <= 2) - min = ha->max_cmds - 1; - scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min); - } - return 0; + ha = IPS_HA(SDptr->host); + if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) { + min = ha->max_cmds / 2; + if (ha->enq->ucLogDriveCount <= 2) + min = ha->max_cmds - 1; + scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min); + } + return 0; } #endif @@ -1283,38 +1311,39 @@ /* */ /****************************************************************************/ irqreturn_t -do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) { - ips_ha_t *ha; - unsigned long cpu_flags; - struct Scsi_Host *host; - int irqstatus; - - METHOD_TRACE("do_ipsintr", 2); +do_ipsintr(int irq, void *dev_id, struct pt_regs * regs) +{ + ips_ha_t *ha; + unsigned long cpu_flags; + struct Scsi_Host *host; + int irqstatus; + + METHOD_TRACE("do_ipsintr", 2); + + ha = (ips_ha_t *) dev_id; + if (!ha) + return IRQ_NONE; + host = ips_sh[ha->host_num]; + /* interrupt during initialization */ + if (!host) { + (*ha->func.intr) (ha); + return IRQ_HANDLED; + } + + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + + if (!ha->active) { + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + return IRQ_HANDLED; + } + + irqstatus = (*ha->func.intr) (ha); - ha = (ips_ha_t *) dev_id; - if (!ha) - return IRQ_NONE; - host = ips_sh[ha->host_num]; - /* interrupt during initialization */ - if(!host){ - (*ha->func.intr)(ha); - return IRQ_HANDLED; - } - - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - - if (!ha->active) { - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - return IRQ_HANDLED; - } - - irqstatus = (*ha->func.intr)(ha); - - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - - /* start the next command */ - ips_next(ha, IPS_INTR_ON); - return IRQ_RETVAL(irqstatus); + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + + /* start the next command */ + ips_next(ha, IPS_INTR_ON); + return IRQ_RETVAL(irqstatus); } /****************************************************************************/ @@ -1329,55 +1358,56 @@ /* */ /****************************************************************************/ int -ips_intr_copperhead(ips_ha_t *ha) { - ips_stat_t *sp; - ips_scb_t *scb; - IPS_STATUS cstatus; - int intrstatus; - - METHOD_TRACE("ips_intr", 2); - - if (!ha) - return 0; - - if (!ha->active) - return 0; - - intrstatus = (*ha->func.isintr)(ha); - - if (!intrstatus) { - /* - * Unexpected/Shared interrupt - */ - - return 0; - } - - while (TRUE) { - sp = &ha->sp; - - intrstatus = (*ha->func.isintr)(ha); - - if (!intrstatus) - break; - else - cstatus.value = (*ha->func.statupd)(ha); - - if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { - /* Spurious Interupt ? */ - continue; - } - - ips_chkstatus(ha, &cstatus); - scb = (ips_scb_t *) sp->scb_addr; - - /* - * use the callback function to finish things up - * NOTE: interrupts are OFF for this - */ - (*scb->callback) (ha, scb); - } /* end while */ - return 1; +ips_intr_copperhead(ips_ha_t * ha) +{ + ips_stat_t *sp; + ips_scb_t *scb; + IPS_STATUS cstatus; + int intrstatus; + + METHOD_TRACE("ips_intr", 2); + + if (!ha) + return 0; + + if (!ha->active) + return 0; + + intrstatus = (*ha->func.isintr) (ha); + + if (!intrstatus) { + /* + * Unexpected/Shared interrupt + */ + + return 0; + } + + while (TRUE) { + sp = &ha->sp; + + intrstatus = (*ha->func.isintr) (ha); + + if (!intrstatus) + break; + else + cstatus.value = (*ha->func.statupd) (ha); + + if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { + /* Spurious Interupt ? */ + continue; + } + + ips_chkstatus(ha, &cstatus); + scb = (ips_scb_t *) sp->scb_addr; + + /* + * use the callback function to finish things up + * NOTE: interrupts are OFF for this + */ + (*scb->callback) (ha, scb); + } /* end while */ + return 1; } /****************************************************************************/ @@ -1392,60 +1422,62 @@ /* */ /****************************************************************************/ int -ips_intr_morpheus(ips_ha_t *ha) { - ips_stat_t *sp; - ips_scb_t *scb; - IPS_STATUS cstatus; - int intrstatus; +ips_intr_morpheus(ips_ha_t * ha) +{ + ips_stat_t *sp; + ips_scb_t *scb; + IPS_STATUS cstatus; + int intrstatus; - METHOD_TRACE("ips_intr_morpheus", 2); + METHOD_TRACE("ips_intr_morpheus", 2); - if (!ha) - return 0; + if (!ha) + return 0; - if (!ha->active) - return 0; + if (!ha->active) + return 0; - intrstatus = (*ha->func.isintr)(ha); + intrstatus = (*ha->func.isintr) (ha); - if (!intrstatus) { - /* - * Unexpected/Shared interrupt - */ + if (!intrstatus) { + /* + * Unexpected/Shared interrupt + */ - return 0; - } + return 0; + } - while (TRUE) { - sp = &ha->sp; + while (TRUE) { + sp = &ha->sp; - intrstatus = (*ha->func.isintr)(ha); + intrstatus = (*ha->func.isintr) (ha); - if (!intrstatus) - break; - else - cstatus.value = (*ha->func.statupd)(ha); + if (!intrstatus) + break; + else + cstatus.value = (*ha->func.statupd) (ha); - if (cstatus.value == 0xffffffff) - /* No more to process */ - break; + if (cstatus.value == 0xffffffff) + /* No more to process */ + break; - if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Spurious interrupt; no ccb.\n"); + if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Spurious interrupt; no ccb.\n"); - continue; - } + continue; + } - ips_chkstatus(ha, &cstatus); - scb = (ips_scb_t *) sp->scb_addr; + ips_chkstatus(ha, &cstatus); + scb = (ips_scb_t *) sp->scb_addr; - /* - * use the callback function to finish things up - * NOTE: interrupts are OFF for this - */ - (*scb->callback) (ha, scb); - } /* end while */ - return 1; + /* + * use the callback function to finish things up + * NOTE: interrupts are OFF for this + */ + (*scb->callback) (ha, scb); + } /* end while */ + return 1; } /****************************************************************************/ @@ -1458,32 +1490,32 @@ /* */ /****************************************************************************/ const char * -ips_info(struct Scsi_Host *SH) { - static char buffer[256]; - char *bp; - ips_ha_t *ha; +ips_info(struct Scsi_Host *SH) +{ + static char buffer[256]; + char *bp; + ips_ha_t *ha; - METHOD_TRACE("ips_info", 1); + METHOD_TRACE("ips_info", 1); - ha = IPS_HA(SH); + ha = IPS_HA(SH); - if (!ha) - return (NULL); + if (!ha) + return (NULL); - bp = &buffer[0]; - memset(bp, 0, sizeof(buffer)); + bp = &buffer[0]; + memset(bp, 0, sizeof (buffer)); - sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ", - IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT ); + 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) { - strcat(bp, " <"); - strcat(bp, ips_adapter_name[ha->ad_type-1]); - strcat(bp, ">"); - } + if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) { + strcat(bp, " <"); + strcat(bp, ips_adapter_name[ha->ad_type - 1]); + strcat(bp, ">"); + } - return (bp); + return (bp); } /****************************************************************************/ @@ -1497,38 +1529,39 @@ /****************************************************************************/ int ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, - int length, int func) { - int i; - int ret; - ips_ha_t *ha = NULL; - - METHOD_TRACE("ips_proc_info", 1); - - /* Find our host structure */ - for (i = 0; i < ips_next_controller; i++) { - if (ips_sh[i]) { - if (ips_sh[i] == host) { - ha = (ips_ha_t *) ips_sh[i]->hostdata; - break; - } - } - } - - if (!ha) - return (-EINVAL); - - if (func) { - /* write */ - return (0); - } else { - /* read */ - if (start) - *start = buffer; + int length, int func) +{ + int i; + int ret; + ips_ha_t *ha = NULL; + + METHOD_TRACE("ips_proc_info", 1); + + /* Find our host structure */ + for (i = 0; i < ips_next_controller; i++) { + if (ips_sh[i]) { + if (ips_sh[i] == host) { + ha = (ips_ha_t *) ips_sh[i]->hostdata; + break; + } + } + } + + if (!ha) + return (-EINVAL); - ret = ips_host_info(ha, buffer, offset, length); + if (func) { + /* write */ + return (0); + } else { + /* read */ + if (start) + *start = buffer; + + ret = ips_host_info(ha, buffer, offset, length); - return (ret); - } + return (ret); + } } /*--------------------------------------------------------------------------*/ @@ -1545,32 +1578,32 @@ /* */ /****************************************************************************/ static int -ips_is_passthru(Scsi_Cmnd *SC) { - METHOD_TRACE("ips_is_passthru", 1); +ips_is_passthru(Scsi_Cmnd * SC) +{ + METHOD_TRACE("ips_is_passthru", 1); - if (!SC) - return (0); + if (!SC) + return (0); - if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) && - (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') && - (((char *) SC->request_buffer)[1] == 'O') && - (((char *) SC->request_buffer)[2] == 'P') && - (((char *) SC->request_buffer)[3] == 'P')) - return 1; - else if(SC->use_sg){ - struct scatterlist *sg = SC->request_buffer; - char *buffer = IPS_SG_ADDRESS(sg); - if(buffer && buffer[0] == 'C' && buffer[1] == 'O' && - buffer[2] == 'P' && buffer[3] == 'P') - return 1; - } - } - return 0; + if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) && + (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') && + (((char *) SC->request_buffer)[1] == 'O') && + (((char *) SC->request_buffer)[2] == 'P') && + (((char *) SC->request_buffer)[3] == 'P')) + return 1; + else if (SC->use_sg) { + struct scatterlist *sg = SC->request_buffer; + char *buffer = IPS_SG_ADDRESS(sg); + if (buffer && buffer[0] == 'C' && buffer[1] == 'O' && + buffer[2] == 'P' && buffer[3] == 'P') + return 1; + } + } + return 0; } /****************************************************************************/ @@ -1582,24 +1615,23 @@ /* is too small or doesn't exist */ /****************************************************************************/ static int -ips_alloc_passthru_buffer(ips_ha_t *ha, int length){ +ips_alloc_passthru_buffer(ips_ha_t * ha, int length) +{ void *bigger_buf; - int count; - int order; + dma_addr_t dma_busaddr; - if(ha->ioctl_data && length <= (PAGE_SIZE << ha->ioctl_order)) + if (ha->ioctl_data && length <= ha->ioctl_len) 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); + bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr); if (bigger_buf) { /* free the old memory */ - free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); + pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data, + ha->ioctl_busaddr); /* use the new memory */ ha->ioctl_data = (char *) bigger_buf; - ha->ioctl_order = order; + ha->ioctl_len = length; + ha->ioctl_busaddr = dma_busaddr; } else { return -1; } @@ -1616,92 +1648,96 @@ /* */ /****************************************************************************/ static int -ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { - ips_passthru_t *pt; - int length = 0; - int ret; - - METHOD_TRACE("ips_make_passthru", 1); - - if(!SC->use_sg){ - 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); - } - 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 - * - * IF the scsi op_code == 0x0d then we assume - * that the data came along with/goes with the - * 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. - */ - - switch (pt->CoppCmd) { - case IPS_NUMCTRLS: - memcpy(ha->ioctl_data + sizeof(ips_passthru_t), - &ips_num_controllers, sizeof(int)); - ips_scmd_buf_write(SC, ha->ioctl_data, - sizeof(ips_passthru_t) + sizeof(int)); - SC->result = DID_OK << 16; - - return (IPS_SUCCESS_IMM); - - case IPS_COPPUSRCMD: - case IPS_COPPIOCCMD: - if (SC->cmnd[0] == IPS_IOCTL_COMMAND) { - if (length < (sizeof(ips_passthru_t) + pt->CmdBSize)) { - /* wrong size */ - DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", - ips_name, ha->host_num); - - return (IPS_FAILURE); - } - - if(ha->device_id == IPS_DEVICEID_COPPERHEAD && - 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 - return (IPS_FAILURE); - } - - break; +ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr) +{ + ips_passthru_t *pt; + int length = 0; + int ret; + + METHOD_TRACE("ips_make_passthru", 1); + + if (!SC->use_sg) { + 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); + } + 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 + * + * IF the scsi op_code == 0x0d then we assume + * that the data came along with/goes with the + * 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. + */ + + switch (pt->CoppCmd) { + case IPS_NUMCTRLS: + memcpy(ha->ioctl_data + sizeof (ips_passthru_t), + &ips_num_controllers, sizeof (int)); + ips_scmd_buf_write(SC, ha->ioctl_data, + sizeof (ips_passthru_t) + sizeof (int)); + SC->result = DID_OK << 16; + + return (IPS_SUCCESS_IMM); + + case IPS_COPPUSRCMD: + case IPS_COPPIOCCMD: + if (SC->cmnd[0] == IPS_IOCTL_COMMAND) { + if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) { + /* wrong size */ + DEBUG_VAR(1, + "(%s%d) Passthru structure wrong size", + ips_name, ha->host_num); + + return (IPS_FAILURE); + } + + if (ha->device_id == IPS_DEVICEID_COPPERHEAD && + 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 + return (IPS_FAILURE); + } - } /* end switch */ + break; - return (IPS_FAILURE); + } /* end switch */ + + return (IPS_FAILURE); } /****************************************************************************/ @@ -1710,62 +1746,70 @@ /* Flash the BIOS/FW on a Copperhead style controller */ /****************************************************************************/ static int -ips_flash_copperhead(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb){ - int datasize, count; +ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + int datasize; - /* Trombone is the only copperhead that can do packet flash, but only - * for firmware. No one said it had to make sence. */ - if(IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE){ - if(ips_usrcmd(ha, pt, scb)) - return IPS_SUCCESS; - else - return IPS_FAILURE; - } - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0; - scb->scsi_cmd->result = DID_OK <<16; - /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */ - /* avoid allocating a huge buffer per adapter ( which can fail ). */ - if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){ - pt->BasicStatus = 0; - return ips_flash_bios(ha, pt, scb); - }else if(pt->CoppCP.cmd.flashfw.packet_num == 0){ - if(ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){ - ha->flash_data = ips_FlashData; - ha->flash_order = 7; - ha->flash_datasize = 0; - }else if(!ha->flash_data){ - datasize = pt->CoppCP.cmd.flashfw.total_packets * - 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(IPS_ATOMIC_GFP, ha->flash_order); - ha->flash_datasize = 0; - }else - return IPS_FAILURE; - }else{ - if(pt->CoppCP.cmd.flashfw.count + ha->flash_datasize > - (PAGE_SIZE << ha->flash_order)){ - ips_free_flash_copperhead(ha); - IPS_PRINTK(KERN_WARNING, ha->pcidev, "failed size sanity check\n"); - return IPS_FAILURE; - } - } - if(!ha->flash_data) - return IPS_FAILURE; - pt->BasicStatus = 0; - memcpy(&ha->flash_data[ha->flash_datasize], pt + 1, - pt->CoppCP.cmd.flashfw.count); - ha->flash_datasize += pt->CoppCP.cmd.flashfw.count; - if(pt->CoppCP.cmd.flashfw.packet_num == - pt->CoppCP.cmd.flashfw.total_packets - 1){ - if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE) - return ips_flash_bios(ha, pt, scb); - else if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) - return ips_flash_firmware(ha, pt, scb); - } - return IPS_SUCCESS_IMM; + /* Trombone is the only copperhead that can do packet flash, but only + * for firmware. No one said it had to make sence. */ + if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) { + if (ips_usrcmd(ha, pt, scb)) + return IPS_SUCCESS; + else + return IPS_FAILURE; + } + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0; + scb->scsi_cmd->result = DID_OK << 16; + /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */ + /* avoid allocating a huge buffer per adapter ( which can fail ). */ + if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) { + pt->BasicStatus = 0; + return ips_flash_bios(ha, pt, scb); + } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) { + if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){ + ha->flash_data = ips_FlashData; + ha->flash_busaddr = ips_flashbusaddr; + ha->flash_len = PAGE_SIZE << 7; + ha->flash_datasize = 0; + } else if (!ha->flash_data) { + datasize = pt->CoppCP.cmd.flashfw.total_packets * + pt->CoppCP.cmd.flashfw.count; + ha->flash_data = pci_alloc_consistent(ha->pcidev, + datasize, + &ha->flash_busaddr); + if (!ha->flash_data){ + printk(KERN_WARNING "Unable to allocate a flash buffer\n"); + return IPS_FAILURE; + } + ha->flash_datasize = 0; + ha->flash_len = datasize; + } else + return IPS_FAILURE; + } else { + if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize > + ha->flash_len) { + ips_free_flash_copperhead(ha); + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "failed size sanity check\n"); + return IPS_FAILURE; + } + } + if (!ha->flash_data) + return IPS_FAILURE; + pt->BasicStatus = 0; + memcpy(&ha->flash_data[ha->flash_datasize], pt + 1, + pt->CoppCP.cmd.flashfw.count); + ha->flash_datasize += pt->CoppCP.cmd.flashfw.count; + if (pt->CoppCP.cmd.flashfw.packet_num == + pt->CoppCP.cmd.flashfw.total_packets - 1) { + if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE) + return ips_flash_bios(ha, pt, scb); + else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) + return ips_flash_firmware(ha, pt, scb); + } + return IPS_SUCCESS_IMM; } /****************************************************************************/ @@ -1774,46 +1818,59 @@ /* flashes the bios of a copperhead adapter */ /****************************************************************************/ static int -ips_flash_bios(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){ +ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ - if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS){ - if ((!ha->func.programbios) || (!ha->func.erasebios) || - (!ha->func.verifybios)) - goto error; - if((*ha->func.erasebios)(ha)){ - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", - ips_name, ha->host_num); - goto error; - }else if ((*ha->func.programbios)(ha, ha->flash_data + IPS_BIOS_HEADER, - ha->flash_datasize - IPS_BIOS_HEADER, 0 )) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to flash", - ips_name, ha->host_num); - goto error; - }else if ((*ha->func.verifybios)(ha, ha->flash_data + IPS_BIOS_HEADER, - ha->flash_datasize - IPS_BIOS_HEADER, 0 )) { - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash", - ips_name, ha->host_num); - goto error; - } - ips_free_flash_copperhead(ha); - return IPS_SUCCESS_IMM; - }else if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){ - if(!ha->func.erasebios) - goto error; - if((*ha->func.erasebios)(ha)){ - DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash", - ips_name, ha->host_num); - goto error; - } - return IPS_SUCCESS_IMM; - } -error: - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0x00; - ips_free_flash_copperhead(ha); - return IPS_FAILURE; + if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) { + if ((!ha->func.programbios) || (!ha->func.erasebios) || + (!ha->func.verifybios)) + goto error; + if ((*ha->func.erasebios) (ha)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to erase flash", + ips_name, ha->host_num); + goto error; + } else + if ((*ha->func.programbios) (ha, + ha->flash_data + + IPS_BIOS_HEADER, + ha->flash_datasize - + IPS_BIOS_HEADER, 0)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to flash", + ips_name, ha->host_num); + goto error; + } else + if ((*ha->func.verifybios) (ha, + ha->flash_data + + IPS_BIOS_HEADER, + ha->flash_datasize - + IPS_BIOS_HEADER, 0)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to verify flash", + ips_name, ha->host_num); + goto error; + } + ips_free_flash_copperhead(ha); + return IPS_SUCCESS_IMM; + } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) { + if (!ha->func.erasebios) + goto error; + if ((*ha->func.erasebios) (ha)) { + DEBUG_VAR(1, + "(%s%d) flash bios failed - unable to erase flash", + ips_name, ha->host_num); + goto error; + } + return IPS_SUCCESS_IMM; + } + error: + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0x00; + ips_free_flash_copperhead(ha); + return IPS_FAILURE; } /****************************************************************************/ @@ -1824,38 +1881,37 @@ /* Fill in a single scb sg_list element from an address */ /* return a -1 if a breakup occurred */ /****************************************************************************/ -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) +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; + 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); + } - 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; + ++scb->sg_len; + scb->data_len += e_len; + return ret_val; } /****************************************************************************/ @@ -1864,49 +1920,51 @@ /* 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; - uint32_t cmd_busaddr; - - if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE && - pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW ){ - memset(&pt->CoppCP.cmd, 0, sizeof(IPS_HOST_COMMAND)); - pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD; - pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize); - }else{ - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0x00; - ips_free_flash_copperhead(ha); - return IPS_FAILURE; - } - /* Save the S/G list pointer so it doesn't get clobbered */ - 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.list = sg_list.list; - scb->scb_busaddr = cmd_busaddr; - 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; - scb->op_code = 0; - scb->callback = ipsintr_done; - scb->timeout = ips_cmd_timeout; - - scb->data_len = ha->flash_datasize; - scb->data_busaddr = pci_map_single(ha->pcidev, ha->flash_data, scb->data_len, - 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 = cpu_to_le32(scb->data_busaddr); - if (pt->TimeOut) - scb->timeout = pt->TimeOut; - scb->scsi_cmd->result = DID_OK <<16; - return IPS_SUCCESS; +ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + IPS_SG_LIST sg_list; + uint32_t cmd_busaddr; + + if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE && + pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) { + memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND)); + pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD; + pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize); + } else { + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0x00; + ips_free_flash_copperhead(ha); + return IPS_FAILURE; + } + /* Save the S/G list pointer so it doesn't get clobbered */ + 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.list = sg_list.list; + scb->scb_busaddr = cmd_busaddr; + 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; + scb->op_code = 0; + scb->callback = ipsintr_done; + scb->timeout = ips_cmd_timeout; + + scb->data_len = ha->flash_datasize; + scb->data_busaddr = + pci_map_single(ha->pcidev, ha->flash_data, scb->data_len, + 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 = cpu_to_le32(scb->data_busaddr); + if (pt->TimeOut) + scb->timeout = pt->TimeOut; + scb->scsi_cmd->result = DID_OK << 16; + return IPS_SUCCESS; } /****************************************************************************/ @@ -1915,12 +1973,14 @@ /* release the memory resources used to hold the flash image */ /****************************************************************************/ static void -ips_free_flash_copperhead(ips_ha_t *ha){ - if(ha->flash_data == ips_FlashData) - test_and_clear_bit(0, &ips_FlashDataInUse); - else if(ha->flash_data) - free_pages((unsigned long)ha->flash_data, ha->flash_order); - ha->flash_data = NULL; +ips_free_flash_copperhead(ips_ha_t * ha) +{ + if (ha->flash_data == ips_FlashData) + test_and_clear_bit(0, &ips_FlashDataInUse); + else if (ha->flash_data) + pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data, + ha->flash_busaddr); + ha->flash_data = NULL; } /****************************************************************************/ @@ -1933,83 +1993,82 @@ /* */ /****************************************************************************/ static int -ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { - IPS_SG_LIST sg_list; - uint32_t cmd_busaddr; - - METHOD_TRACE("ips_usrcmd", 1); - - if ((!scb) || (!pt) || (!ha)) - return (0); - - /* Save the S/G list pointer so it doesn't get clobbered */ - 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.list = sg_list.list; - scb->scb_busaddr = cmd_busaddr; - 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; - scb->op_code = 0; - scb->callback = ipsintr_done; - scb->timeout = ips_cmd_timeout; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - - /* we don't support DCDB/READ/WRITE Scatter Gather */ - if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) || - (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) || - (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG)) - return (0); - - if (pt->CmdBSize) { - 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; - } - - if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + - (unsigned long)&scb->dcdb - - (unsigned long)scb); - - if (pt->CmdBSize) { - if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) - scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); - else - scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); - } - - /* set timeouts */ - if (pt->TimeOut) { - scb->timeout = pt->TimeOut; - - if (pt->TimeOut <= 10) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; - else if (pt->TimeOut <= 60) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; - else - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; - } +ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) +{ + IPS_SG_LIST sg_list; + uint32_t cmd_busaddr; - /* assume success */ - scb->scsi_cmd->result = DID_OK << 16; + METHOD_TRACE("ips_usrcmd", 1); - /* success */ - return (1); + if ((!scb) || (!pt) || (!ha)) + return (0); + + /* Save the S/G list pointer so it doesn't get clobbered */ + 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.list = sg_list.list; + scb->scb_busaddr = cmd_busaddr; + 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; + scb->op_code = 0; + scb->callback = ipsintr_done; + scb->timeout = ips_cmd_timeout; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + + /* we don't support DCDB/READ/WRITE Scatter Gather */ + if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) || + (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) || + (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG)) + return (0); + + if (pt->CmdBSize) { + scb->data_len = pt->CmdBSize; + scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t); + } else { + scb->data_busaddr = 0L; + } + + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + + (unsigned long) &scb-> + dcdb - + (unsigned long) scb); + + if (pt->CmdBSize) { + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) + scb->dcdb.buffer_pointer = + cpu_to_le32(scb->data_busaddr); + else + scb->cmd.basic_io.sg_addr = + cpu_to_le32(scb->data_busaddr); + } + + /* set timeouts */ + if (pt->TimeOut) { + scb->timeout = pt->TimeOut; + + if (pt->TimeOut <= 10) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; + else if (pt->TimeOut <= 60) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; + else + scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; + } + + /* assume success */ + scb->scsi_cmd->result = DID_OK << 16; + + /* success */ + return (1); } /****************************************************************************/ @@ -2022,33 +2081,34 @@ /* */ /****************************************************************************/ static void -ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) { - ips_passthru_t *pt; +ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb) +{ + ips_passthru_t *pt; - METHOD_TRACE("ips_cleanup_passthru", 1); + METHOD_TRACE("ips_cleanup_passthru", 1); - if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) { - DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru", - ips_name, ha->host_num); - - return ; - } - 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 */ - memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE)); - - pt->BasicStatus = scb->basic_status; - pt->ExtendedStatus = scb->extended_status; - pt->AdapterType = ha->ad_type; - - if(ha->device_id == IPS_DEVICEID_COPPERHEAD && - (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD || - scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)) - ips_free_flash_copperhead(ha); + if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) { + DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru", + ips_name, ha->host_num); + + return; + } + pt = (ips_passthru_t *) ha->ioctl_data; - ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize); + /* Copy data back to the user */ + if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */ + memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE)); + + pt->BasicStatus = scb->basic_status; + pt->ExtendedStatus = scb->extended_status; + pt->AdapterType = ha->ad_type; + + if (ha->device_id == IPS_DEVICEID_COPPERHEAD && + (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD || + scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)) + ips_free_flash_copperhead(ha); + + ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize); } /****************************************************************************/ @@ -2061,78 +2121,88 @@ /* */ /****************************************************************************/ static int -ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) { - IPS_INFOSTR info; +ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len) +{ + IPS_INFOSTR info; - METHOD_TRACE("ips_host_info", 1); + METHOD_TRACE("ips_host_info", 1); + + info.buffer = ptr; + info.length = len; + info.offset = offset; + info.pos = 0; + info.localpos = 0; + + copy_info(&info, "\nIBM ServeRAID General Information:\n\n"); + + if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) && + (le16_to_cpu(ha->nvram->adapter_type) != 0)) + copy_info(&info, "\tController Type : %s\n", + ips_adapter_name[ha->ad_type - 1]); + else + copy_info(&info, + "\tController Type : Unknown\n"); + + if (ha->io_addr) + copy_info(&info, + "\tIO region : 0x%lx (%d bytes)\n", + ha->io_addr, ha->io_len); + + if (ha->mem_addr) { + copy_info(&info, + "\tMemory region : 0x%lx (%d bytes)\n", + ha->mem_addr, ha->mem_len); + copy_info(&info, + "\tShared memory address : 0x%lx\n", + ha->mem_ptr); + } - info.buffer = ptr; - info.length = len; - info.offset = offset; - info.pos = 0; - info.localpos = 0; - - copy_info(&info, "\nIBM ServeRAID General Information:\n\n"); - - if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) && - (le16_to_cpu(ha->nvram->adapter_type) != 0)) - copy_info(&info, "\tController Type : %s\n", ips_adapter_name[ha->ad_type-1]); - else - copy_info(&info, "\tController Type : Unknown\n"); - - if (ha->io_addr) - copy_info(&info, "\tIO region : 0x%lx (%d bytes)\n", - ha->io_addr, ha->io_len); - - if (ha->mem_addr) { - copy_info(&info, "\tMemory region : 0x%lx (%d bytes)\n", - ha->mem_addr, ha->mem_len); - copy_info(&info, "\tShared memory address : 0x%lx\n", ha->mem_ptr); - } - - copy_info(&info, "\tIRQ number : %d\n", ha->irq); - - if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) - copy_info(&info, "\tBIOS Version : %c%c%c%c%c%c%c%c\n", - ha->nvram->bios_high[0], ha->nvram->bios_high[1], - ha->nvram->bios_high[2], ha->nvram->bios_high[3], - ha->nvram->bios_low[0], ha->nvram->bios_low[1], - ha->nvram->bios_low[2], ha->nvram->bios_low[3]); - - copy_info(&info, "\tFirmware Version : %c%c%c%c%c%c%c%c\n", - ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], - ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], - ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], - ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]); - - copy_info(&info, "\tBoot Block Version : %c%c%c%c%c%c%c%c\n", - ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], - ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], - ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], - ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]); - - 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", - ha->max_cmds); - copy_info(&info, "\tCurrent Queued Commands : %d\n", - ha->scb_waitlist.count); - copy_info(&info, "\tCurrent Active Commands : %d\n", - ha->scb_activelist.count - ha->num_ioctl); - copy_info(&info, "\tCurrent Queued PT Commands : %d\n", - ha->copp_waitlist.count); - copy_info(&info, "\tCurrent Active PT Commands : %d\n", - ha->num_ioctl); + copy_info(&info, "\tIRQ number : %d\n", ha->irq); - copy_info(&info, "\n"); + if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) + copy_info(&info, + "\tBIOS Version : %c%c%c%c%c%c%c%c\n", + ha->nvram->bios_high[0], ha->nvram->bios_high[1], + ha->nvram->bios_high[2], ha->nvram->bios_high[3], + ha->nvram->bios_low[0], ha->nvram->bios_low[1], + ha->nvram->bios_low[2], ha->nvram->bios_low[3]); + + copy_info(&info, + "\tFirmware Version : %c%c%c%c%c%c%c%c\n", + ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1], + ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3], + ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5], + ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]); + + copy_info(&info, + "\tBoot Block Version : %c%c%c%c%c%c%c%c\n", + ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1], + ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3], + ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5], + ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]); + + 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", + ha->max_cmds); + copy_info(&info, "\tCurrent Queued Commands : %d\n", + ha->scb_waitlist.count); + copy_info(&info, "\tCurrent Active Commands : %d\n", + ha->scb_activelist.count - ha->num_ioctl); + copy_info(&info, "\tCurrent Queued PT Commands : %d\n", + ha->copp_waitlist.count); + copy_info(&info, "\tCurrent Active PT Commands : %d\n", + ha->num_ioctl); - return (info.localpos); + copy_info(&info, "\n"); + + return (info.localpos); } /****************************************************************************/ @@ -2145,28 +2215,29 @@ /* */ /****************************************************************************/ static void -copy_mem_info(IPS_INFOSTR *info, char *data, int len) { - METHOD_TRACE("copy_mem_info", 1); +copy_mem_info(IPS_INFOSTR * info, char *data, int len) +{ + METHOD_TRACE("copy_mem_info", 1); + + if (info->pos + len < info->offset) { + info->pos += len; + return; + } + + if (info->pos < info->offset) { + data += (info->offset - info->pos); + len -= (info->offset - info->pos); + info->pos += (info->offset - info->pos); + } - if (info->pos + len < info->offset) { - info->pos += len; - return; - } - - if (info->pos < info->offset) { - data += (info->offset - info->pos); - len -= (info->offset - info->pos); - info->pos += (info->offset - info->pos); - } - - if (info->localpos + len > info->length) - len = info->length - info->localpos; - - if (len > 0) { - memcpy(info->buffer + info->localpos, data, len); - info->pos += len; - info->localpos += len; - } + if (info->localpos + len > info->length) + len = info->length - info->localpos; + + if (len > 0) { + memcpy(info->buffer + info->localpos, data, len); + info->pos += len; + info->localpos += len; + } } /****************************************************************************/ @@ -2179,20 +2250,21 @@ /* */ /****************************************************************************/ static int -copy_info(IPS_INFOSTR *info, char *fmt, ...) { - va_list args; - char buf[128]; - int len; +copy_info(IPS_INFOSTR * info, char *fmt, ...) +{ + va_list args; + char buf[128]; + int len; - METHOD_TRACE("copy_info", 1); + METHOD_TRACE("copy_info", 1); - va_start(args, fmt); - len = vsprintf(buf, fmt, args); - va_end(args); + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); - copy_mem_info(info, buf, len); + copy_mem_info(info, buf, len); - return (len); + return (len); } /****************************************************************************/ @@ -2205,71 +2277,73 @@ /* */ /****************************************************************************/ static void -ips_identify_controller(ips_ha_t *ha) { - METHOD_TRACE("ips_identify_controller", 1); +ips_identify_controller(ips_ha_t * ha) +{ + METHOD_TRACE("ips_identify_controller", 1); + + switch (ha->device_id) { + case IPS_DEVICEID_COPPERHEAD: + if (ha->revision_id <= IPS_REVID_SERVERAID) { + ha->ad_type = IPS_ADTYPE_SERVERAID; + } else if (ha->revision_id == IPS_REVID_SERVERAID2) { + ha->ad_type = IPS_ADTYPE_SERVERAID2; + } else if (ha->revision_id == IPS_REVID_NAVAJO) { + ha->ad_type = IPS_ADTYPE_NAVAJO; + } else if ((ha->revision_id == IPS_REVID_SERVERAID2) + && (ha->slot_num == 0)) { + ha->ad_type = IPS_ADTYPE_KIOWA; + } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) && + (ha->revision_id <= IPS_REVID_CLARINETP3)) { + if (ha->enq->ucMaxPhysicalDevices == 15) + ha->ad_type = IPS_ADTYPE_SERVERAID3L; + else + ha->ad_type = IPS_ADTYPE_SERVERAID3; + } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) && + (ha->revision_id <= IPS_REVID_TROMBONE64)) { + ha->ad_type = IPS_ADTYPE_SERVERAID4H; + } + break; - switch (ha->device_id) { - case IPS_DEVICEID_COPPERHEAD: - if (ha->revision_id <= IPS_REVID_SERVERAID) { - ha->ad_type = IPS_ADTYPE_SERVERAID; - } else if (ha->revision_id == IPS_REVID_SERVERAID2) { - ha->ad_type = IPS_ADTYPE_SERVERAID2; - } else if (ha->revision_id == IPS_REVID_NAVAJO) { - ha->ad_type = IPS_ADTYPE_NAVAJO; - } else if ((ha->revision_id == IPS_REVID_SERVERAID2) && (ha->slot_num == 0)) { - ha->ad_type = IPS_ADTYPE_KIOWA; - } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) && - (ha->revision_id <= IPS_REVID_CLARINETP3)) { - if (ha->enq->ucMaxPhysicalDevices == 15) - ha->ad_type = IPS_ADTYPE_SERVERAID3L; - else - ha->ad_type = IPS_ADTYPE_SERVERAID3; - } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) && - (ha->revision_id <= IPS_REVID_TROMBONE64)) { - ha->ad_type = IPS_ADTYPE_SERVERAID4H; - } - break; - - case IPS_DEVICEID_MORPHEUS: - switch (ha->subdevice_id) { - case IPS_SUBDEVICEID_4L: - ha->ad_type = IPS_ADTYPE_SERVERAID4L; - break; - - case IPS_SUBDEVICEID_4M: - ha->ad_type = IPS_ADTYPE_SERVERAID4M; - break; - - case IPS_SUBDEVICEID_4MX: - ha->ad_type = IPS_ADTYPE_SERVERAID4MX; - break; - - case IPS_SUBDEVICEID_4LX: - ha->ad_type = IPS_ADTYPE_SERVERAID4LX; - break; - - case IPS_SUBDEVICEID_5I2: - ha->ad_type = IPS_ADTYPE_SERVERAID5I2; - break; - - case IPS_SUBDEVICEID_5I1: - ha->ad_type = IPS_ADTYPE_SERVERAID5I1; - break; - } - - 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; - } + case IPS_DEVICEID_MORPHEUS: + switch (ha->subdevice_id) { + case IPS_SUBDEVICEID_4L: + ha->ad_type = IPS_ADTYPE_SERVERAID4L; + break; + + case IPS_SUBDEVICEID_4M: + ha->ad_type = IPS_ADTYPE_SERVERAID4M; + break; + + case IPS_SUBDEVICEID_4MX: + ha->ad_type = IPS_ADTYPE_SERVERAID4MX; + break; + + case IPS_SUBDEVICEID_4LX: + ha->ad_type = IPS_ADTYPE_SERVERAID4LX; + break; + + case IPS_SUBDEVICEID_5I2: + ha->ad_type = IPS_ADTYPE_SERVERAID5I2; + break; + + case IPS_SUBDEVICEID_5I1: + ha->ad_type = IPS_ADTYPE_SERVERAID5I1; + break; + } + + 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; + } } /****************************************************************************/ @@ -2282,159 +2356,155 @@ /* */ /****************************************************************************/ static void -ips_get_bios_version(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t *buffer; - char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - - METHOD_TRACE("ips_get_bios_version", 1); - - major = 0; - minor = 0; - - strncpy(ha->bios_version, " ?", 8); - - if (ha->device_id == IPS_DEVICEID_COPPERHEAD) { - if (IPS_USE_MEMIO(ha)) { - /* Memory Mapped I/O */ - - /* test 1st byte */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) - return; - - writel(1, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) - return; - - /* Get Major version */ - writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - major = readb(ha->mem_ptr + IPS_REG_FLDP); - - /* Get Minor version */ - writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - minor = readb(ha->mem_ptr + IPS_REG_FLDP); - - /* Get SubMinor version */ - writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - subminor = readb(ha->mem_ptr + IPS_REG_FLDP); - - } else { - /* Programmed I/O */ - - /* test 1st byte */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) - return ; - - outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) - return ; - - /* Get Major version */ - outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - major = inb(ha->io_addr + IPS_REG_FLDP); - - /* Get Minor version */ - outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - minor = inb(ha->io_addr + IPS_REG_FLDP); - - /* Get SubMinor version */ - outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - subminor = inb(ha->io_addr + IPS_REG_FLDP); - - } - } else { - /* Morpheus Family - Send Command to the card */ - - buffer = kmalloc(0x1000, IPS_ATOMIC_GFP); - if (!buffer) - return; - - memset(buffer, 0, 0x1000); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_RW_BIOSFW; - - scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW; - scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flashfw.type = 1; - scb->cmd.flashfw.direction = 0; - scb->cmd.flashfw.count = cpu_to_le32(0x800); - scb->cmd.flashfw.total_packets = 1; - scb->cmd.flashfw.packet_num = 0; - scb->data_len = 0x1000; - scb->data_busaddr = pci_map_single(ha->pcidev, buffer, scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.flashfw.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* issue the command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { - /* Error occurred */ - kfree(buffer); - - return; - } - - if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) { - major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */ - minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ - subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */ - } else { - kfree(buffer); - return; - } - - kfree(buffer); - } - - ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4]; - ha->bios_version[1] = '.'; - ha->bios_version[2] = hexDigits[major & 0x0F]; - ha->bios_version[3] = hexDigits[subminor]; - ha->bios_version[4] = '.'; - ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4]; - ha->bios_version[6] = hexDigits[minor & 0x0F]; - ha->bios_version[7] = 0; +ips_get_bios_version(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t *buffer; + char hexDigits[] = + { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', + 'D', 'E', 'F' }; + + METHOD_TRACE("ips_get_bios_version", 1); + + major = 0; + minor = 0; + + strncpy(ha->bios_version, " ?", 8); + + if (ha->device_id == IPS_DEVICEID_COPPERHEAD) { + if (IPS_USE_MEMIO(ha)) { + /* Memory Mapped I/O */ + + /* test 1st byte */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) + return; + + writel(1, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) + return; + + /* Get Major version */ + writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + major = readb(ha->mem_ptr + IPS_REG_FLDP); + + /* Get Minor version */ + writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + minor = readb(ha->mem_ptr + IPS_REG_FLDP); + + /* Get SubMinor version */ + writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + subminor = readb(ha->mem_ptr + IPS_REG_FLDP); + + } else { + /* Programmed I/O */ + + /* test 1st byte */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) + return; + + outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) + return; + + /* Get Major version */ + outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + major = inb(ha->io_addr + IPS_REG_FLDP); + + /* Get Minor version */ + outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + minor = inb(ha->io_addr + IPS_REG_FLDP); + + /* Get SubMinor version */ + outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + subminor = inb(ha->io_addr + IPS_REG_FLDP); + + } + } else { + /* Morpheus Family - Send Command to the card */ + + buffer = ha->ioctl_data; + + memset(buffer, 0, 0x1000); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_RW_BIOSFW; + + scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW; + scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.flashfw.type = 1; + scb->cmd.flashfw.direction = 0; + scb->cmd.flashfw.count = cpu_to_le32(0x800); + scb->cmd.flashfw.total_packets = 1; + scb->cmd.flashfw.packet_num = 0; + scb->data_len = 0x1000; + scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr; + + /* issue the command */ + if (((ret = + ips_send_wait(ha, scb, ips_cmd_timeout, + intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { + /* Error occurred */ + + return; + } + + if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) { + major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */ + minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ + subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */ + } else { + return; + } + } + + ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4]; + ha->bios_version[1] = '.'; + ha->bios_version[2] = hexDigits[major & 0x0F]; + ha->bios_version[3] = hexDigits[subminor]; + ha->bios_version[4] = '.'; + ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4]; + ha->bios_version[6] = hexDigits[minor & 0x0F]; + ha->bios_version[7] = 0; } /****************************************************************************/ @@ -2449,125 +2519,130 @@ /* */ /****************************************************************************/ static int -ips_hainit(ips_ha_t *ha) { - int i; - struct timeval tv; +ips_hainit(ips_ha_t * ha) +{ + int i; + struct timeval tv; + + METHOD_TRACE("ips_hainit", 1); - METHOD_TRACE("ips_hainit", 1); + if (!ha) + return (0); - if (!ha) - return (0); + if (ha->func.statinit) + (*ha->func.statinit) (ha); - if (ha->func.statinit) - (*ha->func.statinit)(ha); + if (ha->func.enableint) + (*ha->func.enableint) (ha); - if (ha->func.enableint) - (*ha->func.enableint)(ha); + /* Send FFDC */ + ha->reset_count = 1; + do_gettimeofday(&tv); + ha->last_ffdc = tv.tv_sec; + ips_ffdc_reset(ha, IPS_INTR_IORL); - /* Send FFDC */ - ha->reset_count = 1; - do_gettimeofday(&tv); - ha->last_ffdc = tv.tv_sec; - ips_ffdc_reset(ha, IPS_INTR_IORL); + if (!ips_read_config(ha, IPS_INTR_IORL)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "unable to read config from controller.\n"); - if (!ips_read_config(ha, IPS_INTR_IORL)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read config from controller.\n"); + return (0); + } + /* end if */ + if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "unable to read controller status.\n"); + + return (0); + } - return (0); - } /* end if */ + /* Identify this controller */ + ips_identify_controller(ha); - if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read controller status.\n"); + if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "unable to read subsystem parameters.\n"); - return (0); - } + return (0); + } - /* Identify this controller */ - ips_identify_controller(ha); + /* write nvram user page 5 */ + if (!ips_write_driver_status(ha, IPS_INTR_IORL)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "unable to write driver info to controller.\n"); - if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read subsystem parameters.\n"); + return (0); + } - 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; + ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1; + + switch (ha->conf->logical_drive[0].ucStripeSize) { + case 4: + ha->max_xfer = 0x10000; + break; + + case 5: + ha->max_xfer = 0x20000; + break; + + case 6: + ha->max_xfer = 0x40000; + break; + + case 7: + default: + ha->max_xfer = 0x80000; + break; + } - /* write nvram user page 5 */ - if (!ips_write_driver_status(ha, IPS_INTR_IORL)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to write driver info to controller.\n"); + /* setup max concurrent commands */ + if (le32_to_cpu(ha->subsys->param[4]) & 0x1) { + /* Use the new method */ + ha->max_cmds = ha->enq->ucConcurrentCmdCount; + } else { + /* use the old method */ + switch (ha->conf->logical_drive[0].ucStripeSize) { + case 4: + ha->max_cmds = 32; + break; + + case 5: + ha->max_cmds = 16; + break; + + case 6: + ha->max_cmds = 8; + break; + + case 7: + default: + ha->max_cmds = 4; + break; + } + } - return (0); - } + /* Limit the Active Commands on a Lite Adapter */ + if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) || + (ha->ad_type == IPS_ADTYPE_SERVERAID4L) || + (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) { + if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds)) + ha->max_cmds = MaxLiteCmds; + } - /* 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; - ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1; - - switch (ha->conf->logical_drive[0].ucStripeSize) { - case 4: - ha->max_xfer = 0x10000; - break; - - case 5: - ha->max_xfer = 0x20000; - break; - - case 6: - ha->max_xfer = 0x40000; - break; - - case 7: - default: - ha->max_xfer = 0x80000; - break; - } - - /* setup max concurrent commands */ - if (le32_to_cpu(ha->subsys->param[4]) & 0x1) { - /* Use the new method */ - ha->max_cmds = ha->enq->ucConcurrentCmdCount; - } else { - /* use the old method */ - switch (ha->conf->logical_drive[0].ucStripeSize) { - case 4: - ha->max_cmds = 32; - break; - - case 5: - ha->max_cmds = 16; - break; - - case 6: - ha->max_cmds = 8; - break; - - case 7: - default: - ha->max_cmds = 4; - break; - } - } - - /* Limit the Active Commands on a Lite Adapter */ - if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) || - (ha->ad_type == IPS_ADTYPE_SERVERAID4L) || - (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) { - if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds)) - ha->max_cmds = MaxLiteCmds; - } - - /* set controller IDs */ - ha->ha_id[0] = IPS_ADAPTER_ID; - for (i = 1; i < ha->nbus; i++) { - ha->ha_id[i] = ha->conf->init_id[i-1] & 0x1f; - ha->dcdb_active[i-1] = 0; - } + /* set controller IDs */ + ha->ha_id[0] = IPS_ADAPTER_ID; + for (i = 1; i < ha->nbus; i++) { + ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f; + ha->dcdb_active[i - 1] = 0; + } - return (1); + return (1); } /****************************************************************************/ @@ -2580,227 +2655,240 @@ /* */ /****************************************************************************/ static void -ips_next(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - Scsi_Cmnd *SC; - Scsi_Cmnd *p; - Scsi_Cmnd *q; - ips_copp_wait_item_t *item; - int ret; - unsigned long cpu_flags = 0; - struct Scsi_Host *host; - METHOD_TRACE("ips_next", 1); - - if (!ha) - return ; - host = ips_sh[ha->host_num]; - /* - * Block access to the queue function so - * this command won't time out - */ - if(intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - - if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) { - struct timeval tv; +ips_next(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + Scsi_Cmnd *SC; + Scsi_Cmnd *p; + Scsi_Cmnd *q; + ips_copp_wait_item_t *item; + int ret; + unsigned long cpu_flags = 0; + struct Scsi_Host *host; + METHOD_TRACE("ips_next", 1); - do_gettimeofday(&tv); + if (!ha) + return; + host = ips_sh[ha->host_num]; + /* + * Block access to the queue function so + * this command won't time out + */ + if (intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + + if ((ha->subsys->param[3] & 0x300000) + && (ha->scb_activelist.count == 0)) { + struct timeval tv; + + do_gettimeofday(&tv); + + if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { + ha->last_ffdc = tv.tv_sec; + ips_ffdc_time(ha); + } + } - if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { - ha->last_ffdc = tv.tv_sec; - ips_ffdc_time(ha); - } - } - - /* - * Send passthru commands - * These have priority over normal I/O - * but shouldn't affect performance too much - * since we limit the number that can be active - * on the card at any one time - */ - while ((ha->num_ioctl < IPS_MAX_IOCTL) && - (ha->copp_waitlist.head) && - (scb = ips_getscb(ha))) { - - item = ips_removeq_copp_head(&ha->copp_waitlist); - ha->num_ioctl++; - if(intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - scb->scsi_cmd = item->scsi_cmd; - kfree(item); - - ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); - - if(intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - switch (ret) { - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_OK << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ - - if (ret != IPS_SUCCESS) { - ha->num_ioctl--; - continue; - } - - ret = ips_send_cmd(ha, scb); - - if (ret == IPS_SUCCESS) - ips_putq_scb_head(&ha->scb_activelist, scb); - else - ha->num_ioctl--; - - switch(ret) { - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - } - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ - - } - - - /* - * Send "Normal" I/O commands - */ - - p = ha->scb_waitlist.head; - while ((p) && (scb = ips_getscb(ha))) { - 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; - } - - q = p; - SC = ips_removeq_wait(&ha->scb_waitlist, q); - - if(intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */ - - SC->result = DID_OK; - SC->host_scribble = NULL; - - memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer)); - - 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; - scb->callback = ipsintr_done; - scb->timeout = ips_cmd_timeout; - memset(&scb->cmd, 0, 16); - - /* copy in the CDB */ - memcpy(scb->cdb, SC->cmnd, SC->cmd_len); - - /* Now handle the data buffer */ - if (SC->use_sg) { - struct scatterlist *sg; - int i; - - sg = SC->request_buffer; - 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; - 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) { - scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer, - SC->request_bufflen, - scsi_to_pci_dma_dir(SC->sc_data_direction)); - scb->flags |= IPS_SCB_MAP_SINGLE; - 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; - scb->data_len = 0; - scb->dcdb.transfer_length = 0; - } - - } - - scb->dcdb.cmd_attribute = ips_command_direction[scb->scsi_cmd->cmnd[0]]; - - if (!(scb->dcdb.cmd_attribute & 0x3)) - scb->dcdb.transfer_length = 0; - - if (scb->data_len >= IPS_MAX_XFER) { - scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; - scb->dcdb.transfer_length = 0; - } - if(intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags); - - ret = ips_send_cmd(ha, scb); - - switch(ret) { - case IPS_SUCCESS: - ips_putq_scb_head(&ha->scb_activelist, scb); - break; - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - if (scb->bus) - ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - if (scb->scsi_cmd) - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - - if (scb->bus) - ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ + /* + * Send passthru commands + * These have priority over normal I/O + * but shouldn't affect performance too much + * since we limit the number that can be active + * on the card at any one time + */ + while ((ha->num_ioctl < IPS_MAX_IOCTL) && + (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) { + + item = ips_removeq_copp_head(&ha->copp_waitlist); + ha->num_ioctl++; + if (intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + scb->scsi_cmd = item->scsi_cmd; + kfree(item); + + ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); + + if (intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + switch (ret) { + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_OK << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + if (ret != IPS_SUCCESS) { + ha->num_ioctl--; + continue; + } + + ret = ips_send_cmd(ha, scb); + + if (ret == IPS_SUCCESS) + ips_putq_scb_head(&ha->scb_activelist, scb); + else + ha->num_ioctl--; + + switch (ret) { + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + } + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + } + + /* + * Send "Normal" I/O commands + */ + + p = ha->scb_waitlist.head; + while ((p) && (scb = ips_getscb(ha))) { + 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; + } + + q = p; + SC = ips_removeq_wait(&ha->scb_waitlist, q); - p = (Scsi_Cmnd *) p->host_scribble; + if (intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */ - } /* end while */ + SC->result = DID_OK; + SC->host_scribble = NULL; + + memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer)); + + 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; + scb->callback = ipsintr_done; + scb->timeout = ips_cmd_timeout; + memset(&scb->cmd, 0, 16); + + /* copy in the CDB */ + memcpy(scb->cdb, SC->cmnd, SC->cmd_len); + + /* Now handle the data buffer */ + if (SC->use_sg) { + struct scatterlist *sg; + int i; + + sg = SC->request_buffer; + 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; + 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) { + scb->data_busaddr = + pci_map_single(ha->pcidev, + SC->request_buffer, + SC->request_bufflen, + scsi_to_pci_dma_dir(SC-> + sc_data_direction)); + scb->flags |= IPS_SCB_MAP_SINGLE; + 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; + scb->data_len = 0; + scb->dcdb.transfer_length = 0; + } + + } + + scb->dcdb.cmd_attribute = + ips_command_direction[scb->scsi_cmd->cmnd[0]]; + + if (!(scb->dcdb.cmd_attribute & 0x3)) + scb->dcdb.transfer_length = 0; + + if (scb->data_len >= IPS_MAX_XFER) { + scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; + scb->dcdb.transfer_length = 0; + } + if (intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + + ret = ips_send_cmd(ha, scb); + + switch (ret) { + case IPS_SUCCESS: + ips_putq_scb_head(&ha->scb_activelist, scb); + break; + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } - if(intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); + if (scb->bus) + ha->dcdb_active[scb->bus - 1] &= + ~(1 << scb->target_id); + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + if (scb->scsi_cmd) + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + + if (scb->bus) + ha->dcdb_active[scb->bus - 1] &= + ~(1 << scb->target_id); + + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + p = (Scsi_Cmnd *) p->host_scribble; + + } /* end while */ + + if (intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); } /****************************************************************************/ @@ -2815,19 +2903,20 @@ /* */ /****************************************************************************/ static inline void -ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { - METHOD_TRACE("ips_putq_scb_head", 1); +ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item) +{ + METHOD_TRACE("ips_putq_scb_head", 1); - if (!item) - return ; + if (!item) + return; - item->q_next = queue->head; - queue->head = item; + item->q_next = queue->head; + queue->head = item; - if (!queue->tail) - queue->tail = item; + if (!queue->tail) + queue->tail = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -2842,23 +2931,24 @@ /* */ /****************************************************************************/ static inline void -ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { - METHOD_TRACE("ips_putq_scb_tail", 1); +ips_putq_scb_tail(ips_scb_queue_t * queue, ips_scb_t * item) +{ + METHOD_TRACE("ips_putq_scb_tail", 1); - if (!item) - return ; + if (!item) + return; - item->q_next = NULL; + item->q_next = NULL; - if (queue->tail) - queue->tail->q_next = item; + if (queue->tail) + queue->tail->q_next = item; - queue->tail = item; + queue->tail = item; - if (!queue->head) - queue->head = item; + if (!queue->head) + queue->head = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -2873,26 +2963,27 @@ /* */ /****************************************************************************/ static inline ips_scb_t * -ips_removeq_scb_head(ips_scb_queue_t *queue) { - ips_scb_t *item; +ips_removeq_scb_head(ips_scb_queue_t * queue) +{ + ips_scb_t *item; - METHOD_TRACE("ips_removeq_scb_head", 1); + METHOD_TRACE("ips_removeq_scb_head", 1); - item = queue->head; + item = queue->head; - if (!item) { - return (NULL); - } + if (!item) { + return (NULL); + } - queue->head = item->q_next; - item->q_next = NULL; + queue->head = item->q_next; + item->q_next = NULL; - if (queue->tail == item) - queue->tail = NULL; + if (queue->tail == item) + queue->tail = NULL; - queue->count--; + queue->count--; - return (item); + return (item); } /****************************************************************************/ @@ -2907,37 +2998,38 @@ /* */ /****************************************************************************/ static inline ips_scb_t * -ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { - ips_scb_t *p; +ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item) +{ + ips_scb_t *p; - METHOD_TRACE("ips_removeq_scb", 1); + METHOD_TRACE("ips_removeq_scb", 1); - if (!item) - return (NULL); + if (!item) + return (NULL); - if (item == queue->head) { - return (ips_removeq_scb_head(queue)); - } + if (item == queue->head) { + return (ips_removeq_scb_head(queue)); + } - p = queue->head; + p = queue->head; - while ((p) && (item != p->q_next)) - p = p->q_next; + while ((p) && (item != p->q_next)) + p = p->q_next; - if (p) { - /* found a match */ - p->q_next = item->q_next; + if (p) { + /* found a match */ + p->q_next = item->q_next; - if (!item->q_next) - queue->tail = p; + if (!item->q_next) + queue->tail = p; - item->q_next = NULL; - queue->count--; + item->q_next = NULL; + queue->count--; - return (item); - } + return (item); + } - return (NULL); + return (NULL); } /****************************************************************************/ @@ -2952,19 +3044,20 @@ /* */ /****************************************************************************/ static inline void -ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { - METHOD_TRACE("ips_putq_wait_head", 1); +ips_putq_wait_head(ips_wait_queue_t * queue, Scsi_Cmnd * item) +{ + METHOD_TRACE("ips_putq_wait_head", 1); - if (!item) - return ; + if (!item) + return; - item->host_scribble = (char *) queue->head; - queue->head = item; + item->host_scribble = (char *) queue->head; + queue->head = item; - if (!queue->tail) - queue->tail = item; + if (!queue->tail) + queue->tail = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -2979,23 +3072,24 @@ /* */ /****************************************************************************/ static inline void -ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { - METHOD_TRACE("ips_putq_wait_tail", 1); +ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item) +{ + METHOD_TRACE("ips_putq_wait_tail", 1); - if (!item) - return ; + if (!item) + return; - item->host_scribble = NULL; + item->host_scribble = NULL; - if (queue->tail) - queue->tail->host_scribble = (char *)item; + if (queue->tail) + queue->tail->host_scribble = (char *) item; - queue->tail = item; + queue->tail = item; - if (!queue->head) - queue->head = item; + if (!queue->head) + queue->head = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3010,26 +3104,27 @@ /* */ /****************************************************************************/ static inline Scsi_Cmnd * -ips_removeq_wait_head(ips_wait_queue_t *queue) { - Scsi_Cmnd *item; +ips_removeq_wait_head(ips_wait_queue_t * queue) +{ + Scsi_Cmnd *item; - METHOD_TRACE("ips_removeq_wait_head", 1); + METHOD_TRACE("ips_removeq_wait_head", 1); - item = queue->head; + item = queue->head; - if (!item) { - return (NULL); - } + if (!item) { + return (NULL); + } - queue->head = (Scsi_Cmnd *) item->host_scribble; - item->host_scribble = NULL; + queue->head = (Scsi_Cmnd *) item->host_scribble; + item->host_scribble = NULL; - if (queue->tail == item) - queue->tail = NULL; + if (queue->tail == item) + queue->tail = NULL; - queue->count--; + queue->count--; - return (item); + return (item); } /****************************************************************************/ @@ -3044,37 +3139,38 @@ /* */ /****************************************************************************/ static inline Scsi_Cmnd * -ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { - Scsi_Cmnd *p; +ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item) +{ + Scsi_Cmnd *p; - METHOD_TRACE("ips_removeq_wait", 1); + METHOD_TRACE("ips_removeq_wait", 1); - if (!item) - return (NULL); + if (!item) + return (NULL); - if (item == queue->head) { - return (ips_removeq_wait_head(queue)); - } + if (item == queue->head) { + return (ips_removeq_wait_head(queue)); + } - p = queue->head; + p = queue->head; - while ((p) && (item != (Scsi_Cmnd *) p->host_scribble)) - p = (Scsi_Cmnd *) p->host_scribble; + while ((p) && (item != (Scsi_Cmnd *) p->host_scribble)) + p = (Scsi_Cmnd *) p->host_scribble; - if (p) { - /* found a match */ - p->host_scribble = item->host_scribble; + if (p) { + /* found a match */ + p->host_scribble = item->host_scribble; - if (!item->host_scribble) - queue->tail = p; + if (!item->host_scribble) + queue->tail = p; - item->host_scribble = NULL; - queue->count--; + item->host_scribble = NULL; + queue->count--; - return (item); - } + return (item); + } - return (NULL); + return (NULL); } /****************************************************************************/ @@ -3089,19 +3185,20 @@ /* */ /****************************************************************************/ static inline void -ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { - METHOD_TRACE("ips_putq_copp_head", 1); +ips_putq_copp_head(ips_copp_queue_t * queue, ips_copp_wait_item_t * item) +{ + METHOD_TRACE("ips_putq_copp_head", 1); - if (!item) - return ; + if (!item) + return; - item->next = queue->head; - queue->head = item; + item->next = queue->head; + queue->head = item; - if (!queue->tail) - queue->tail = item; + if (!queue->tail) + queue->tail = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3116,23 +3213,24 @@ /* */ /****************************************************************************/ static inline void -ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { - METHOD_TRACE("ips_putq_copp_tail", 1); +ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item) +{ + METHOD_TRACE("ips_putq_copp_tail", 1); - if (!item) - return ; + if (!item) + return; - item->next = NULL; + item->next = NULL; - if (queue->tail) - queue->tail->next = item; + if (queue->tail) + queue->tail->next = item; - queue->tail = item; + queue->tail = item; - if (!queue->head) - queue->head = item; + if (!queue->head) + queue->head = item; - queue->count++; + queue->count++; } /****************************************************************************/ @@ -3147,26 +3245,27 @@ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * -ips_removeq_copp_head(ips_copp_queue_t *queue) { - ips_copp_wait_item_t *item; +ips_removeq_copp_head(ips_copp_queue_t * queue) +{ + ips_copp_wait_item_t *item; - METHOD_TRACE("ips_removeq_copp_head", 1); + METHOD_TRACE("ips_removeq_copp_head", 1); - item = queue->head; + item = queue->head; - if (!item) { - return (NULL); - } + if (!item) { + return (NULL); + } - queue->head = item->next; - item->next = NULL; + queue->head = item->next; + item->next = NULL; - if (queue->tail == item) - queue->tail = NULL; + if (queue->tail == item) + queue->tail = NULL; - queue->count--; + queue->count--; - return (item); + return (item); } /****************************************************************************/ @@ -3181,37 +3280,38 @@ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * -ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { - ips_copp_wait_item_t *p; +ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item) +{ + ips_copp_wait_item_t *p; - METHOD_TRACE("ips_removeq_copp", 1); + METHOD_TRACE("ips_removeq_copp", 1); - if (!item) - return (NULL); + if (!item) + return (NULL); - if (item == queue->head) { - return (ips_removeq_copp_head(queue)); - } + if (item == queue->head) { + return (ips_removeq_copp_head(queue)); + } - p = queue->head; + p = queue->head; - while ((p) && (item != p->next)) - p = p->next; + while ((p) && (item != p->next)) + p = p->next; - if (p) { - /* found a match */ - p->next = item->next; + if (p) { + /* found a match */ + p->next = item->next; - if (!item->next) - queue->tail = p; + if (!item->next) + queue->tail = p; - item->next = NULL; - queue->count--; + item->next = NULL; + queue->count--; - return (item); - } + return (item); + } - return (NULL); + return (NULL); } /****************************************************************************/ @@ -3224,16 +3324,16 @@ /* */ /****************************************************************************/ static void -ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) { - METHOD_TRACE("ipsintr_blocking", 2); +ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb) +{ + METHOD_TRACE("ipsintr_blocking", 2); - ips_freescb(ha, scb); - if ((ha->waitflag == TRUE) && - (ha->cmd_in_progress == scb->cdb[0])) { - ha->waitflag = FALSE; + ips_freescb(ha, scb); + if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) { + ha->waitflag = FALSE; - return ; - } + return; + } } /****************************************************************************/ @@ -3246,23 +3346,26 @@ /* */ /****************************************************************************/ static void -ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) { - METHOD_TRACE("ipsintr_done", 2); +ipsintr_done(ips_ha_t * ha, ips_scb_t * scb) +{ + METHOD_TRACE("ipsintr_done", 2); - if (!scb) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Spurious interrupt; scb NULL.\n"); + if (!scb) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Spurious interrupt; scb NULL.\n"); - return ; - } + return; + } - if (scb->scsi_cmd == NULL) { - /* unexpected interrupt */ - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Spurious interrupt; scsi_cmd not set.\n"); + if (scb->scsi_cmd == NULL) { + /* unexpected interrupt */ + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Spurious interrupt; scsi_cmd not set.\n"); - return; - } + return; + } - ips_done(ha, scb); + ips_done(ha, scb); } /****************************************************************************/ @@ -3275,104 +3378,118 @@ /* ASSUMED to be called form within the request lock */ /****************************************************************************/ static void -ips_done(ips_ha_t *ha, ips_scb_t *scb) { - int ret; +ips_done(ips_ha_t * ha, ips_scb_t * scb) +{ + int ret; - METHOD_TRACE("ips_done", 1); + METHOD_TRACE("ips_done", 1); - if (!scb) - return ; + if (!scb) + return; - if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { - ips_cleanup_passthru(ha, scb); - ha->num_ioctl--; - } else { - /* - * Check to see if this command had too much - * data and had to be broke up. If so, queue - * the rest of the data and continue. - */ - if ((scb->breakup) || (scb->sg_break)) { - /* we had a data breakup */ - scb->data_len = 0; - - if (scb->sg_count) { - /* S/G request */ - struct scatterlist *sg; - int ips_sg_index = 0; - int sg_dma_index; - - sg = scb->scsi_cmd->request_buffer; - - /* Spin forward to last dma chunk */ - sg_dma_index = scb->breakup; - - /* 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; - - } - - } 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)) - scb->dcdb.transfer_length = 0; - - if (scb->data_len >= IPS_MAX_XFER) { - scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; - scb->dcdb.transfer_length = 0; - } - - ret = ips_send_cmd(ha, scb); - - switch(ret) { - case IPS_FAILURE: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - case IPS_SUCCESS_IMM: - if (scb->scsi_cmd) { - scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); - } - - ips_freescb(ha, scb); - break; - default: - break; - } /* end case */ - - return ; - } - } /* end if passthru */ - - if (scb->bus) { - ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - } + if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { + ips_cleanup_passthru(ha, scb); + ha->num_ioctl--; + } else { + /* + * Check to see if this command had too much + * data and had to be broke up. If so, queue + * the rest of the data and continue. + */ + if ((scb->breakup) || (scb->sg_break)) { + /* we had a data breakup */ + scb->data_len = 0; + + if (scb->sg_count) { + /* S/G request */ + struct scatterlist *sg; + int ips_sg_index = 0; + int sg_dma_index; + + sg = scb->scsi_cmd->request_buffer; + + /* Spin forward to last dma chunk */ + sg_dma_index = scb->breakup; + + /* 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->scsi_cmd->scsi_done(scb->scsi_cmd); + } - ips_freescb(ha, scb); + } 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)) + scb->dcdb.transfer_length = 0; + + if (scb->data_len >= IPS_MAX_XFER) { + scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; + scb->dcdb.transfer_length = 0; + } + + ret = ips_send_cmd(ha, scb); + + switch (ret) { + case IPS_FAILURE: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + case IPS_SUCCESS_IMM: + if (scb->scsi_cmd) { + scb->scsi_cmd->result = DID_ERROR << 16; + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + } + + ips_freescb(ha, scb); + break; + default: + break; + } /* end case */ + + return; + } + } /* end if passthru */ + + if (scb->bus) { + ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id); + } + + scb->scsi_cmd->scsi_done(scb->scsi_cmd); + + ips_freescb(ha, scb); } /****************************************************************************/ @@ -3381,122 +3498,134 @@ /* */ /* Routine Description: */ /* */ -/* Map ServeRAID error codes to Linux Error Codes */ +/* Map Controller Error codes to Linux Error Codes */ /* */ /****************************************************************************/ static int -ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) { - int errcode; - int device_error; - uint32_t transfer_len; - IPS_DCDB_TABLE_TAPE *tapeDCDB; - - METHOD_TRACE("ips_map_status", 1); - - if (scb->bus) { - 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->device->channel, - scb->scsi_cmd->device->id, - scb->scsi_cmd->device->lun, - scb->basic_status, - scb->extended_status, - scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0, - scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0, - scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0); - } - - /* default driver error */ - errcode = DID_ERROR; - device_error = 0; - - switch (scb->basic_status & IPS_GSC_STATUS_MASK) { - case IPS_CMD_TIMEOUT: - errcode = DID_TIME_OUT; - break; - - case IPS_INVAL_OPCO: - case IPS_INVAL_CMD_BLK: - case IPS_INVAL_PARM_BLK: - case IPS_LD_ERROR: - case IPS_CMD_CMPLT_WERROR: - break; - - case IPS_PHYS_DRV_ERROR: - switch (scb->extended_status) { - case IPS_ERR_SEL_TO: - if (scb->bus) - errcode = DID_NO_CONNECT; - - break; - - case IPS_ERR_OU_RUN: - if ( ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB ) || - ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG ) ) { - tapeDCDB = ( IPS_DCDB_TABLE_TAPE * ) &scb->dcdb; - transfer_len = tapeDCDB->transfer_length; - } else { - transfer_len = ( uint32_t ) scb->dcdb.transfer_length; - } - - if ((scb->bus) && (transfer_len < scb->data_len)) { - /* Underrun - set default to no error */ - errcode = DID_OK; - - /* Restrict access to physical DASD */ - if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && - ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) { - /* underflow -- no error */ - /* restrict access to physical DASD */ - errcode = DID_TIME_OUT; - break; - } - } else - errcode = DID_ERROR; - - break; - - case IPS_ERR_RECOVERY: - /* don't fail recovered errors */ - if (scb->bus) - errcode = DID_OK; - - break; - - case IPS_ERR_HOST_RESET: - case IPS_ERR_DEV_RESET: - errcode = DID_RESET; - break; - - case IPS_ERR_CKCOND: - if (scb->bus) { - if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) || - (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)) { - tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; - memcpy(scb->scsi_cmd->sense_buffer, tapeDCDB->sense_info, - sizeof(scb->scsi_cmd->sense_buffer)); - } else { - memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info, - sizeof(scb->scsi_cmd->sense_buffer)); - } - device_error = 2; /* check condition */ - } - - errcode = DID_OK; - - break; - - default: - errcode = DID_ERROR; - break; +ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp) +{ + int errcode; + int device_error; + uint32_t transfer_len; + IPS_DCDB_TABLE_TAPE *tapeDCDB; + + METHOD_TRACE("ips_map_status", 1); + + if (scb->bus) { + 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->device->channel, + scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun, + scb->basic_status, scb->extended_status, + scb->extended_status == + IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0, + scb->extended_status == + IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0, + scb->extended_status == + IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0); + } + + /* default driver error */ + errcode = DID_ERROR; + device_error = 0; + + switch (scb->basic_status & IPS_GSC_STATUS_MASK) { + case IPS_CMD_TIMEOUT: + errcode = DID_TIME_OUT; + break; + + case IPS_INVAL_OPCO: + case IPS_INVAL_CMD_BLK: + case IPS_INVAL_PARM_BLK: + case IPS_LD_ERROR: + case IPS_CMD_CMPLT_WERROR: + break; + + case IPS_PHYS_DRV_ERROR: + switch (scb->extended_status) { + case IPS_ERR_SEL_TO: + if (scb->bus) + errcode = DID_NO_CONNECT; + + break; + + case IPS_ERR_OU_RUN: + if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) || + (scb->cmd.dcdb.op_code == + IPS_CMD_EXTENDED_DCDB_SG)) { + tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; + transfer_len = tapeDCDB->transfer_length; + } else { + transfer_len = + (uint32_t) scb->dcdb.transfer_length; + } + + if ((scb->bus) && (transfer_len < scb->data_len)) { + /* Underrun - set default to no error */ + errcode = DID_OK; + + /* Restrict access to physical DASD */ + if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && + ((((char *) scb->scsi_cmd-> + buffer)[0] & 0x1f) == TYPE_DISK)) { + /* underflow -- no error */ + /* restrict access to physical DASD */ + errcode = DID_TIME_OUT; + break; + } + } else + errcode = DID_ERROR; + + break; + + case IPS_ERR_RECOVERY: + /* don't fail recovered errors */ + if (scb->bus) + errcode = DID_OK; + + break; + + case IPS_ERR_HOST_RESET: + case IPS_ERR_DEV_RESET: + errcode = DID_RESET; + break; + + case IPS_ERR_CKCOND: + if (scb->bus) { + if ((scb->cmd.dcdb.op_code == + IPS_CMD_EXTENDED_DCDB) + || (scb->cmd.dcdb.op_code == + IPS_CMD_EXTENDED_DCDB_SG)) { + tapeDCDB = + (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; + memcpy(scb->scsi_cmd->sense_buffer, + tapeDCDB->sense_info, + sizeof (scb->scsi_cmd-> + sense_buffer)); + } else { + memcpy(scb->scsi_cmd->sense_buffer, + scb->dcdb.sense_info, + sizeof (scb->scsi_cmd-> + sense_buffer)); + } + device_error = 2; /* check condition */ + } + + errcode = DID_OK; - } /* end switch */ - } /* end switch */ + break; - scb->scsi_cmd->result = device_error | (errcode << 16); + default: + errcode = DID_ERROR; + break; - return (1); + } /* end switch */ + } /* end switch */ + + scb->scsi_cmd->result = device_error | (errcode << 16); + + return (1); } /****************************************************************************/ @@ -3511,25 +3640,26 @@ /* actually need to wait. */ /****************************************************************************/ static int -ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) { - int ret; +ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr) +{ + int ret; - METHOD_TRACE("ips_send_wait", 1); + METHOD_TRACE("ips_send_wait", 1); - if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */ - ha->waitflag = TRUE; - ha->cmd_in_progress = scb->cdb[0]; - } - scb->callback = ipsintr_blocking; - ret = ips_send_cmd(ha, scb); + if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */ + ha->waitflag = TRUE; + ha->cmd_in_progress = scb->cdb[0]; + } + scb->callback = ipsintr_blocking; + ret = ips_send_cmd(ha, scb); - if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM)) - return (ret); + if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM)) + return (ret); - if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */ - ret = ips_wait(ha, timeout, intr); + if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */ + ret = ips_wait(ha, timeout, intr); - return (ret); + return (ret); } /****************************************************************************/ @@ -3539,19 +3669,20 @@ /* 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) +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; + 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])) + (i < scmd->use_sg) && (xfer_cnt < count); i++) { + if (!IPS_SG_ADDRESS(&sg[i])) return; - min_cnt = min( count - xfer_cnt, sg[i].length); + min_cnt = min(count - xfer_cnt, sg[i].length); memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt], min_cnt); xfer_cnt += min_cnt; @@ -3570,20 +3701,21 @@ /* 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) +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; + 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])) + (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 = min(count - xfer_cnt, sg[i].length); + memcpy(&cdata[xfer_cnt], IPS_SG_ADDRESS(&sg[i]), min_cnt); xfer_cnt += min_cnt; } @@ -3604,338 +3736,395 @@ /* */ /****************************************************************************/ static int -ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { - int ret; - char *sp; - int device_error; - IPS_DCDB_TABLE_TAPE *tapeDCDB; - int TimeOut; - - METHOD_TRACE("ips_send_cmd", 1); - - ret = IPS_SUCCESS; - - if (!scb->scsi_cmd) { - /* internal command */ - - if (scb->bus > 0) { - /* ServeRAID commands can't be issued */ - /* to real devices -- fail them */ - if ((ha->waitflag == TRUE) && - (ha->cmd_in_progress == scb->cdb[0])) { - ha->waitflag = FALSE; - } - - return (1); - } - } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) { - /* command to logical bus -- interpret */ - ret = IPS_SUCCESS_IMM; - - switch (scb->scsi_cmd->cmnd[0]) { - case ALLOW_MEDIUM_REMOVAL: - case REZERO_UNIT: - case ERASE: - case WRITE_FILEMARKS: - case SPACE: - scb->scsi_cmd->result = DID_ERROR << 16; - break; - - case START_STOP: - scb->scsi_cmd->result = DID_OK << 16; - - case TEST_UNIT_READY: - case INQUIRY: - if (scb->target_id == IPS_ADAPTER_ID) { - /* - * Either we have a TUR - * or we have a SCSI inquiry - */ - if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY) - scb->scsi_cmd->result = DID_OK << 16; - - if (scb->scsi_cmd->cmnd[0] == INQUIRY) { - IPS_SCSI_INQ_DATA inquiry; - - memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); - - inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR; - inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; - inquiry.Version = IPS_SCSI_INQ_REV2; - inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; - inquiry.AdditionalLength = 31; - inquiry.Flags[0] = IPS_SCSI_INQ_Address16; - inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync; - strncpy(inquiry.VendorId, "IBM ", 8); - strncpy(inquiry.ProductId, "SERVERAID ", 16); - strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - - ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry)); - - scb->scsi_cmd->result = DID_OK << 16; - } - } else { - scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.reserved = 0; - scb->cmd.logical_info.reserved2 = 0; - scb->data_len = sizeof(ha->adapt->logical_drive_info); - scb->data_busaddr = pci_map_single(ha->pcidev, - &ha->adapt->logical_drive_info, - scb->data_len, IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->cmd.logical_info.buffer_addr = scb->data_busaddr; - ret = IPS_SUCCESS; - } - - break; - - case REQUEST_SENSE: - ips_reqsen(ha, scb); - scb->scsi_cmd->result = DID_OK << 16; - break; - - case READ_6: - case WRITE_6: - 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; - - if (scb->cmd.basic_io.lba) - scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + - le16_to_cpu(scb->cmd.basic_io.sector_count)); - else - scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) | - (scb->scsi_cmd->cmnd[2] << 8) | - (scb->scsi_cmd->cmnd[3])); - - scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); - - if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0) - scb->cmd.basic_io.sector_count = cpu_to_le16(256); - - ret = IPS_SUCCESS; - break; - - case READ_10: - case WRITE_10: - 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; - - if (scb->cmd.basic_io.lba) - scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + - le16_to_cpu(scb->cmd.basic_io.sector_count)); - else - scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) | - (scb->scsi_cmd->cmnd[3] << 16) | - (scb->scsi_cmd->cmnd[4] << 8) | - scb->scsi_cmd->cmnd[5]); - - scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); - - - if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) { - /* - * This is a null condition - * we don't have to do anything - * so just return - */ - scb->scsi_cmd->result = DID_OK << 16; - } else - ret = IPS_SUCCESS; - - break; - - case RESERVE: - case RELEASE: - scb->scsi_cmd->result = DID_OK << 16; - break; - - 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)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - ret = IPS_SUCCESS; - break; - - case READ_CAPACITY: - scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.logical_info.reserved = 0; - scb->cmd.logical_info.reserved2 = 0; - scb->cmd.logical_info.reserved3 = 0; - scb->data_len = sizeof(ha->adapt->logical_drive_info); - scb->data_busaddr = pci_map_single(ha->pcidev, - &ha->adapt->logical_drive_info, - scb->data_len, IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->cmd.logical_info.buffer_addr = scb->data_busaddr; - ret = IPS_SUCCESS; - break; - - case SEND_DIAGNOSTIC: - case REASSIGN_BLOCKS: - case FORMAT_UNIT: - case SEEK_10: - case VERIFY: - case READ_DEFECT_DATA: - case READ_BUFFER: - case WRITE_BUFFER: - scb->scsi_cmd->result = DID_OK << 16; - break; - - default: - /* Set the Return Info to appear like the Command was */ - /* attempted, a Check Condition occurred, and Sense */ - /* Data indicating an Invalid CDB OpCode is returned. */ - sp = (char *) scb->scsi_cmd->sense_buffer; - memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer)); - - sp[0] = 0x70; /* Error Code */ - sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */ - sp[7] = 0x0A; /* Additional Sense Length */ - sp[12] = 0x20; /* ASC = Invalid OpCode */ - sp[13] = 0x00; /* ASCQ */ - - device_error = 2; /* Indicate Check Condition */ - scb->scsi_cmd->result = device_error | (DID_OK << 16); - break; - } /* end switch */ - } /* end if */ - - if (ret == IPS_SUCCESS_IMM) - return (ret); - - /* setup DCDB */ - if (scb->bus > 0) { - - /* 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 */ - if ( ha->conf->dev[scb->bus-1][scb->target_id].ucState == 0 ) { - scb->scsi_cmd->result = DID_NO_CONNECT << 16; - return (IPS_SUCCESS_IMM); - } - - ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); - scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + - (unsigned long)&scb->dcdb - - (unsigned long)scb); - scb->cmd.dcdb.reserved = 0; - scb->cmd.dcdb.reserved2 = 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) { - scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB; - } 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; - tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; - tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */ - - if (TimeOut) { - if (TimeOut < ( 10 * HZ )) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ - else if (TimeOut < (60 * HZ)) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ - else if (TimeOut < (1200 * HZ)) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ - } - - tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; - tapeDCDB->reserved_for_LUN = 0; - tapeDCDB->transfer_length = scb->data_len; - 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; - - if (TimeOut) { - if (TimeOut < (10 * HZ)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ - else if (TimeOut < (60 * HZ)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ - else if (TimeOut < (1200 * HZ)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ - } - - scb->dcdb.transfer_length = scb->data_len; - if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K ) - scb->dcdb.transfer_length = 0; - 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; - scb->dcdb.reserved = 0; - memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); - scb->dcdb.scsi_status = 0; - scb->dcdb.reserved2[0] = 0; - scb->dcdb.reserved2[1] = 0; - scb->dcdb.reserved2[2] = 0; - } - } +ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) +{ + int ret; + char *sp; + int device_error; + IPS_DCDB_TABLE_TAPE *tapeDCDB; + int TimeOut; + + METHOD_TRACE("ips_send_cmd", 1); + + ret = IPS_SUCCESS; + + if (!scb->scsi_cmd) { + /* internal command */ + + if (scb->bus > 0) { + /* Controller commands can't be issued */ + /* to real devices -- fail them */ + if ((ha->waitflag == TRUE) && + (ha->cmd_in_progress == scb->cdb[0])) { + ha->waitflag = FALSE; + } + + return (1); + } + } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) { + /* command to logical bus -- interpret */ + ret = IPS_SUCCESS_IMM; + + switch (scb->scsi_cmd->cmnd[0]) { + case ALLOW_MEDIUM_REMOVAL: + case REZERO_UNIT: + case ERASE: + case WRITE_FILEMARKS: + case SPACE: + scb->scsi_cmd->result = DID_ERROR << 16; + break; + + case START_STOP: + scb->scsi_cmd->result = DID_OK << 16; + + case TEST_UNIT_READY: + case INQUIRY: + if (scb->target_id == IPS_ADAPTER_ID) { + /* + * Either we have a TUR + * or we have a SCSI inquiry + */ + if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY) + scb->scsi_cmd->result = DID_OK << 16; + + if (scb->scsi_cmd->cmnd[0] == INQUIRY) { + IPS_SCSI_INQ_DATA inquiry; + + memset(&inquiry, 0, + sizeof (IPS_SCSI_INQ_DATA)); + + inquiry.DeviceType = + IPS_SCSI_INQ_TYPE_PROCESSOR; + inquiry.DeviceTypeQualifier = + IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = + IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = + IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = + IPS_SCSI_INQ_WBus16 | + IPS_SCSI_INQ_Sync; + strncpy(inquiry.VendorId, "IBM ", + 8); + strncpy(inquiry.ProductId, + "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, + "1.00", 4); + + ips_scmd_buf_write(scb->scsi_cmd, + &inquiry, + sizeof (inquiry)); + + scb->scsi_cmd->result = DID_OK << 16; + } + } else { + scb->cmd.logical_info.op_code = + IPS_CMD_GET_LD_INFO; + scb->cmd.logical_info.command_id = + IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.reserved = 0; + scb->cmd.logical_info.reserved2 = 0; + scb->data_len = + sizeof (ha->adapt->logical_drive_info); + scb->data_busaddr = + pci_map_single(ha->pcidev, + &ha->adapt-> + logical_drive_info, + scb->data_len, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.logical_info.buffer_addr = + scb->data_busaddr; + ret = IPS_SUCCESS; + } + + break; + + case REQUEST_SENSE: + ips_reqsen(ha, scb); + scb->scsi_cmd->result = DID_OK << 16; + break; + + case READ_6: + case WRITE_6: + 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; + + if (scb->cmd.basic_io.lba) + scb->cmd.basic_io.lba = + cpu_to_le32(le32_to_cpu + (scb->cmd.basic_io.lba) + + le16_to_cpu(scb->cmd.basic_io. + sector_count)); + else + scb->cmd.basic_io.lba = + (((scb->scsi_cmd-> + cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd-> + cmnd[2] << 8) | + (scb->scsi_cmd->cmnd[3])); + + scb->cmd.basic_io.sector_count = + cpu_to_le16(scb->data_len / IPS_BLKSIZE); + + if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0) + scb->cmd.basic_io.sector_count = + cpu_to_le16(256); + + ret = IPS_SUCCESS; + break; + + case READ_10: + case WRITE_10: + 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; + + if (scb->cmd.basic_io.lba) + scb->cmd.basic_io.lba = + cpu_to_le32(le32_to_cpu + (scb->cmd.basic_io.lba) + + le16_to_cpu(scb->cmd.basic_io. + sector_count)); + else + scb->cmd.basic_io.lba = + ((scb->scsi_cmd->cmnd[2] << 24) | (scb-> + scsi_cmd-> + cmnd[3] + << 16) | + (scb->scsi_cmd->cmnd[4] << 8) | scb-> + scsi_cmd->cmnd[5]); + + scb->cmd.basic_io.sector_count = + cpu_to_le16(scb->data_len / IPS_BLKSIZE); + + if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) { + /* + * This is a null condition + * we don't have to do anything + * so just return + */ + scb->scsi_cmd->result = DID_OK << 16; + } else + ret = IPS_SUCCESS; + + break; + + case RESERVE: + case RELEASE: + scb->scsi_cmd->result = DID_OK << 16; + break; + + 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->cmd.basic_io.sg_addr = ha->enq_busaddr; + ret = IPS_SUCCESS; + break; + + case READ_CAPACITY: + scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; + scb->cmd.logical_info.command_id = + IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.reserved = 0; + scb->cmd.logical_info.reserved2 = 0; + scb->cmd.logical_info.reserved3 = 0; + scb->data_len = sizeof (ha->adapt->logical_drive_info); + scb->data_busaddr = pci_map_single(ha->pcidev, + &ha->adapt-> + logical_drive_info, + scb->data_len, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.logical_info.buffer_addr = scb->data_busaddr; + ret = IPS_SUCCESS; + break; + + case SEND_DIAGNOSTIC: + case REASSIGN_BLOCKS: + case FORMAT_UNIT: + case SEEK_10: + case VERIFY: + case READ_DEFECT_DATA: + case READ_BUFFER: + case WRITE_BUFFER: + scb->scsi_cmd->result = DID_OK << 16; + break; + + default: + /* Set the Return Info to appear like the Command was */ + /* attempted, a Check Condition occurred, and Sense */ + /* Data indicating an Invalid CDB OpCode is returned. */ + sp = (char *) scb->scsi_cmd->sense_buffer; + memset(sp, 0, sizeof (scb->scsi_cmd->sense_buffer)); + + sp[0] = 0x70; /* Error Code */ + sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */ + sp[7] = 0x0A; /* Additional Sense Length */ + sp[12] = 0x20; /* ASC = Invalid OpCode */ + sp[13] = 0x00; /* ASCQ */ + + device_error = 2; /* Indicate Check Condition */ + scb->scsi_cmd->result = device_error | (DID_OK << 16); + break; + } /* end switch */ + } + /* end if */ + if (ret == IPS_SUCCESS_IMM) + return (ret); + + /* setup DCDB */ + if (scb->bus > 0) { + + /* 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 */ + if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) { + scb->scsi_cmd->result = DID_NO_CONNECT << 16; + return (IPS_SUCCESS_IMM); + } + + ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id); + scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + + (unsigned long) &scb-> + dcdb - + (unsigned long) scb); + scb->cmd.dcdb.reserved = 0; + scb->cmd.dcdb.reserved2 = 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) { + scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB; + } else { + scb->cmd.dcdb.op_code = + IPS_CMD_EXTENDED_DCDB_SG; + scb->cmd.dcdb.enhanced_sg = + IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + } - return ((*ha->func.issue)(ha, scb)); + 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; + tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; + tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */ + + if (TimeOut) { + if (TimeOut < (10 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ + } + + tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; + tapeDCDB->reserved_for_LUN = 0; + tapeDCDB->transfer_length = scb->data_len; + 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; + + if (TimeOut) { + if (TimeOut < (10 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ + } + + scb->dcdb.transfer_length = scb->data_len; + if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K) + scb->dcdb.transfer_length = 0; + 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; + scb->dcdb.reserved = 0; + memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, + scb->scsi_cmd->cmd_len); + scb->dcdb.scsi_status = 0; + scb->dcdb.reserved2[0] = 0; + scb->dcdb.reserved2[1] = 0; + scb->dcdb.reserved2[2] = 0; + } + } + + return ((*ha->func.issue) (ha, scb)); } /****************************************************************************/ @@ -3948,144 +4137,151 @@ /* Assumed to be called with the HA lock */ /****************************************************************************/ static void -ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { - ips_scb_t *scb; - ips_stat_t *sp; - uint8_t basic_status; - uint8_t ext_status; - int errcode; - - METHOD_TRACE("ips_chkstatus", 1); - - scb = &ha->scbs[pstatus->fields.command_id]; - scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK; - scb->extended_status = ext_status = pstatus->fields.extended_status; - - sp = &ha->sp; - sp->residue_len = 0; - sp->scb_addr = (void *) scb; - - /* Remove the item from the active queue */ - ips_removeq_scb(&ha->scb_activelist, scb); - - if (!scb->scsi_cmd) - /* internal commands are handled in do_ipsintr */ - return ; - - DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - - if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) - /* passthru - just returns the raw result */ - return ; - - errcode = DID_OK; - - if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) || - ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) { - - if (scb->bus == 0) { - if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) { - DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", - ips_name, ha->host_num, - scb->cmd.basic_io.op_code, basic_status, ext_status); - } - - switch (scb->scsi_cmd->cmnd[0]) { - case ALLOW_MEDIUM_REMOVAL: - case REZERO_UNIT: - case ERASE: - case WRITE_FILEMARKS: - case SPACE: - errcode = DID_ERROR; - break; - - case START_STOP: - break; - - case TEST_UNIT_READY: - if (!ips_online(ha, scb)) { - errcode = DID_TIME_OUT; - } - break; - - case INQUIRY: - if (ips_online(ha, scb)) { - ips_inquiry(ha, scb); - } else { - errcode = DID_TIME_OUT; - } - break; - - case REQUEST_SENSE: - ips_reqsen(ha, scb); - break; - - case READ_6: - case WRITE_6: - case READ_10: - case WRITE_10: - case RESERVE: - case RELEASE: - break; - - case MODE_SENSE: - if (!ips_online(ha, scb) || !ips_msense(ha, scb)) { - errcode = DID_ERROR; - } - break; - - case READ_CAPACITY: - if (ips_online(ha, scb)) - ips_rdcap(ha, scb); - else { - errcode = DID_TIME_OUT; - } - break; - - case SEND_DIAGNOSTIC: - case REASSIGN_BLOCKS: - break; - - case FORMAT_UNIT: - errcode = DID_ERROR; - break; - - case SEEK_10: - case VERIFY: - case READ_DEFECT_DATA: - case READ_BUFFER: - case WRITE_BUFFER: - break; - - default: - errcode = DID_ERROR; - } /* end switch */ - - scb->scsi_cmd->result = errcode << 16; - } else { /* bus == 0 */ - /* restrict access to physical drives */ - if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && - ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) { - - scb->scsi_cmd->result = DID_TIME_OUT << 16; - } - } /* else */ - } else { /* recovered error / success */ - if (scb->bus == 0) { - DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", - ips_name, ha->host_num, - scb->cmd.basic_io.op_code, basic_status, ext_status); - } +ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus) +{ + ips_scb_t *scb; + ips_stat_t *sp; + uint8_t basic_status; + uint8_t ext_status; + int errcode; + + METHOD_TRACE("ips_chkstatus", 1); + + scb = &ha->scbs[pstatus->fields.command_id]; + scb->basic_status = basic_status = + pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK; + scb->extended_status = ext_status = pstatus->fields.extended_status; + + sp = &ha->sp; + sp->residue_len = 0; + sp->scb_addr = (void *) scb; + + /* Remove the item from the active queue */ + ips_removeq_scb(&ha->scb_activelist, scb); + + if (!scb->scsi_cmd) + /* internal commands are handled in do_ipsintr */ + return; + + DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + + if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) + /* passthru - just returns the raw result */ + return; - ips_map_status(ha, scb, sp); - } /* else */ + errcode = DID_OK; + + if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) || + ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) { + + if (scb->bus == 0) { + if ((basic_status & IPS_GSC_STATUS_MASK) == + IPS_CMD_RECOVERED_ERROR) { + DEBUG_VAR(1, + "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", + ips_name, ha->host_num, + scb->cmd.basic_io.op_code, + basic_status, ext_status); + } + + switch (scb->scsi_cmd->cmnd[0]) { + case ALLOW_MEDIUM_REMOVAL: + case REZERO_UNIT: + case ERASE: + case WRITE_FILEMARKS: + case SPACE: + errcode = DID_ERROR; + break; + + case START_STOP: + break; + + case TEST_UNIT_READY: + if (!ips_online(ha, scb)) { + errcode = DID_TIME_OUT; + } + break; + + case INQUIRY: + if (ips_online(ha, scb)) { + ips_inquiry(ha, scb); + } else { + errcode = DID_TIME_OUT; + } + break; + + case REQUEST_SENSE: + ips_reqsen(ha, scb); + break; + + case READ_6: + case WRITE_6: + case READ_10: + case WRITE_10: + case RESERVE: + case RELEASE: + break; + + case MODE_SENSE: + if (!ips_online(ha, scb) + || !ips_msense(ha, scb)) { + errcode = DID_ERROR; + } + break; + + case READ_CAPACITY: + if (ips_online(ha, scb)) + ips_rdcap(ha, scb); + else { + errcode = DID_TIME_OUT; + } + break; + + case SEND_DIAGNOSTIC: + case REASSIGN_BLOCKS: + break; + + case FORMAT_UNIT: + errcode = DID_ERROR; + break; + + case SEEK_10: + case VERIFY: + case READ_DEFECT_DATA: + case READ_BUFFER: + case WRITE_BUFFER: + break; + + default: + errcode = DID_ERROR; + } /* end switch */ + + scb->scsi_cmd->result = errcode << 16; + } else { /* bus == 0 */ + /* restrict access to physical drives */ + if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && + ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == + TYPE_DISK)) { + + scb->scsi_cmd->result = DID_TIME_OUT << 16; + } + } /* else */ + } else { /* recovered error / success */ + if (scb->bus == 0) { + DEBUG_VAR(1, + "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x", + ips_name, ha->host_num, + scb->cmd.basic_io.op_code, basic_status, + ext_status); + } + + ips_map_status(ha, scb, sp); + } /* else */ } /****************************************************************************/ @@ -4098,25 +4294,31 @@ /* */ /****************************************************************************/ static int -ips_online(ips_ha_t *ha, ips_scb_t *scb) { - METHOD_TRACE("ips_online", 1); +ips_online(ips_ha_t * ha, ips_scb_t * scb) +{ + METHOD_TRACE("ips_online", 1); - if (scb->target_id >= IPS_MAX_LD) - return (0); + if (scb->target_id >= IPS_MAX_LD) + return (0); - if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) { - memset(&ha->adapt->logical_drive_info, 0, sizeof(ha->adapt->logical_drive_info)); + if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) { + memset(&ha->adapt->logical_drive_info, 0, + sizeof (ha->adapt->logical_drive_info)); - return (0); - } - - if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_OFFLINE && - ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_FREE && - ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_CRS && - ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_SYS) - return (1); - else - return (0); + return (0); + } + + if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + IPS_LD_OFFLINE + && ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + IPS_LD_FREE + && ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + IPS_LD_CRS + && ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + IPS_LD_SYS) + return (1); + else + return (0); } /****************************************************************************/ @@ -4129,27 +4331,29 @@ /* */ /****************************************************************************/ static int -ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_INQ_DATA inquiry; +ips_inquiry(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SCSI_INQ_DATA inquiry; - METHOD_TRACE("ips_inquiry", 1); + METHOD_TRACE("ips_inquiry", 1); - memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA)); + memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA)); - inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD; - inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; - inquiry.Version = IPS_SCSI_INQ_REV2; - inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; - inquiry.AdditionalLength = 31; - inquiry.Flags[0] = IPS_SCSI_INQ_Address16; - inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue; - strncpy(inquiry.VendorId, "IBM ", 8); - strncpy(inquiry.ProductId, "SERVERAID ", 16); - strncpy(inquiry.ProductRevisionLevel, "1.00", 4); + inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD; + inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED; + inquiry.Version = IPS_SCSI_INQ_REV2; + inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2; + inquiry.AdditionalLength = 31; + inquiry.Flags[0] = IPS_SCSI_INQ_Address16; + inquiry.Flags[1] = + IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue; + strncpy(inquiry.VendorId, "IBM ", 8); + strncpy(inquiry.ProductId, "SERVERAID ", 16); + strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry)); + ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry)); - return (1); + return (1); } /****************************************************************************/ @@ -4162,20 +4366,24 @@ /* */ /****************************************************************************/ static int -ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_CAPACITY cap; +ips_rdcap(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SCSI_CAPACITY cap; - METHOD_TRACE("ips_rdcap", 1); + METHOD_TRACE("ips_rdcap", 1); - if (scb->scsi_cmd->bufflen < 8) - return (0); + if (scb->scsi_cmd->bufflen < 8) + return (0); - 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)); + ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap)); - return (1); + return (1); } /****************************************************************************/ @@ -4188,78 +4396,85 @@ /* */ /****************************************************************************/ static int -ips_msense(ips_ha_t *ha, ips_scb_t *scb) { - uint16_t heads; - uint16_t sectors; - uint32_t cylinders; - IPS_SCSI_MODE_PAGE_DATA mdata; - - METHOD_TRACE("ips_msense", 1); - - if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 && - (ha->enq->ucMiscFlag & 0x8) == 0) { - heads = IPS_NORM_HEADS; - sectors = IPS_NORM_SECTORS; - } else { - heads = IPS_COMP_HEADS; - sectors = IPS_COMP_SECTORS; - } - - cylinders = (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - 1) / (heads * sectors); - - memset(&mdata, 0, sizeof(IPS_SCSI_MODE_PAGE_DATA)); - - mdata.hdr.BlockDescLength = 8; - - switch (scb->scsi_cmd->cmnd[2] & 0x3f) { - case 0x03: /* page 3 */ - mdata.pdata.pg3.PageCode = 3; - mdata.pdata.pg3.PageLength = sizeof(IPS_SCSI_MODE_PAGE3); - mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength; - mdata.pdata.pg3.TracksPerZone = 0; - mdata.pdata.pg3.AltSectorsPerZone = 0; - mdata.pdata.pg3.AltTracksPerZone = 0; - mdata.pdata.pg3.AltTracksPerVolume = 0; - mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors); - mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE); - mdata.pdata.pg3.Interleave = cpu_to_be16(1); - mdata.pdata.pg3.TrackSkew = 0; - mdata.pdata.pg3.CylinderSkew = 0; - mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector; - break; - - case 0x4: - mdata.pdata.pg4.PageCode = 4; - mdata.pdata.pg4.PageLength = sizeof(IPS_SCSI_MODE_PAGE4); - mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength; - mdata.pdata.pg4.CylindersHigh = cpu_to_be16((cylinders >> 8) & 0xFFFF); - mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF); - mdata.pdata.pg4.Heads = heads; - mdata.pdata.pg4.WritePrecompHigh = 0; - mdata.pdata.pg4.WritePrecompLow = 0; - mdata.pdata.pg4.ReducedWriteCurrentHigh = 0; - mdata.pdata.pg4.ReducedWriteCurrentLow = 0; - mdata.pdata.pg4.StepRate = cpu_to_be16(1); - mdata.pdata.pg4.LandingZoneHigh = 0; - mdata.pdata.pg4.LandingZoneLow = 0; - mdata.pdata.pg4.flags = 0; - mdata.pdata.pg4.RotationalOffset = 0; - mdata.pdata.pg4.MediumRotationRate = 0; - break; - case 0x8: - mdata.pdata.pg8.PageCode = 8; - mdata.pdata.pg8.PageLength = sizeof(IPS_SCSI_MODE_PAGE8); - mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength; - /* everything else is left set to 0 */ - break; - - default: - return (0); - } /* end switch */ +ips_msense(ips_ha_t * ha, ips_scb_t * scb) +{ + uint16_t heads; + uint16_t sectors; + uint32_t cylinders; + IPS_SCSI_MODE_PAGE_DATA mdata; + + METHOD_TRACE("ips_msense", 1); + + if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 && + (ha->enq->ucMiscFlag & 0x8) == 0) { + heads = IPS_NORM_HEADS; + sectors = IPS_NORM_SECTORS; + } else { + heads = IPS_COMP_HEADS; + sectors = IPS_COMP_SECTORS; + } + + cylinders = + (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - + 1) / (heads * sectors); + + memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA)); + + mdata.hdr.BlockDescLength = 8; + + switch (scb->scsi_cmd->cmnd[2] & 0x3f) { + case 0x03: /* page 3 */ + mdata.pdata.pg3.PageCode = 3; + mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3); + mdata.hdr.DataLength = + 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength; + mdata.pdata.pg3.TracksPerZone = 0; + mdata.pdata.pg3.AltSectorsPerZone = 0; + mdata.pdata.pg3.AltTracksPerZone = 0; + mdata.pdata.pg3.AltTracksPerVolume = 0; + mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors); + mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE); + mdata.pdata.pg3.Interleave = cpu_to_be16(1); + mdata.pdata.pg3.TrackSkew = 0; + mdata.pdata.pg3.CylinderSkew = 0; + mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector; + break; + + case 0x4: + mdata.pdata.pg4.PageCode = 4; + mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4); + mdata.hdr.DataLength = + 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength; + mdata.pdata.pg4.CylindersHigh = + cpu_to_be16((cylinders >> 8) & 0xFFFF); + mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF); + mdata.pdata.pg4.Heads = heads; + mdata.pdata.pg4.WritePrecompHigh = 0; + mdata.pdata.pg4.WritePrecompLow = 0; + mdata.pdata.pg4.ReducedWriteCurrentHigh = 0; + mdata.pdata.pg4.ReducedWriteCurrentLow = 0; + mdata.pdata.pg4.StepRate = cpu_to_be16(1); + mdata.pdata.pg4.LandingZoneHigh = 0; + mdata.pdata.pg4.LandingZoneLow = 0; + mdata.pdata.pg4.flags = 0; + mdata.pdata.pg4.RotationalOffset = 0; + mdata.pdata.pg4.MediumRotationRate = 0; + break; + case 0x8: + mdata.pdata.pg8.PageCode = 8; + mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8); + mdata.hdr.DataLength = + 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength; + /* everything else is left set to 0 */ + break; + + default: + return (0); + } /* end switch */ - ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof(mdata)); + ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata)); - return (1); + return (1); } /****************************************************************************/ @@ -4272,21 +4487,23 @@ /* */ /****************************************************************************/ static int -ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_REQSEN reqsen; +ips_reqsen(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SCSI_REQSEN reqsen; - METHOD_TRACE("ips_reqsen", 1); + METHOD_TRACE("ips_reqsen", 1); - memset(&reqsen, 0, sizeof(IPS_SCSI_REQSEN)); + memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN)); - reqsen.ResponseCode = IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR; - reqsen.AdditionalLength = 10; - reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE; - reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE; + reqsen.ResponseCode = + IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR; + reqsen.AdditionalLength = 10; + reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE; + reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE; - ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof(reqsen)); + ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen)); - return (1); + return (1); } /****************************************************************************/ @@ -4299,58 +4516,64 @@ /* */ /****************************************************************************/ static void -ips_free(ips_ha_t *ha) { +ips_free(ips_ha_t * ha) +{ - METHOD_TRACE("ips_free", 1); + METHOD_TRACE("ips_free", 1); - if (ha) { - if (ha->enq) { - kfree(ha->enq); - ha->enq = NULL; - } - - if (ha->conf) { - kfree(ha->conf); - ha->conf = NULL; - } - - if (ha->adapt) { - pci_free_consistent(ha->pcidev,sizeof(IPS_ADAPTER)+ sizeof(IPS_IO_CMD), - ha->adapt, ha->adapt->hw_status_start); - ha->adapt = NULL; - } - - if (ha->nvram) { - kfree(ha->nvram); - ha->nvram = NULL; - } - - if (ha->subsys) { - kfree(ha->subsys); - ha->subsys = NULL; - } - - if (ha->ioctl_data) { - free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); - ha->ioctl_data = NULL; - ha->ioctl_datasize = 0; - ha->ioctl_order = 0; - } - ips_deallocatescbs(ha, ha->max_cmds); - - /* free memory mapped (if applicable) */ - if (ha->mem_ptr) { - iounmap(ha->ioremap_ptr); - ha->ioremap_ptr = NULL; - ha->mem_ptr = NULL; - } - - if (ha->mem_addr) - release_mem_region(ha->mem_addr, ha->mem_len); - ha->mem_addr = 0; + if (ha) { + if (ha->enq) { + pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ), + ha->enq, ha->enq_busaddr); + ha->enq = NULL; + } - } + if (ha->conf) { + kfree(ha->conf); + ha->conf = NULL; + } + + if (ha->adapt) { + pci_free_consistent(ha->pcidev, + sizeof (IPS_ADAPTER) + + sizeof (IPS_IO_CMD), ha->adapt, + ha->adapt->hw_status_start); + ha->adapt = NULL; + } + + if (ha->nvram) { + kfree(ha->nvram); + ha->nvram = NULL; + } + + if (ha->subsys) { + kfree(ha->subsys); + ha->subsys = NULL; + } + + if (ha->ioctl_data) { + pci_free_consistent(ha->pcidev, ha->ioctl_len, + ha->ioctl_data, ha->ioctl_busaddr); + ha->ioctl_data = NULL; + ha->ioctl_datasize = 0; + ha->ioctl_len = 0; + } + ips_deallocatescbs(ha, ha->max_cmds); + + /* free memory mapped (if applicable) */ + if (ha->mem_ptr) { + iounmap(ha->ioremap_ptr); + ha->ioremap_ptr = NULL; + ha->mem_ptr = NULL; + } + + if (ha->mem_addr) + release_mem_region(ha->mem_addr, ha->mem_len); + ha->mem_addr = 0; + + } } + /****************************************************************************/ /* */ /* Routine Name: ips_deallocatescbs */ @@ -4361,15 +4584,18 @@ /* */ /****************************************************************************/ static int -ips_deallocatescbs(ips_ha_t *ha, int cmds) { - if (ha->scbs) { - 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; - } /* end if */ -return 1; +ips_deallocatescbs(ips_ha_t * ha, int cmds) +{ + if (ha->scbs) { + 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; + } /* end if */ + return 1; } /****************************************************************************/ @@ -4382,49 +4608,59 @@ /* */ /****************************************************************************/ static int -ips_allocatescbs(ips_ha_t *ha) { - ips_scb_t *scb_p; - IPS_SG_LIST ips_sg; - int i; - dma_addr_t command_dma, sg_dma; - - METHOD_TRACE("ips_allocatescbs", 1); +ips_allocatescbs(ips_ha_t * ha) +{ + ips_scb_t *scb_p; + IPS_SG_LIST ips_sg; + int i; + dma_addr_t command_dma, sg_dma; + + METHOD_TRACE("ips_allocatescbs", 1); + + /* Allocate memory for the SCBs */ + ha->scbs = + pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t), + &command_dma); + if (ha->scbs == NULL) + return 0; + 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; + } + + memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t)); + + for (i = 0; i < ha->max_cmds; i++) { + scb_p = &ha->scbs[i]; + scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i; + /* set up S/G list */ + 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; + } - /* Allocate memory for the SCBs */ - ha->scbs = pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof(ips_scb_t), - &command_dma); - if (ha->scbs == NULL) - return 0; - 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; - } - - memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t)); - - for (i = 0; i < ha->max_cmds; i++) { - scb_p = &ha->scbs[i]; - scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i; - /* set up S/G list */ - 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) { - scb_p->q_next = ha->scb_freelist; - ha->scb_freelist = scb_p; - } - } + /* add to the free list */ + if (i < ha->max_cmds - 1) { + scb_p->q_next = ha->scb_freelist; + ha->scb_freelist = scb_p; + } + } - /* success */ - return (1); + /* success */ + return (1); } /****************************************************************************/ @@ -4437,36 +4673,37 @@ /* */ /****************************************************************************/ static void -ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SG_LIST sg_list; - uint32_t cmd_busaddr, sg_busaddr; - METHOD_TRACE("ips_init_scb", 1); - - if (scb == NULL) - return ; - - sg_list.list = scb->sg_list.list; - cmd_busaddr = scb->scb_busaddr; - sg_busaddr = scb->sg_busaddr; - /* zero fill */ - memset(scb, 0, sizeof(ips_scb_t)); - memset(ha->dummy, 0, sizeof(IPS_IO_CMD)); - - /* Initialize dummy command bucket */ - ha->dummy->op_code = 0xFF; - ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start - + sizeof(IPS_ADAPTER)); - ha->dummy->command_id = IPS_MAX_CMDS; - - /* set bus address of scb */ - scb->scb_busaddr = cmd_busaddr; - scb->sg_busaddr = sg_busaddr; - scb->sg_list.list = sg_list.list; - - /* Neptune Fix */ - scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE); - scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start - + sizeof(IPS_ADAPTER)); +ips_init_scb(ips_ha_t * ha, ips_scb_t * scb) +{ + IPS_SG_LIST sg_list; + uint32_t cmd_busaddr, sg_busaddr; + METHOD_TRACE("ips_init_scb", 1); + + if (scb == NULL) + return; + + sg_list.list = scb->sg_list.list; + cmd_busaddr = scb->scb_busaddr; + sg_busaddr = scb->sg_busaddr; + /* zero fill */ + memset(scb, 0, sizeof (ips_scb_t)); + memset(ha->dummy, 0, sizeof (IPS_IO_CMD)); + + /* Initialize dummy command bucket */ + ha->dummy->op_code = 0xFF; + ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start + + sizeof (IPS_ADAPTER)); + ha->dummy->command_id = IPS_MAX_CMDS; + + /* set bus address of scb */ + scb->scb_busaddr = cmd_busaddr; + scb->sg_busaddr = sg_busaddr; + scb->sg_list.list = sg_list.list; + + /* Neptune Fix */ + scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE); + scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start + + sizeof (IPS_ADAPTER)); } /****************************************************************************/ @@ -4481,22 +4718,23 @@ /* */ /****************************************************************************/ static ips_scb_t * -ips_getscb(ips_ha_t *ha) { - ips_scb_t *scb; +ips_getscb(ips_ha_t * ha) +{ + ips_scb_t *scb; - METHOD_TRACE("ips_getscb", 1); + METHOD_TRACE("ips_getscb", 1); - if ((scb = ha->scb_freelist) == NULL) { + if ((scb = ha->scb_freelist) == NULL) { - return (NULL); - } + return (NULL); + } - ha->scb_freelist = scb->q_next; - scb->q_next = NULL; + ha->scb_freelist = scb->q_next; + scb->q_next = NULL; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - return (scb); + return (scb); } /****************************************************************************/ @@ -4511,21 +4749,22 @@ /* */ /****************************************************************************/ static void -ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { +ips_freescb(ips_ha_t * ha, ips_scb_t * scb) +{ - 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, - IPS_DMA_DIR(scb)); - else if(scb->flags & IPS_SCB_MAP_SINGLE) - pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, - IPS_DMA_DIR(scb)); - - /* check to make sure this is not our "special" scb */ - if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { - scb->q_next = ha->scb_freelist; - ha->scb_freelist = scb; - } + 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, IPS_DMA_DIR(scb)); + else if (scb->flags & IPS_SCB_MAP_SINGLE) + pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, + IPS_DMA_DIR(scb)); + + /* check to make sure this is not our "special" scb */ + if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { + scb->q_next = ha->scb_freelist; + ha->scb_freelist = scb; + } } /****************************************************************************/ @@ -4538,19 +4777,20 @@ /* */ /****************************************************************************/ static int -ips_isinit_copperhead(ips_ha_t *ha) { - uint8_t scpr; - uint8_t isr; - - METHOD_TRACE("ips_isinit_copperhead", 1); - - isr = inb(ha->io_addr + IPS_REG_HISR); - scpr = inb(ha->io_addr + IPS_REG_SCPR); - - if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) - return (0); - else - return (1); +ips_isinit_copperhead(ips_ha_t * ha) +{ + uint8_t scpr; + uint8_t isr; + + METHOD_TRACE("ips_isinit_copperhead", 1); + + isr = inb(ha->io_addr + IPS_REG_HISR); + scpr = inb(ha->io_addr + IPS_REG_SCPR); + + if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) + return (0); + else + return (1); } /****************************************************************************/ @@ -4563,19 +4803,20 @@ /* */ /****************************************************************************/ static int -ips_isinit_copperhead_memio(ips_ha_t *ha) { - uint8_t isr=0; - uint8_t scpr; - - METHOD_TRACE("ips_is_init_copperhead_memio", 1); - - isr = readb(ha->mem_ptr + IPS_REG_HISR); - scpr = readb(ha->mem_ptr + IPS_REG_SCPR); - - if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) - return (0); - else - return (1); +ips_isinit_copperhead_memio(ips_ha_t * ha) +{ + uint8_t isr = 0; + uint8_t scpr; + + METHOD_TRACE("ips_is_init_copperhead_memio", 1); + + isr = readb(ha->mem_ptr + IPS_REG_HISR); + scpr = readb(ha->mem_ptr + IPS_REG_SCPR); + + if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0)) + return (0); + else + return (1); } /****************************************************************************/ @@ -4588,21 +4829,22 @@ /* */ /****************************************************************************/ static int -ips_isinit_morpheus(ips_ha_t *ha) { - uint32_t post; - uint32_t bits; - - METHOD_TRACE("ips_is_init_morpheus", 1); - - post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - - if (post == 0) - return (0); - else if (bits & 0x3) - return (0); - else - return (1); +ips_isinit_morpheus(ips_ha_t * ha) +{ + uint32_t post; + uint32_t bits; + + METHOD_TRACE("ips_is_init_morpheus", 1); + + post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + + if (post == 0) + return (0); + else if (bits & 0x3) + return (0); + else + return (1); } /****************************************************************************/ @@ -4614,10 +4856,12 @@ /* */ /****************************************************************************/ static void -ips_enable_int_copperhead(ips_ha_t *ha) { - METHOD_TRACE("ips_enable_int_copperhead", 1); +ips_enable_int_copperhead(ips_ha_t * ha) +{ + METHOD_TRACE("ips_enable_int_copperhead", 1); - outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI); + outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI); + inb(ha->io_addr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/ } /****************************************************************************/ @@ -4629,10 +4873,12 @@ /* */ /****************************************************************************/ static void -ips_enable_int_copperhead_memio(ips_ha_t *ha) { - METHOD_TRACE("ips_enable_int_copperhead_memio", 1); +ips_enable_int_copperhead_memio(ips_ha_t * ha) +{ + METHOD_TRACE("ips_enable_int_copperhead_memio", 1); - writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + readb(ha->mem_ptr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/ } /****************************************************************************/ @@ -4644,14 +4890,16 @@ /* */ /****************************************************************************/ static void -ips_enable_int_morpheus(ips_ha_t *ha) { - uint32_t Oimr; +ips_enable_int_morpheus(ips_ha_t * ha) +{ + uint32_t Oimr; - METHOD_TRACE("ips_enable_int_morpheus", 1); + METHOD_TRACE("ips_enable_int_morpheus", 1); - Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); - Oimr &= ~0x08; - writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr &= ~0x08; + writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + readl(ha->mem_ptr + IPS_REG_I960_OIMR); /*Ensure PCI Posting Completes*/ } /****************************************************************************/ @@ -4664,86 +4912,88 @@ /* */ /****************************************************************************/ static int -ips_init_copperhead(ips_ha_t *ha) { - uint8_t Isr; - uint8_t Cbsp; - uint8_t PostByte[IPS_MAX_POST_BYTES]; - uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; - int i, j; - - METHOD_TRACE("ips_init_copperhead", 1); - - for (i = 0; i < IPS_MAX_POST_BYTES; i++) { - for (j = 0; j < 45; j++) { - Isr = inb(ha->io_addr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 45) - /* error occurred */ - return (0); - - PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR); - outb(Isr, ha->io_addr + IPS_REG_HISR); - } - - if (PostByte[0] < IPS_GOOD_POST_STATUS) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "reset controller fails (post status %x %x).\n", - PostByte[0], PostByte[1]); - - return (0); - } - - for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { - for (j = 0; j < 240; j++) { - Isr = inb(ha->io_addr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 240) - /* error occurred */ - return (0); - - ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR); - outb(Isr, ha->io_addr + IPS_REG_HISR); - } - - for (i = 0; i < 240; i++) { - Cbsp = inb(ha->io_addr + IPS_REG_CBSP); - - if ((Cbsp & IPS_BIT_OP) == 0) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 240) - /* reset failed */ - return (0); - - /* setup CCCR */ - outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); - - /* Enable busmastering */ - outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); - - if (ha->revision_id == IPS_REVID_TROMBONE64) - /* fix for anaconda64 */ - outl(0, ha->io_addr + IPS_REG_NDAE); +ips_init_copperhead(ips_ha_t * ha) +{ + uint8_t Isr; + uint8_t Cbsp; + uint8_t PostByte[IPS_MAX_POST_BYTES]; + uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; + int i, j; + + METHOD_TRACE("ips_init_copperhead", 1); + + for (i = 0; i < IPS_MAX_POST_BYTES; i++) { + for (j = 0; j < 45; j++) { + Isr = inb(ha->io_addr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } - /* Enable interrupts */ - outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR); + if (j >= 45) + /* error occurred */ + return (0); - return (1); + PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR); + outb(Isr, ha->io_addr + IPS_REG_HISR); + } + + if (PostByte[0] < IPS_GOOD_POST_STATUS) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "reset controller fails (post status %x %x).\n", + PostByte[0], PostByte[1]); + + return (0); + } + + for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { + for (j = 0; j < 240; j++) { + Isr = inb(ha->io_addr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 240) + /* error occurred */ + return (0); + + ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR); + outb(Isr, ha->io_addr + IPS_REG_HISR); + } + + for (i = 0; i < 240; i++) { + Cbsp = inb(ha->io_addr + IPS_REG_CBSP); + + if ((Cbsp & IPS_BIT_OP) == 0) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 240) + /* reset failed */ + return (0); + + /* setup CCCR */ + outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); + + /* Enable busmastering */ + outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); + + if (ha->revision_id == IPS_REVID_TROMBONE64) + /* fix for anaconda64 */ + outl(0, ha->io_addr + IPS_REG_NDAE); + + /* Enable interrupts */ + outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR); + + return (1); } /****************************************************************************/ @@ -4756,87 +5006,89 @@ /* */ /****************************************************************************/ static int -ips_init_copperhead_memio(ips_ha_t *ha) { - uint8_t Isr=0; - uint8_t Cbsp; - uint8_t PostByte[IPS_MAX_POST_BYTES]; - uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; - int i, j; - - METHOD_TRACE("ips_init_copperhead_memio", 1); - - for (i = 0; i < IPS_MAX_POST_BYTES; i++) { - for (j = 0; j < 45; j++) { - Isr = readb(ha->mem_ptr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 45) - /* error occurred */ - return (0); - - PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); - writeb(Isr, ha->mem_ptr + IPS_REG_HISR); - } - - if (PostByte[0] < IPS_GOOD_POST_STATUS) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "reset controller fails (post status %x %x).\n", - PostByte[0], PostByte[1]); - - return (0); - } - - for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { - for (j = 0; j < 240; j++) { - Isr = readb(ha->mem_ptr + IPS_REG_HISR); - if (Isr & IPS_BIT_GHI) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (j >= 240) - /* error occurred */ - return (0); - - ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); - writeb(Isr, ha->mem_ptr + IPS_REG_HISR); - } - - for (i = 0; i < 240; i++) { - Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP); - - if ((Cbsp & IPS_BIT_OP) == 0) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 240) - /* error occurred */ - return (0); - - /* setup CCCR */ - writel(0x1010, ha->mem_ptr + IPS_REG_CCCR); - - /* Enable busmastering */ - writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR); - - if (ha->revision_id == IPS_REVID_TROMBONE64) - /* fix for anaconda64 */ - writel(0, ha->mem_ptr + IPS_REG_NDAE); +ips_init_copperhead_memio(ips_ha_t * ha) +{ + uint8_t Isr = 0; + uint8_t Cbsp; + uint8_t PostByte[IPS_MAX_POST_BYTES]; + uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES]; + int i, j; + + METHOD_TRACE("ips_init_copperhead_memio", 1); + + for (i = 0; i < IPS_MAX_POST_BYTES; i++) { + for (j = 0; j < 45; j++) { + Isr = readb(ha->mem_ptr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; - /* Enable interrupts */ - writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 45) + /* error occurred */ + return (0); + + PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); + writeb(Isr, ha->mem_ptr + IPS_REG_HISR); + } + + if (PostByte[0] < IPS_GOOD_POST_STATUS) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "reset controller fails (post status %x %x).\n", + PostByte[0], PostByte[1]); - /* if we get here then everything went OK */ - return (1); + return (0); + } + + for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) { + for (j = 0; j < 240; j++) { + Isr = readb(ha->mem_ptr + IPS_REG_HISR); + if (Isr & IPS_BIT_GHI) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (j >= 240) + /* error occurred */ + return (0); + + ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR); + writeb(Isr, ha->mem_ptr + IPS_REG_HISR); + } + + for (i = 0; i < 240; i++) { + Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP); + + if ((Cbsp & IPS_BIT_OP) == 0) + break; + + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } + + if (i >= 240) + /* error occurred */ + return (0); + + /* setup CCCR */ + writel(0x1010, ha->mem_ptr + IPS_REG_CCCR); + + /* Enable busmastering */ + writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR); + + if (ha->revision_id == IPS_REVID_TROMBONE64) + /* fix for anaconda64 */ + writel(0, ha->mem_ptr + IPS_REG_NDAE); + + /* Enable interrupts */ + writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR); + + /* if we get here then everything went OK */ + return (1); } /****************************************************************************/ @@ -4849,105 +5101,111 @@ /* */ /****************************************************************************/ static int -ips_init_morpheus(ips_ha_t *ha) { - uint32_t Post; - uint32_t Config; - uint32_t Isr; - uint32_t Oimr; - int i; - - METHOD_TRACE("ips_init_morpheus", 1); - - /* Wait up to 45 secs for Post */ - for (i = 0; i < 45; i++) { - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - - if (Isr & IPS_BIT_I960_MSG0I) - break; - - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } - - if (i >= 45) { - /* error occurred */ - IPS_PRINTK(KERN_WARNING, ha->pcidev, "timeout waiting for post.\n"); - - return (0); - } +ips_init_morpheus(ips_ha_t * ha) +{ + uint32_t Post; + uint32_t Config; + uint32_t Isr; + uint32_t Oimr; + int i; - Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + METHOD_TRACE("ips_init_morpheus", 1); - if (Post == 0x4F00) { /* If Flashing the Battery PIC */ - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flashing Battery PIC, Please wait ...\n" ); + /* Wait up to 45 secs for Post */ + for (i = 0; i < 45; i++) { + Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - /* Clear the interrupt bit */ - Isr = (uint32_t) IPS_BIT_I960_MSG0I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + if (Isr & IPS_BIT_I960_MSG0I) + break; - for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */ - Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - if (Post != 0x4F00) - break; - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } - if (i >= 120) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "timeout waiting for Battery PIC Flash\n"); - return (0); - } + if (i >= 45) { + /* error occurred */ + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "timeout waiting for post.\n"); - } + return (0); + } - /* Clear the interrupt bit */ - Isr = (uint32_t) IPS_BIT_I960_MSG0I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); - if (Post < (IPS_GOOD_POST_STATUS << 8)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "reset controller fails (post status %x).\n", Post); + if (Post == 0x4F00) { /* If Flashing the Battery PIC */ + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Flashing Battery PIC, Please wait ...\n"); + + /* Clear the interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG0I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */ + Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); + if (Post != 0x4F00) + break; + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } - return (0); - } + if (i >= 120) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "timeout waiting for Battery PIC Flash\n"); + return (0); + } - /* Wait up to 240 secs for config bytes */ - for (i = 0; i < 240; i++) { - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + } - if (Isr & IPS_BIT_I960_MSG1I) - break; + /* Clear the interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG0I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + if (Post < (IPS_GOOD_POST_STATUS << 8)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "reset controller fails (post status %x).\n", Post); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - } + return (0); + } - if (i >= 240) { - /* error occurred */ - IPS_PRINTK(KERN_WARNING, ha->pcidev, "timeout waiting for config.\n"); + /* Wait up to 240 secs for config bytes */ + for (i = 0; i < 240; i++) { + Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - return (0); - } + if (Isr & IPS_BIT_I960_MSG1I) + break; - Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1); + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); + } - /* Clear interrupt bit */ - Isr = (uint32_t) IPS_BIT_I960_MSG1I; - writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + if (i >= 240) { + /* error occurred */ + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "timeout waiting for config.\n"); - /* Turn on the interrupts */ - Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); - Oimr &= ~0x8; - writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); + return (0); + } - /* if we get here then everything went OK */ + Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1); - /* Since we did a RESET, an EraseStripeLock may be needed */ - if (Post == 0xEF10) { - if ( (Config == 0x000F) || (Config == 0x0009) ) - ha->requires_esl = 1; - } + /* Clear interrupt bit */ + Isr = (uint32_t) IPS_BIT_I960_MSG1I; + writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); + + /* Turn on the interrupts */ + Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR); + Oimr &= ~0x8; + 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); + return (1); } /****************************************************************************/ @@ -4960,38 +5218,39 @@ /* */ /****************************************************************************/ static int -ips_reset_copperhead(ips_ha_t *ha) { - int reset_counter; +ips_reset_copperhead(ips_ha_t * ha) +{ + int reset_counter; + + METHOD_TRACE("ips_reset_copperhead", 1); - METHOD_TRACE("ips_reset_copperhead", 1); + DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", + ips_name, ha->host_num, ha->io_addr, ha->irq); - DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", - ips_name, ha->host_num, ha->io_addr, ha->irq); + reset_counter = 0; - reset_counter = 0; + while (reset_counter < 2) { + reset_counter++; - while (reset_counter < 2) { - reset_counter++; + outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); - outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - outb(0, ha->io_addr + IPS_REG_SCPR); + outb(0, ha->io_addr + IPS_REG_SCPR); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - if ((*ha->func.init)(ha)) - break; - else if (reset_counter >= 2) { + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - return (0); - } - } + if ((*ha->func.init) (ha)) + break; + else if (reset_counter >= 2) { - return (1); + return (0); + } + } + + return (1); } /****************************************************************************/ @@ -5004,38 +5263,39 @@ /* */ /****************************************************************************/ static int -ips_reset_copperhead_memio(ips_ha_t *ha) { - int reset_counter; +ips_reset_copperhead_memio(ips_ha_t * ha) +{ + int reset_counter; - METHOD_TRACE("ips_reset_copperhead_memio", 1); + METHOD_TRACE("ips_reset_copperhead_memio", 1); - DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", - ips_name, ha->host_num, ha->mem_addr, ha->irq); + DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", + ips_name, ha->host_num, ha->mem_addr, ha->irq); - reset_counter = 0; + reset_counter = 0; - while (reset_counter < 2) { - reset_counter++; + while (reset_counter < 2) { + reset_counter++; - writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); + writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - writeb(0, ha->mem_ptr + IPS_REG_SCPR); + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); - - if ((*ha->func.init)(ha)) - break; - else if (reset_counter >= 2) { + writeb(0, ha->mem_ptr + IPS_REG_SCPR); - return (0); - } - } + /* Delay for 1 Second */ + MDELAY(IPS_ONE_SEC); - return (1); + if ((*ha->func.init) (ha)) + break; + else if (reset_counter >= 2) { + + return (0); + } + } + + return (1); } /****************************************************************************/ @@ -5048,37 +5308,38 @@ /* */ /****************************************************************************/ static int -ips_reset_morpheus(ips_ha_t *ha) { - int reset_counter; - uint8_t junk; +ips_reset_morpheus(ips_ha_t * ha) +{ + int reset_counter; + uint8_t junk; - METHOD_TRACE("ips_reset_morpheus", 1); + METHOD_TRACE("ips_reset_morpheus", 1); - DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", - ips_name, ha->host_num, ha->mem_addr, ha->irq); + DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", + ips_name, ha->host_num, ha->mem_addr, ha->irq); - reset_counter = 0; + reset_counter = 0; - while (reset_counter < 2) { - reset_counter++; + while (reset_counter < 2) { + reset_counter++; - writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); + writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); - /* Delay for 5 Seconds */ - MDELAY(5 * IPS_ONE_SEC); - - /* Do a PCI config read to wait for adapter */ - pci_read_config_byte(ha->pcidev, 4, &junk); + /* Delay for 5 Seconds */ + MDELAY(5 * IPS_ONE_SEC); - if ((*ha->func.init)(ha)) - break; - else if (reset_counter >= 2) { + /* Do a PCI config read to wait for adapter */ + pci_read_config_byte(ha->pcidev, 4, &junk); - return (0); - } - } + if ((*ha->func.init) (ha)) + break; + else if (reset_counter >= 2) { - return (1); + return (0); + } + } + + return (1); } /****************************************************************************/ @@ -5091,22 +5352,25 @@ /* */ /****************************************************************************/ static void -ips_statinit(ips_ha_t *ha) { - uint32_t phys_status_start; +ips_statinit(ips_ha_t * ha) +{ + uint32_t phys_status_start; - METHOD_TRACE("ips_statinit", 1); + METHOD_TRACE("ips_statinit", 1); - ha->adapt->p_status_start = ha->adapt->status; - ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; - ha->adapt->p_status_tail = ha->adapt->status; - - phys_status_start = ha->adapt->hw_status_start; - outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); - outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER); - outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR); - outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); + ha->adapt->p_status_start = ha->adapt->status; + ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; + ha->adapt->p_status_tail = ha->adapt->status; + + phys_status_start = ha->adapt->hw_status_start; + outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); + outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), + ha->io_addr + IPS_REG_SQER); + outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), + ha->io_addr + IPS_REG_SQHR); + outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); - ha->adapt->hw_status_tail = phys_status_start; + ha->adapt->hw_status_tail = phys_status_start; } /****************************************************************************/ @@ -5119,22 +5383,24 @@ /* */ /****************************************************************************/ static void -ips_statinit_memio(ips_ha_t *ha) { - uint32_t phys_status_start; +ips_statinit_memio(ips_ha_t * ha) +{ + uint32_t phys_status_start; - METHOD_TRACE("ips_statinit_memio", 1); + METHOD_TRACE("ips_statinit_memio", 1); - ha->adapt->p_status_start = ha->adapt->status; - ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; - ha->adapt->p_status_tail = ha->adapt->status; - - phys_status_start = ha->adapt->hw_status_start; - writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR); - writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER); - writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR); - writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR); + ha->adapt->p_status_start = ha->adapt->status; + ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS; + ha->adapt->p_status_tail = ha->adapt->status; + + phys_status_start = ha->adapt->hw_status_start; + writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR); + writel(phys_status_start + IPS_STATUS_Q_SIZE, + ha->mem_ptr + IPS_REG_SQER); + writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR); + writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR); - ha->adapt->hw_status_tail = phys_status_start; + ha->adapt->hw_status_tail = phys_status_start; } /****************************************************************************/ @@ -5147,20 +5413,22 @@ /* */ /****************************************************************************/ static uint32_t -ips_statupd_copperhead(ips_ha_t *ha) { - METHOD_TRACE("ips_statupd_copperhead", 1); +ips_statupd_copperhead(ips_ha_t * ha) +{ + METHOD_TRACE("ips_statupd_copperhead", 1); - if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { - ha->adapt->p_status_tail++; - ha->adapt->hw_status_tail += sizeof(IPS_STATUS); - } else { - ha->adapt->p_status_tail = ha->adapt->p_status_start; - ha->adapt->hw_status_tail = ha->adapt->hw_status_start; - } + if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { + ha->adapt->p_status_tail++; + ha->adapt->hw_status_tail += sizeof (IPS_STATUS); + } else { + ha->adapt->p_status_tail = ha->adapt->p_status_start; + ha->adapt->hw_status_tail = ha->adapt->hw_status_start; + } - outl(cpu_to_le32(ha->adapt->hw_status_tail), ha->io_addr + IPS_REG_SQTR); + outl(cpu_to_le32(ha->adapt->hw_status_tail), + ha->io_addr + IPS_REG_SQTR); - return (ha->adapt->p_status_tail->value); + return (ha->adapt->p_status_tail->value); } /****************************************************************************/ @@ -5173,20 +5441,21 @@ /* */ /****************************************************************************/ static uint32_t -ips_statupd_copperhead_memio(ips_ha_t *ha) { - METHOD_TRACE("ips_statupd_copperhead_memio", 1); +ips_statupd_copperhead_memio(ips_ha_t * ha) +{ + METHOD_TRACE("ips_statupd_copperhead_memio", 1); - if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { - ha->adapt->p_status_tail++; - ha->adapt->hw_status_tail += sizeof(IPS_STATUS); - } else { - ha->adapt->p_status_tail = ha->adapt->p_status_start; - ha->adapt->hw_status_tail = ha->adapt->hw_status_start; - } + if (ha->adapt->p_status_tail != ha->adapt->p_status_end) { + ha->adapt->p_status_tail++; + ha->adapt->hw_status_tail += sizeof (IPS_STATUS); + } else { + ha->adapt->p_status_tail = ha->adapt->p_status_start; + ha->adapt->hw_status_tail = ha->adapt->hw_status_start; + } - writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR); + writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR); - return (ha->adapt->p_status_tail->value); + return (ha->adapt->p_status_tail->value); } /****************************************************************************/ @@ -5199,14 +5468,15 @@ /* */ /****************************************************************************/ static uint32_t -ips_statupd_morpheus(ips_ha_t *ha) { - uint32_t val; +ips_statupd_morpheus(ips_ha_t * ha) +{ + uint32_t val; - METHOD_TRACE("ips_statupd_morpheus", 1); + METHOD_TRACE("ips_statupd_morpheus", 1); - val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ); + val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ); - return (val); + return (val); } /****************************************************************************/ @@ -5219,48 +5489,48 @@ /* */ /****************************************************************************/ static int -ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { - uint32_t TimeOut; - uint32_t val; - - METHOD_TRACE("ips_issue_copperhead", 1); - - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } - - TimeOut = 0; - - while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { - udelay(1000); - - if (++TimeOut >= IPS_SEM_TIMEOUT) { - if (!(val & IPS_BIT_START_STOP)) - break; - - IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue val [0x%x].\n", val); - IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue semaphore chk timeout.\n"); - - return (IPS_FAILURE); - } /* end if */ - } /* end while */ +ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb) +{ + uint32_t TimeOut; + uint32_t val; + + METHOD_TRACE("ips_issue_copperhead", 1); + + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } + + TimeOut = 0; - outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); - outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); + while ((val = + le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { + udelay(1000); - return (IPS_SUCCESS); + if (++TimeOut >= IPS_SEM_TIMEOUT) { + if (!(val & IPS_BIT_START_STOP)) + break; + + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "ips_issue val [0x%x].\n", val); + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "ips_issue semaphore chk timeout.\n"); + + return (IPS_FAILURE); + } /* end if */ + } /* end while */ + + outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); + outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); + + return (IPS_SUCCESS); } /****************************************************************************/ @@ -5273,48 +5543,47 @@ /* */ /****************************************************************************/ static int -ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { - uint32_t TimeOut; - uint32_t val; - - METHOD_TRACE("ips_issue_copperhead_memio", 1); - - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } - - TimeOut = 0; - - while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { - udelay(1000); - - if (++TimeOut >= IPS_SEM_TIMEOUT) { - if (!(val & IPS_BIT_START_STOP)) - break; - - IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue val [0x%x].\n", val); - IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue semaphore chk timeout.\n"); - - return (IPS_FAILURE); - } /* end if */ - } /* end while */ +ips_issue_copperhead_memio(ips_ha_t * ha, ips_scb_t * scb) +{ + uint32_t TimeOut; + uint32_t val; - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); - writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); + METHOD_TRACE("ips_issue_copperhead_memio", 1); - return (IPS_SUCCESS); + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } + + TimeOut = 0; + + while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { + udelay(1000); + + if (++TimeOut >= IPS_SEM_TIMEOUT) { + if (!(val & IPS_BIT_START_STOP)) + break; + + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "ips_issue val [0x%x].\n", val); + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "ips_issue semaphore chk timeout.\n"); + + return (IPS_FAILURE); + } /* end if */ + } /* end while */ + + writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); + writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); + + return (IPS_SUCCESS); } /****************************************************************************/ @@ -5327,29 +5596,26 @@ /* */ /****************************************************************************/ static int -ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { +ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb) +{ - METHOD_TRACE("ips_issue_i2o", 1); + METHOD_TRACE("ips_issue_i2o", 1); - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } - outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); + outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); - return (IPS_SUCCESS); + return (IPS_SUCCESS); } /****************************************************************************/ @@ -5362,29 +5628,26 @@ /* */ /****************************************************************************/ static int -ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { +ips_issue_i2o_memio(ips_ha_t * ha, ips_scb_t * scb) +{ - METHOD_TRACE("ips_issue_i2o_memio", 1); + METHOD_TRACE("ips_issue_i2o_memio", 1); - if (scb->scsi_cmd) { - DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", - ips_name, - ha->host_num, - scb->cdb[0], - scb->cmd.basic_io.command_id, - scb->bus, - scb->target_id, - scb->lun); - } else { - DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", - ips_name, - ha->host_num, - scb->cmd.basic_io.command_id); - } + if (scb->scsi_cmd) { + DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)", + ips_name, + ha->host_num, + scb->cdb[0], + scb->cmd.basic_io.command_id, + scb->bus, scb->target_id, scb->lun); + } else { + DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d", + ips_name, ha->host_num, scb->cmd.basic_io.command_id); + } - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); + writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); - return (IPS_SUCCESS); + return (IPS_SUCCESS); } /****************************************************************************/ @@ -5397,26 +5660,27 @@ /* */ /****************************************************************************/ static int -ips_isintr_copperhead(ips_ha_t *ha) { - uint8_t Isr; +ips_isintr_copperhead(ips_ha_t * ha) +{ + uint8_t Isr; - METHOD_TRACE("ips_isintr_copperhead", 2); + METHOD_TRACE("ips_isintr_copperhead", 2); - Isr = inb(ha->io_addr + IPS_REG_HISR); + Isr = inb(ha->io_addr + IPS_REG_HISR); - if (Isr == 0xFF) - /* ?!?! Nothing really there */ - return (0); - - if (Isr & IPS_BIT_SCE) - return (1); - else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { - /* status queue overflow or GHI */ - /* just clear the interrupt */ - outb(Isr, ha->io_addr + IPS_REG_HISR); - } + if (Isr == 0xFF) + /* ?!?! Nothing really there */ + return (0); + + if (Isr & IPS_BIT_SCE) + return (1); + else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { + /* status queue overflow or GHI */ + /* just clear the interrupt */ + outb(Isr, ha->io_addr + IPS_REG_HISR); + } - return (0); + return (0); } /****************************************************************************/ @@ -5429,26 +5693,27 @@ /* */ /****************************************************************************/ static int -ips_isintr_copperhead_memio(ips_ha_t *ha) { - uint8_t Isr; +ips_isintr_copperhead_memio(ips_ha_t * ha) +{ + uint8_t Isr; - METHOD_TRACE("ips_isintr_memio", 2); + METHOD_TRACE("ips_isintr_memio", 2); - Isr = readb(ha->mem_ptr + IPS_REG_HISR); + Isr = readb(ha->mem_ptr + IPS_REG_HISR); - if (Isr == 0xFF) - /* ?!?! Nothing really there */ - return (0); - - if (Isr & IPS_BIT_SCE) - return (1); - else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { - /* status queue overflow or GHI */ - /* just clear the interrupt */ - writeb(Isr, ha->mem_ptr + IPS_REG_HISR); - } + if (Isr == 0xFF) + /* ?!?! Nothing really there */ + return (0); + + if (Isr & IPS_BIT_SCE) + return (1); + else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) { + /* status queue overflow or GHI */ + /* just clear the interrupt */ + writeb(Isr, ha->mem_ptr + IPS_REG_HISR); + } - return (0); + return (0); } /****************************************************************************/ @@ -5461,17 +5726,18 @@ /* */ /****************************************************************************/ static int -ips_isintr_morpheus(ips_ha_t *ha) { - uint32_t Isr; +ips_isintr_morpheus(ips_ha_t * ha) +{ + uint32_t Isr; - METHOD_TRACE("ips_isintr_morpheus", 2); + METHOD_TRACE("ips_isintr_morpheus", 2); - Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); + Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR); - if (Isr & IPS_BIT_I2O_OPQI) - return (1); - else - return (0); + if (Isr & IPS_BIT_I2O_OPQI) + return (1); + else + return (0); } /****************************************************************************/ @@ -5484,51 +5750,52 @@ /* */ /****************************************************************************/ static int -ips_wait(ips_ha_t *ha, int time, int intr) { - int ret; - int done; - - METHOD_TRACE("ips_wait", 1); - - ret = IPS_FAILURE; - done = FALSE; - - time *= IPS_ONE_SEC; /* convert seconds */ - - while ((time > 0) && (!done)) { - if (intr == IPS_INTR_ON) { - if (ha->waitflag == FALSE) { - ret = IPS_SUCCESS; - done = TRUE; - break; - } - } else if (intr == IPS_INTR_IORL) { - if (ha->waitflag == FALSE) { - /* - * controller generated an interrupt to - * acknowledge completion of the command - * and ips_intr() has serviced the interrupt. - */ - ret = IPS_SUCCESS; - done = TRUE; - break; - } - - /* - * NOTE: we already have the io_request_lock so - * even if we get an interrupt it won't get serviced - * until after we finish. - */ - - (*ha->func.intr)(ha); - } - - /* This looks like a very evil loop, but it only does this during start-up */ - udelay(1000); - time--; - } +ips_wait(ips_ha_t * ha, int time, int intr) +{ + int ret; + int done; + + METHOD_TRACE("ips_wait", 1); + + ret = IPS_FAILURE; + done = FALSE; + + time *= IPS_ONE_SEC; /* convert seconds */ + + while ((time > 0) && (!done)) { + if (intr == IPS_INTR_ON) { + if (ha->waitflag == FALSE) { + ret = IPS_SUCCESS; + done = TRUE; + break; + } + } else if (intr == IPS_INTR_IORL) { + if (ha->waitflag == FALSE) { + /* + * controller generated an interrupt to + * acknowledge completion of the command + * and ips_intr() has serviced the interrupt. + */ + ret = IPS_SUCCESS; + done = TRUE; + break; + } + + /* + * NOTE: we already have the io_request_lock so + * even if we get an interrupt it won't get serviced + * until after we finish. + */ + + (*ha->func.intr) (ha); + } - return (ret); + /* This looks like a very evil loop, but it only does this during start-up */ + udelay(1000); + time--; + } + + return (ret); } /****************************************************************************/ @@ -5541,55 +5808,59 @@ /* */ /****************************************************************************/ static int -ips_write_driver_status(ips_ha_t *ha, int intr) { - METHOD_TRACE("ips_write_driver_status", 1); +ips_write_driver_status(ips_ha_t * ha, int intr) +{ + METHOD_TRACE("ips_write_driver_status", 1); - if (!ips_readwrite_page5(ha, FALSE, intr)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read NVRAM page 5.\n"); + if (!ips_readwrite_page5(ha, FALSE, intr)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "unable to read NVRAM page 5.\n"); - return (0); - } + return (0); + } - /* check to make sure the page has a valid */ - /* signature */ - if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { - DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.", - ips_name, ha->host_num, ha->nvram->signature); - ha->nvram->signature = IPS_NVRAM_P5_SIG; - } - - DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", - ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type), - ha->nvram->adapter_slot, - ha->nvram->bios_high[0], ha->nvram->bios_high[1], - ha->nvram->bios_high[2], ha->nvram->bios_high[3], - ha->nvram->bios_low[0], ha->nvram->bios_low[1], - ha->nvram->bios_low[2], ha->nvram->bios_low[3]); - - ips_get_bios_version(ha, intr); - - /* change values (as needed) */ - ha->nvram->operating_system = IPS_OS_LINUX; - ha->nvram->adapter_type = ha->ad_type; - strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4); - strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4); - strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4); - strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4); - - ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */ - - /* now update the page */ - if (!ips_readwrite_page5(ha, TRUE, intr)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to write NVRAM page 5.\n"); + /* check to make sure the page has a valid */ + /* signature */ + if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { + DEBUG_VAR(1, + "(%s%d) NVRAM page 5 has an invalid signature: %X.", + ips_name, ha->host_num, ha->nvram->signature); + ha->nvram->signature = IPS_NVRAM_P5_SIG; + } - return (0); - } + DEBUG_VAR(2, + "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", + ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type), + ha->nvram->adapter_slot, ha->nvram->bios_high[0], + ha->nvram->bios_high[1], ha->nvram->bios_high[2], + ha->nvram->bios_high[3], ha->nvram->bios_low[0], + ha->nvram->bios_low[1], ha->nvram->bios_low[2], + ha->nvram->bios_low[3]); + + ips_get_bios_version(ha, intr); + + /* change values (as needed) */ + ha->nvram->operating_system = IPS_OS_LINUX; + ha->nvram->adapter_type = ha->ad_type; + strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4); + strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4); + strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4); + strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4); + + ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */ + + /* now update the page */ + if (!ips_readwrite_page5(ha, TRUE, intr)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "unable to write NVRAM page 5.\n"); - /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */ - ha->slot_num = ha->nvram->adapter_slot; + return (0); + } + /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */ + ha->slot_num = ha->nvram->adapter_slot; - return (1); + return (1); } /****************************************************************************/ @@ -5602,38 +5873,37 @@ /* */ /****************************************************************************/ static int -ips_read_adapter_status(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_read_adapter_status", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_ENQUIRY; - - scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.lba = 0; - scb->cmd.basic_io.sector_count = 0; - scb->cmd.basic_io.log_drv = 0; - scb->data_len = sizeof(*ha->enq); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* send command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); +ips_read_adapter_status(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; - return (1); + METHOD_TRACE("ips_read_adapter_status", 1); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_ENQUIRY; + + scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.sg_count = 0; + scb->cmd.basic_io.lba = 0; + scb->cmd.basic_io.sector_count = 0; + scb->cmd.basic_io.log_drv = 0; + scb->data_len = sizeof (*ha->enq); + scb->cmd.basic_io.sg_addr = ha->enq_busaddr; + + /* send command */ + if (((ret = + ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + return (1); } /****************************************************************************/ @@ -5646,38 +5916,38 @@ /* */ /****************************************************************************/ static int -ips_read_subsystem_parameters(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_read_subsystem_parameters", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_GET_SUBSYS; - - scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.basic_io.sg_count = 0; - scb->cmd.basic_io.lba = 0; - scb->cmd.basic_io.sector_count = 0; - scb->cmd.basic_io.log_drv = 0; - scb->data_len = sizeof(*ha->subsys); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* send command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); +ips_read_subsystem_parameters(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; + + METHOD_TRACE("ips_read_subsystem_parameters", 1); - return (1); + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_GET_SUBSYS; + + scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.sg_count = 0; + scb->cmd.basic_io.lba = 0; + scb->cmd.basic_io.sector_count = 0; + scb->cmd.basic_io.log_drv = 0; + scb->data_len = sizeof (*ha->subsys); + scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr; + + /* send command */ + if (((ret = + ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys)); + return (1); } /****************************************************************************/ @@ -5690,51 +5960,52 @@ /* */ /****************************************************************************/ static int -ips_read_config(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int i; - int ret; - - METHOD_TRACE("ips_read_config", 1); - - /* set defaults for initiator IDs */ - for (i = 0; i < 4; i++) - ha->conf->init_id[i] = 7; - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_READ_CONF; - - scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; - scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); - scb->data_len = sizeof(*ha->conf); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->conf, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* send command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { - - memset(ha->conf, 0, sizeof(IPS_CONF)); - - /* reset initiator IDs */ - for (i = 0; i < 4; i++) - ha->conf->init_id[i] = 7; - - /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */ - if ((scb->basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_CMPLT_WERROR) - return (1); - - return (0); - } +ips_read_config(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int i; + int ret; + + METHOD_TRACE("ips_read_config", 1); + + /* set defaults for initiator IDs */ + for (i = 0; i < 4; i++) + ha->conf->init_id[i] = 7; + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_READ_CONF; + + scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; + scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->data_len = sizeof (*ha->conf); + scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr; + + /* send command */ + if (((ret = + ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { + + memset(ha->conf, 0, sizeof (IPS_CONF)); + + /* reset initiator IDs */ + for (i = 0; i < 4; i++) + ha->conf->init_id[i] = 7; - return (1); + /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */ + if ((scb->basic_status & IPS_GSC_STATUS_MASK) == + IPS_CMD_CMPLT_WERROR) + return (1); + + return (0); + } + + memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf)); + return (1); } /****************************************************************************/ @@ -5747,42 +6018,44 @@ /* */ /****************************************************************************/ static int -ips_readwrite_page5(ips_ha_t *ha, int write, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_readwrite_page5", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE; - - scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE; - scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.nvram.page = 5; - scb->cmd.nvram.write = write; - scb->cmd.nvram.reserved = 0; - scb->cmd.nvram.reserved2 = 0; - scb->data_len = sizeof(*ha->nvram); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->nvram, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.nvram.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* issue the command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { +ips_readwrite_page5(ips_ha_t * ha, int write, int intr) +{ + ips_scb_t *scb; + int ret; + + METHOD_TRACE("ips_readwrite_page5", 1); - memset(ha->nvram, 0, sizeof(IPS_NVRAM_P5)); + scb = &ha->scbs[ha->max_cmds - 1]; - return (0); - } + ips_init_scb(ha, scb); - return (1); + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE; + + scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE; + scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.nvram.page = 5; + scb->cmd.nvram.write = write; + scb->cmd.nvram.reserved = 0; + scb->cmd.nvram.reserved2 = 0; + scb->data_len = sizeof (*ha->nvram); + scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr; + if (write) + memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram)); + + /* issue the command */ + if (((ret = + ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { + + memset(ha->nvram, 0, sizeof (IPS_NVRAM_P5)); + + return (0); + } + if (!write) + memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram)); + return (1); } /****************************************************************************/ @@ -5795,54 +6068,57 @@ /* */ /****************************************************************************/ static int -ips_clear_adapter(ips_ha_t *ha, int intr) { - ips_scb_t *scb; - int ret; - - METHOD_TRACE("ips_clear_adapter", 1); - - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_reset_timeout; - scb->cdb[0] = IPS_CMD_CONFIG_SYNC; - - scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC; - scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.config_sync.channel = 0; - scb->cmd.config_sync.source_target = IPS_POCL; - scb->cmd.config_sync.reserved = 0; - scb->cmd.config_sync.reserved2 = 0; - scb->cmd.config_sync.reserved3 = 0; - - /* issue command */ - if (((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); - - /* send unlock stripe command */ - ips_init_scb(ha, scb); - - scb->cdb[0] = IPS_CMD_ERROR_TABLE; - scb->timeout = ips_reset_timeout; - - scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE; - scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.unlock_stripe.log_drv = 0; - scb->cmd.unlock_stripe.control = IPS_CSL; - scb->cmd.unlock_stripe.reserved = 0; - scb->cmd.unlock_stripe.reserved2 = 0; - scb->cmd.unlock_stripe.reserved3 = 0; - - /* issue command */ - if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) || - (ret == IPS_SUCCESS_IMM) || - ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) - return (0); +ips_clear_adapter(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; + int ret; + + METHOD_TRACE("ips_clear_adapter", 1); + + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); - return (1); + scb->timeout = ips_reset_timeout; + scb->cdb[0] = IPS_CMD_CONFIG_SYNC; + + scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC; + scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.config_sync.channel = 0; + scb->cmd.config_sync.source_target = IPS_POCL; + scb->cmd.config_sync.reserved = 0; + scb->cmd.config_sync.reserved2 = 0; + scb->cmd.config_sync.reserved3 = 0; + + /* issue command */ + if (((ret = + ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + /* send unlock stripe command */ + ips_init_scb(ha, scb); + + scb->cdb[0] = IPS_CMD_ERROR_TABLE; + scb->timeout = ips_reset_timeout; + + scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE; + scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.unlock_stripe.log_drv = 0; + scb->cmd.unlock_stripe.control = IPS_CSL; + scb->cmd.unlock_stripe.reserved = 0; + scb->cmd.unlock_stripe.reserved2 = 0; + scb->cmd.unlock_stripe.reserved3 = 0; + + /* issue command */ + if (((ret = + ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) + || (ret == IPS_SUCCESS_IMM) + || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) + return (0); + + return (1); } /****************************************************************************/ @@ -5855,27 +6131,28 @@ /* */ /****************************************************************************/ static void -ips_ffdc_reset(ips_ha_t *ha, int intr) { - ips_scb_t *scb; +ips_ffdc_reset(ips_ha_t * ha, int intr) +{ + ips_scb_t *scb; - METHOD_TRACE("ips_ffdc_reset", 1); + METHOD_TRACE("ips_ffdc_reset", 1); - scb = &ha->scbs[ha->max_cmds-1]; + scb = &ha->scbs[ha->max_cmds - 1]; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FFDC; - scb->cmd.ffdc.op_code = IPS_CMD_FFDC; - scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.ffdc.reset_count = ha->reset_count; - scb->cmd.ffdc.reset_type = 0x80; + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FFDC; + scb->cmd.ffdc.op_code = IPS_CMD_FFDC; + scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.ffdc.reset_count = ha->reset_count; + scb->cmd.ffdc.reset_type = 0x80; - /* convert time to what the card wants */ - ips_fix_ffdc_time(ha, scb, ha->last_ffdc); + /* convert time to what the card wants */ + ips_fix_ffdc_time(ha, scb, ha->last_ffdc); - /* issue command */ - ips_send_wait(ha, scb, ips_cmd_timeout, intr); + /* issue command */ + ips_send_wait(ha, scb, ips_cmd_timeout, intr); } /****************************************************************************/ @@ -5888,30 +6165,30 @@ /* */ /****************************************************************************/ static void -ips_ffdc_time(ips_ha_t *ha) { - ips_scb_t *scb; +ips_ffdc_time(ips_ha_t * ha) +{ + ips_scb_t *scb; - METHOD_TRACE("ips_ffdc_time", 1); + METHOD_TRACE("ips_ffdc_time", 1); - DEBUG_VAR(1, "(%s%d) Sending time update.", - ips_name, ha->host_num); + DEBUG_VAR(1, "(%s%d) Sending time update.", ips_name, ha->host_num); - scb = &ha->scbs[ha->max_cmds-1]; + scb = &ha->scbs[ha->max_cmds - 1]; - ips_init_scb(ha, scb); + ips_init_scb(ha, scb); - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_FFDC; - scb->cmd.ffdc.op_code = IPS_CMD_FFDC; - scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.ffdc.reset_count = 0; - scb->cmd.ffdc.reset_type = 0x80; + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_FFDC; + scb->cmd.ffdc.op_code = IPS_CMD_FFDC; + scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.ffdc.reset_count = 0; + scb->cmd.ffdc.reset_type = 0; - /* convert time to what the card wants */ - ips_fix_ffdc_time(ha, scb, ha->last_ffdc); + /* convert time to what the card wants */ + ips_fix_ffdc_time(ha, scb, ha->last_ffdc); - /* issue command */ - ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC); + /* issue command */ + ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC); } /****************************************************************************/ @@ -5923,57 +6200,59 @@ /* */ /****************************************************************************/ static void -ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) { - long days; - long rem; - int i; - int year; - int yleap; - int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR }; - int month_lengths[12][2] = { {31, 31}, - {28, 29}, - {31, 31}, - {30, 30}, - {31, 31}, - {30, 30}, - {31, 31}, - {31, 31}, - {30, 30}, - {31, 31}, - {30, 30}, - {31, 31} }; - - METHOD_TRACE("ips_fix_ffdc_time", 1); - - days = current_time / IPS_SECS_DAY; - rem = current_time % IPS_SECS_DAY; - - scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR); - rem = rem % IPS_SECS_HOUR; - scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN); - scb->cmd.ffdc.second = (rem % IPS_SECS_MIN); - - year = IPS_EPOCH_YEAR; - while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) { - int newy; - - newy = year + (days / IPS_DAYS_NORMAL_YEAR); - if (days < 0) - --newy; - days -= (newy - year) * IPS_DAYS_NORMAL_YEAR + - IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) - - IPS_NUM_LEAP_YEARS_THROUGH(year - 1); - year = newy; - } +ips_fix_ffdc_time(ips_ha_t * ha, ips_scb_t * scb, time_t current_time) +{ + long days; + long rem; + int i; + int year; + int yleap; + int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR }; + int month_lengths[12][2] = { {31, 31}, + {28, 29}, + {31, 31}, + {30, 30}, + {31, 31}, + {30, 30}, + {31, 31}, + {31, 31}, + {30, 30}, + {31, 31}, + {30, 30}, + {31, 31} + }; + + METHOD_TRACE("ips_fix_ffdc_time", 1); + + days = current_time / IPS_SECS_DAY; + rem = current_time % IPS_SECS_DAY; + + scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR); + rem = rem % IPS_SECS_HOUR; + scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN); + scb->cmd.ffdc.second = (rem % IPS_SECS_MIN); + + year = IPS_EPOCH_YEAR; + while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) { + int newy; + + newy = year + (days / IPS_DAYS_NORMAL_YEAR); + if (days < 0) + --newy; + days -= (newy - year) * IPS_DAYS_NORMAL_YEAR + + IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) - + IPS_NUM_LEAP_YEARS_THROUGH(year - 1); + year = newy; + } - scb->cmd.ffdc.yearH = year / 100; - scb->cmd.ffdc.yearL = year % 100; + scb->cmd.ffdc.yearH = year / 100; + scb->cmd.ffdc.yearL = year % 100; - for (i = 0; days >= month_lengths[i][yleap]; ++i) - days -= month_lengths[i][yleap]; + for (i = 0; days >= month_lengths[i][yleap]; ++i) + days -= month_lengths[i][yleap]; - scb->cmd.ffdc.month = i + 1; - scb->cmd.ffdc.day = days + 1; + scb->cmd.ffdc.month = i + 1; + scb->cmd.ffdc.day = days + 1; } /**************************************************************************** @@ -5989,106 +6268,107 @@ /* */ /****************************************************************************/ static int -ips_erase_bios(ips_ha_t *ha) { - int timeout; - uint8_t status=0; - - METHOD_TRACE("ips_erase_bios", 1); - - status = 0; - - /* Clear the status register */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0x50, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Setup */ - outb(0x20, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Confirm */ - outb(0xD0, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Status */ - outb(0x70, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - timeout = 80000; /* 80 seconds */ - - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - outl(0, ha->io_addr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = inb(ha->io_addr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - /* check for timeout */ - if (timeout <= 0) { - /* timeout */ - - /* try to suspend the erase */ - outb(0xB0, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait for 10 seconds */ - timeout = 10000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - outl(0, ha->io_addr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = inb(ha->io_addr + IPS_REG_FLDP); - - if (status & 0xC0) - break; - - MDELAY(1); - timeout--; - } - - return (1); - } - - /* check for valid VPP */ - if (status & 0x08) - /* VPP failure */ - return (1); - - /* check for succesful flash */ - if (status & 0x30) - /* sequence error */ - return (1); - - /* Otherwise, we were successful */ - /* clear status */ - outb(0x50, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* enable reads */ - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_erase_bios(ips_ha_t * ha) +{ + int timeout; + uint8_t status = 0; + + METHOD_TRACE("ips_erase_bios", 1); + + status = 0; + + /* Clear the status register */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0x50, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Setup */ + outb(0x20, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Confirm */ + outb(0xD0, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Status */ + outb(0x70, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + timeout = 80000; /* 80 seconds */ + + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + outl(0, ha->io_addr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = inb(ha->io_addr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + /* check for timeout */ + if (timeout <= 0) { + /* timeout */ + + /* try to suspend the erase */ + outb(0xB0, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait for 10 seconds */ + timeout = 10000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + outl(0, ha->io_addr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } - return (0); + status = inb(ha->io_addr + IPS_REG_FLDP); + + if (status & 0xC0) + break; + + MDELAY(1); + timeout--; + } + + return (1); + } + + /* check for valid VPP */ + if (status & 0x08) + /* VPP failure */ + return (1); + + /* check for succesful flash */ + if (status & 0x30) + /* sequence error */ + return (1); + + /* Otherwise, we were successful */ + /* clear status */ + outb(0x50, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* enable reads */ + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (0); } /****************************************************************************/ @@ -6100,106 +6380,107 @@ /* */ /****************************************************************************/ static int -ips_erase_bios_memio(ips_ha_t *ha) { - int timeout; - uint8_t status; - - METHOD_TRACE("ips_erase_bios_memio", 1); - - status = 0; - - /* Clear the status register */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Setup */ - writeb(0x20, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Confirm */ - writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* Erase Status */ - writeb(0x70, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - timeout = 80000; /* 80 seconds */ - - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - writel(0, ha->mem_ptr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = readb(ha->mem_ptr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - /* check for timeout */ - if (timeout <= 0) { - /* timeout */ - - /* try to suspend the erase */ - writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait for 10 seconds */ - timeout = 10000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - writel(0, ha->mem_ptr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = readb(ha->mem_ptr + IPS_REG_FLDP); - - if (status & 0xC0) - break; - - MDELAY(1); - timeout--; - } - - return (1); - } - - /* check for valid VPP */ - if (status & 0x08) - /* VPP failure */ - return (1); - - /* check for succesful flash */ - if (status & 0x30) - /* sequence error */ - return (1); - - /* Otherwise, we were successful */ - /* clear status */ - writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* enable reads */ - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_erase_bios_memio(ips_ha_t * ha) +{ + int timeout; + uint8_t status; + + METHOD_TRACE("ips_erase_bios_memio", 1); + + status = 0; + + /* Clear the status register */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Setup */ + writeb(0x20, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Confirm */ + writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* Erase Status */ + writeb(0x70, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + timeout = 80000; /* 80 seconds */ + + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + writel(0, ha->mem_ptr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = readb(ha->mem_ptr + IPS_REG_FLDP); - return (0); + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + /* check for timeout */ + if (timeout <= 0) { + /* timeout */ + + /* try to suspend the erase */ + writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait for 10 seconds */ + timeout = 10000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + writel(0, ha->mem_ptr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = readb(ha->mem_ptr + IPS_REG_FLDP); + + if (status & 0xC0) + break; + + MDELAY(1); + timeout--; + } + + return (1); + } + + /* check for valid VPP */ + if (status & 0x08) + /* VPP failure */ + return (1); + + /* check for succesful flash */ + if (status & 0x30) + /* sequence error */ + return (1); + + /* Otherwise, we were successful */ + /* clear status */ + writeb(0x50, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* enable reads */ + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (0); } /****************************************************************************/ @@ -6211,84 +6492,86 @@ /* */ /****************************************************************************/ static int -ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - int i; - int timeout; - uint8_t status=0; - - METHOD_TRACE("ips_program_bios", 1); - - status = 0; - - for (i = 0; i < buffersize; i++) { - /* write a byte */ - outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0x40, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(buffer[i], ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait up to one second */ - timeout = 1000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - outl(0, ha->io_addr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = inb(ha->io_addr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - if (timeout == 0) { - /* timeout error */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - - /* check the status */ - if (status & 0x18) { - /* programming error */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - } /* end for */ - - /* Enable reading */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - outb(0xFF, ha->io_addr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + int i; + int timeout; + uint8_t status = 0; + + METHOD_TRACE("ips_program_bios", 1); + + status = 0; + + for (i = 0; i < buffersize; i++) { + /* write a byte */ + outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0x40, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(buffer[i], ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait up to one second */ + timeout = 1000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + outl(0, ha->io_addr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = inb(ha->io_addr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + if (timeout == 0) { + /* timeout error */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + + /* check the status */ + if (status & 0x18) { + /* programming error */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + } /* end for */ - return (0); + /* Enable reading */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + outb(0xFF, ha->io_addr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (0); } /****************************************************************************/ @@ -6300,84 +6583,86 @@ /* */ /****************************************************************************/ static int -ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - int i; - int timeout; - uint8_t status=0; - - METHOD_TRACE("ips_program_bios_memio", 1); - - status = 0; - - for (i = 0; i < buffersize; i++) { - /* write a byte */ - writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0x40, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - /* wait up to one second */ - timeout = 1000; - while (timeout > 0) { - if (ha->revision_id == IPS_REVID_TROMBONE64) { - writel(0, ha->mem_ptr + IPS_REG_FLAP); - udelay(25); /* 25 us */ - } - - status = readb(ha->mem_ptr + IPS_REG_FLDP); - - if (status & 0x80) - break; - - MDELAY(1); - timeout--; - } - - if (timeout == 0) { - /* timeout error */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - - /* check the status */ - if (status & 0x18) { - /* programming error */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - return (1); - } - } /* end for */ - - /* Enable reading */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ +ips_program_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + int i; + int timeout; + uint8_t status = 0; + + METHOD_TRACE("ips_program_bios_memio", 1); + + status = 0; + + for (i = 0; i < buffersize; i++) { + /* write a byte */ + writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0x40, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + /* wait up to one second */ + timeout = 1000; + while (timeout > 0) { + if (ha->revision_id == IPS_REVID_TROMBONE64) { + writel(0, ha->mem_ptr + IPS_REG_FLAP); + udelay(25); /* 25 us */ + } + + status = readb(ha->mem_ptr + IPS_REG_FLDP); + + if (status & 0x80) + break; + + MDELAY(1); + timeout--; + } + + if (timeout == 0) { + /* timeout error */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } - return (0); + /* check the status */ + if (status & 0x18) { + /* programming error */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (1); + } + } /* end for */ + + /* Enable reading */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + return (0); } /****************************************************************************/ @@ -6389,42 +6674,44 @@ /* */ /****************************************************************************/ static int -ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - uint8_t checksum; - int i; - - METHOD_TRACE("ips_verify_bios", 1); - - /* test 1st byte */ - outl(0, ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) - return (1); - - outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) - return (1); - - checksum = 0xff; - for (i = 2; i < buffersize; i++) { - - outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP); - } - - if (checksum != 0) - /* failure */ - return (1); - else - /* success */ - return (0); +ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + uint8_t checksum; + int i; + + METHOD_TRACE("ips_verify_bios", 1); + + /* test 1st byte */ + outl(0, ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) + return (1); + + outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) + return (1); + + checksum = 0xff; + for (i = 2; i < buffersize; i++) { + + outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP); + } + + if (checksum != 0) + /* failure */ + return (1); + else + /* success */ + return (0); } /****************************************************************************/ @@ -6436,42 +6723,45 @@ /* */ /****************************************************************************/ static int -ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) { - uint8_t checksum; - int i; - - METHOD_TRACE("ips_verify_bios_memio", 1); - - /* test 1st byte */ - writel(0, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) - return (1); - - writel(1, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) - return (1); - - checksum = 0xff; - for (i = 2; i < buffersize; i++) { - - writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); - if (ha->revision_id == IPS_REVID_TROMBONE64) - udelay(25); /* 25 us */ - - checksum = (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP); - } - - if (checksum != 0) - /* failure */ - return (1); - else - /* success */ - return (0); +ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize, + uint32_t offset) +{ + uint8_t checksum; + int i; + + METHOD_TRACE("ips_verify_bios_memio", 1); + + /* test 1st byte */ + writel(0, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55) + return (1); + + writel(1, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA) + return (1); + + checksum = 0xff; + for (i = 2; i < buffersize; i++) { + + writel(i + offset, ha->mem_ptr + IPS_REG_FLAP); + if (ha->revision_id == IPS_REVID_TROMBONE64) + udelay(25); /* 25 us */ + + checksum = + (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP); + } + + if (checksum != 0) + /* failure */ + return (1); + else + /* success */ + return (0); } /*---------------------------------------------------------------------------*/ @@ -6481,118 +6771,125 @@ /* Assumes that ips_read_adapter_status() is called first filling in */ /* the data for SubSystem Parameters. */ /* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */ -/* Data is availaible. */ +/* Data is available. */ /* */ /*---------------------------------------------------------------------------*/ -static void ips_version_check(ips_ha_t *ha, int intr) { - IPS_VERSION_DATA VersionInfo; - uint8_t FirmwareVersion[ IPS_COMPAT_ID_LENGTH + 1 ]; - uint8_t BiosVersion[ IPS_COMPAT_ID_LENGTH + 1]; - int MatchError; - int rc; - char BiosString[10]; - char FirmwareString[10]; - - METHOD_TRACE("ips_version_check", 1); - - memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1); - memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1); - - /* Get the Compatible BIOS Version from NVRAM Page 5 */ - memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, IPS_COMPAT_ID_LENGTH); - - rc = IPS_FAILURE; - if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) /* If Versioning is Supported */ - { - /* Get the Version Info with a Get Version Command */ - rc = ips_get_version_info(ha, &VersionInfo, intr); - if (rc == IPS_SUCCESS) - memcpy(FirmwareVersion, VersionInfo.compatibilityId, IPS_COMPAT_ID_LENGTH); - } - - if (rc != IPS_SUCCESS) /* If Data Not Obtainable from a GetVersion Command */ - { - /* Get the Firmware Version from Enquiry Data */ - memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, IPS_COMPAT_ID_LENGTH); - } - - /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */ - /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */ - /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */ - /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */ - - MatchError = 0; - - if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0) - MatchError = 1; - - if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) - MatchError = 1; - - ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ - - if (MatchError) - { - ha->nvram->version_mismatch = 1; - 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; - - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Warning ! ! ! ServeRAID Version Mismatch\n"); - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Bios = %s, Firmware = %s, Device Driver = %s%s\n", - BiosString, FirmwareString, IPS_VERSION_HIGH, IPS_VERSION_LOW ); - IPS_PRINTK(KERN_WARNING, ha->pcidev, "These levels should match to avoid possible compatibility problems.\n"); - } - } - else - { - ha->nvram->version_mismatch = 0; - } +static void +ips_version_check(ips_ha_t * ha, int intr) +{ + IPS_VERSION_DATA VersionInfo; + uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1]; + uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1]; + int MatchError; + int rc; + char BiosString[10]; + char FirmwareString[10]; + + METHOD_TRACE("ips_version_check", 1); + + memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1); + memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1); + + /* Get the Compatible BIOS Version from NVRAM Page 5 */ + memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, + IPS_COMPAT_ID_LENGTH); + + rc = IPS_FAILURE; + if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */ + /* Get the Version Info with a Get Version Command */ + rc = ips_get_version_info(ha, &VersionInfo, intr); + if (rc == IPS_SUCCESS) + memcpy(FirmwareVersion, VersionInfo.compatibilityId, + IPS_COMPAT_ID_LENGTH); + } + + if (rc != IPS_SUCCESS) { /* If Data Not Obtainable from a GetVersion Command */ + /* Get the Firmware Version from Enquiry Data */ + memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, + IPS_COMPAT_ID_LENGTH); + } + + /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */ + /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */ + /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */ + /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */ + + MatchError = 0; + + if (strncmp + (FirmwareVersion, Compatable[ha->nvram->adapter_type], + IPS_COMPAT_ID_LENGTH) != 0) + MatchError = 1; + + if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) + MatchError = 1; + + ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ + + if (MatchError) { + ha->nvram->version_mismatch = 1; + 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; + + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Warning ! ! ! ServeRAID Version Mismatch\n"); + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Bios = %s, Firmware = %s, Device Driver = %s%s\n", + BiosString, FirmwareString, IPS_VERSION_HIGH, + IPS_VERSION_LOW); + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "These levels should match to avoid possible compatibility problems.\n"); + } + } else { + ha->nvram->version_mismatch = 0; + } - return; + return; } /*---------------------------------------------------------------------------*/ /* Routine Name: ips_get_version_info */ /* */ /* Routine Description: */ -/* Issue an internal GETVERSION ServeRAID Command */ +/* Issue an internal GETVERSION Command */ /* */ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ) { - ips_scb_t *scb; - int rc; - - METHOD_TRACE("ips_get_version_info", 1); - - memset(Buffer, 0, sizeof(IPS_VERSION_DATA)); - scb = &ha->scbs[ha->max_cmds-1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_GET_VERSION_INFO; - scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO; - scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.version_info.reserved = 0; - scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA); - scb->cmd.version_info.reserved2 = 0; - scb->data_len = sizeof(*Buffer); - scb->data_busaddr = pci_map_single(ha->pcidev, Buffer, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.version_info.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - - /* issue command */ - rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); - return( rc ); +static int +ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer, int intr) +{ + ips_scb_t *scb; + int rc; + + METHOD_TRACE("ips_get_version_info", 1); + + memset(Buffer, 0, sizeof (IPS_VERSION_DATA)); + scb = &ha->scbs[ha->max_cmds - 1]; + + ips_init_scb(ha, scb); + + scb->timeout = ips_cmd_timeout; + scb->cdb[0] = IPS_CMD_GET_VERSION_INFO; + scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO; + scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.version_info.reserved = 0; + scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA); + scb->cmd.version_info.reserved2 = 0; + scb->data_len = sizeof (*Buffer); + scb->data_busaddr = pci_map_single(ha->pcidev, Buffer, + scb->data_len, IPS_DMA_DIR(scb)); + scb->cmd.version_info.buffer_addr = scb->data_busaddr; + scb->flags |= IPS_SCB_MAP_SINGLE; + + /* issue command */ + rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); + return (rc); } /****************************************************************************/ @@ -6601,14 +6898,17 @@ /* */ /* 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); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; +/****************************************************************************/ +static int +ips_abort_init(ips_ha_t * ha, int index) +{ + ha->active = 0; + ips_free(ha); + ips_ha[index] = 0; + ips_sh[index] = 0; + return -1; } + /****************************************************************************/ /* */ /* Routine Name: ips_shift_controllers */ @@ -6617,12 +6917,13 @@ /* helper function for ordering adapters */ /****************************************************************************/ static void -ips_shift_controllers(int lowindex, int highindex){ +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--){ + 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; @@ -6640,20 +6941,22 @@ /* place controllers is the "proper" boot order */ /****************************************************************************/ static void -ips_order_controllers(void){ +ips_order_controllers(void) +{ int i, j, tmp, position = 0; IPS_NVRAM_P5 *nvram; - if(!ips_ha[0]) + 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){ + 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); + if (nvram->adapter_order[i] == 'M') { + ips_shift_controllers(position, + j); position++; } break; @@ -6661,16 +6964,18 @@ case IPS_ADTYPE_SERVERAID4M: case IPS_ADTYPE_SERVERAID4MX: case IPS_ADTYPE_SERVERAID4LX: - if(nvram->adapter_order[i] == 'N'){ - ips_shift_controllers(position, j); + 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); + if (nvram->adapter_order[i] == 'S') { + ips_shift_controllers(position, + j); position++; } break; @@ -6681,8 +6986,9 @@ case IPS_ADTYPE_SERVERAID3L: case IPS_ADTYPE_SERVERAID3: case IPS_ADTYPE_SERVERAID4H: - if(nvram->adapter_order[i] == 'A'){ - ips_shift_controllers(position, j); + if (nvram->adapter_order[i] == 'A') { + ips_shift_controllers(position, + j); position++; } break; @@ -6696,9 +7002,9 @@ } /* old bios, use older ordering */ tmp = 0; - for(i = position; i < ips_num_controllers; i++){ + 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_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1) { ips_shift_controllers(position, i); position++; tmp = 1; @@ -6707,11 +7013,11 @@ /* if there were no 5I cards, then don't do any extra ordering */ if (!tmp) return; - for(i = position; i < ips_num_controllers; i++){ + 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_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX) { ips_shift_controllers(position, i); position++; } @@ -6720,7 +7026,6 @@ return; } - /****************************************************************************/ /* */ /* Routine Name: ips_register_scsi */ @@ -6729,20 +7034,23 @@ /* perform any registration and setup with the scsi layer */ /****************************************************************************/ static int -ips_register_scsi( int index){ +ips_register_scsi(int index) +{ struct Scsi_Host *sh; ips_ha_t *ha, *oldha = ips_ha[index]; - sh = scsi_host_alloc(&ips_driver_template, sizeof(ips_ha_t)); - if(!sh) { - IPS_PRINTK(KERN_WARNING, oldha->pcidev, "Unable to register controller with SCSI subsystem\n"); + sh = scsi_host_alloc(&ips_driver_template, sizeof (ips_ha_t)); + if (!sh) { + IPS_PRINTK(KERN_WARNING, oldha->pcidev, + "Unable to register controller with SCSI subsystem\n"); return -1; } ha = IPS_HA(sh); - memcpy(ha, oldha, sizeof(ips_ha_t)); + 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)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to install interrupt handler\n" ); + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Unable to install interrupt handler\n"); scsi_host_put(sh); return -1; } @@ -6765,12 +7073,12 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) sh->max_sectors = 128; -#endif +#endif sh->max_id = ha->ntargets; sh->max_lun = ha->nlun; sh->max_channel = ha->nbus - 1; - sh->can_queue = ha->max_cmds-1; + sh->can_queue = ha->max_cmds - 1; IPS_ADD_HOST(sh, NULL); return 0; @@ -6782,22 +7090,23 @@ /* Routine Description: */ /* Remove one Adapter ( Hot Plugging ) */ /*---------------------------------------------------------------------------*/ -static void __devexit ips_remove_device(struct pci_dev *pci_dev) +static void __devexit +ips_remove_device(struct pci_dev *pci_dev) { - int i; - struct Scsi_Host *sh; - ips_ha_t *ha; - - for (i = 0; i < IPS_MAX_ADAPTERS; i++) { - ha = ips_ha[i]; - if (ha) { - if ( (pci_dev->bus->number == ha->pcidev->bus->number) && - (pci_dev->devfn == ha->pcidev->devfn)) { - sh = ips_sh[i]; - ips_release(sh); - } - } - } + int i; + struct Scsi_Host *sh; + ips_ha_t *ha; + + for (i = 0; i < IPS_MAX_ADAPTERS; i++) { + ha = ips_ha[i]; + if (ha) { + if ((pci_dev->bus->number == ha->pcidev->bus->number) && + (pci_dev->devfn == ha->pcidev->devfn)) { + sh = ips_sh[i]; + ips_release(sh); + } + } + } } /****************************************************************************/ @@ -6808,12 +7117,13 @@ /* function called on module load */ /****************************************************************************/ static int __init -ips_module_init(void){ - if( pci_module_init(&ips_pci_driver) < 0 ) +ips_module_init(void) +{ + if (pci_module_init(&ips_pci_driver) < 0) return -ENODEV; ips_driver_template.module = THIS_MODULE; ips_order_controllers(); - if( IPS_REGISTER_HOSTS(&ips_driver_template) ){ + if (IPS_REGISTER_HOSTS(&ips_driver_template)) { pci_unregister_driver(&ips_pci_driver); return -ENODEV; } @@ -6829,7 +7139,8 @@ /* function called on module unload */ /****************************************************************************/ static void __exit -ips_module_exit(void){ +ips_module_exit(void) +{ IPS_UNREGISTER_HOSTS(&ips_driver_template); pci_unregister_driver(&ips_pci_driver); unregister_reboot_notifier(&ips_notifier); @@ -6847,33 +7158,33 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) +static int __devinit +ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) { - int index; - int rc; + int index; + int rc; - METHOD_TRACE("ips_insert_device", 1); - if (pci_enable_device(pci_dev)) + METHOD_TRACE("ips_insert_device", 1); + if (pci_enable_device(pci_dev)) return -1; - rc = ips_init_phase1(pci_dev, &index); - if (rc == SUCCESS) - rc = ips_init_phase2(index); - - if(ips_hotplug) - if(ips_register_scsi(index)){ - ips_free(ips_ha[index]); - rc = -1; - } + rc = ips_init_phase1(pci_dev, &index); + if (rc == SUCCESS) + rc = ips_init_phase2(index); + + if (ips_hotplug) + if (ips_register_scsi(index)) { + ips_free(ips_ha[index]); + rc = -1; + } - if (rc == SUCCESS) - ips_num_controllers++; + if (rc == SUCCESS) + ips_num_controllers++; - ips_next_controller = ips_num_controllers; - return rc; + ips_next_controller = ips_num_controllers; + return rc; } - /*---------------------------------------------------------------------------*/ /* Routine Name: ips_init_phase1 */ /* */ @@ -6883,221 +7194,236 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) -{ - ips_ha_t *ha; - uint32_t io_addr; - uint32_t mem_addr; - uint32_t io_len; - uint32_t mem_len; - uint8_t revision_id; - uint8_t bus; - uint8_t func; - uint8_t irq; - uint16_t subdevice_id; - int j; - int index; - uint32_t count; - dma_addr_t dma_address; - char *ioremap_ptr; - char *mem_ptr; - uint32_t IsDead; - - METHOD_TRACE("ips_init_phase1", 1); - index = IPS_MAX_ADAPTERS; - for (j = 0; j < IPS_MAX_ADAPTERS; j++) { - if (ips_ha[j] ==0) { - index = j; - break; - } - } +static int +ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) +{ + ips_ha_t *ha; + uint32_t io_addr; + uint32_t mem_addr; + uint32_t io_len; + uint32_t mem_len; + uint8_t revision_id; + uint8_t bus; + uint8_t func; + uint8_t irq; + uint16_t subdevice_id; + int j; + int index; + dma_addr_t dma_address; + char *ioremap_ptr; + char *mem_ptr; + uint32_t IsDead; + + METHOD_TRACE("ips_init_phase1", 1); + index = IPS_MAX_ADAPTERS; + for (j = 0; j < IPS_MAX_ADAPTERS; j++) { + if (ips_ha[j] == 0) { + index = j; + break; + } + } - if (index >= IPS_MAX_ADAPTERS) - return -1; - - /* stuff that we get in dev */ - irq = pci_dev->irq; - bus = pci_dev->bus->number; - func = pci_dev->devfn; - - /* Init MEM/IO addresses to 0 */ - mem_addr = 0; - io_addr = 0; - mem_len = 0; - io_len = 0; - - for (j = 0; j < 2; j++) { - if (!pci_resource_start(pci_dev, j)) - break; - - if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) { - io_addr = pci_resource_start(pci_dev, j); - io_len = pci_resource_len(pci_dev, j); - } else { - mem_addr = pci_resource_start(pci_dev, j); - mem_len = pci_resource_len(pci_dev, j); - } - } - - /* setup memory mapped area (if applicable) */ - if (mem_addr) { - uint32_t base; - uint32_t offs; - - if (!request_mem_region(mem_addr, mem_len, "ips")) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Couldn't allocate IO Memory space %x len %d.\n", mem_addr, mem_len); - return -1; - } - - base = mem_addr & PAGE_MASK; - offs = mem_addr - base; - ioremap_ptr = ioremap(base, PAGE_SIZE); - mem_ptr = ioremap_ptr + offs; - } else { - ioremap_ptr = NULL; - mem_ptr = NULL; - } - - /* setup I/O mapped area (if applicable) */ - if (io_addr) { - if (!request_region(io_addr, io_len, "ips")) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Couldn't allocate IO space %x len %d.\n", io_addr, io_len); - return -1; - } - } - - /* get the revision ID */ - if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Can't get revision id.\n"); - return -1; - } - - subdevice_id = pci_dev->subsystem_device; - - /* found a controller */ - ha = kmalloc(sizeof(ips_ha_t), GFP_KERNEL); - if (ha == NULL) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate temporary ha struct\n"); - return -1; - } - - memset(ha, 0, sizeof(ips_ha_t)); - - ips_sh[index] = NULL; - ips_ha[index] = ha; - ha->active = 1; - - /* 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, 0xffffffffffffffffULL)) { - (ha)->flags |= IPS_HA_ENH_SG; - } else { - if ( pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0 ) { - printk(KERN_WARNING "Unable to set DMA Mask\n"); - return ips_abort_init(ha, index); - } - } - - ha->enq = kmalloc(sizeof(IPS_ENQ), IPS_INIT_GFP); - - if (!ha->enq) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host inquiry structure\n" ); - 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) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host adapt & dummy structures\n"); - 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), IPS_INIT_GFP); - - if (!ha->conf) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host conf structure\n"); - return ips_abort_init(ha, index); - } - - ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), IPS_INIT_GFP); - - if (!ha->nvram) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host NVRAM structure\n"); - return ips_abort_init(ha, index); - } - - ha->subsys = kmalloc(sizeof(IPS_SUBSYS), IPS_INIT_GFP); - - if (!ha->subsys) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host subsystem structure\n"); - 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(IPS_INIT_GFP, ha->ioctl_order); - ha->ioctl_datasize = count; - - if (!ha->ioctl_data) { - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate IOCTL data\n"); - ha->ioctl_data = NULL; - ha->ioctl_order = 0; - ha->ioctl_datasize = 0; - } - - /* - * Setup Functions - */ - ips_setup_funclist(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 - */ - - if (!(*ha->func.isinit)(ha)) { - if (!(*ha->func.init)(ha)) { - /* - * Initialization failed - */ - IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to initialize controller\n"); - return ips_abort_init(ha, index); - } - } + if (index >= IPS_MAX_ADAPTERS) + return -1; + + /* stuff that we get in dev */ + irq = pci_dev->irq; + bus = pci_dev->bus->number; + func = pci_dev->devfn; + + /* Init MEM/IO addresses to 0 */ + mem_addr = 0; + io_addr = 0; + mem_len = 0; + io_len = 0; + + for (j = 0; j < 2; j++) { + if (!pci_resource_start(pci_dev, j)) + break; + + if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) { + io_addr = pci_resource_start(pci_dev, j); + io_len = pci_resource_len(pci_dev, j); + } else { + mem_addr = pci_resource_start(pci_dev, j); + mem_len = pci_resource_len(pci_dev, j); + } + } - *indexPtr = index; - return SUCCESS; + /* setup memory mapped area (if applicable) */ + if (mem_addr) { + uint32_t base; + uint32_t offs; + + if (!request_mem_region(mem_addr, mem_len, "ips")) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Couldn't allocate IO Memory space %x len %d.\n", + mem_addr, mem_len); + return -1; + } + + base = mem_addr & PAGE_MASK; + offs = mem_addr - base; + ioremap_ptr = ioremap(base, PAGE_SIZE); + mem_ptr = ioremap_ptr + offs; + } else { + ioremap_ptr = NULL; + mem_ptr = NULL; + } + + /* setup I/O mapped area (if applicable) */ + if (io_addr) { + if (!request_region(io_addr, io_len, "ips")) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Couldn't allocate IO space %x len %d.\n", + io_addr, io_len); + return -1; + } + } + + /* get the revision ID */ + if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) { + IPS_PRINTK(KERN_WARNING, pci_dev, "Can't get revision id.\n"); + return -1; + } + + subdevice_id = pci_dev->subsystem_device; + + /* found a controller */ + ha = kmalloc(sizeof (ips_ha_t), GFP_KERNEL); + if (ha == NULL) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate temporary ha struct\n"); + return -1; + } + + memset(ha, 0, sizeof (ips_ha_t)); + + ips_sh[index] = NULL; + ips_ha[index] = ha; + ha->active = 1; + + /* 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, 0xffffffffffffffffULL)) { + (ha)->flags |= IPS_HA_ENH_SG; + } else { + if (pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0) { + printk(KERN_WARNING "Unable to set DMA Mask\n"); + return ips_abort_init(ha, index); + } + } + if(ips_cd_boot && !ips_FlashData){ + ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7, + &ips_flashbusaddr); + } + + ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ), + &ha->enq_busaddr); + if (!ha->enq) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate host inquiry structure\n"); + 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) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate host adapt & dummy structures\n"); + 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); + + if (!ha->conf) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate host conf structure\n"); + return ips_abort_init(ha, index); + } + + ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL); + + if (!ha->nvram) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate host NVRAM structure\n"); + return ips_abort_init(ha, index); + } + + ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL); + + if (!ha->subsys) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate host subsystem structure\n"); + return ips_abort_init(ha, index); + } + + /* the ioctl buffer is now used during adapter initialization, so its + * successful allocation is now required */ + if (ips_ioctlsize < PAGE_SIZE) + ips_ioctlsize = PAGE_SIZE; + + ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize, + &ha->ioctl_busaddr); + ha->ioctl_len = ips_ioctlsize; + if (!ha->ioctl_data) { + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to allocate IOCTL data\n"); + return ips_abort_init(ha, index); + } + + /* + * Setup Functions + */ + ips_setup_funclist(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 + */ + + if (!(*ha->func.isinit) (ha)) { + if (!(*ha->func.init) (ha)) { + /* + * Initialization failed + */ + IPS_PRINTK(KERN_WARNING, pci_dev, + "Unable to initialize controller\n"); + return ips_abort_init(ha, index); + } + } + + *indexPtr = index; + return SUCCESS; } /*---------------------------------------------------------------------------*/ @@ -7109,52 +7435,56 @@ /* Return Value: */ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ -static int ips_init_phase2( int index ) -{ - ips_ha_t *ha; - - ha = ips_ha[index]; - - METHOD_TRACE("ips_init_phase2", 1); - if (!ha->active) { - ips_ha[index] = NULL; - return -1; - } - - /* Install the interrupt handler */ - if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "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)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to allocate a CCB\n"); - free_irq(ha->irq, ha); - return ips_abort_init(ha, index); - } - - if (!ips_hainit(ha)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to initialize controller\n"); - free_irq(ha->irq, ha); - return ips_abort_init(ha, index); - } - /* Free the temporary SCB */ - ips_deallocatescbs(ha, 1); - - /* allocate CCBs */ - if (!ips_allocatescbs(ha)) { - IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to allocate CCBs\n"); - free_irq(ha->irq, ha); - return ips_abort_init(ha, index); - } +static int +ips_init_phase2(int index) +{ + ips_ha_t *ha; - return SUCCESS; -} + ha = ips_ha[index]; + METHOD_TRACE("ips_init_phase2", 1); + if (!ha->active) { + ips_ha[index] = NULL; + return -1; + } + + /* Install the interrupt handler */ + if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "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)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Unable to allocate a CCB\n"); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); + } + + if (!ips_hainit(ha)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Unable to initialize controller\n"); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); + } + /* Free the temporary SCB */ + ips_deallocatescbs(ha, 1); + + /* allocate CCBs */ + if (!ips_allocatescbs(ha)) { + IPS_PRINTK(KERN_WARNING, ha->pcidev, + "Unable to allocate CCBs\n"); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); + } + + return SUCCESS; +} #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) MODULE_LICENSE("GPL"); diff -Nru a/drivers/scsi/ips.h b/drivers/scsi/ips.h --- a/drivers/scsi/ips.h Mon Aug 18 22:21:02 2003 +++ b/drivers/scsi/ips.h Mon Aug 18 22:21:02 2003 @@ -106,8 +106,10 @@ #define IPS_REMOVE_HOST(shost) #define IPS_SCSI_SET_DEVICE(sh,ha) scsi_set_pci_device(sh, (ha)->pcidev) #define IPS_PRINTK(level, pcidev, format, arg...) \ - printk(level "%s %s:" format , (pcidev)->driver->name , \ - pci_name(pcidev) , ## arg) + printk(level "%s %s:" format , "ips" , \ + (pcidev)->slot_name , ## arg) + #define scsi_host_alloc(sh,size) scsi_register(sh,size) + #define scsi_host_put(sh) scsi_unregister(sh) #else #define IPS_REGISTER_HOSTS(SHT) (!ips_detect(SHT)) #define IPS_UNREGISTER_HOSTS(SHT) @@ -126,22 +128,13 @@ #define min(x,y) ((x) < (y) ? x : y) #endif + #define pci_dma_hi32(a) ((a >> 16) >> 16) #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 /* @@ -451,9 +444,11 @@ * Scsi_Host Template */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + static int ips_proc24_info(char *, char **, off_t, int, int, int); static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]); #else + int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); int ips_slave_configure(Scsi_Device *SDptr); @@ -1106,7 +1101,8 @@ uint16_t device_id; /* PCI device ID */ uint8_t slot_num; /* PCI Slot Number */ uint16_t subdevice_id; /* Subsystem device ID */ - uint8_t ioctl_order; /* Number of pages in ioctl */ + int ioctl_len; /* size of ioctl buffer */ + dma_addr_t ioctl_busaddr; /* dma address of ioctl buffer*/ uint8_t bios_version[8]; /* BIOS Revision */ uint32_t mem_addr; /* Memory mapped address */ uint32_t io_len; /* Size of IO Address */ @@ -1116,8 +1112,10 @@ 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 */ + int flash_len; /* length of flash buffer */ u32 flash_datasize; /* Save Area for flash data size */ + dma_addr_t flash_busaddr; /* dma address of flash buffer*/ + dma_addr_t enq_busaddr; /* dma address of enq struct */ uint8_t requires_esl; /* Requires an EraseStripeLock */ } ips_ha_t; @@ -1203,25 +1201,29 @@ * *************************************************************************/ -#define IPS_VER_MAJOR 5 -#define IPS_VER_MAJOR_STRING "5" -#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 +#define IPS_VER_MAJOR 6 +#define IPS_VER_MAJOR_STRING "6" +#define IPS_VER_MINOR 10 +#define IPS_VER_MINOR_STRING "10" +#define IPS_VER_BUILD 90 +#define IPS_VER_BUILD_STRING "90" +#define IPS_VER_STRING "6.10.90" +#define IPS_RELEASE_ID 0x00010000 +#define IPS_BUILD_IDENT 364 +#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved." +#define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved." +#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003." /* 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.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" +#define IPS_VER_SERVERAID3 "6.10.24" +#define IPS_VER_SERVERAID4H "6.10.24" +#define IPS_VER_SERVERAID4MLx "6.10.24" +#define IPS_VER_SARASOTA "6.10.24" +#define IPS_VER_MARCO "6.10.24" +#define IPS_VER_SEBRING "6.10.24" /* Compatability IDs for various adapters */ #define IPS_COMPAT_UNKNOWN "" @@ -1230,17 +1232,17 @@ #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_MARCO "SA000" -#define IPS_COMPAT_SEBRING "SA000" -#define IPS_COMPAT_BIOS "SA510" +#define IPS_COMPAT_SERVERAID3H "SB610" +#define IPS_COMPAT_SERVERAID3L "SB610" +#define IPS_COMPAT_SERVERAID4H "SB610" +#define IPS_COMPAT_SERVERAID4M "SB610" +#define IPS_COMPAT_SERVERAID4L "SB610" +#define IPS_COMPAT_SERVERAID4Mx "SB610" +#define IPS_COMPAT_SERVERAID4Lx "SB610" +#define IPS_COMPAT_SARASOTA "SB610" +#define IPS_COMPAT_MARCO "SB610" +#define IPS_COMPAT_SEBRING "SB610" +#define IPS_COMPAT_BIOS "SB610" #define IPS_COMPAT_MAX_ADAPTER_TYPE 16 #define IPS_COMPAT_ID_LENGTH 8 diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c --- a/drivers/scsi/lasi700.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/lasi700.c Mon Aug 18 22:21:01 2003 @@ -86,14 +86,10 @@ struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; - snprintf(dev->dev.name, sizeof(dev->dev.name), "%s", - (dev->id.sversion == LASI_700_SVERSION) ? - "lasi700" : "lasi710"); - hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL); if (!hostdata) { printk(KERN_ERR "%s: Failed to allocate host data\n", - dev->dev.name); + dev->dev.bus_id); return 1; } memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); @@ -121,9 +117,9 @@ host->irq = dev->irq; if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, - dev->dev.name, host)) { + dev->dev.bus_id, host)) { printk(KERN_ERR "%s: irq problem, detaching\n", - dev->dev.name); + dev->dev.bus_id); goto out_put_host; } diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Mon Aug 18 22:21:00 2003 +++ b/drivers/scsi/megaraid.c Mon Aug 18 22:21:00 2003 @@ -2275,8 +2275,7 @@ if( !cmd->use_sg ) { page = virt_to_page(cmd->request_buffer); - - offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK); + offset = offset_in_page(cmd->request_buffer); scb->dma_h_bulkdata = pci_map_page(adapter->dev, page, offset, @@ -5361,7 +5360,6 @@ .eh_device_reset_handler = megaraid_reset, .eh_bus_reset_handler = megaraid_reset, .eh_host_reset_handler = megaraid_reset, - .highmem_io = 1, }; #include "scsi_module.c" diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c --- a/drivers/scsi/pcmcia/aha152x_stub.c Mon Aug 18 22:21:05 2003 +++ b/drivers/scsi/pcmcia/aha152x_stub.c Mon Aug 18 22:21:05 2003 @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -102,7 +101,7 @@ struct Scsi_Host *host; } scsi_info_t; -static void aha152x_release_cs(u_long arg); +static void aha152x_release_cs(dev_link_t *link); static int aha152x_event(event_t event, int priority, event_callback_args_t *args); @@ -126,9 +125,6 @@ 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; link->io.NumPorts1 = 0x20; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -181,14 +177,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); - if (link->state & DEV_CONFIG) { - aha152x_release_cs((u_long)link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } - } + if (link->state & DEV_CONFIG) + aha152x_release_cs(link); if (link->handle) CardServices(DeregisterClient, link->handle); @@ -290,13 +280,12 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); - aha152x_release_cs((u_long)link); + aha152x_release_cs(link); return; } -static void aha152x_release_cs(u_long arg) +static void aha152x_release_cs(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; scsi_info_t *info = link->priv; scsi_remove_host(info->host); @@ -308,9 +297,6 @@ link->state &= ~DEV_CONFIG; scsi_unregister(info->host); - - if (link->state & DEV_STALE_LINK) - aha152x_detach(link); } static int aha152x_event(event_t event, int priority, @@ -325,7 +311,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + aha152x_release_cs(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c --- a/drivers/scsi/pcmcia/fdomain_stub.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/pcmcia/fdomain_stub.c Mon Aug 18 22:21:04 2003 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -90,7 +89,7 @@ extern struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ); extern int fdomain_16x0_bus_reset(Scsi_Cmnd *SCpnt); -static void fdomain_release(u_long arg); +static void fdomain_release(dev_link_t *link); static int fdomain_event(event_t event, int priority, event_callback_args_t *args); @@ -116,10 +115,6 @@ 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; - link->io.NumPorts1 = 0x10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; @@ -171,14 +166,8 @@ if (*linkp == NULL) return; - del_timer(&link->release); - if (link->state & DEV_CONFIG) { - fdomain_release((u_long)link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } - } + if (link->state & DEV_CONFIG) + fdomain_release(link); if (link->handle) CardServices(DeregisterClient, link->handle); @@ -266,16 +255,15 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); - fdomain_release((u_long)link); + fdomain_release(link); return; } /* fdomain_config */ /*====================================================================*/ -static void fdomain_release(u_long arg) +static void fdomain_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; scsi_info_t *info = link->priv; DEBUG(0, "fdomain_release(0x%p)\n", link); @@ -290,9 +278,7 @@ scsi_unregister(info->host); link->state &= ~DEV_CONFIG; - if (link->state & DEV_STALE_LINK) - fdomain_detach(link); -} /* fdomain_release */ +} /*====================================================================*/ @@ -307,7 +293,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); + fdomain_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c --- a/drivers/scsi/pcmcia/nsp_cs.c Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/pcmcia/nsp_cs.c Mon Aug 18 22:21:06 2003 @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -1477,10 +1476,6 @@ link = &info->link; link->priv = info; - /* Initialize the dev_link_t structure */ - link->release.function = &nsp_cs_release; - link->release.data = (u_long)link; - /* The io structure describes IO port mapping */ link->io.NumPorts1 = 0x10; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -1558,19 +1553,12 @@ return; } - del_timer(&link->release); - if (link->state & DEV_CONFIG) { - nsp_cs_release((u_long)link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } - } + if (link->state & DEV_CONFIG) + nsp_cs_release(link); /* Break the link with Card Services */ - if (link->handle) { + if (link->handle) CardServices(DeregisterClient, link->handle); - } /* Unlink device structure, free bits */ *linkp = link->next; @@ -1780,7 +1768,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); - nsp_cs_release((u_long)link); + nsp_cs_release(link); return; } /* nsp_cs_config */ @@ -1792,24 +1780,12 @@ device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. ======================================================================*/ -static void nsp_cs_release(u_long arg) +static void nsp_cs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; scsi_info_t *info = link->priv; DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link); - /* - * If the device is currently in use, we won't release until it - * is actually closed. - */ - if (link->open) { - DEBUG(1, "nsp_cs: release postponed, '%s' still open\n", - link->dev->dev_name); - link->state |= DEV_STALE_CONFIG; - return; - } - /* Unlink the device chain */ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,2)) scsi_unregister_module(MODULE_SCSI_HA, &nsp_driver_template); @@ -1831,11 +1807,7 @@ CardServices(ReleaseIRQ, link->handle, &link->irq); } link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) { - nsp_cs_detach(link); - } -} /* nsp_cs_release */ +} /*====================================================================== @@ -1866,7 +1838,7 @@ link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { ((scsi_info_t *)link->priv)->stop = 1; - mod_timer(&link->release, jiffies + HZ/20); + nsp_cs_release(link); } break; @@ -1933,7 +1905,7 @@ /* XXX: this really needs to move into generic code.. */ while (dev_list != NULL) { if (dev_list->state & DEV_CONFIG) { - nsp_cs_release((u_long)dev_list); + nsp_cs_release(dev_list); } nsp_cs_detach(dev_list); } diff -Nru a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h --- a/drivers/scsi/pcmcia/nsp_cs.h Mon Aug 18 22:21:02 2003 +++ b/drivers/scsi/pcmcia/nsp_cs.h Mon Aug 18 22:21:02 2003 @@ -272,7 +272,7 @@ -static void nsp_cs_release(u_long arg); +static void nsp_cs_release(dev_link_t *link); static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args); static dev_link_t *nsp_cs_attach(void); static void nsp_cs_detach(dev_link_t *); diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c --- a/drivers/scsi/pcmcia/qlogic_stub.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/pcmcia/qlogic_stub.c Mon Aug 18 22:21:03 2003 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -90,7 +89,7 @@ unsigned short manf_id; } scsi_info_t; -static void qlogic_release(u_long arg); +static void qlogic_release(dev_link_t *link); static int qlogic_event(event_t event, int priority, event_callback_args_t * args); static dev_link_t *qlogic_attach(void); @@ -117,10 +116,6 @@ 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; - link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; @@ -170,14 +165,8 @@ if (*linkp == NULL) return; - del_timer_sync(&link->release); - if (link->state & DEV_CONFIG) { - qlogic_release((u_long) link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } - } + if (link->state & DEV_CONFIG) + qlogic_release(link); if (link->handle) CardServices(DeregisterClient, link->handle); @@ -279,16 +268,15 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); - qlogic_release((u_long) link); + qlogic_release(link); return; } /* qlogic_config */ /*====================================================================*/ -static void qlogic_release(u_long arg) +static void qlogic_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *) arg; scsi_info_t *info = link->priv; DEBUG(0, "qlogic_release(0x%p)\n", link); @@ -303,9 +291,7 @@ scsi_unregister(info->host); link->state &= ~DEV_CONFIG; - if (link->state & DEV_STALE_LINK) - qlogic_detach(link); -} /* qlogic_release */ +} /*====================================================================*/ @@ -319,7 +305,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ / 20); + qlogic_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c --- a/drivers/scsi/ppa.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/ppa.c Mon Aug 18 22:21:04 2003 @@ -76,6 +76,7 @@ int host_no = host->unique_id; printk("Releasing ppa%i\n", host_no); + scsi_unregister(host); parport_unregister_device(ppa_hosts[host_no].dev); return 0; } diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/qla1280.c Mon Aug 18 22:21:06 2003 @@ -3,7 +3,7 @@ * * QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver * Copyright (C) 2000 Qlogic Corporation (www.qlogic.com) -* Copyright (C) 2001-2002 Jes Sorensen, Wild Open Source Inc. +* Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source 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 the @@ -16,9 +16,54 @@ * General Public License for more details. * ******************************************************************************/ -#define QLA1280_VERSION "3.23.19 Beta" -/****************************************************************************** +#define QLA1280_VERSION "3.23.35" +/***************************************************************************** Revision History: + Rev 3.23.35 August 14, 2003, Jes Sorensen + - Build against 2.6 + Rev 3.23.34 July 23, 2003, Jes Sorensen + - Remove pointless TRUE/FALSE macros + - Clean up vchan handling + Rev 3.23.33 July 3, 2003, Jes Sorensen + - Don't define register access macros before define determining MMIO. + This just happend to work out on ia64 but not elsewhere. + - Don't try and read from the card while it is in reset as + it won't respond and causes an MCA + Rev 3.23.32 June 23, 2003, Jes Sorensen + - Basic support for boot time arguments + Rev 3.23.31 June 8, 2003, Jes Sorensen + - Reduce boot time messages + Rev 3.23.30 June 6, 2003, Jes Sorensen + - Do not enable sync/wide/ppr before it has been determined + that the target device actually supports it + - Enable DMA arbitration for multi channel controllers + Rev 3.23.29 June 3, 2003, Jes Sorensen + - Port to 2.5.69 + Rev 3.23.28 June 3, 2003, Jes Sorensen + - Eliminate duplicate marker commands on bus resets + - Handle outstanding commands appropriately on bus/device resets + Rev 3.23.27 May 28, 2003, Jes Sorensen + - Remove bogus input queue code, let the Linux SCSI layer do the work + - Clean up NVRAM handling, only read it once from the card + - Add a number of missing default nvram parameters + Rev 3.23.26 Beta May 28, 2003, Jes Sorensen + - Use completion queue for mailbox commands instead of busy wait + Rev 3.23.25 Beta May 27, 2003, James Bottomley + - Migrate to use new error handling code + Rev 3.23.24 Beta May 21, 2003, James Bottomley + - Big endian support + - Cleanup data direction code + Rev 3.23.23 Beta May 12, 2003, Jes Sorensen + - Switch to using MMIO instead of PIO + Rev 3.23.22 Beta April 15, 2003, Jes Sorensen + - Fix PCI parity problem with 12160 during reset. + Rev 3.23.21 Beta April 14, 2003, Jes Sorensen + - Use pci_map_page()/pci_unmap_page() instead of map_single version. + Rev 3.23.20 Beta April 9, 2003, Jes Sorensen + - Remove < 2.4.x support + - Introduce HOST_LOCK to make the spin lock changes portable. + - Remove a bunch of idiotic and unnecessary typedef's + - Kill all leftovers of target-mode support which never worked anyway Rev 3.23.19 Beta April 11, 2002, Linus Torvalds - Do qla1280_pci_config() before calling request_irq() and request_region() @@ -107,8 +152,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 dependent device probe code - - Move duplicate probe/init code to separate function + - Reduce size of kernel version dependant device probe code + - Move duplicate probe/init code to seperate 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) @@ -131,14 +176,14 @@ - Added check of device_id when handling non QLA12160s during detect(). Rev 3.22 Beta January 5, 2001 BN Qlogic - - Changed queue_task() to schedule_work() + - Changed queue_task() to schedule_task() for kernels 2.4.0 and higher. Note: 2.4.0-testxx kernels released prior to the actual 2.4.0 kernel release on January 2001 - will get compile/link errors with schedule_work(). + will get compile/link errors with schedule_task(). Please update your kernel to released 2.4.0 level, or comment lines in this file flagged with 3.22 - to resolve compile/link error of schedule_work(). + to resolve compile/link error of schedule_task(). - Added -DCONFIG_SMP in addition to -D__SMP__ in Makefile for 2.4.0 builds of driver as module. Rev 3.21 Beta January 4, 2001 BN Qlogic @@ -238,6 +283,7 @@ - Initial Beta Release. *****************************************************************************/ + #include #include @@ -246,56 +292,55 @@ #include #include #include -#include #include #include #include +#include #include #include -#include -#include #include #include +#include +#include +#include #include #include #include #include +#include +#include -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#if LINUX_VERSION_CODE < 0x020545 +#include +#include "sd.h" +#else +#include #endif +#include "scsi.h" +#include "hosts.h" -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) -#include +#if LINUX_VERSION_CODE < 0x020407 +#error "Kernels older than 2.4.7 are no longer supported" #endif -#include "scsi.h" -#include "hosts.h" -#define UNIQUE_FW_NAME -#include "qla1280.h" -#include "ql12160_fw.h" /* ISP RISC codes */ -#include "ql1280_fw.h" /* * Compile time Options: * 0 - Disable and 1 - Enable */ -#define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */ -#define QL1280_LUN_SUPPORT 0 -#define WATCHDOGTIMER 0 -#define MEMORY_MAPPED_IO 0 -#define DEBUG_QLA1280_INTR 0 -#define USE_NVRAM_DEFAULTS 0 -#define DEBUG_PRINT_NVRAM 0 -#define LOADING_RISC_ACTIVITY 0 -#define AUTO_ESCALATE_RESET 0 /* Automatically escalate resets */ -#define AUTO_ESCALATE_ABORT 0 /* Automatically escalate aborts */ -#define STOP_ON_ERROR 0 /* Stop on aborts and resets */ -#define STOP_ON_RESET 0 -#define STOP_ON_ABORT 0 -#define QLA1280_PROFILE 1 /* 3.20 */ -#define DEBUG_QLA1280 0 +#define QL1280_LUN_SUPPORT 0 +#define WATCHDOGTIMER 0 +#define MEMORY_MAPPED_IO 1 +#define DEBUG_QLA1280_INTR 0 +#define DEBUG_PRINT_NVRAM 0 +#define DEBUG_QLA1280 0 + +#define UNIQUE_FW_NAME +#include "qla1280.h" +#include "ql12160_fw.h" /* ISP RISC codes */ +#include "ql1280_fw.h" + /* * Missing PCI ID's @@ -320,97 +365,65 @@ #define PCI_VENDOR_ID_AMI 0x101e #endif +#ifndef BITS_PER_LONG +#error "BITS_PER_LONG not defined!" +#endif #if (BITS_PER_LONG == 64) || defined CONFIG_HIGHMEM #define QLA_64BIT_PTR 1 #endif -/* 3.16 */ -#ifdef QLA_64BIT_PTR -#define pci_dma_lo32(a) (a & 0xffffffff) -#define pci_dma_hi32(a) ((a >> 16)>>16) -#else -#define pci_dma_lo32(a) (a & 0xffffffff) -#define pci_dma_hi32(a) 0 +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) +#include +/* Ugly hack needed for the virtual channel fix on SN2 */ +extern int snia_pcibr_rrb_alloc(struct pci_dev *pci_dev, + int *count_vchan0, int *count_vchan1); #endif -/* MACROS for managing the endian addresses */ -static inline uint16_t qla1280_addr0_15(dma_addr_t dma) -{ - return ((uint16_t)(dma & 0xffff)); -} -static inline uint16_t qla1280_addr16_31(dma_addr_t dma) -{ - return ((uint16_t)((dma >> 16) & 0xffff)); -} -static inline uint16_t qla1280_addr32_47(dma_addr_t dma) -{ - return ((uint16_t)(pci_dma_hi32(dma) & 0xffff)); -} -static inline uint16_t qla1280_addr48_63(dma_addr_t dma) -{ - return ((uint16_t)((pci_dma_hi32(dma) >> 16) & 0xffff)); -} -#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */ - -#define CACHE_FLUSH(a) RD_REG_WORD(a) -#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 1) - -/* - * Compat macros - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) -#define pci_set_dma_mask(dev, mask) dev->dma_mask = mask; -#define pci_enable_device(pdev) 0 -#define pci_find_subsys(id, dev, sid, sdev, pdev) pci_find_device(id,dev,pdev) -#define scsi_set_pci_device(host, pdev) +#ifdef QLA_64BIT_PTR +#define pci_dma_hi32(a) ((a >> 16) >> 16) +#else +#define pci_dma_hi32(a) 0 #endif +#define pci_dma_lo32(a) (a & 0xffffffff) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) -typedef unsigned long dma_addr_t; +#define NVRAM_DELAY() udelay(500) /* 2 microseconds */ -static inline void * -pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t * dma_handle) +#if LINUX_VERSION_CODE < 0x020500 +#define HOST_LOCK &io_request_lock +#define irqreturn_t void +#define IRQ_RETVAL(foo) +#define MSG_ORDERED_TAG 1 +static inline void +scsi_adjust_queue_depth(Scsi_Device *device, int tag, int depth) { - void *virt_ptr; - - virt_ptr = kmalloc(size, GFP_KERNEL); - if (!virt_ptr) - return NULL; - *dma_handle = virt_to_bus(virt_ptr); - return virt_ptr; + if (tag) { + device->tagged_queue = tag; + device->current_tag = 0; + } + device->queue_depth = depth; } - -#define pci_free_consistent(cookie, size, ptr, dma_ptr) kfree(ptr) -#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -#define pci_map_sg(cookie, scatter, ents, dir) ents -#define pci_unmap_single(cookie, address, size, dir) -#define pci_unmap_sg(cookie, scatter, ents, dir) - -#define pci_resource_start(dev, i) dev->base_address[i] +#else +#define HOST_LOCK ha->host->host_lock +#endif +#if defined(__ia64__) && !defined(ia64_platform_is) +#define ia64_platform_is(foo) (!strcmp(x, platform_name)) #endif /* * QLogic Driver Support Function Prototypes. */ -static void qla1280_done(struct scsi_qla_host *, srb_t **, srb_t **); -static void qla1280_next(struct scsi_qla_host *, scsi_lu_t *, int); -static void qla1280_putq_t(scsi_lu_t *, srb_t *); -static void qla1280_done_q_put(srb_t *, srb_t **, srb_t **); +static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **); +static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **); static int qla1280_slave_configure(Scsi_Device *); -#if STOP_ON_ERROR -static void qla1280_panic(char *, struct Scsi_Host *host); +#if LINUX_VERSION_CODE < 0x020545 +static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *); +void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *); #endif -static void qla1280_abort_queue_single(struct scsi_qla_host *, int, int, - int, uint32_t); -static int qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp); -static void qla1280_removeq(scsi_lu_t * q, srb_t * sp); +static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp); static void qla1280_mem_free(struct scsi_qla_host *ha); void qla1280_do_dpc(void *p); -#ifdef MODULE -static char *qla1280_get_token(char *, char *); -#endif +static int qla1280_get_token(char *); static inline void qla1280_enable_intrs(struct scsi_qla_host *); static inline void qla1280_disable_intrs(struct scsi_qla_host *); @@ -418,7 +431,6 @@ * QLogic ISP1280 Hardware Support Function Prototypes. */ static int qla1280_initialize_adapter(struct scsi_qla_host *ha); -static int qla1280_enable_tgt(struct scsi_qla_host *, int); static int qla1280_isp_firmware(struct scsi_qla_host *); static int qla1280_pci_config(struct scsi_qla_host *); static int qla1280_chip_diag(struct scsi_qla_host *); @@ -430,23 +442,22 @@ static int qla1280_bus_reset(struct scsi_qla_host *, int); static int qla1280_device_reset(struct scsi_qla_host *, int, int); static int qla1280_abort_device(struct scsi_qla_host *, int, int, int); -static int qla1280_abort_command(struct scsi_qla_host *, srb_t *); +static int qla1280_abort_command(struct scsi_qla_host *, struct srb *, int); static int qla1280_abort_isp(struct scsi_qla_host *); -static int qla1280_64bit_start_scsi(struct scsi_qla_host *, srb_t *); -static int qla1280_32bit_start_scsi(struct scsi_qla_host *, srb_t *); +static int qla1280_64bit_start_scsi(struct scsi_qla_host *, struct srb *); +static int qla1280_32bit_start_scsi(struct scsi_qla_host *, struct srb *); static void qla1280_nv_write(struct scsi_qla_host *, uint16_t); static void qla1280_poll(struct scsi_qla_host *); static void qla1280_reset_adapter(struct scsi_qla_host *); static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8); static void qla1280_isp_cmd(struct scsi_qla_host *); -static void qla1280_isr(struct scsi_qla_host *, srb_t **, srb_t **); +irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *); +static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **); static void qla1280_rst_aen(struct scsi_qla_host *); -static void qla1280_status_entry(struct scsi_qla_host *, sts_entry_t *, - srb_t **, srb_t **); -static void qla1280_error_entry(struct scsi_qla_host *, response_t *, - srb_t **, srb_t **); -static void qla1280_restart_queues(struct scsi_qla_host *); -static void qla1280_abort_queues(struct scsi_qla_host *); +static void qla1280_status_entry(struct scsi_qla_host *, struct response *, + struct srb **, struct srb **); +static void qla1280_error_entry(struct scsi_qla_host *, struct response *, + struct srb **, struct srb **); static uint16_t qla1280_get_nvram_word(struct scsi_qla_host *, uint32_t); static uint16_t qla1280_nvram_request(struct scsi_qla_host *, uint32_t); static uint16_t qla1280_debounce_register(volatile uint16_t *); @@ -456,9 +467,14 @@ static int qla1280_mem_alloc(struct scsi_qla_host *ha); static void qla12160_get_target_parameters(struct scsi_qla_host *, - uint32_t, uint32_t, uint32_t); + Scsi_Device *); +static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int); + + +static struct qla_driver_setup driver_setup __initdata; -/* convert scsi data direction to request_t control flags +/* + * convert scsi data direction to request_t control flags */ static inline uint16_t qla1280_data_direction(struct scsi_cmnd *cmnd) @@ -491,58 +507,26 @@ static void qla1280_enable_lun(struct scsi_qla_host *, int, int); #endif -#if QL1280_TARGET_MODE_SUPPORT -static void qla1280_notify_ack(struct scsi_qla_host *, notify_entry_t *); -static void qla1280_immed_notify(struct scsi_qla_host *, notify_entry_t *); -static void qla1280_accept_io(struct scsi_qla_host *, ctio_ret_entry_t *); -static void qla1280_64bit_continue_io(struct scsi_qla_host *, atio_entry_t *, - uint32_t, paddr32_t *); -static void qla1280_32bit_continue_io(struct scsi_qla_host *, atio_entry_t *, - uint32_t, paddr32_t *); -static void qla1280_atio_entry(struct scsi_qla_host *, atio_entry_t *); -static void qla1280_notify_entry(struct scsi_qla_host *, notify_entry_t *); -#endif /* QLA1280_TARGET_MODE_SUPPORT */ - -#ifdef QL_DEBUG_ROUTINES -/* - * Driver Debug Function Prototypes. - */ -static u8 qla1280_getbyte(u8 *); -static u16 qla1280_getword(u16 *); -static u32 qla1280_getdword(u32 *); -static void qla1280_putbyte(u8 *, u8); -static void qla1280_putword(u16 *, u8); -static void qla1280_putdword(u32 *, u32); +#if DEBUG_QLA1280 static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd); -static void __qla1280_dump_buffer(char *, u32); +static void __qla1280_dump_buffer(char *, int); #endif + /* * insmod needs to find the variable and make it point to something */ #ifdef MODULE -static char *options = NULL; +static char *qla1280; /* insmod qla1280 options=verbose" */ -MODULE_PARM(options, "s"); +MODULE_PARM(qla1280, "s"); +#else +__setup("qla1280=", qla1280_setup); #endif MODULE_LICENSE("GPL"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) -/* - * Our directory Entry in /proc/scsi for the user to - * access the driver. - */ -/* Need to add in proc_fs.h PROC_SCSI_QL1280 */ -#define PROC_SCSI_QL1280 PROC_SCSI_QLOGICISP - -struct proc_dir_entry proc_scsi_qla1280 = { - PROC_SCSI_QL1280, 7, "qla1280", - S_IFDIR | S_IRUGO | S_IXUGO, 2, - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; -#endif /* We use the Scsi_Pointer structure that's included with each command * SCSI_Cmnd as a scratchpad for our SRB. @@ -565,6 +549,19 @@ #define CMD_SNSLEN(Cmnd) sizeof(Cmnd->sense_buffer) #define CMD_RESULT(Cmnd) Cmnd->result #define CMD_HANDLE(Cmnd) Cmnd->host_scribble +#if LINUX_VERSION_CODE < 0x020545 +#define CMD_HOST(Cmnd) Cmnd->host +#define CMD_REQUEST(Cmnd) Cmnd->request.cmd +#define SCSI_BUS_32(Cmnd) Cmnd->channel +#define SCSI_TCN_32(Cmnd) Cmnd->target +#define SCSI_LUN_32(Cmnd) Cmnd->lun +#else +#define CMD_HOST(Cmnd) Cmnd->device->host +#define CMD_REQUEST(Cmnd) Cmnd->request->cmd +#define SCSI_BUS_32(Cmnd) Cmnd->device->channel +#define SCSI_TCN_32(Cmnd) Cmnd->device->id +#define SCSI_LUN_32(Cmnd) Cmnd->device->lun +#endif /*****************************************/ /* ISP Boards supported by this driver */ @@ -573,7 +570,7 @@ #define NUM_OF_ISP_DEVICES 6 struct qla_boards { - unsigned char bdName[9]; /* Board ID String */ + unsigned char name[9]; /* Board ID String */ unsigned long device_id; /* Device PCI ID */ int numPorts; /* Number of SCSI ports */ unsigned short *fwcode; /* pointer to FW array */ @@ -584,44 +581,38 @@ struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = { /* Name , Board PCI Device ID, Number of ports */ - {"QLA12160 ", PCI_DEVICE_ID_QLOGIC_ISP12160, 2, + {"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2, &fw12160i_code01[0], &fw12160i_length01, &fw12160i_addr01, &fw12160i_version_str[0]}, - {"QLA1080 ", PCI_DEVICE_ID_QLOGIC_ISP1080, 1, + {"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, - {"QLA1240 ", PCI_DEVICE_ID_QLOGIC_ISP1240, 2, + {"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, - {"QLA1280 ", PCI_DEVICE_ID_QLOGIC_ISP1280, 2, + {"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, - {"QLA10160 ", PCI_DEVICE_ID_QLOGIC_ISP10160, 1, + {"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1, &fw12160i_code01[0], &fw12160i_length01, &fw12160i_addr01, &fw12160i_version_str[0]}, {" ", 0, 0} }; static int qla1280_verbose = 1; -static struct scsi_qla_host *qla1280_hostlist = NULL; -#if QLA1280_PROFILE -static int qla1280_buffer_size = 0; -static char *qla1280_buffer = NULL; -#endif +static struct scsi_qla_host *qla1280_hostlist; +static int qla1280_buffer_size; +static char *qla1280_buffer; #if DEBUG_QLA1280 -static int ql_debug_print = 1; -char debug_buff[80]; -#define DEBUG(x) x -static int ql_debug_level = 0; +static int ql_debug_level = 1; #define dprintk(level, format, a...) \ - if ((ql_debug_level >= level) && ql_debug_print) printk(KERN_DEBUG format, ##a) + do { if (ql_debug_level >= level) printk(KERN_ERR format, ##a); } while(0) #define qla1280_dump_buffer(level, buf, size) \ if (ql_debug_level >= level) __qla1280_dump_buffer(buf, size) -#define qla1280_dump_print_cmd(level, cmd) \ +#define qla1280_print_scsi_cmd(level, cmd) \ if (ql_debug_level >= level) __qla1280_print_scsi_cmd(cmd) #else -#define DEBUG(x) #define ql_debug_level 0 #define dprintk(level, format, a...) do{}while(0) #define qla1280_dump_buffer(a, b, c) do{}while(0) @@ -630,30 +621,9 @@ #define ENTER(x) dprintk(3, "qla1280 : Entering %s()\n", x); #define LEAVE(x) dprintk(3, "qla1280 : Leaving %s()\n", x); -#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->device->channel -#define SCSI_TCN_32(scp) scp->device->id -#define SCSI_LUN_32(scp) scp->device->lun - -/****************************************************************************/ -/* LINUX - Loadable Module Functions. */ -/****************************************************************************/ +#define ENTER_INTR(x) dprintk(4, "qla1280 : Entering %s()\n", x); +#define LEAVE_INTR(x) dprintk(4, "qla1280 : Leaving %s()\n", x); -/************************************************************************* - * qla1280_set_info - * - * Description: - * Set parameters for the driver from the /proc filesystem. - * - * Returns: - *************************************************************************/ -int -qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) -{ - return -ENOSYS; /* Currently this is a no-op */ -} /************************************************************************* * qla1280_proc_info @@ -667,29 +637,47 @@ *************************************************************************/ #define PROC_BUF &qla1280_buffer[len] -int -qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, - int inout) +#if LINUX_VERSION_CODE < 0x020600 +int qla1280_proc_info(char *buffer, char **start, off_t offset, int length, + int hostno, int inout) +#else +int qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, + off_t offset, int length, int inout) +#endif { -#if QLA1280_PROFILE struct scsi_qla_host *ha; int size = 0; - scsi_lu_t *up; int len = 0; struct qla_boards *bdp; +#ifdef BOGUS_QUEUE + struct scsi_lu *up; uint32_t b, t, l; - host = NULL; - +#endif +#if LINUX_VERSION_CODE >= 0x020600 + ha = (struct scsi_qla_host *)host->hostdata; +#else + struct Scsi_Host *host; /* Find the host that was specified */ - for (ha = qla1280_hostlist; (ha != NULL) && ha->host != host; - ha = ha->next) ; + for (ha = qla1280_hostlist; (ha != NULL) + && ha->host->host_no != hostno; ha = ha->next) ; - if (inout == TRUE) { /* Has data been written to the file? */ - printk(KERN_INFO - "qla1280_proc: has data been written to the file.\n"); - return qla1280_set_info(buffer, length, host); + /* if host wasn't found then exit */ + if (!ha) { + size = sprintf(buffer, "Can't find adapter for host " + "number %d\n", hostno); + if (size > length) { + return size; + } else { + return 0; + } } + host = ha->host; +#endif + + if (inout) + return -ENOSYS; + /* * if our old buffer is the right size use it otherwise * allocate a new one. @@ -724,10 +712,7 @@ len += size; size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", - bdp->bdName); - len += size; - size = sprintf(PROC_BUF, "Request Queue = 0x%p, Response Queue = 0x%p\n", - (void *)ha->request_dma, (void *)ha->response_dma); + bdp->name); len += size; size = sprintf(PROC_BUF, "Request Queue count= 0x%x, Response " "Queue count= 0x%x\n", @@ -736,9 +721,6 @@ size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n", ha->actthreads); len += size; - size = sprintf(PROC_BUF, "Number of queued commands = 0x%lx\n", - ha->qthreads); - len += size; size = sprintf(PROC_BUF, "Number of free request entries = %d\n", ha->req_q_cnt); len += size; @@ -747,6 +729,7 @@ size = sprintf(PROC_BUF, "SCSI device Information:\n"); len += size; +#ifdef BOGUS_QUEUE /* scan for all equipment stats */ for (b = 0; b < MAX_BUSES; b++) for (t = 0; t < MAX_TARGETS; t++) { @@ -787,6 +770,7 @@ if (len >= qla1280_buffer_size) break; } +#endif if (len >= qla1280_buffer_size) { printk(KERN_WARNING @@ -805,11 +789,67 @@ } } return length; -#else - return 0; -#endif } + +static int qla1280_read_nvram(struct scsi_qla_host *ha) +{ + uint16_t *wptr; + uint8_t chksum; + int cnt; + struct nvram *nv; + + ENTER("qla1280_read_nvram"); + + if (driver_setup.no_nvram) + return 1; + + printk(KERN_INFO "scsi(%ld): Reading NVRAM\n", ha->host_no); + + wptr = (uint16_t *)&ha->nvram; + nv = &ha->nvram; + chksum = 0; + for (cnt = 0; cnt < 3; cnt++) { + *wptr = qla1280_get_nvram_word(ha, cnt); + chksum += *wptr & 0xff; + chksum += (*wptr >> 8) & 0xff; + wptr++; + } + + if (nv->id0 != 'I' || nv->id1 != 'S' || + nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) { + dprintk(2, "Invalid nvram ID or version!\n"); + chksum = 1; + } else { + for (; cnt < sizeof(struct nvram); cnt++) { + *wptr = qla1280_get_nvram_word(ha, cnt); + chksum += *wptr & 0xff; + chksum += (*wptr >> 8) & 0xff; + wptr++; + } + } + + dprintk(3, "qla1280_read_nvram: NVRAM Magic ID= %c %c %c %02x" + " version %i\n", nv->id0, nv->id1, nv->id2, nv->id3, + nv->version); + + + if (chksum) { + if (!driver_setup.no_nvram) + printk(KERN_WARNING "scsi(%ld): Unable to identify or " + "validate NVRAM checksum, using default " + "settings\n", ha->host_no); + ha->nvram_valid = 0; + } else + ha->nvram_valid = 1; + + dprintk(1, "qla1280_read_nvram: Completed Reading NVRAM\n"); + LEAVE("qla1280_read_nvram"); + + return chksum; +} + + /************************************************************************** * qla1280_do_device_init * This routine will register the device with the SCSI subsystem, @@ -827,17 +867,18 @@ * host - pointer to SCSI host structure **************************************************************************/ struct Scsi_Host * -qla1280_do_device_init(struct pci_dev *pdev, - Scsi_Host_Template * template, +qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template, int devnum, struct qla_boards *bdp, int num_hosts) { struct Scsi_Host *host; struct scsi_qla_host *ha; - struct device_reg *reg; - printk("qla1x160: Initializing ISP12160 on PCI bus %i, dev %i, irq %i\n", - pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->irq); + printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n", + bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn)); +#if LINUX_VERSION_CODE >= 0x020545 + template->slave_configure = qla1280_slave_configure; +#endif host = scsi_register(template, sizeof(struct scsi_qla_host)); if (!host) { printk(KERN_WARNING @@ -845,7 +886,11 @@ goto error; } +#if LINUX_VERSION_CODE < 0x020545 + scsi_set_pci_device(host, pdev); +#else scsi_set_device(host, &pdev->dev); +#endif ha = (struct scsi_qla_host *)host->hostdata; /* Clear our data area */ memset(ha, 0, sizeof(struct scsi_qla_host)); @@ -869,16 +914,13 @@ host->can_queue = 0xfffff; /* unlimited */ host->cmd_per_lun = 1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) - host->base = (unsigned char *)ha->mmpbase; -#else host->base = (unsigned long)ha->mmpbase; -#endif host->max_channel = bdp->numPorts - 1; host->max_lun = MAX_LUNS - 1; host->max_id = MAX_TARGETS; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) host->max_sectors = 1024; +#if LINUX_VERSION_CODE < 0x020545 + host->select_queue_depths = qla1280_select_queue_depth; #endif ha->instance = num_hosts; @@ -897,25 +939,25 @@ "qla1280", ha)) { printk("qla1280 : Failed to reserve interrupt %d already " "in use\n", host->irq); - goto error_unmap; + goto error_mem_alloced; } #if !MEMORY_MAPPED_IO /* Register the I/O space with Linux */ - if (!request_region(host->io_port, 0xff, "qla1280")) { - printk("qla1280 : Failed to reserve i/o region 0x%04lx-0x%04lx" + if (check_region(host->io_port, 0xff)) { + printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx" " already in use\n", host->io_port, host->io_port + 0xff); - goto error_irq; + free_irq(host->irq, ha); + goto error_mem_alloced; } + request_region(host->io_port, 0xff, "qla1280"); #endif - reg = ha->iobase; - /* 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_region; + printk(KERN_INFO "qla1x160: Failed to initialize adapter\n"); + goto error_mem_alloced; } /* set our host ID (need to do something about our two IDs) */ @@ -923,21 +965,6 @@ 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); @@ -975,14 +1002,12 @@ ENTER("qla1280_detect"); - if (sizeof(srb_t) > sizeof(Scsi_Pointer)) { + if (sizeof(struct srb) > sizeof(Scsi_Pointer)) { printk(KERN_WARNING - "qla1280_detect: [WARNING] srb_t too big\n"); + "qla1280_detect: [WARNING] struct srb too big\n"); return 0; } #ifdef MODULE - dprintk(1, "DEBUG: qla1280_detect starts at address = %p\n", - qla1280_detect); /* * If we are called as a module, the qla1280 pointer may not be null * and it would point to our bootup string, just like on the lilo @@ -995,28 +1020,14 @@ * which will result in the first four devices on the first two * controllers being set to a tagged queue depth of 32. */ - if (options) - qla1280_setup(options, NULL); - - printk(KERN_WARNING - "qla1280: Please read the file /usr/src/linux/Documentation" - "/scsi/qla1280.txt\n" - "qla1280: to see the proper way to specify options to the qla1280 " - "module\n" - "qla1280: Specifically, don't use any commas when passing " - "arguments to\n" - "qla1280: insmod or else it might trash certain memory areas.\n"); + if (qla1280) + qla1280_setup(qla1280); #endif bdp = &ql1280_board_tbl[0]; qla1280_hostlist = NULL; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) - template->proc_dir = &proc_scsi_qla1280; -#else template->proc_name = "qla1280"; -#endif - /* 3.20 */ /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */ while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id, PCI_ANY_ID, PCI_ANY_ID, pdev))) { @@ -1059,15 +1070,9 @@ if (pci_enable_device(pdev)) continue; /* found an adapter */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) subsys_vendor = pdev->subsystem_vendor; subsys_device = pdev->subsystem_device; -#else - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, - &subsys_vendor); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, - &subsys_device); -#endif + /* * skip QLA12160 already initialized on * PCI Bus 1 Dev 2 since we already initialized @@ -1084,8 +1089,7 @@ "qla1x160: Skip AMI SubSys Vendor ID Chip\n"); continue; } - printk(KERN_INFO - "qla1x160: Supported Device Found VID=%x " + dprintk(1, "qla1x160: Supported Device Found VID=%x " "DID=%x SSVID=%x SSDID=%x\n", pdev->vendor, pdev->device, subsys_vendor, subsys_device); @@ -1135,7 +1139,7 @@ #if MEMORY_MAPPED_IO if (ha->mmpbase) - iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK)); + iounmap(ha->mmpbase); #else /* release io space registers */ if (host->io_port) @@ -1167,7 +1171,7 @@ sprintf (bp, "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n" " Firmware version: %2d.%02d.%02d, Driver version %s", - &bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, + &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], QLA1280_VERSION); return bp; @@ -1188,19 +1192,20 @@ qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *)) { struct scsi_qla_host *ha; - srb_t *sp; + struct srb *sp; struct Scsi_Host *host; int bus, target, lun; - scsi_lu_t *q; + int status; /*ENTER("qla1280_queuecommand"); */ + dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies); - host = cmd->device->host; + host = CMD_HOST(cmd); ha = (struct scsi_qla_host *)host->hostdata; /* send command to adapter */ - sp = (srb_t *)CMD_SP(cmd); + sp = (struct srb *)CMD_SP(cmd); sp->cmd = cmd; cmd->scsi_done = fn; if (cmd->flags == 0) { /* new command */ @@ -1213,63 +1218,46 @@ bus = SCSI_BUS_32(cmd); target = SCSI_TCN_32(cmd); lun = SCSI_LUN_32(cmd); - if ((q = LU_Q(ha, bus, target, lun)) == NULL) { - if ((q = (scsi_lu_t *)kmalloc(sizeof(struct scsi_lu), - GFP_ATOMIC))) { - LU_Q(ha, bus, target, lun) = q; - memset(q, 0, sizeof(struct scsi_lu)); - dprintk(1, "Allocate new device queue 0x%p\n", - (void *)q); - } else { - CMD_RESULT(cmd) = DID_BUS_BUSY << 16; - qla1280_done_q_put(sp, &ha->done_q_first, - &ha->done_q_last); -/* 3.22 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) /* 3.22 */ - schedule_work(&ha->run_qla_bh); -#else /* 3.22 */ - schedule_work(&ha->run_qla_bh); /* 3.22 */ -#endif /* 3.22 */ - return 0; - } - } - /* Set an invalid handle until we issue the command to ISP */ - /* then we will set the real handle value. */ - CMD_HANDLE(cmd) = (unsigned char *)INVALID_HANDLE; - - /* add the command to our queue */ - ha->qthreads++; - qla1280_putq_t(q, sp); - - dprintk(1, "qla1280_QC: t=%x CDB=%x I/OSize=0x%x haQueueCount=0x%lx\n", - target, cmd->cmnd[0], cmd->request_bufflen, ha->qthreads); - - /* send command to adapter */ - if (q->q_outcnt == 0) - qla1280_restart_queues(ha); + if (ha->flags.enable_64bit_addressing) + status = qla1280_64bit_start_scsi(ha, sp); + else + status = qla1280_32bit_start_scsi(ha, sp); /*LEAVE("qla1280_queuecommand"); */ - return 0; + return status; } -typedef enum { +enum action { ABORT_COMMAND, ABORT_DEVICE, DEVICE_RESET, BUS_RESET, ADAPTER_RESET, FAIL -} action_t; +}; /* timer action for error action processor */ static void qla1280_error_wait_timeout(unsigned long __data) { struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data; - srb_t *sp = (srb_t *)CMD_SP(cmd); + struct srb *sp = (struct srb *)CMD_SP(cmd); complete(sp->wait); } +static void qla1280_mailbox_timeout(unsigned long __data) +{ + struct scsi_qla_host *ha = (struct scsi_qla_host *)__data; + struct device_reg *reg; + reg = ha->iobase; + + ha->mailbox_out[0] = RD_REG_WORD(®->mailbox0); + printk(KERN_ERR "scsi(%ld): mailbox timed out, mailbox0 %04x, " + "ictrl %04x, istatus %04x\n", ha->host_no, ha->mailbox_out[0], + RD_REG_WORD(®->ictrl), RD_REG_WORD(®->istatus)); + complete(ha->mailbox_wait); +} + /************************************************************************** * qla1200_error_action * The function will attempt to perform a specified error action and @@ -1281,7 +1269,7 @@ * action = error action to take (see action_t) * * Returns: - * SUCCESS or FAIL + * SUCCESS or FAILED * * Note: * Resetting the bus always succeeds - is has to, otherwise the @@ -1290,39 +1278,43 @@ * the SCSI bus reset line. **************************************************************************/ int -qla1280_error_action(Scsi_Cmnd * cmd, action_t action) +qla1280_error_action(Scsi_Cmnd * cmd, enum action action) { struct scsi_qla_host *ha; int bus, target, lun; - srb_t *sp; + struct srb *sp; uint16_t data; unsigned char *handle; - scsi_lu_t *q; - int result; + int result, i; DECLARE_COMPLETION(wait); struct timer_list timer; + ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata); + + dprintk(4, "error_action %i, istatus 0x%04x\n", action, + RD_REG_WORD(&ha->iobase->istatus)); + + dprintk(4, "host_cmd 0x%04x, ictrl 0x%04x, jiffies %li\n", + RD_REG_WORD(&ha->iobase->host_cmd), + RD_REG_WORD(&ha->iobase->ictrl), jiffies); + ENTER("qla1280_error_action"); if (qla1280_verbose) - printk(KERN_INFO "scsi(): Resetting Cmnd=0x%p, Handle=0x%p, " - "action=0x%x\n", cmd, CMD_HANDLE(cmd), action); + printk(KERN_INFO "scsi(%li): Resetting Cmnd=0x%p, " + "Handle=0x%p, action=0x%x\n", + ha->host_no, cmd, CMD_HANDLE(cmd), action); if (cmd == NULL) { - printk(KERN_WARNING - "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd " - "pointer, failing.\n"); + printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL " + "si_Cmnd pointer, failing.\n"); LEAVE("qla1280_error_action"); - return FAIL; + return FAILED; } ha = (struct scsi_qla_host *)cmd->device->host->hostdata; - sp = (srb_t *)CMD_SP(cmd); + sp = (struct srb *)CMD_SP(cmd); handle = CMD_HANDLE(cmd); -#if STOP_ON_RESET - qla1280_panic("qla1280_reset", ha->host); -#endif - /* Check for pending interrupts. */ data = qla1280_debounce_register(&ha->iobase->istatus); /* @@ -1337,7 +1329,7 @@ * Determine the suggested action that the mid-level driver wants * us to perform. */ - if (handle == NULL) { + if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) { if(action == ABORT_COMMAND) { /* we never got this command */ printk(KERN_INFO "qla1280: Aborting a NULL handle\n"); @@ -1350,23 +1342,16 @@ bus = SCSI_BUS_32(cmd); target = SCSI_TCN_32(cmd); lun = SCSI_LUN_32(cmd); - q = LU_Q(ha, bus, target, lun); /* Overloading result. Here it means the success or fail of the * *issue* of the action. When we return from the routine, it must * mean the actual success or fail of the action */ - result = FAIL; + result = FAILED; switch (action) { case FAIL: break; case ABORT_COMMAND: - if (q == NULL) { - /* No lun queue -- command must not be active */ - printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the " - "specified device\n", bus, target, lun); - break; - } if ((sp->flags & SRB_ABORT_PENDING)) { printk(KERN_WARNING "scsi(): Command has a pending abort " @@ -1376,50 +1361,35 @@ break; } - /* - * Normally, would would need to search our queue for - * the specified command but; since our sp contains - * the cmd ptr, we can just remove it from our LUN - * queue. - */ - if (!(sp->flags & SRB_SENT)) { - if (qla1280_verbose) - printk(KERN_WARNING - "scsi(): Command returned from queue " - "aborted.\n"); - - /* Remove srb from SCSI LU queue. */ - qla1280_removeq(q, sp); - sp->flags |= SRB_ABORTED; - CMD_RESULT(cmd) = DID_ABORT << 16; - qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last); - if (ha->done_q_first) - qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); - - qla1280_restart_queues(ha); - - } else { /* find the command in our active list */ - int i; - - for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { - if (sp == ha->outstanding_cmds[i]) { - dprintk(1, - "qla1280: RISC aborting command.\n"); - qla1280_abort_command(ha, sp); + for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { + if (sp == ha->outstanding_cmds[i]) { + dprintk(1, "qla1280: RISC aborting command\n"); + if (qla1280_abort_command(ha, sp, i) == 0) + result = SUCCESS; + else { + /* + * Since we don't know what might + * have happend to the command, it + * is unsafe to remove it from the + * device's queue at this point. + * Wait and let the escalation + * process take care of it. + */ + printk(KERN_WARNING + "scsi(%li:%i:%i:%i): Unable" + " to abort command!\n", + ha->host_no, bus, target, lun); } } } break; - - case ABORT_DEVICE: - ha->flags.in_reset = TRUE; + ha->flags.in_reset = 1; if (qla1280_verbose) printk(KERN_INFO "scsi(%ld:%d:%d:%d): Queueing abort device " "command.\n", ha->host_no, bus, target, lun); - qla1280_abort_queue_single(ha, bus, target, lun, DID_ABORT); if (qla1280_abort_device(ha, bus, target, lun) == 0) result = SUCCESS; break; @@ -1429,31 +1399,18 @@ printk(KERN_INFO "scsi(%ld:%d:%d:%d): Queueing device reset " "command.\n", ha->host_no, bus, target, lun); - ha->flags.in_reset = TRUE; - for (lun = 0; lun < MAX_LUNS; lun++) - qla1280_abort_queue_single(ha, bus, target, lun, - DID_ABORT); + ha->flags.in_reset = 1; if (qla1280_device_reset(ha, bus, target) == 0) result = SUCCESS; - q->q_flag |= QLA1280_QRESET; break; case BUS_RESET: if (qla1280_verbose) - printk(KERN_INFO "qla1280(%ld:%d:%d:%d): Issuing BUS " - "DEVICE RESET.\n", ha->host_no, bus, target, - lun); - ha->flags.in_reset = TRUE; - for (target = 0; target < MAX_TARGETS; target++) - for (lun = 0; lun < MAX_LUNS; lun++) - qla1280_abort_queue_single(ha, bus, target, - lun, DID_RESET); - qla1280_bus_reset(ha, bus); - - /* wait 4 seconds */ - schedule_timeout(4*HZ); - - result = SUCCESS; + printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS " + "DEVICE RESET\n", ha->host_no, bus); + ha->flags.in_reset = 1; + if (qla1280_bus_reset(ha, bus == 0)) + result = SUCCESS; break; @@ -1461,14 +1418,12 @@ default: if (qla1280_verbose) { printk(KERN_INFO - "scsi(%ld:%d:%d:%d): Issued an ADAPTER " - "RESET.\n", ha->host_no, bus, target, lun); - printk(KERN_INFO - "scsi(%ld:%d:%d:%d): I/O processing will " - "continue automatically.\n", ha->host_no, bus, - target, lun); + "scsi(%ld): Issued ADAPTER RESET\n", + ha->host_no); + printk(KERN_INFO "scsi(%ld): I/O processing will " + "continue automatically\n", ha->host_no); } - ha->flags.reset_active = TRUE; + ha->flags.reset_active = 1; /* * We restarted all of the commands automatically, so the * mid-level code can expect completions momentitarily. @@ -1476,17 +1431,17 @@ if (qla1280_abort_isp(ha) == 0) result = SUCCESS; - ha->flags.reset_active = FALSE; + ha->flags.reset_active = 0; } if (ha->done_q_first) qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); - qla1280_restart_queues(ha); - ha->flags.in_reset = FALSE; + ha->flags.in_reset = 0; /* If we didn't manage to issue the action, or we have no * command to wait for, exit here */ - if(result == FAIL || handle == NULL) + if (result == FAILED || handle == NULL || + handle == (unsigned char *)INVALID_HANDLE) goto leave; /* set up a timer just in case we're really jammed */ @@ -1497,14 +1452,14 @@ add_timer(&timer); /* wait for the action to complete (or the timer to expire) */ - spin_unlock_irq(ha->host->host_lock); + spin_unlock_irq(HOST_LOCK); wait_for_completion(&wait); del_timer_sync(&timer); - spin_lock_irq(ha->host->host_lock); + spin_lock_irq(HOST_LOCK); sp->wait = NULL; - + /* the only action we might get a fail for is abort */ - if(action == ABORT_COMMAND) { + if (action == ABORT_COMMAND) { if(sp->flags & SRB_ABORTED) result = SUCCESS; else @@ -1519,7 +1474,7 @@ } /************************************************************************** - * qla1200_abort + * qla1280_abort * Abort the specified SCSI command(s). **************************************************************************/ int @@ -1529,7 +1484,7 @@ } /************************************************************************** - * qla1200_device_reset + * qla1280_device_reset * Reset the specified SCSI device **************************************************************************/ int @@ -1539,7 +1494,7 @@ } /************************************************************************** - * qla1200_bus_reset + * qla1280_bus_reset * Reset the specified bus. **************************************************************************/ int @@ -1549,7 +1504,7 @@ } /************************************************************************** - * qla1200_adapter_reset + * qla1280_adapter_reset * Reset the specified adapter (both channels) **************************************************************************/ int @@ -1563,10 +1518,17 @@ * Return the disk geometry for the given SCSI device. **************************************************************************/ int +#if LINUX_VERSION_CODE < 0x020545 +qla1280_biosparam(Disk * disk, kdev_t dev, int geom[]) +#else qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int geom[]) + sector_t capacity, int geom[]) +#endif { int heads, sectors, cylinders; +#if LINUX_VERSION_CODE < 0x020545 + unsigned long capacity = disk->capacity; +#endif heads = 64; sectors = 32; @@ -1595,13 +1557,13 @@ { struct scsi_qla_host *ha; struct device_reg *reg; - int handled = 0; u16 data; + int handled = 0; ENTER_INTR ("qla1280_intr_handler"); ha = (struct scsi_qla_host *)dev_id; - spin_lock(ha->host->host_lock); + spin_lock(HOST_LOCK); ha->isr_count++; reg = ha->iobase; @@ -1613,16 +1575,11 @@ if (data & RISC_INT) { qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last); handled = 1; - } else { - /* spurious interrupts can happen legally */ - dprintk(1, "scsi(%ld): Spurious interrupt - ignoring\n", - ha->host_no); } - if (ha->done_q_first) qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); - spin_unlock(ha->host->host_lock); + spin_unlock(HOST_LOCK); /* enable our interrupt. */ WRT_REG_WORD(®->ictrl, (ISP_EN_INT | ISP_EN_RISC)); @@ -1649,10 +1606,7 @@ struct scsi_qla_host *ha = (struct scsi_qla_host *) p; unsigned long cpu_flags; - spin_lock_irqsave(ha->host->host_lock, cpu_flags); - - if (ha->flags.isp_abort_needed) - qla1280_abort_isp(ha); + spin_lock_irqsave(HOST_LOCK, cpu_flags); if (ha->flags.reset_marker) qla1280_rst_aen(ha); @@ -1660,9 +1614,58 @@ if (ha->done_q_first) qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); - spin_unlock_irqrestore(ha->host->host_lock, cpu_flags); + spin_unlock_irqrestore(HOST_LOCK, cpu_flags); } + +static int +qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target) +{ + uint8_t mr; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + struct nvram *nv; + int is1x160, status; + + nv = &ha->nvram; + + if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) + is1x160 = 1; + else + is1x160 = 0; + + mr = BIT_3 | BIT_2 | BIT_1 | BIT_0; + + /* Set Target Parameters. */ + mb[0] = MBC_SET_TARGET_PARAMETERS; + mb[1] = (uint16_t) (bus ? target | BIT_7 : target); + mb[1] <<= 8; + + mb[2] = (nv->bus[bus].target[target].parameter.c << 8); + + if (is1x160) + mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8; + else + mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8; + mb[3] |= nv->bus[bus].target[target].sync_period; + + if (is1x160) { + mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5; + mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8; + mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width; + mr |= BIT_6; + } + + status = qla1280_mailbox_command(ha, mr, &mb[0]); + + if (status) + printk(KERN_WARNING "scsi(%ld:%i:%i): " + "qla1280_set_target_parameters() failed\n", + ha->host_no, bus, target); + return status; +} + + /************************************************************************** * qla1280_slave_configure * @@ -1675,28 +1678,94 @@ * default queue depth (dependent on the number of hardware SCBs). **************************************************************************/ static int -qla1280_slave_configure(Scsi_Device * device) +qla1280_slave_configure(Scsi_Device *device) { - struct scsi_qla_host *p = (struct scsi_qla_host *)device->host->hostdata; + struct scsi_qla_host *ha; + int default_depth = 3; int bus = device->channel; int target = device->id; + int status = 0; + struct nvram *nv; +#if LINUX_VERSION_CODE < 0x020500 + unsigned long flags; +#endif + + ha = (struct scsi_qla_host *)device->host->hostdata; + nv = &ha->nvram; - if (qla1280_check_for_dead_scsi_bus(p, bus)) + if (qla1280_check_for_dead_scsi_bus(ha, bus)) return 1; + if (device->tagged_supported && - (p->bus_settings[bus].qtag_enables & (BIT_0 << target))) { + (ha->bus_settings[bus].qtag_enables & (BIT_0 << target))) { scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, - p->bus_settings[bus].hiwat); - /* 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->queue_depth); + ha->bus_settings[bus].hiwat); } else { - scsi_adjust_queue_depth(device, 0 /* TCQ off */, 3); + scsi_adjust_queue_depth(device, 0, default_depth); } - qla12160_get_target_parameters(p, bus, target, device->lun); - return 0; + +#if LINUX_VERSION_CODE > 0x020500 + nv->bus[bus].target[target].parameter.f.enable_sync = device->sdtr; + nv->bus[bus].target[target].parameter.f.enable_wide = device->wdtr; + nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = device->ppr; +#endif + + if (driver_setup.no_sync || + (driver_setup.sync_mask && + (~driver_setup.sync_mask & (1 << target)))) + nv->bus[bus].target[target].parameter.f.enable_sync = 0; + if (driver_setup.no_wide || + (driver_setup.wide_mask && + (~driver_setup.wide_mask & (1 << target)))) + nv->bus[bus].target[target].parameter.f.enable_wide = 0; + if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) { + if (driver_setup.no_ppr || + (driver_setup.ppr_mask && + (~driver_setup.ppr_mask & (1 << target)))) + nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; + } + +#if LINUX_VERSION_CODE < 0x020500 + spin_lock_irqsave(HOST_LOCK, flags); +#endif + if (nv->bus[bus].target[target].parameter.f.enable_sync) { + status = qla12160_set_target_parameters(ha, bus, target); + } + + qla12160_get_target_parameters(ha, device); +#if LINUX_VERSION_CODE < 0x020500 + spin_unlock_irqrestore(HOST_LOCK, flags); +#endif + return status; +} + +#if LINUX_VERSION_CODE < 0x020545 +/************************************************************************** + * qla1280_select_queue_depth + * + * Sets the queue depth for each SCSI device hanging off the input + * host adapter. We use a queue depth of 2 for devices that do not + * support tagged queueing. + **************************************************************************/ +static void +qla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) +{ + Scsi_Device *device; + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; + + ENTER("qla1280_select_queue_depth"); + for (device = scsi_devs; device != NULL; device = device->next) { + if (device->host == host) + qla1280_slave_configure(device); + } + + if (scsi_devs) + qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel); + + LEAVE("qla1280_select_queue_depth"); } +#endif /* * Driver Support Routines @@ -1712,11 +1781,10 @@ * done_q_last = done queue last pointer. */ static void -qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first, - srb_t ** done_q_last) +qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first, + struct srb ** done_q_last) { - srb_t *sp; - scsi_lu_t *q; + struct srb *sp; int bus, target, lun; Scsi_Cmnd *cmd; @@ -1734,24 +1802,9 @@ bus = SCSI_BUS_32(cmd); target = SCSI_TCN_32(cmd); lun = SCSI_LUN_32(cmd); - q = LU_Q(ha, bus, target, lun); - - /* Decrement outstanding commands on device. */ - if (q->q_outcnt) - q->q_outcnt--; - if (q->q_outcnt < ha->bus_settings[bus].hiwat) { - q->q_flag &= ~QLA1280_QBUSY; - } - - q->io_cnt++; - if (sp->dir & BIT_5) - q->r_cnt++; - else - q->w_cnt++; switch ((CMD_RESULT(cmd) >> 16)) { case DID_RESET: - q->q_flag &= ~QLA1280_QRESET; /* Issue marker command. */ qla1280_marker(ha, bus, target, 0, MK_SYNC_ID); break; @@ -1765,10 +1818,9 @@ break; } - /* 3.13 64 and 32 bit */ /* Release memory used for this I/O */ if (cmd->use_sg) { - dprintk(1, "S/G unmap_sg cmd=%p\n", cmd); + dprintk(3, "S/G unmap_sg cmd=%p\n", cmd); pci_unmap_sg(ha->pdev, cmd->request_buffer, cmd->use_sg, @@ -1777,21 +1829,24 @@ /*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n", cmd, sp->saved_dma_handle); */ - pci_unmap_single(ha->pdev, sp->saved_dma_handle, - cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + pci_unmap_page(ha->pdev, sp->saved_dma_handle, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); } /* Call the mid-level driver interrupt handler */ - CMD_HANDLE(sp->cmd) = NULL; + CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE; ha->actthreads--; +#if LINUX_VERSION_CODE < 0x020500 + if (cmd->cmnd[0] == INQUIRY) + qla1280_get_target_options(cmd, ha); +#endif (*(cmd)->scsi_done)(cmd); if(sp->wait != NULL) complete(sp->wait); - qla1280_next(ha, q, bus); } LEAVE("qla1280_done"); } @@ -1800,7 +1855,7 @@ * Translates a ISP error to a Linux SCSI error */ static int -qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp) +qla1280_return_status(struct response * sts, Scsi_Cmnd * cp) { int host_status = DID_ERROR; #if DEBUG_QLA1280_INTR @@ -1901,7 +1956,8 @@ * done_q_last = done queue last pointer. */ static void -qla1280_done_q_put(srb_t * sp, srb_t ** done_q_first, srb_t ** done_q_last) +qla1280_done_q_put(struct srb * sp, struct srb ** done_q_first, + struct srb ** done_q_last) { ENTER("qla1280_put_done_q"); @@ -1917,160 +1973,6 @@ LEAVE("qla1280_put_done_q"); } -/* - * qla1280_next - * Retrieve and process next job in the queue. - * - * Input: - * ha = adapter block pointer. - * q = SCSI LU pointer. - * bus = SCSI bus number. - * SCSI_LU_Qlock must be already obtained and no other locks. - * - * Output: - * Releases SCSI_LU_Qupon exit. - */ -static void -qla1280_next(struct scsi_qla_host *ha, scsi_lu_t * q, int bus) -{ - srb_t *sp; - int cnt, status; - - ENTER("qla1280_next"); - - while (((sp = q->q_first) != NULL) && /* we have a queue pending */ - /* device not busy/suspended */ - !(q->q_flag & (QLA1280_QBUSY | QLA1280_QSUSP)) && !ha->flags.abort_isp_active) { /* not resetting the adapter */ - /* Remove srb from SCSI LU queue. */ - qla1280_removeq(q, sp); - - dprintk(1, "starting request 0x%p<-(0x%p)\n", q, sp); - { - /* Set busy flag if reached high water mark. */ - q->q_outcnt++; - if (q->q_outcnt >= ha->bus_settings[bus].hiwat) - q->q_flag |= QLA1280_QBUSY; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) - if (ha->flags.enable_64bit_addressing) - status = qla1280_64bit_start_scsi(ha, sp); - else -#endif - status = qla1280_32bit_start_scsi(ha, sp); - - if (status) { /* if couldn't start the request */ - if (q->q_outcnt == 1) { - /* Wait for 30 sec for command to be accepted. */ - for (cnt = 6000000; cnt; cnt--) { -#if QLA_64BIT_PTR - if (ha->flags.enable_64bit_addressing) - status = - qla1280_64bit_start_scsi(ha, sp); - else -#endif - status = - qla1280_32bit_start_scsi(ha, sp); - - if (!status) - break; - - /* Go check for pending interrupts. */ - qla1280_poll(ha); - - udelay(5); /* 10 */ - } - if (!cnt) { - /* Set timeout status */ - CMD_RESULT(sp->cmd) = - DID_TIME_OUT << 16; - -#if WATCHDOGTIMER - /* Remove command from watchdog queue. */ - if (sp->flags & SRB_WATCHDOG) - qla1280_timeout_remove - (ha, sp); -#endif - CMD_HANDLE(sp->cmd) = NULL; - - /* Call the mid-level driver interrupt handler */ - (*(sp->cmd)->scsi_done)(sp->cmd); - - if (q->q_outcnt) - q->q_outcnt--; - } - } else { /* Place request back on top of device queue. */ - qla1280_putq_t(q, sp); - - if (q->q_outcnt) - q->q_outcnt--; - if (q->q_outcnt < - ha->bus_settings[bus].hiwat) - q->q_flag &= ~QLA1280_QBUSY; - break; - } - } - } - } - - LEAVE("qla1280_next"); -} - -/* - * qla1280_putq_t - * Add the standard SCB job to the top of standard SCB commands. - * - * Input: - * q = SCSI LU pointer. - * sp = srb pointer. - * SCSI_LU_Qlock must be already obtained. - */ -static void -qla1280_putq_t(scsi_lu_t * q, srb_t * sp) -{ - ENTER("qla1280_putq_t"); - - dprintk(1, "Adding to device q=0x%p<-(0x%p)sp\n", (void *) q, - (void *) sp); - - sp->s_next = NULL; - if (!q->q_first) { /* If queue empty */ - sp->s_prev = NULL; - q->q_first = sp; - q->q_last = sp; - } else { - sp->s_prev = q->q_last; - q->q_last->s_next = sp; - q->q_last = sp; - } - - LEAVE("qla1280_putq_t"); -} - -/* - * qla1280_removeq - * Function used to remove a command block from the - * LU queue. - * - * Input: - * q = SCSI LU pointer. - * sp = srb pointer. - * SCSI_LU_Qlock must be already obtained. - */ -static void -qla1280_removeq(scsi_lu_t * q, srb_t * sp) -{ - dprintk(1, "Removing from device_q (0x%p)->(0x%p)\n", q, sp); - - if (sp->s_prev) { - if ((sp->s_prev->s_next = sp->s_next) != NULL) - sp->s_next->s_prev = sp->s_prev; - else - q->q_last = sp->s_prev; - } else if (!(q->q_first = sp->s_next)) - q->q_last = NULL; - else - q->q_first->s_prev = NULL; -} /* * qla1280_mem_alloc @@ -2088,7 +1990,6 @@ ENTER("qla1280_mem_alloc"); - /* 3.13 */ /* get consistent memory allocated for request and response rings */ ha->request_ring = pci_alloc_consistent(ha->pdev, ((REQUEST_ENTRY_CNT + 1) * @@ -2099,7 +2000,7 @@ ha->request_dma = dma_handle; ha->response_ring = pci_alloc_consistent(ha->pdev, ((RESPONSE_ENTRY_CNT + 1) * - (sizeof(response_t))), + (sizeof(struct response))), &dma_handle); if (!ha->request_ring) goto error; @@ -2124,26 +2025,7 @@ static void qla1280_mem_free(struct scsi_qla_host *ha) { - scsi_lu_t *q; - int bus, target, lun; - ENTER("qlc1280_mem_free"); - if (ha) { - /* Free device queues. */ - for (bus = 0; bus < MAX_BUSES; bus++) { - q = LU_Q(ha, bus, ha->bus_settings[bus].id, 0); - for (target = 0; target < MAX_TARGETS; target++) - for (lun = 0; lun < MAX_LUNS; lun++) - if (LU_Q(ha, bus, target, lun) != NULL - && LU_Q(ha, bus, target, lun) != q) - kfree(LU_Q(ha, bus, target, lun)); - kfree(q); - } - for (bus = 0; bus < MAX_EQ; bus++) - ha->dev[bus] = NULL; - } - - /* 3.13 */ /* free consistent memory allocated for request and response rings */ if (ha->request_ring) pci_free_consistent(ha->pdev, @@ -2154,7 +2036,7 @@ if (ha->response_ring) pci_free_consistent(ha->pdev, ((RESPONSE_ENTRY_CNT + 1) * - (sizeof(response_t))), + (sizeof(struct response))), ha->response_ring, ha->response_dma); if (qla1280_buffer) { @@ -2187,10 +2069,8 @@ reg = ha->iobase; /* enable risc and host interrupts */ WRT_REG_WORD(®->ictrl, (ISP_EN_INT | ISP_EN_RISC)); + RD_REG_WORD(®->ictrl); /* PCI Posted Write flush */ ha->flags.ints_enabled = 1; -#if 0 - printk("Enabling ints\n"); -#endif } static inline void @@ -2201,10 +2081,8 @@ reg = ha->iobase; /* disable risc and host interrupts */ WRT_REG_WORD(®->ictrl, 0); + RD_REG_WORD(®->ictrl); /* PCI Posted Write flush */ ha->flags.ints_enabled = 0; -#if 0 - printk("Disabling ints\n"); -#endif } /* @@ -2227,13 +2105,29 @@ ENTER("qla1280_initialize_adapter"); /* Clear adapter flags. */ - ha->flags.online = FALSE; - ha->flags.isp_abort_needed = FALSE; - ha->flags.disable_host_adapter = FALSE; - ha->flags.reset_active = FALSE; - ha->flags.abort_isp_active = FALSE; + ha->flags.online = 0; + ha->flags.disable_host_adapter = 0; + ha->flags.reset_active = 0; + ha->flags.abort_isp_active = 0; + + ha->flags.ints_enabled = 0; +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ia64_platform_is("sn2")) { + int count1, count2; + int c; + + count1 = 3; + count2 = 3; + printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA " + "dual channel lockup workaround\n", ha->host_no); + if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0) + printk(KERN_ERR "scsi(%li): Unable to allocate SN2 " + "virtual DMA channels\n", ha->host_no); + ha->flags.use_pci_vchannel = 1; - ha->flags.ints_enabled = FALSE; + driver_setup.no_nvram = 1; + } +#endif dprintk(1, "Configure PCI space for adapter...\n"); @@ -2243,79 +2137,65 @@ WRT_REG_WORD(®->semaphore, 0); WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); + RD_REG_WORD(®->host_cmd); + + if (qla1280_read_nvram(ha)) { + dprintk(2, "qla1280_initialize_adapter: failed to read " + "NVRAM\n"); + } /* If firmware needs to be loaded */ - if (qla1280_verbose) - printk(KERN_INFO "scsi(%li): Determining if RISC is " - "loaded...\n", ha->host_no); if (qla1280_isp_firmware(ha)) { - if (qla1280_verbose) - printk(KERN_INFO "scsi(%ld): Verifying chip...\n", - ha->host_no); if (!(status = qla1280_chip_diag (ha))) { - if (qla1280_verbose) - printk(KERN_INFO "scsi(%ld): Setup chip...\n", - ha->host_no); status = qla1280_setup_chip(ha); } } else { - printk(KERN_ERR "initialize: isp_firmware() failed!\n"); + printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n", + ha->host_no); status = 1; } - if (!status) { - /* Setup adapter based on NVRAM parameters. */ - if (qla1280_verbose) - printk(KERN_INFO - "scsi(%ld): Configure NVRAM parameters...\n", - ha->host_no); - qla1280_nvram_config(ha); + if (status) { + printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n", + ha->host_no); + goto out; + } - if (!ha->flags.disable_host_adapter - && !qla1280_init_rings(ha)) { - /* Issue SCSI reset. */ - /* dg 03/13 if we can't reset twice then bus is dead */ - for (bus = 0; bus < ha->ports; bus++) { - if (!ha->bus_settings[bus].disable_scsi_reset){ + /* Setup adapter based on NVRAM parameters. */ + dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no); + qla1280_nvram_config(ha); + + if (!ha->flags.disable_host_adapter && !qla1280_init_rings(ha)) { + /* Issue SCSI reset. */ + /* dg 03/13 if we can't reset twice then bus is dead */ + for (bus = 0; bus < ha->ports; bus++) { + if (!ha->bus_settings[bus].disable_scsi_reset){ + if (qla1280_bus_reset(ha, bus)) { if (qla1280_bus_reset(ha, bus)) { - if (qla1280_bus_reset(ha, bus)) { - ha->bus_settings[bus].scsi_bus_dead = TRUE; - } + ha->bus_settings[bus].scsi_bus_dead = 1; } } } - do { - /* Issue marker command. */ - ha->flags.reset_marker = FALSE; - for (bus = 0; bus < ha->ports; bus++) { - ha->bus_settings[bus].reset_marker = FALSE; - qla1280_marker(ha, bus, 0, 0, - MK_SYNC_ALL); - } - } while (ha->flags.reset_marker); - - ha->flags.online = TRUE; + } - /* Enable host adapter target mode. */ - for (bus = 0; bus < ha->ports; bus++) { - if (!(status = qla1280_enable_tgt(ha, bus))) { + /* + * qla1280_bus_reset() will take care of issueing markers, + * no need to do that here as well! + */ #if 0 - int cnt; - for (cnt = 0; cnt < MAX_LUNS; cnt++) { - qla1280_enable_lun(ha, bus, - cnt); - qla1280_poll(ha); - } + /* Issue marker command. */ + ha->flags.reset_marker = 0; + for (bus = 0; bus < ha->ports; bus++) { + ha->bus_settings[bus].reset_marker = 0; + qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL); + } #endif - } else - break; - } - } else - status = 1; + + ha->flags.online = 1; } else - printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n", - ha->host_no); + status = 1; + out: if (status) dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n"); @@ -2323,39 +2203,6 @@ return status; } -/* - * qla1280_enable_tgt - * Enable target mode. - * - * Input: - * ha = adapter block pointer. - * bus = SCSI bus number. - * - * Returns: - * 0 = success. - */ -static int -qla1280_enable_tgt(struct scsi_qla_host *ha, int bus) -{ - int status = 0; - /* uint16_t mb[MAILBOX_REGISTER_COUNT]; */ - - dprintk(3, "qla1280_enable_tgt: entered\n"); - - /* Enable target mode. */ -#if 0 - mb[0] = MBC_ENABLE_TARGET_MODE; - mb[1] = BIT_15; - mb[2] = (uint16_t) (bus << 15); - status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); -#endif - if (status) - dprintk(2, "qla1280_enable_tgt: **** FAILED ****\n"); - else - dprintk(3, "qla1280_enable_tgt: exiting normally\n"); - - return status; -} /* * ISP Firmware Test @@ -2371,54 +2218,32 @@ static int qla1280_isp_firmware(struct scsi_qla_host *ha) { - nvram_t *nv = (nvram_t *) ha->response_ring; - uint16_t *wptr; + struct nvram *nv = (struct nvram *) ha->response_ring; int status = 0; /* dg 2/27 always loads RISC */ - int cnt; - uint8_t chksum; uint16_t mb[MAILBOX_REGISTER_COUNT]; ENTER("qla1280_isp_firmware"); - /* Verify valid NVRAM checksum. */ - wptr = (uint16_t *) ha->response_ring; - dprintk(1, "qla1280_isp_firmware: Reading NVRAM\n"); - - chksum = 0; - for (cnt = 0; cnt < sizeof(nvram_t) / 2; cnt++) { - *wptr = qla1280_get_nvram_word (ha, cnt); - chksum += (uint8_t) * wptr; - chksum += (uint8_t) (*wptr >> 8); - wptr++; - } - dprintk(1, "qla1280_isp_firmware: Completed Reading NVRAM\n"); - - dprintk(3, "qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n", - nv->id0, nv->id1, nv->id2); + dprintk(1, "scsi(%li): Determining if RISC is loaded\n", ha->host_no); /* Bad NVRAM data, load RISC code. */ - if (chksum || nv->id0 != 'I' || nv->id1 != 'S' || - nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) { - printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic " - "number or version in NVRAM.\n"); - ha->flags.disable_risc_code_load = FALSE; + if (!ha->nvram_valid) { + ha->flags.disable_risc_code_load = 0; } else ha->flags.disable_risc_code_load = nv->cntr_flags_1.disable_loading_risc_code; if (ha->flags.disable_risc_code_load) { - dprintk(3, - "qla1280_isp_firmware: Telling RISC to verify checksum " - "of loaded BIOS code.\n"); + dprintk(3, "qla1280_isp_firmware: Telling RISC to verify " + "checksum of loaded BIOS code.\n"); /* Verify checksum of loaded RISC code. */ mb[0] = MBC_VERIFY_CHECKSUM; /* mb[1] = ql12_risc_code_addr01; */ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; - if (! - (status = - qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) { + if (!(status = + qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) { /* Start firmware execution. */ dprintk(3, "qla1280_isp_firmware: Startng F/W " "execution.\n"); @@ -2455,8 +2280,8 @@ qla1280_pci_config(struct scsi_qla_host *ha) { #if MEMORY_MAPPED_IO - uint32_t page_offset, base; - uint32_t mmapbase; + unsigned long base; + int size; #endif uint16_t buf_wd; int status = 1; @@ -2470,16 +2295,14 @@ */ pci_read_config_word (ha->pdev, PCI_COMMAND, &buf_wd); #if MEMORY_MAPPED_IO - dprintk(1, "qla1280: MEMORY MAPPED IO is enabled.\n"); - buf_wd |= PCI_COMMAND_MEMORY + PCI_COMMAND_IO; -#else - buf_wd |= PCI_COMMAND_IO; + buf_wd |= PCI_COMMAND_MEMORY; #endif + buf_wd |= PCI_COMMAND_IO; pci_write_config_word (ha->pdev, PCI_COMMAND, buf_wd); /* * Reset expansion ROM address decode enable. */ - pci_read_config_word (ha->pdev, PCI_ROM_ADDRESS, &buf_wd); + pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &buf_wd); buf_wd &= ~PCI_ROM_ADDRESS_ENABLE; pci_write_config_word (ha->pdev, PCI_ROM_ADDRESS, buf_wd); @@ -2489,23 +2312,16 @@ #if MEMORY_MAPPED_IO /* - * Get memory mapped I/O address. - */ - pci_read_config_word (ha->pdev, PCI_BASE_ADDRESS_1, &mmapbase); - mmapbase &= PCI_BASE_ADDRESS_MEM_MASK; - - /* * Find proper memory chunk for memory map I/O reg. */ - base = mmapbase & PAGE_MASK; - page_offset = mmapbase - base; + base = pci_resource_start(ha->pdev, 1); + size = pci_resource_len(ha->pdev, 1); /* * Get virtual address for I/O registers. */ - ha->mmpbase = ioremap(base, page_offset + 256); + ha->mmpbase = ioremap(base, size); if (ha->mmpbase) { - ha->mmpbase += page_offset; - /* ha->iobase = ha->mmpbase; */ + ha->iobase = (struct device_reg *)ha->mmpbase; status = 0; } #else /* MEMORY_MAPPED_IO */ @@ -2537,50 +2353,69 @@ dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", ®->id_l); + dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no); + /* Soft reset chip and wait for it to finish. */ WRT_REG_WORD(®->ictrl, ISP_RESET); + /* + * We can't do a traditional PCI write flush here by reading + * back the register. The card will not respond once the reset + * is in action and we end up with a machine check exception + * instead. Nothing to do but wait and hope for the best. + * A portable pci_write_flush(pdev) call would be very useful here. + */ + udelay(20); data = qla1280_debounce_register(®->ictrl); /* - * This is *AWESOME* + * Yet another QLogic gem ;-( */ - for (cnt = 6000000; cnt && data & ISP_RESET; cnt--) { + for (cnt = 1000000; cnt && data & ISP_RESET; cnt--) { udelay(5); data = RD_REG_WORD(®->ictrl); } + if (cnt) { - /* Reset register not cleared by chip reset. */ - dprintk(3, - "qla1280_chip_diag: reset register cleared by chip reset\n"); + /* Reset register cleared by chip reset. */ + dprintk(3, "qla1280_chip_diag: reset register cleared by " + "chip reset\n"); WRT_REG_WORD(®->cfg_1, 0); /* Reset RISC and disable BIOS which allows RISC to execute out of RAM. */ +#if 0 WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); + RD_REG_WORD(®->id_l); /* Flush PCI write */ WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); + RD_REG_WORD(®->id_l); /* Flush PCI write */ WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); +#else + WRT_REG_WORD(®->host_cmd, HC_RESET_RISC | + HC_RELEASE_RISC | HC_DISABLE_BIOS); +#endif + RD_REG_WORD(®->id_l); /* Flush PCI write */ data = qla1280_debounce_register(®->mailbox0); /* * I *LOVE* this code! */ - for (cnt = 6000000; cnt && data == MBS_BUSY; cnt--) { + for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) { udelay(5); data = RD_REG_WORD(®->mailbox0); } if (cnt) { /* Check product ID of chip */ - dprintk(3, - "qla1280_chip_diag: Checking product ID of chip\n"); + dprintk(3, "qla1280_chip_diag: Checking product " + "ID of chip\n"); if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 || (RD_REG_WORD(®->mailbox2) != PROD_ID_2 && RD_REG_WORD(®->mailbox2) != PROD_ID_2a) || RD_REG_WORD(®->mailbox3) != PROD_ID_3 || RD_REG_WORD(®->mailbox4) != PROD_ID_4) { - printk(KERN_INFO - "qla1280: Wrong product ID = 0x%x,0x%x,0x%x," - "0x%x\n", RD_REG_WORD(®->mailbox1), + printk(KERN_INFO "qla1280: Wrong product ID = " + "0x%x,0x%x,0x%x,0x%x\n", + RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2), RD_REG_WORD(®->mailbox3), RD_REG_WORD(®->mailbox4)); @@ -2590,8 +2425,9 @@ * Enable ints early!!! */ qla1280_enable_intrs(ha); - dprintk(1, - "qla1280_chip_diag: Checking mailboxes of chip\n"); + + dprintk(1, "qla1280_chip_diag: Checking " + "mailboxes of chip\n"); /* Wrap Incoming Mailboxes Test. */ mb[0] = MBC_MAILBOX_REGISTER_TEST; mb[1] = 0xAAAA; @@ -2602,14 +2438,7 @@ mb[6] = 0x5A5A; mb[7] = 0x2525; if (!(status = qla1280_mailbox_command(ha, - BIT_7 | - BIT_6 | - BIT_5 | - BIT_4 | - BIT_3 | - BIT_2 | - BIT_1 | - BIT_0, + 0xff, &mb [0]))) { if (mb[1] != 0xAAAA || @@ -2618,11 +2447,11 @@ mb[4] != 0x55AA || mb[5] != 0xA5A5 || mb[6] != 0x5A5A || - mb[7] != 0x2525) + mb[7] != 0x2525) { status = 1; - if (status == 1) - printk(KERN_INFO - "qla1280: Failed mailbox check\n"); + printk(KERN_INFO "qla1280: " + "Failed mbox check\n"); + } } } } else @@ -2648,7 +2477,7 @@ * Returns: * 0 = success. */ -#define DUMP_IT_BACK 1 /* for debug of RISC loading */ +#define DUMP_IT_BACK 0 /* for debug of RISC loading */ static int qla1280_setup_chip(struct scsi_qla_host *ha) { @@ -2658,9 +2487,8 @@ int risc_code_size; uint16_t mb[MAILBOX_REGISTER_COUNT]; uint16_t cnt; - int num; + int num, i; #if DUMP_IT_BACK - int i; uint8_t *sp; uint8_t *tbuf; dma_addr_t p_tbuf; @@ -2668,7 +2496,8 @@ ENTER("qla1280_setup_chip"); - /* 3.13 */ + dprintk(1, "scsi(%ld): Setup chip\n", ha->host_no); + #if DUMP_IT_BACK /* get consistent memory allocated for setup_chip */ tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf); @@ -2691,7 +2520,7 @@ if (cnt > risc_code_size) cnt = risc_code_size; - dprintk(1, "qla1280_setup_chip: loading risc @ =(0x%p)," + dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," "%d,%d(0x%x)\n", risc_code_address, cnt, num, risc_address); for(i = 0; i < cnt; i++) @@ -2703,18 +2532,18 @@ mb[0] = MBC_LOAD_RAM; mb[1] = risc_address; mb[4] = cnt; - mb[3] = qla1280_addr0_15(ha->request_dma); - mb[2] = qla1280_addr16_31(ha->request_dma); - mb[7] = qla1280_addr32_47(ha->request_dma); - mb[6] = qla1280_addr48_63(ha->request_dma); - dprintk(1, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x," - "0x%4x,0x%4x\n", - mb[0], (void *)ha->request_dma, mb[6], mb[7], mb[2], mb[3]); + mb[3] = ha->request_dma & 0xffff; + mb[2] = (ha->request_dma >> 16) & 0xffff; + mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff; + mb[6] = pci_dma_hi32(ha->request_dma) >> 16; + dprintk(2, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x," + "0x%4x,0x%4x\n", mb[0], (void *)(long)ha->request_dma, + mb[6], mb[7], mb[2], mb[3]); if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0, &mb[0]))) { - printk(KERN_ERR - "Failed to load partial segment of f/w\n"); + printk(KERN_ERR "scsi(%li): Failed to load partial " + "segment of f\n", ha->host_no); break; } @@ -2722,10 +2551,10 @@ mb[0] = MBC_DUMP_RAM; mb[1] = risc_address; mb[4] = cnt; - mb[3] = qla1280_addr0_15(p_tbuf); - mb[2] = qla1280_addr16_31(p_tbuf); - mb[7] = qla1280_addr32_47(p_tbuf); - mb[6] = qla1280_addr48_63(p_tbuf); + mb[3] = p_tbuf & 0xffff; + mb[2] = (p_tbuf >> 16) & 0xffff; + mb[7] = pci_dma_hi32(p_tbuf) & 0xffff; + mb[6] = pci_dma_hi32(p_tbuf) >> 16; if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 | @@ -2737,7 +2566,7 @@ } sp = (uint8_t *)ha->request_ring; for (i = 0; i < (cnt << 1); i++) { - if (tbuf[i] != sp[i] &&warn++ < 10) { + if (tbuf[i] != sp[i] && warn++ < 10) { printk(KERN_ERR "qla1280_setup_chip: FW " "compare error @ byte(0x%x) loop#=%x\n", i, num); @@ -2770,11 +2599,10 @@ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); } else - printk(KERN_ERR - "qla1280_setup_chip: Failed checksum.\n"); + printk(KERN_ERR "scsi(%li): qla1280_setup_chip: " + "Failed checksum\n", ha->host_no); } - /* 3.13 */ #if DUMP_IT_BACK /* free consistent memory allocated for setup_chip */ pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); @@ -2805,13 +2633,12 @@ { uint16_t mb[MAILBOX_REGISTER_COUNT]; int status = 0; - int cnt; ENTER("qla1280_init_rings"); /* Clear outstanding commands array. */ - for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) - ha->outstanding_cmds[cnt] = 0; + memset(ha->outstanding_cmds, 0, + sizeof(struct srb *) * MAX_OUTSTANDING_COMMANDS); /* Initialize request queue. */ ha->request_ring_ptr = ha->request_ring; @@ -2868,61 +2695,51 @@ qla1280_nvram_config(struct scsi_qla_host *ha) { struct device_reg *reg = ha->iobase; - nvram_t *nv = (nvram_t *)ha->response_ring; - int status = 0; - int cnt; + struct nvram *nv; + int is1x160, status = 0; int bus, target, lun; - uint16_t *wptr; uint16_t mb[MAILBOX_REGISTER_COUNT]; - uint8_t chksum; - int nvsize; + uint16_t mask; -#if DEBUG_PRINT_NVRAM - int saved_print_status = ql_debug_print; -#endif ENTER("qla1280_nvram_config"); - /* Verify valid NVRAM checksum. */ -#if USE_NVRAM_DEFAULTS - chksum = 1; -#else - wptr = (uint16_t *) ha->response_ring; - chksum = 0; if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) - nvsize = sizeof(nvram160_t) / 2; + is1x160 = 1; else - nvsize = sizeof(nvram_t) / 2; - for (cnt = 0; cnt < nvsize; cnt++) { - *wptr = qla1280_get_nvram_word(ha, cnt); - chksum += (uint8_t) * wptr; - chksum += (uint8_t) (*wptr >> 8); - wptr++; - } -#endif + is1x160 = 0; - /* Bad NVRAM data, set defaults parameters. */ - if (chksum || nv->id0 != 'I' || nv->id1 != 'S' || - nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) { -#if USE_NVRAM_DEFAULTS - dprintk(1, "Using defaults for NVRAM\n"); -#else + nv = &ha->nvram; + if (!ha->nvram_valid) { dprintk(1, "Using defaults for NVRAM: \n"); - dprintk(1, "checksum=0x%x, Id=%c, version=0x%x\n", - chksum, nv->id[0], nv->version); - memset(ha->response_ring, 0, sizeof(nvram_t)); -#endif + memset(nv, 0, sizeof(struct nvram)); /* nv->cntr_flags_1.disable_loading_risc_code = 1; */ - nv->firmware_feature.w = BIT_0; + nv->firmware_feature.f.enable_fast_posting = 1; + nv->firmware_feature.f.disable_synchronous_backoff = 1; + nv->termination.f.scsi_bus_0_control = 3; nv->termination.f.scsi_bus_1_control = 3; nv->termination.f.auto_term_support = 1; + /* + * Set default FIFO magic - What appropriate values + * would be here is unknown. This is what I have found + * testing with 12160s. + * Now, I would love the magic decoder ring for this one, + * the header file provided by QLogic seems to be bogus + * or incomplete at best. + */ + nv->isp_config.c = 0x44; + + if (is1x160) + nv->isp_parameter = 0x01; + for (bus = 0; bus < MAX_BUSES; bus++) { nv->bus[bus].config_1.initiator_id = 7; nv->bus[bus].bus_reset_delay = 5; - nv->bus[bus].config_2.async_data_setup_time = 9; + /* 8 = 5.0 clocks */ + nv->bus[bus].config_2.async_data_setup_time = 8; nv->bus[bus].config_2.req_ack_active_negation = 1; nv->bus[bus].config_2.data_line_active_negation = 1; nv->bus[bus].selection_timeout = 250; @@ -2930,21 +2747,46 @@ for (target = 0; target < MAX_TARGETS; target++) { nv->bus[bus].target[target].parameter.f. - auto_request_sense = 1; + renegotiate_on_error = 1; nv->bus[bus].target[target].parameter.f. - disconnect_allowed = 1; + auto_request_sense = 1; nv->bus[bus].target[target].parameter.f. tag_queuing = 1; - nv->bus[bus].target[target].flags. - device_enable = 1; + nv->bus[bus].target[target].parameter.f. + enable_sync = 1; +#if 1 /* Some SCSI Processors do not seem to like this */ + nv->bus[bus].target[target].parameter.f. + enable_wide = 1; +#endif + nv->bus[bus].target[target].parameter.f. + parity_checking = 1; + nv->bus[bus].target[target].parameter.f. + disconnect_allowed = 1; + nv->bus[bus].target[target].execution_throttle= + nv->bus[bus].max_queue_depth - 1; + if (is1x160) { + nv->bus[bus].target[target].flags. + flags1x160.device_enable = 1; + nv->bus[bus].target[target].flags. + flags1x160.sync_offset = 0x0e; + nv->bus[bus].target[target]. + sync_period = 9; + nv->bus[bus].target[target]. + ppr_1x160.flags.enable_ppr = 1; + nv->bus[bus].target[target].ppr_1x160. + flags.ppr_options = 2; + nv->bus[bus].target[target].ppr_1x160. + flags.ppr_bus_width = 1; + } else { + nv->bus[bus].target[target].flags. + flags1x80.device_enable = 1; + nv->bus[bus].target[target].flags. + flags1x80.sync_offset = 0x8; + nv->bus[bus].target[target]. + sync_period = 10; + } } } - -#if USE_NVRAM_DEFAULTS - status = 0; -#else - status = 1; -#endif } else { /* Always force AUTO sense for LINUX SCSI */ for (bus = 0; bus < MAX_BUSES; bus++) @@ -2953,9 +2795,6 @@ auto_request_sense = 1; } } -#if DEBUG_PRINT_NVRAM - ql_debug_print = 1; -#endif dprintk(1, "qla1280 : initiator scsi id bus[0]=%d\n", nv->bus[0].config_1.initiator_id); dprintk(1, "qla1280 : initiator scsi id bus[1]=%d\n", @@ -3016,33 +2855,50 @@ ha->flags.enable_64bit_addressing = 0; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) if (ha->flags.enable_64bit_addressing) { - printk(KERN_INFO "scsi(%li): 64 Bit PCI Addressing Enabled\n", - ha->host_no); + dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n", + ha->host_no); pci_set_dma_mask(ha->pdev, (dma_addr_t) ~ 0ULL); } -#endif /* Set ISP hardware DMA burst */ mb[0] = nv->isp_config.c; + /* Enable DMA arbitration on dual channel controllers */ + if (ha->ports > 1) + mb[0] |= BIT_13; WRT_REG_WORD(®->cfg_1, mb[0]); +#if 1 /* Is this safe? */ /* Set SCSI termination. */ WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0)); mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0); WRT_REG_WORD(®->gpio_data, mb[0]); +#endif /* ISP parameter word. */ mb[0] = MBC_SET_SYSTEM_PARAMETER; mb[1] = nv->isp_parameter; status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); +#if 0 + /* clock rate - for qla1240 and older, only */ + mb[0] = MBC_SET_CLOCK_RATE; + mb[1] = 0x50; + status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); +#endif /* Firmware feature word. */ mb[0] = MBC_SET_FIRMWARE_FEATURES; - mb[1] = nv->firmware_feature.w & (BIT_1 | BIT_0); - status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + mask = BIT_5 | BIT_1 | BIT_0; + mb[1] = le16_to_cpu(nv->firmware_feature.w) & (mask); +#if defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_SGI_SN2) + if (ia64_platform_is("sn2")) { + printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA " + "workaround\n", ha->host_no); + mb[1] |= BIT_9; + } +#endif + status |= qla1280_mailbox_command(ha, mask, &mb[0]); /* Retry count and delay. */ mb[0] = MBC_SET_RETRY_COUNT; @@ -3050,9 +2906,8 @@ mb[2] = nv->bus[0].retry_delay; mb[6] = nv->bus[1].retry_count; mb[7] = nv->bus[1].retry_delay; - status |= - qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_2 | BIT_1 | BIT_0, - &mb[0]); + status |= qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_2 | + BIT_1 | BIT_0, &mb[0]); /* ASYNC data setup time. */ mb[0] = MBC_SET_ASYNC_DATA_SETUP; @@ -3074,6 +2929,16 @@ mb[2] |= BIT_4; status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + mb[0] = MBC_SET_DATA_OVERRUN_RECOVERY; + mb[1] = 2; /* Reset SCSI bus and return all outstanding IO */ + status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + + /* thingy */ + mb[0] = MBC_SET_PCI_CONTROL; + mb[1] = 2; /* Data DMA Channel Burst Enable */ + mb[2] = 2; /* Command DMA Channel Burst Enable */ + status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); + /* Selection timeout. */ mb[0] = MBC_SET_SELECTION_TIMEOUT; mb[1] = nv->bus[0].selection_timeout; @@ -3101,36 +2966,52 @@ /* Set target parameters. */ for (target = 0; target < MAX_TARGETS; target++) { - uint8_t mr = BIT_3 | BIT_2 | BIT_1 | BIT_0; + uint8_t mr = BIT_2 | BIT_1 | BIT_0; /* Set Target Parameters. */ mb[0] = MBC_SET_TARGET_PARAMETERS; mb[1] = (uint16_t) (bus ? target | BIT_7 : target); mb[1] <<= 8; + /* + * Do not enable wide, sync, and ppr for the initial + * INQUIRY run. We enable this later if we determine + * the target actually supports it. + */ + nv->bus[bus].target[target].parameter.f. + auto_request_sense = 1; + nv->bus[bus].target[target].parameter.f. + stop_queue_on_check = 0; + + if (is1x160) + nv->bus[bus].target[target].ppr_1x160. + flags.enable_ppr = 0; + /* + * No sync, wide, etc. while probing + */ + mb[2] = (nv->bus[bus].target[target].parameter.c << 8)& + ~(TP_SYNC /*| TP_WIDE | TP_PPR*/); - mb[2] = nv->bus[bus].target[target].parameter.c << 8; - mb[2] |= TP_AUTO_REQUEST_SENSE; - mb[2] &= ~TP_STOP_QUEUE; - - mb[3] = - nv->bus[bus].target[target].flags.sync_offset << 8; + if (is1x160) + mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8; + else + mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8; mb[3] |= nv->bus[bus].target[target].sync_period; + mr |= BIT_3; - if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || - ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) { - nvram160_t *nv2 = (nvram160_t *) nv; - mb[2] |= - nv2->bus[bus].target[target].flags2. - enable_ppr << 5; - - mb[6] = - nv2->bus[bus].target[target].flags2. - ppr_options << 8; - mb[6] |= - nv2->bus[bus].target[target].flags2. - ppr_bus_width; + /* + * We don't want to enable ppr etc. before we have + * determined that the target actually supports it + */ +#if 0 + if (is1x160) { + mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5; + + mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8; + mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width; mr |= BIT_6; } +#endif + status = qla1280_mailbox_command(ha, mr, &mb[0]); /* Save Tag queuing enable flag. */ @@ -3139,12 +3020,18 @@ ha->bus_settings[bus].qtag_enables |= mb[0]; /* Save Device enable flag. */ - if (nv->bus[bus].target[target].flags.device_enable) - ha->bus_settings[bus].device_enables |= mb[0]; - - /* Save LUN disable flag. */ - if (nv->bus[bus].target[target].flags.lun_disable) + if (is1x160) { + if (nv->bus[bus].target[target].flags.flags1x160.device_enable) + ha->bus_settings[bus].device_enables |= mb[0]; + ha->bus_settings[bus].lun_disables |= 0; + } else { + if (nv->bus[bus].target[target].flags.flags1x80.device_enable) + ha->bus_settings[bus].device_enables |= mb[0]; + /* Save LUN disable flag. */ + if (nv->bus[bus].target[target].flags.flags1x80.lun_disable) ha->bus_settings[bus].lun_disables |= mb[0]; + } + /* Set Device Queue Parameters. */ for (lun = 0; lun < MAX_LUNS; lun++) { @@ -3153,19 +3040,12 @@ mb[1] = mb[1] << 8 | lun; mb[2] = nv->bus[bus].max_queue_depth; mb[3] = nv->bus[bus].target[target].execution_throttle; - status |= - qla1280_mailbox_command(ha, - BIT_3 | BIT_2 | - BIT_1 | BIT_0, - &mb[0]); + status |= qla1280_mailbox_command(ha, 0x0f, + &mb[0]); } } } -#if DEBUG_PRINT_NVRAM - ql_debug_print = saved_print_status; -#endif - if (status) dprintk(2, "qla1280_nvram_config: **** FAILED ****\n"); @@ -3191,24 +3071,13 @@ uint32_t nv_cmd; uint16_t data; -#ifdef QL_DEBUG_ROUTINES - int saved_print_status = ql_debug_print; -#endif - nv_cmd = address << 16; nv_cmd |= NV_READ_OP; -#ifdef QL_DEBUG_ROUTINES - ql_debug_print = FALSE; -#endif - data = qla1280_nvram_request(ha, nv_cmd); -#ifdef QL_DEBUG_ROUTINES - ql_debug_print = saved_print_status; -#endif + data = le16_to_cpu(qla1280_nvram_request(ha, nv_cmd)); - dprintk(4, - "qla1280_get_nvram_word: exiting normally NVRAM data = 0x%x", - data); + dprintk(8, "qla1280_get_nvram_word: exiting normally NVRAM data = " + "0x%x", data); return data; } @@ -3250,18 +3119,21 @@ for (cnt = 0; cnt < 16; cnt++) { WRT_REG_WORD(®->nvram, (NV_SELECT | NV_CLOCK)); + RD_REG_WORD(®->id_l); /* Flush PCI write */ NVRAM_DELAY(); data <<= 1; reg_data = RD_REG_WORD(®->nvram); if (reg_data & NV_DATA_IN) data |= BIT_0; WRT_REG_WORD(®->nvram, NV_SELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ NVRAM_DELAY(); } /* Deselect chip. */ WRT_REG_WORD(®->nvram, NV_DESELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ NVRAM_DELAY(); return data; @@ -3273,10 +3145,13 @@ struct device_reg *reg = ha->iobase; WRT_REG_WORD(®->nvram, data | NV_SELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ NVRAM_DELAY(); WRT_REG_WORD(®->nvram, data | NV_SELECT | NV_CLOCK); + RD_REG_WORD(®->id_l); /* Flush PCI write */ NVRAM_DELAY(); WRT_REG_WORD(®->nvram, data | NV_SELECT); + RD_REG_WORD(®->id_l); /* Flush PCI write */ NVRAM_DELAY(); } @@ -3296,29 +3171,32 @@ * 0 = success */ static int -qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t * mb) +qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb) { struct device_reg *reg = ha->iobase; #if 0 - srb_t *done_q_first = 0; - srb_t *done_q_last = 0; + struct srb *done_q_first = 0; + struct srb *done_q_last = 0; #endif int status = 0; int cnt; uint16_t *optr, *iptr; uint16_t data; + DECLARE_COMPLETION(wait); + struct timer_list timer; ENTER("qla1280_mailbox_command"); - ha->flags.mbox_busy = TRUE; + ha->flags.mbox_busy = 1; + + if (ha->mailbox_wait) { + printk(KERN_ERR "Warning mailbox wait already in use!\n"); + } + ha->mailbox_wait = &wait; - if (!ha->flags.ints_enabled) - printk(KERN_DEBUG - "Running qla1280_mailbox_command() with interrupts " - "disabled!\n"); /* - * We really should start out by verifying that the mailbox is available - * before starting sending the command data + * We really should start out by verifying that the mailbox is + * available before starting sending the command data */ /* Load mailbox registers. */ optr = (uint16_t *) ®->mailbox0; @@ -3334,41 +3212,44 @@ } /* Issue set host interrupt command. */ - ha->flags.mbox_int = FALSE; - ha->flags.mbox_busy = FALSE; + ha->flags.mbox_busy = 0; + + /* set up a timer just in case we're really jammed */ + init_timer(&timer); + timer.expires = jiffies + 20*HZ; + timer.data = (unsigned long)ha; + timer.function = qla1280_mailbox_timeout; + add_timer(&timer); + +#if LINUX_VERSION_CODE < 0x020500 + spin_unlock_irq(HOST_LOCK); +#endif WRT_REG_WORD(®->host_cmd, HC_SET_HOST_INT); data = qla1280_debounce_register(®->istatus); - /* - * This is insane - instead of looping to wait for the interrupt - * to appear and run the handler (this is insane!!), use a waitqueue - * and go to sleep. - * - * We are never called here from interrupt context anyway! /Jes - */ - /* Wait for 30 seconds for command to finish. */ - for (cnt = 30000000; cnt > 0 && !ha->flags.mbox_int; cnt--) { - /* Check for pending interrupts. */ -#if 0 - if (data & RISC_INT) { - qla1280_isr(ha, &done_q_first, &done_q_last); - } else + wait_for_completion(&wait); + del_timer_sync(&timer); + +#if LINUX_VERSION_CODE < 0x020500 + spin_lock_irq(HOST_LOCK); #endif - udelay(1); - data = RD_REG_WORD(®->istatus); - } + ha->mailbox_wait = NULL; /* Check for mailbox command timeout. */ - if (!cnt) { - printk(KERN_WARNING - "qla1280_mailbox_command: **** Command Timeout, " - "mailbox0 = 0x%x****\n", mb[0]); - - ha->flags.isp_abort_needed = TRUE; - status = 1; - } else if (ha->mailbox_out[0] != MBS_CMD_CMP) + if (ha->mailbox_out[0] != MBS_CMD_CMP) { + printk(KERN_WARNING "qla1280_mailbox_command: Command failed, " + "mailbox0 = 0x%04x, mailbox_out0 = 0x%04x, istatus = " + "0x%04x\n", + mb[0], ha->mailbox_out[0], RD_REG_WORD(®->istatus)); + printk(KERN_WARNING "m0 %04x, m1 %04x, m2 %04x, m3 %04x\n", + RD_REG_WORD(®->mailbox0), RD_REG_WORD(®->mailbox1), + RD_REG_WORD(®->mailbox2), RD_REG_WORD(®->mailbox3)); + printk(KERN_WARNING "m4 %04x, m5 %04x, m6 %04x, m7 %04x\n", + RD_REG_WORD(®->mailbox4), RD_REG_WORD(®->mailbox5), + RD_REG_WORD(®->mailbox6), RD_REG_WORD(®->mailbox7)); status = 1; + } /* Load return mailbox registers. */ optr = mb; @@ -3381,9 +3262,6 @@ qla1280_isr(ha, &done_q_first, &done_q_last); #endif - if (ha->flags.isp_abort_needed) - qla1280_abort_isp(ha); - if (ha->flags.reset_marker) qla1280_rst_aen(ha); @@ -3393,9 +3271,8 @@ #endif if (status) - dprintk(2, - "qla1280_mailbox_command: **** FAILED, mailbox0 = 0x%x " - "****n", mb[0]); + dprintk(2, "qla1280_mailbox_command: **** FAILED, mailbox0 = " + "0x%x ****\n", mb[0]); LEAVE("qla1280_mailbox_command"); return status; @@ -3413,8 +3290,8 @@ { struct device_reg *reg = ha->iobase; uint16_t data; - srb_t *done_q_first = 0; - srb_t *done_q_last = 0; + struct srb *done_q_first = 0; + struct srb *done_q_last = 0; /* ENTER("qla1280_poll"); */ @@ -3424,8 +3301,6 @@ qla1280_isr(ha, &done_q_first, &done_q_last); if (!ha->flags.mbox_busy) { - if (ha->flags.isp_abort_needed) - qla1280_abort_isp(ha); if (ha->flags.reset_marker) qla1280_rst_aen(ha); } @@ -3451,38 +3326,42 @@ qla1280_bus_reset(struct scsi_qla_host *ha, int bus) { uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint16_t reset_delay; int status; dprintk(3, "qla1280_bus_reset: entered\n"); if (qla1280_verbose) - printk(KERN_INFO "scsi(%li): Resetting SCSI BUS (%i)\n", + printk(KERN_INFO "scsi(%li:%i): Resetting SCSI BUS\n", ha->host_no, bus); + reset_delay = ha->bus_settings[bus].bus_reset_delay; mb[0] = MBC_BUS_RESET; - mb[1] = ha->bus_settings[bus].bus_reset_delay; + mb[1] = reset_delay; mb[2] = (uint16_t) bus; status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]); if (status) { - if (ha->bus_settings[bus].failed_reset_count > 2) /* dg - 03/13/99 */ - ha->bus_settings[bus].scsi_bus_dead = TRUE; + if (ha->bus_settings[bus].failed_reset_count > 2) + ha->bus_settings[bus].scsi_bus_dead = 1; ha->bus_settings[bus].failed_reset_count++; } else { - /* - * Eeeeep! This is evil! /Jes - */ -#if 0 - mdelay(4000); -#else - schedule_timeout(4 * HZ); -#endif - ha->bus_settings[bus].scsi_bus_dead = FALSE; /* dg - 03/13/99 */ + spin_unlock_irq(HOST_LOCK); + schedule_timeout(reset_delay * HZ); + spin_lock_irq(HOST_LOCK); + + ha->bus_settings[bus].scsi_bus_dead = 0; ha->bus_settings[bus].failed_reset_count = 0; + ha->bus_settings[bus].reset_marker = 0; /* Issue marker command. */ qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL); } + /* + * We should probably call qla1280_set_target_parameters() + * here as well for all devices on the bus. + */ + if (status) dprintk(2, "qla1280_bus_reset: **** FAILED ****\n"); else @@ -3573,35 +3452,31 @@ * 0 = success */ static int -qla1280_abort_command(struct scsi_qla_host *ha, srb_t * sp) +qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle) { uint16_t mb[MAILBOX_REGISTER_COUNT]; unsigned int bus, target, lun; - uint32_t handle; int status; ENTER("qla1280_abort_command"); - /* Locate handle number. */ - for (handle = 0; handle < MAX_OUTSTANDING_COMMANDS; handle++) - if (ha->outstanding_cmds[handle] == sp) - break; - bus = SCSI_BUS_32(sp->cmd); target = SCSI_TCN_32(sp->cmd); lun = SCSI_LUN_32(sp->cmd); + sp->flags |= SRB_ABORT_PENDING; + mb[0] = MBC_ABORT_COMMAND; mb[1] = (bus ? target | BIT_7 : target) << 8 | lun; mb[2] = handle >> 16; mb[3] = handle & 0xffff; - status = - qla1280_mailbox_command(ha, BIT_3 | BIT_2 | BIT_1 | BIT_0, &mb[0]); + status = qla1280_mailbox_command(ha, 0x0f, &mb[0]); - if (status) + if (status) { dprintk(2, "qla1280_abort_command: **** FAILED ****\n"); + sp->flags &= ~SRB_ABORT_PENDING; + } - sp->flags |= SRB_ABORT_PENDING; LEAVE("qla1280_abort_command"); return status; @@ -3622,11 +3497,11 @@ ENTER("qla1280_reset_adapter"); /* Disable ISP chip */ - ha->flags.online = FALSE; + ha->flags.online = 0; WRT_REG_WORD(®->ictrl, ISP_RESET); - WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); - WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); - WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); + WRT_REG_WORD(®->host_cmd, + HC_RESET_RISC | HC_RELEASE_RISC | HC_DISABLE_BIOS); + RD_REG_WORD(®->id_l); /* Flush PCI write */ LEAVE("qla1280_reset_adapter"); } @@ -3645,16 +3520,17 @@ static void qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type) { - mrk_entry_t *pkt; + struct mrk_entry *pkt; ENTER("qla1280_marker"); /* Get request packet. */ - if ((pkt = (mrk_entry_t *) qla1280_req_pkt(ha))) { + if ((pkt = (struct mrk_entry *) qla1280_req_pkt(ha))) { pkt->entry_type = MARKER_TYPE; pkt->lun = (uint8_t) lun; pkt->target = (uint8_t) (bus ? (id | BIT_7) : id); pkt->modifier = type; + pkt->entry_status = 0; /* Issue command to ISP */ qla1280_isp_cmd(ha); @@ -3663,7 +3539,7 @@ LEAVE("qla1280_marker"); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) + /* * qla1280_64bit_start_scsi * The start SCSI is responsible for building request packets on @@ -3677,7 +3553,7 @@ * 0 = success, was able to issue command. */ static int -qla1280_64bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp) +qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { struct device_reg *reg = ha->iobase; Scsi_Cmnd *cmd = sp->cmd; @@ -3692,15 +3568,12 @@ ENTER("qla1280_64bit_start_scsi:"); - dprintk(1, "64bit_start: cmd=%p sp=%p CDB=%x\n", cmd, sp, - cmd->cmnd[0]); - /* Calculate number of entries and segments required. */ req_cnt = 1; - if (cmd->use_sg) { /* 3.13 64 bit */ + if (cmd->use_sg) { sg = (struct scatterlist *) cmd->request_buffer; - seg_cnt = pci_map_sg (ha->pdev, sg, cmd->use_sg, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); if (seg_cnt > 2) { req_cnt += (seg_cnt - 2) / 5; @@ -3724,220 +3597,218 @@ } /* If room for request in request ring. */ - if ((req_cnt + 2) < ha->req_q_cnt) { - /* Check for room in outstanding command list. */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS && - ha->outstanding_cmds[cnt] != 0; cnt++) ; - - if (cnt < MAX_OUTSTANDING_COMMANDS) { - ha->outstanding_cmds[cnt] = sp; - ha->req_q_cnt -= req_cnt; - CMD_HANDLE(sp->cmd) = - (unsigned char *)(unsigned long)cnt; + if ((req_cnt + 2) >= ha->req_q_cnt) { + status = 1; + dprintk(2, "qla1280_64bit_start_scsi: in-ptr=0x%x req_q_cnt=" + "0x%xreq_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt, + req_cnt); + goto out; + } - /* - * Build command packet. - */ - pkt = (cmd_a64_entry_t *) ha->request_ring_ptr; + /* Check for room in outstanding command list. */ + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && + ha->outstanding_cmds[cnt] != 0; cnt++); - pkt->entry_type = COMMAND_A64_TYPE; - pkt->entry_count = (uint8_t) req_cnt; - pkt->sys_define = (uint8_t) ha->req_ring_index; - pkt->handle = cpu_to_le32(cnt); + if (cnt >= MAX_OUTSTANDING_COMMANDS) { + status = 1; + dprintk(2, "qla1280_64bit_start_scsi: NO ROOM IN " + "OUTSTANDING ARRAY, req_q_cnt=0x%x", ha->req_q_cnt); + goto out; + } + + ha->outstanding_cmds[cnt] = sp; + ha->req_q_cnt -= req_cnt; + CMD_HANDLE(sp->cmd) = (unsigned char *)(unsigned long)(cnt + 1); + + dprintk(2, "64bit_start: cmd=%p sp=%p CDB=%xm, handle %lx\n", cmd, sp, + cmd->cmnd[0], (long)CMD_HANDLE(sp->cmd)); + dprintk(2, " bus %i, target %i, lun %i\n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); + qla1280_dump_buffer(2, cmd->cmnd, MAX_COMMAND_SIZE); - /* Zero out remaining portion of packet. */ - memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); + /* + * Build command packet. + */ + pkt = (cmd_a64_entry_t *) ha->request_ring_ptr; - /* Set ISP command timeout. */ - pkt->timeout = cpu_to_le16(30); + pkt->entry_type = COMMAND_A64_TYPE; + pkt->entry_count = (uint8_t) req_cnt; + pkt->sys_define = (uint8_t) ha->req_ring_index; + pkt->entry_status = 0; + pkt->handle = cpu_to_le32(cnt); + + /* Zero out remaining portion of packet. */ + memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); + + /* Set ISP command timeout. */ + pkt->timeout = cpu_to_le16(30); + + /* Set device target ID and LUN */ + pkt->lun = SCSI_LUN_32(cmd); + pkt->target = SCSI_BUS_32(cmd) ? + (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); + + /* Enable simple tag queuing if device supports it. */ + if (cmd->device->tagged_queue) + pkt->control_flags |= cpu_to_le16(BIT_3); + + /* Load SCSI command packet. */ + pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); + /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ + + /* Set transfer direction. */ + sp->dir = qla1280_data_direction(cmd); + pkt->control_flags |= cpu_to_le16(sp->dir); - /* Set device target ID and LUN */ - pkt->lun = SCSI_LUN_32(cmd); - pkt->target = SCSI_BUS_32(cmd) ? - (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); - - /* Enable simple tag queuing if device supports it. */ - if (cmd->device->tagged_queue) - pkt->control_flags |= cpu_to_le16(BIT_3); - - /* Load SCSI command packet. */ - pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); - memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); - /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ - - /* Set transfer direction. */ - sp->dir = qla1280_data_direction(cmd); - pkt->control_flags |= cpu_to_le16(sp->dir); - - /* Set total data segment count. */ - pkt->dseg_count = cpu_to_le16(seg_cnt); + /* Set total data segment count. */ + pkt->dseg_count = cpu_to_le16(seg_cnt); + + /* + * Load data segments. + */ + if (seg_cnt) { /* If data transfer. */ + /* Setup packet address segment pointer. */ + dword_ptr = (u32 *)&pkt->dseg_0_address; + + if (cmd->use_sg) { /* If scatter gather */ + /* Load command entry data segments. */ + for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) { + dma_handle = sg_dma_address(sg); +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ha->flags.use_pci_vchannel) + sn_pci_set_vchan(ha->pdev, &dma_handle, + SCSI_BUS_32(cmd)); +#endif + *dword_ptr++ = + cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr++ = + cpu_to_le32(pci_dma_hi32(dma_handle)); + *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); + sg++; + dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n", + cpu_to_le32(pci_dma_hi32(dma_handle)), + cpu_to_le32(pci_dma_lo32(dma_handle)), + cpu_to_le32(sg_dma_len(sg))); + } + dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather " + "command packet data - b %i, t %i, l %i \n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), + SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, + REQUEST_ENTRY_SIZE); /* - * Load data segments. + * Build continuation packets. */ - if (seg_cnt) { /* If data transfer. */ - /* Setup packet address segment pointer. */ - dword_ptr = (u32 *)&pkt->dseg_0_address; + dprintk(3, "S/G Building Continuation...seg_cnt=0x%x " + "remains\n", seg_cnt); - if (cmd->use_sg) { /* If scatter gather */ - /* Load command entry data segments. */ - for (cnt = 0; cnt < 2 && seg_cnt; - cnt++, seg_cnt--) { - /* 3.13 64 bit */ - *dword_ptr++ = - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); - *dword_ptr++ = - cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))); - *dword_ptr++ = - cpu_to_le32(sg_dma_len(sg)); - sg++; - dprintk(1, - "S/G Segment phys_addr=%x %x, len=0x%x\n", - cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))), - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), - cpu_to_le32(sg_dma_len(sg))); - } - dprintk(5, - "qla1280_64bit_start_scsi: Scatter/gather " - "command packet data - b %i, t %i, l %i \n", - SCSI_BUS_32(cmd), - SCSI_TCN_32(cmd), - SCSI_LUN_32(cmd)); - qla1280_dump_buffer(5, (char *)pkt, - REQUEST_ENTRY_SIZE); + while (seg_cnt > 0) { + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = + ha->request_ring; + } else + ha->request_ring_ptr++; - /* - * Build continuation packets. - */ - dprintk(1, - "S/G Building Continuation...seg_cnt=0x%x " - "remains\n", seg_cnt); + pkt = (cmd_a64_entry_t *)ha->request_ring_ptr; - while (seg_cnt > 0) { - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == - REQUEST_ENTRY_CNT) { - ha->req_ring_index = 0; - ha->request_ring_ptr = - ha->request_ring; - } else - ha->request_ring_ptr++; - - pkt = (cmd_a64_entry_t *)ha->request_ring_ptr; - - /* Zero out packet. */ - memset(pkt, 0, - REQUEST_ENTRY_SIZE); - - /* Load packet defaults. */ - ((cont_a64_entry_t *) pkt)->entry_type = - CONTINUE_A64_TYPE; - ((cont_a64_entry_t *) pkt)->entry_count = 1; - ((cont_a64_entry_t *) pkt)->sys_define = - (uint8_t)ha->req_ring_index; - /* Setup packet address segment pointer. */ - dword_ptr = - (u32 *)&((cont_a64_entry_t *) pkt)->dseg_0_address; - - /* Load continuation entry data segments. */ - for (cnt = 0; - cnt < 5 && seg_cnt; - cnt++, seg_cnt--) { - /* 3.13 64 bit */ - *dword_ptr++ = - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); - *dword_ptr++ = - cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))); - *dword_ptr++ = - cpu_to_le32(sg_dma_len(sg)); - dprintk(1, - "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n", - cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))), - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), - cpu_to_le32(sg_dma_len(sg))); - sg++; - } - dprintk(5, - "qla1280_64bit_start_scsi: continuation " - "packet data - b %i, t %i, l %i \n", - SCSI_BUS_32(cmd), - SCSI_TCN_32(cmd), - SCSI_LUN_32(cmd)); - qla1280_dump_buffer(5, - (char *)pkt, - REQUEST_ENTRY_SIZE); - } - } else { /* No scatter gather data transfer */ - /* 3.13 64 bit */ - dma_handle = pci_map_single(ha->pdev, - cmd->request_buffer, - cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); - /* save dma_handle for pci_unmap_single */ - sp->saved_dma_handle = dma_handle; + /* Zero out packet. */ + memset(pkt, 0, REQUEST_ENTRY_SIZE); + + /* Load packet defaults. */ + ((struct cont_a64_entry *) pkt)->entry_type = + CONTINUE_A64_TYPE; + ((struct cont_a64_entry *) pkt)->entry_count = 1; + ((struct cont_a64_entry *) pkt)->sys_define = + (uint8_t)ha->req_ring_index; + /* Setup packet address segment pointer. */ + dword_ptr = + (u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address; + /* Load continuation entry data segments. */ + for (cnt = 0; cnt < 5 && seg_cnt; + cnt++, seg_cnt--) { + dma_handle = sg_dma_address(sg); +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ha->flags.use_pci_vchannel) + sn_pci_set_vchan(ha->pdev, &dma_handle, + SCSI_BUS_32(cmd)); +#endif *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); *dword_ptr++ = cpu_to_le32(pci_dma_hi32(dma_handle)); - *dword_ptr = - (uint32_t)cmd->request_bufflen; - /* dprintk(1, - "No S/G map_single saved_dma_handle=%lx\n",dma_handle); - */ - dprintk(5, - "qla1280_64bit_start_scsi: No scatter/gather " - "command packet data - b %i, t %i, l %i \n", - SCSI_BUS_32(cmd), - SCSI_TCN_32(cmd), - SCSI_LUN_32(cmd)); - qla1280_dump_buffer(5, (char *)pkt, - REQUEST_ENTRY_SIZE); + *dword_ptr++ = + cpu_to_le32(sg_dma_len(sg)); + dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n", + cpu_to_le32(pci_dma_hi32(dma_handle)), + cpu_to_le32(pci_dma_lo32(dma_handle)), + cpu_to_le32(sg_dma_len(sg))); + sg++; } - } else { /* No data transfer */ - - dword_ptr = (uint32_t *)(pkt + 1); - *dword_ptr++ = 0; - *dword_ptr++ = 0; - *dword_ptr = 0; - dprintk(5, - "qla1280_64bit_start_scsi: No data, command " - "packet data - b %i, t %i, l %i \n", - SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), - SCSI_LUN_32(cmd)); + dprintk(5, "qla1280_64bit_start_scsi: " + "continuation packet data - b %i, t " + "%i, l %i \n", SCSI_BUS_32(cmd), + SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE); } - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } else - ha->request_ring_ptr++; - - /* Set chip new ring index. */ - dprintk(1, - "qla1280_64bit_start_scsi: Wakeup RISC for pending command\n"); - ha->qthreads--; - sp->flags |= SRB_SENT; - ha->actthreads++; - WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - } else { - status = 1; - dprintk(2, "qla1280_64bit_start_scsi: NO ROOM IN " - "OUTSTANDING ARRAY, req_q_cnt=0x%x", - ha->req_q_cnt); + } else { /* No scatter gather data transfer */ + struct page *page = virt_to_page(cmd->request_buffer); + unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK; + + dma_handle = pci_map_page(ha->pdev, page, off, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + + /* save dma_handle for pci_unmap_page */ + sp->saved_dma_handle = dma_handle; +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) + if (ha->flags.use_pci_vchannel) + sn_pci_set_vchan(ha->pdev, &dma_handle, + SCSI_BUS_32(cmd)); +#endif + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr++ = cpu_to_le32(pci_dma_hi32(dma_handle)); + *dword_ptr = (uint32_t)cmd->request_bufflen; + + dprintk(5, "qla1280_64bit_start_scsi: No scatter/" + "gather command packet data - b %i, t %i, " + "l %i \n", SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), + SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, + REQUEST_ENTRY_SIZE); } - } else { - status = 1; - dprintk(2, - "qla1280_64bit_start_scsi: in-ptr=0x%x req_q_cnt=0x%x" - "req_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt, - req_cnt); + } else { /* No data transfer */ + dword_ptr = (uint32_t *)(pkt + 1); + *dword_ptr++ = 0; + *dword_ptr++ = 0; + *dword_ptr = 0; + dprintk(5, "qla1280_64bit_start_scsi: No data, command " + "packet data - b %i, t %i, l %i \n", + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); + qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE); } + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } else + ha->request_ring_ptr++; + + /* Set chip new ring index. */ + dprintk(2, + "qla1280_64bit_start_scsi: Wakeup RISC for pending command\n"); + sp->flags |= SRB_SENT; + ha->actthreads++; + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + out: if (status) dprintk(2, "qla1280_64bit_start_scsi: **** FAILED ****\n"); else @@ -3945,7 +3816,7 @@ return status; } -#endif + /* * qla1280_32bit_start_scsi @@ -3967,11 +3838,11 @@ * 0 = success, was able to issue command. */ static int -qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp) +qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { struct device_reg *reg = ha->iobase; Scsi_Cmnd *cmd = sp->cmd; - cmd_entry_t *pkt; + struct cmd_entry *pkt; struct scatterlist *sg = NULL; uint32_t *dword_ptr; int status = 0; @@ -3989,15 +3860,14 @@ req_cnt = 1; if (cmd->use_sg) { /* - * We must build an SG list in adapter format, as the kernel's SG list - * cannot be used directly because of data field size (__alpha__) - * differences and the kernel SG list uses virtual addresses where - * we need physical addresses. + * We must build an SG list in adapter format, as the kernel's + * SG list cannot be used directly because of data field size + * (__alpha__) differences and the kernel SG list uses virtual + * addresses where we need physical addresses. */ sg = (struct scatterlist *) cmd->request_buffer; - /* 3.13 32 bit */ - seg_cnt = pci_map_sg (ha->pdev, sg, cmd->use_sg, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); /* * if greater than four sg entries then we need to allocate @@ -4008,10 +3878,10 @@ if ((seg_cnt - 4) % 7) req_cnt++; } - dprintk(1, "S/G Transfer cmd=%p seg_cnt=0x%x, req_cnt=%x\n", + dprintk(3, "S/G Transfer cmd=%p seg_cnt=0x%x, req_cnt=%x\n", cmd, seg_cnt, req_cnt); } else if (cmd->request_bufflen) { /* If data transfer. */ - dprintk(1, "No S/G transfer t=%x cmd=%p len=%x CDB=%x\n", + dprintk(3, "No S/G transfer t=%x cmd=%p len=%x CDB=%x\n", SCSI_TCN_32(cmd), cmd, cmd->request_bufflen, cmd->cmnd[0]); seg_cnt = 1; @@ -4030,234 +3900,184 @@ REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); } - dprintk(1, "Number of free entries=(%d) seg_cnt=0x%x\n", + dprintk(3, "Number of free entries=(%d) seg_cnt=0x%x\n", ha->req_q_cnt, seg_cnt); /* If room for request in request ring. */ - if ((req_cnt + 2) < ha->req_q_cnt) { - /* Check for empty slot in outstanding command list. */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS && - (ha->outstanding_cmds[cnt] != 0); cnt++) ; - - if (cnt < MAX_OUTSTANDING_COMMANDS) { - CMD_HANDLE(sp->cmd) = - (unsigned char *) (unsigned long) cnt; - ha->outstanding_cmds[cnt] = sp; - ha->req_q_cnt -= req_cnt; + if ((req_cnt + 2) >= ha->req_q_cnt) { + status = 1; + dprintk(2, "qla1280_32bit_start_scsi: in-ptr=0x%x, " + "req_q_cnt=0x%x, req_cnt=0x%x", ha->req_ring_index, + ha->req_q_cnt, req_cnt); + goto out; + } - /* - * Build command packet. - */ - pkt = (cmd_entry_t *) ha->request_ring_ptr; + /* Check for empty slot in outstanding command list. */ + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && + (ha->outstanding_cmds[cnt] != 0); cnt++) ; - pkt->entry_type = COMMAND_TYPE; - pkt->entry_count = (uint8_t) req_cnt; - pkt->sys_define = (uint8_t) ha->req_ring_index; - pkt->handle = cpu_to_le32(cnt); + if (cnt >= MAX_OUTSTANDING_COMMANDS) { + status = 1; + dprintk(2, "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING " + "ARRAY, req_q_cnt=0x%x\n", ha->req_q_cnt); + goto out; + } - /* Zero out remaining portion of packet. */ - memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); + CMD_HANDLE(sp->cmd) = (unsigned char *) (unsigned long)(cnt + 1); + ha->outstanding_cmds[cnt] = sp; + ha->req_q_cnt -= req_cnt; + + /* + * Build command packet. + */ + pkt = (struct cmd_entry *) ha->request_ring_ptr; - /* Set ISP command timeout. */ - pkt->timeout = cpu_to_le16(30); + pkt->entry_type = COMMAND_TYPE; + pkt->entry_count = (uint8_t) req_cnt; + pkt->sys_define = (uint8_t) ha->req_ring_index; + pkt->entry_status = 0; + pkt->handle = cpu_to_le32(cnt); + + /* Zero out remaining portion of packet. */ + memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); + + /* Set ISP command timeout. */ + pkt->timeout = cpu_to_le16(30); + + /* Set device target ID and LUN */ + pkt->lun = SCSI_LUN_32(cmd); + pkt->target = SCSI_BUS_32(cmd) ? + (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); + + /* Enable simple tag queuing if device supports it. */ + if (cmd->device->tagged_queue) + pkt->control_flags |= cpu_to_le16(BIT_3); + + /* Load SCSI command packet. */ + pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); + + /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ + /* Set transfer direction. */ + sp->dir = qla1280_data_direction(cmd); + pkt->control_flags |= cpu_to_le16(sp->dir); - /* Set device target ID and LUN */ - pkt->lun = SCSI_LUN_32(cmd); - pkt->target = SCSI_BUS_32(cmd) ? - (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); - - /* Enable simple tag queuing if device supports it. */ - if (cmd->device->tagged_queue) - pkt->control_flags |= cpu_to_le16(BIT_3); - - /* Load SCSI command packet. */ - pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); - memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); - - /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ - /* Set transfer direction. */ - sp->dir = qla1280_data_direction(cmd); - pkt->control_flags |= cpu_to_le16(sp->dir); - - /* Set total data segment count. */ - pkt->dseg_count = cpu_to_le16(seg_cnt); + /* Set total data segment count. */ + pkt->dseg_count = cpu_to_le16(seg_cnt); + /* + * Load data segments. + */ + if (seg_cnt) { + /* Setup packet address segment pointer. */ + dword_ptr = &pkt->dseg_0_address; + + if (cmd->use_sg) { /* If scatter gather */ + dprintk(3, "Building S/G data segments..\n"); + qla1280_dump_buffer(1, (char *)sg, 4 * 16); + + /* Load command entry data segments. */ + for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) { + *dword_ptr++ = + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = + cpu_to_le32(sg_dma_len(sg)); + dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n", + (pci_dma_lo32(sg_dma_address(sg))), + (sg_dma_len(sg))); + sg++; + } /* - * Load data segments. + * Build continuation packets. */ - if (seg_cnt) { - /* Setup packet address segment pointer. */ - dword_ptr = &pkt->dseg_0_address; + dprintk(3, "S/G Building Continuation" + "...seg_cnt=0x%x remains\n", seg_cnt); + while (seg_cnt > 0) { + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = + ha->request_ring; + } else + ha->request_ring_ptr++; - if (cmd->use_sg) { /* If scatter gather */ - dprintk(1, "Building S/G data " - "segments..\n"); - qla1280_dump_buffer(1, (char *)sg, - 4 * 16); - - /* Load command entry data segments. */ - for (cnt = 0; cnt < 4 && seg_cnt; - cnt++, seg_cnt--) { - /* 3.13 32 bit */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) - *dword_ptr++ = - cpu_to_le32(virt_to_bus(sg->address)); - *dword_ptr++ = cpu_to_le32(sg->length); - dprintk(1, - "S/G Segment phys_addr=0x%x, len=0x%x\n", - cpu_to_le32(virt_to_bus(sg->address)), - sg->length); -#else - *dword_ptr++ = - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); - *dword_ptr++ = - cpu_to_le32(sg_dma_len(sg)); - dprintk(1, "S/G Segment phys_addr=0x%x, len=0x%x\n", - (pci_dma_lo32(sg_dma_address(sg))), - (sg_dma_len(sg))); -#endif - sg++; - } - /* - * Build continuation packets. - */ - dprintk(1, "S/G Building Continuation" - "...seg_cnt=0x%x remains\n", - seg_cnt); - while (seg_cnt > 0) { - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == - REQUEST_ENTRY_CNT) { - ha->req_ring_index = 0; - ha->request_ring_ptr = - ha->request_ring; - } else - ha->request_ring_ptr++; - - pkt = (cmd_entry_t *) - ha->request_ring_ptr; - - /* Zero out packet. */ - memset(pkt, 0, - REQUEST_ENTRY_SIZE); - - /* Load packet defaults. */ - ((cont_entry_t *) pkt)-> - entry_type = CONTINUE_TYPE; - ((cont_entry_t *) pkt)-> - entry_count = 1; - - ((cont_entry_t *) pkt)-> - sys_define = - (uint8_t) ha-> - req_ring_index; - - /* Setup packet address segment pointer. */ - dword_ptr = - &((cont_entry_t *) pkt)->dseg_0_address; - - /* Load continuation entry data segments. */ - for (cnt = 0; - cnt < 7 && seg_cnt; - cnt++, seg_cnt--) { - /* 3.13 32 bit */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) - *dword_ptr++ = - cpu_to_le32(virt_to_bus(sg->address)); - *dword_ptr++ = cpu_to_le32(sg->length); - dprintk(1, - "S/G Segment Cont. phys_addr=0x%x, len=0x%x\n", - cpu_to_le32(pci_dma_lo32(virt_to_bus(sg->address))), sg->length); -#else - *dword_ptr++ = - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); - *dword_ptr++ = - cpu_to_le32(sg_dma_len(sg)); - dprintk(1, - "S/G Segment Cont. phys_addr=0x%x, " - "len=0x%x\n", - cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), - cpu_to_le32(sg_dma_len(sg))); -#endif - sg++; - } - dprintk(5, - "qla1280_32bit_start_scsi: continuation " - "packet data - scsi(%i:%i:%i)\n", - SCSI_BUS_32(cmd), - SCSI_TCN_32(cmd), - SCSI_LUN_32(cmd)); - qla1280_dump_buffer(5, - (char *)pkt, - REQUEST_ENTRY_SIZE); - } - } else { /* No S/G data transfer */ + pkt = (struct cmd_entry *)ha->request_ring_ptr; - /* 3.13 32 bit */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) - *dword_ptr++ = - cpu_to_le32 (virt_to_bus - (cmd->request_buffer)); -#else - dma_handle = pci_map_single(ha->pdev, - cmd->request_buffer, - cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); - sp->saved_dma_handle = dma_handle; + /* Zero out packet. */ + memset(pkt, 0, REQUEST_ENTRY_SIZE); + + /* Load packet defaults. */ + ((struct cont_entry *) pkt)-> + entry_type = CONTINUE_TYPE; + ((struct cont_entry *) pkt)->entry_count = 1; + + ((struct cont_entry *) pkt)->sys_define = + (uint8_t) ha->req_ring_index; + /* Setup packet address segment pointer. */ + dword_ptr = + &((struct cont_entry *) pkt)->dseg_0_address; + + /* Load continuation entry data segments. */ + for (cnt = 0; cnt < 7 && seg_cnt; + cnt++, seg_cnt--) { *dword_ptr++ = - cpu_to_le32(pci_dma_lo32(dma_handle)); -#endif - *dword_ptr = - cpu_to_le32(cmd->request_bufflen); - qla1280_dump_buffer(1,(char *)pkt, - REQUEST_ENTRY_SIZE); + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = + cpu_to_le32(sg_dma_len(sg)); + dprintk(1, + "S/G Segment Cont. phys_addr=0x%x, " + "len=0x%x\n", + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), + cpu_to_le32(sg_dma_len(sg))); + sg++; } - } else { /* No data transfer at all */ - - //dword_ptr = (uint32_t *)(pkt + 1); - //*dword_ptr++ = 0; - //*dword_ptr = 0; - dprintk(5, - "qla1280_32bit_start_scsi: No data, command " - "packet data - \n"); + dprintk(5, "qla1280_32bit_start_scsi: " + "continuation packet data - " + "scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd), + SCSI_TCN_32(cmd), SCSI_LUN_32(cmd)); qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE); } - dprintk(5, - "qla1280_32bit_start_scsi: First IOCB block:\n"); - qla1280_dump_buffer(5, (char *)ha->request_ring_ptr, - REQUEST_ENTRY_SIZE); + } else { /* No S/G data transfer */ + struct page *page = virt_to_page(cmd->request_buffer); + unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK; + dma_handle = pci_map_page(ha->pdev, page, off, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + sp->saved_dma_handle = dma_handle; + + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr = cpu_to_le32(cmd->request_bufflen); + } + } else { /* No data transfer at all */ + dword_ptr = (uint32_t *)(pkt + 1); + *dword_ptr++ = 0; + *dword_ptr = 0; + dprintk(5, "qla1280_32bit_start_scsi: No data, command " + "packet data - \n"); + qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE); + } + dprintk(5, "qla1280_32bit_start_scsi: First IOCB block:\n"); + qla1280_dump_buffer(5, (char *)ha->request_ring_ptr, + REQUEST_ENTRY_SIZE); - /* Adjust ring index. */ - ha->req_ring_index++; - if (ha->req_ring_index == REQUEST_ENTRY_CNT) { - ha->req_ring_index = 0; - ha->request_ring_ptr = ha->request_ring; - } else - ha->request_ring_ptr++; + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } else + ha->request_ring_ptr++; - /* Set chip new ring index. */ - dprintk(1, "qla1280_32bit_start_scsi: Wakeup RISC " - "for pending command\n"); - ha->qthreads--; - sp->flags |= SRB_SENT; - ha->actthreads++; - WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - } else { - status = 1; - dprintk(2, - "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING " - "ARRAY, req_q_cnt=0x%x\n", ha->req_q_cnt); - } - } else { - status = 1; - dprintk(2, - "qla1280_32bit_start_scsi: in-ptr=0x%x, req_q_cnt=0x%x, " - "req_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt, - req_cnt); - } + /* Set chip new ring index. */ + dprintk(2, "qla1280_32bit_start_scsi: Wakeup RISC " + "for pending command\n"); + sp->flags |= SRB_SENT; + ha->actthreads++; + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); +out: if (status) dprintk(2, "qla1280_32bit_start_scsi: **** FAILED ****\n"); @@ -4310,6 +4130,10 @@ /* Zero out packet. */ memset(pkt, 0, REQUEST_ENTRY_SIZE); + /* + * How can this be right when we have a ring + * size of 512??? + */ /* Set system defined field. */ pkt->sys_define = (uint8_t) ha->req_ring_index; @@ -4379,13 +4203,13 @@ static void qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun) { - elun_entry_t *pkt; + struct elun_entry *pkt; ENTER("qla1280_enable_lun"); /* Get request packet. */ /* - if (pkt = (elun_entry_t *)qla1280_req_pkt(ha)) + if (pkt = (struct elun_entry *)qla1280_req_pkt(ha)) { pkt->entry_type = ENABLE_LUN_TYPE; pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun); @@ -4398,7 +4222,7 @@ qla1280_isp_cmd(ha); } */ - pkt = (elun_entry_t *) 1; + pkt = (struct elun_entry *) 1; if (!pkt) dprintk(2, "qla1280_enable_lun: **** FAILED ****\n"); @@ -4407,211 +4231,6 @@ } #endif -#if QL1280_TARGET_MODE_SUPPORT -/****************************************************************************/ -/* Target Mode Support Functions. */ -/****************************************************************************/ - -/* - * qla1280_notify_ack - * Issue notify acknowledge IOCB. - * If sequence ID is zero, acknowledgement of - * SCSI bus reset or bus device reset is assumed. - * - * Input: - * ha = adapter block pointer. - * inotify = immediate notify entry pointer. - */ -static void -qla1280_notify_ack(struct scsi_qla_host *ha, notify_entry_t * inotify) -{ - nack_entry_t *pkt; - - dprintk(3, "qla1280_notify_ack: entered\n"); - - /* Get request packet. */ - if (pkt = (nack_entry_t *) qla1280_req_pkt(ha)) { - pkt->entry_type = NOTIFY_ACK_TYPE; - pkt->lun = inotify->lun; - pkt->initiator_id = inotify->initiator_id; - pkt->target_id = inotify->target_id; - if (inotify->seq_id == 0) - pkt->event = BIT_7; - else - pkt->seq_id = cpu_to_le16(inotify->seq_id); - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - - if (!pkt) - dprintk(2, "qla1280_notify_ack: **** FAILED ****\n"); - else - dprintk(3, "qla1280_notify_ack: exiting normally\n"); -} - -/* - * qla1280_immed_notify - * Issue immediate notify IOCB for LUN 0. - * - * Input: - * ha = adapter block pointer. - * inotify = immediate notify entry pointer. - */ -static void -qla1280_immed_notify(struct scsi_qla_host *ha, notify_entry_t * inotify) -{ - notify_entry_t *pkt; - - dprintk(3, "qla1280_immed_notify: entered\n"); - - /* Get request packet. */ - if (pkt = (notify_entry_t *) qla1280_req_pkt(ha)) { - pkt->entry_type = IMMED_NOTIFY_TYPE; - pkt->lun = inotify->lun; - pkt->initiator_id = inotify->initiator_id; - pkt->target_id = inotify->target_id; - pkt->status = 1; - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - - if (!pkt) - dprintk(2, "qla1280_immed_notify: **** FAILED ****\n"); - else - dprintk(3, "qla1280_immed_notify: exiting normally\n"); -} - -/* - * qla1280_accept_io - * Issue accept target I/O IOCB for LUN 0. - * - * Input: - * ha = adapter block pointer. - * ctio = ctio returned entry pointer. - */ -static void -qla1280_accept_io(struct scsi_qla_host *ha, ctio_ret_entry_t * ctio) -{ - atio_entry_t *pkt; - - dprintk(3, "qla1280_accept_io: entered\n"); - - /* Get request packet. */ - if (pkt = (atio_entry_t *) qla1280_req_pkt(ha)) { - pkt->entry_type = ACCEPT_TGT_IO_TYPE; - pkt->lun = ctio->lun; - pkt->initiator_id = ctio->initiator_id; - pkt->target_id = ctio->target_id; - pkt->tag_value = ctio->tag_value; - pkt->status = 1; - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - - if (!pkt) - dprintk(2, "qla1280_accept_io: **** FAILED ****\n"); - else - dprintk(3, "qla1280_accept_io: exiting normally\n"); -} - -/* - * qla1280_64bit_continue_io - * Issue continue target I/O IOCB. - * - * Input: - * ha = adapter block pointer. - * atio = atio pointer. - * len = total bytecount. - * addr = physical address pointer. - */ -static void -qla1280_64bit_continue_io(struct scsi_qla_host *ha, atio_entry_t * atio, - uint32_t len, paddr32_t * addr) -{ - ctio_a64_entry_t *pkt; - uint32_t *dword_ptr; - - dprintk(3, "qla1280_64bit_continue_io: entered\n"); - - /* Get request packet. */ - if (pkt = (ctio_a64_entry_t *) qla1280_req_pkt(ha)) { - pkt->entry_type = CTIO_A64_TYPE; - pkt->lun = atio->lun; - pkt->initiator_id = atio->initiator_id; - pkt->target_id = atio->target_id; - pkt->option_flags = cpu_to_le32(atio->option_flags); - pkt->tag_value = atio->tag_value; - pkt->scsi_status = atio->scsi_status; - - if (len) { - pkt->dseg_count = cpu_to_le16(1); - pkt->transfer_length = cpu_to_le32(len); - pkt->dseg_0_length = cpu_to_le32(len); - dword_ptr = (uint32_t *) addr; - pkt->dseg_0_address[0] = cpu_to_le32(*dword_ptr++); - pkt->dseg_0_address[1] = cpu_to_le32(*dword_ptr); - } - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - - if (!pkt) - dprintk(2, "qla1280_64bit_continue_io: **** FAILED ****\n"); - else - dprintk(3, "qla1280_64bit_continue_io: exiting normally\n"); -} - -/* - * qla1280_32bit_continue_io - * Issue continue target I/O IOCB. - * - * Input: - * ha = adapter block pointer. - * atio = atio pointer. - * len = total bytecount. - * addr = physical address pointer. - */ -static void -qla1280_32bit_continue_io(struct scsi_qla_host *ha, atio_entry_t * atio, - uint32_t len, paddr32_t * addr) -{ - ctio_entry_t *pkt; - uint32_t *dword_ptr; - - dprintk(3, "qla1280_32bit_continue_io: entered\n"); - - /* Get request packet. */ - if (pkt = (ctio_entry_t *) qla1280_req_pkt(ha)) { - pkt->entry_type = CONTINUE_TGT_IO_TYPE; - pkt->lun = atio->lun; - pkt->initiator_id = atio->initiator_id; - pkt->target_id = atio->target_id; - pkt->option_flags = cpu_to_le32(atio->option_flags); - pkt->tag_value = atio->tag_value; - pkt->scsi_status = atio->scsi_status; - - if (len) { - pkt->dseg_count = cpu_to_le16(1); - pkt->transfer_length = cpu_to_le32(len); - pkt->dseg_0_length = cpu_to_le32(len); - dword_ptr = (uint32_t *)addr; - pkt->dseg_0_address = cpu_to_le32(*dword_ptr); - } - - /* Issue command to ISP */ - qla1280_isp_cmd(ha); - } - - if (!pkt) - dprintk(2, "qla1280_32bit_continue_io: **** FAILED ****\n"); - else - dprintk(3, "qla1280_32bit_continue_io: exiting normally\n"); -} -#endif /* QL1280_TARGET_MODE_SUPPORT */ /****************************************************************************/ /* Interrupt Service Routine. */ @@ -4627,12 +4246,12 @@ * done_q_last = done queue last pointer. ****************************************************************************/ static void -qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first, - srb_t ** done_q_last) +qla1280_isr(struct scsi_qla_host *ha, struct srb ** done_q_first, + struct srb ** done_q_last) { struct device_reg *reg = ha->iobase; - response_t *pkt; - srb_t *sp = 0; + struct response *pkt; + struct srb *sp = 0; uint16_t mailbox[MAILBOX_REGISTER_COUNT]; uint16_t *wptr; uint32_t index; @@ -4679,8 +4298,8 @@ /* Handle asynchronous event */ switch (mailbox[0]) { case MBA_SCSI_COMPLETION: /* Response completion */ - dprintk(5, - "qla1280_isr: mailbox SCSI response completion\n"); + dprintk(5, "qla1280_isr: mailbox SCSI response " + "completion\n"); if (ha->flags.online) { /* Get outstanding command index. */ @@ -4713,39 +4332,34 @@ */ printk(KERN_WARNING "qla1280: ISP invalid handle"); - ha->flags.isp_abort_needed = TRUE; } } break; case MBA_BUS_RESET: /* SCSI Bus Reset */ - ha->flags.reset_marker = TRUE; + ha->flags.reset_marker = 1; index = mailbox[6] & BIT_0; - ha->bus_settings[index].reset_marker = TRUE; + ha->bus_settings[index].reset_marker = 1; - printk(KERN_DEBUG - "qla1280_isr(): index %i asynchronous " - "BUS_RESET\n", index); + printk(KERN_DEBUG "qla1280_isr(): index %i " + "asynchronous BUS_RESET\n", index); break; case MBA_SYSTEM_ERR: /* System Error */ printk(KERN_WARNING - "qla1280: ISP System Error - mbx1=%xh, mbx2=%xh, " - "mbx3=%xh\n", mailbox[1], mailbox[2], + "qla1280: ISP System Error - mbx1=%xh, mbx2=" + "%xh, mbx3=%xh\n", mailbox[1], mailbox[2], mailbox[3]); - ha->flags.isp_abort_needed = TRUE; break; case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ printk(KERN_WARNING "qla1280: ISP Request Transfer Error\n"); - ha->flags.isp_abort_needed = TRUE; break; case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ printk(KERN_WARNING "qla1280: ISP Response Transfer Error\n"); - ha->flags.isp_abort_needed = TRUE; break; case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ @@ -4758,14 +4372,12 @@ break; case MBA_DEVICE_RESET: /* Bus Device Reset */ - dprintk(2, - "qla1280_isr: asynchronous BUS_DEVICE_RESET\n"); printk(KERN_INFO "qla1280_isr(): asynchronous " "BUS_DEVICE_RESET\n"); - ha->flags.reset_marker = TRUE; + ha->flags.reset_marker = 1; index = mailbox[6] & BIT_0; - ha->bus_settings[index].reset_marker = TRUE; + ha->bus_settings[index].reset_marker = 1; break; case MBA_BUS_MODE_CHANGE: @@ -4780,7 +4392,9 @@ memcpy((uint16_t *) ha->mailbox_out, wptr, MAILBOX_REGISTER_COUNT * sizeof(uint16_t)); - ha->flags.mbox_int = TRUE; + + if(ha->mailbox_wait != NULL) + complete(ha->mailbox_wait); } break; } @@ -4793,123 +4407,68 @@ * unnecessary as the mailbox data has been copied to ha->mailbox_out * by the time we actually get here! */ - if (ha->flags.online + if (!(ha->flags.online #if 0 && !ha->flags.mbox_busy #endif - ) { - if (mailbox[5] < RESPONSE_ENTRY_CNT) { - while (ha->rsp_ring_index != mailbox[5]) { - pkt = ha->response_ring_ptr; - - dprintk(5, - "qla1280_isr: ha->rsp_ring_index = 0x%x, " - "mailbox[5] = 0x%x\n", - ha->rsp_ring_index, mailbox[5]); - dprintk(5, - "qla1280_isr: response packet data\n"); - qla1280_dump_buffer(5, (char *)pkt, - RESPONSE_ENTRY_SIZE); - - if (pkt->entry_type == STATUS_TYPE) { - if ((le16_to_cpu(pkt->scsi_status) & 0xff) - || pkt->comp_status - || pkt->entry_status) { - dprintk(2, - "qla1280_isr: ha->rsp_ring_index = 0x%x" - "mailbox[5] = 0x%x, comp_status = 0x%x, " - "scsi_status = 0x%x\n", - ha->rsp_ring_index, - mailbox[5], - le16_to_cpu(pkt->comp_status), - le16_to_cpu(pkt->scsi_status)); - } - } else { - dprintk(2, - "qla1280_isr: ha->rsp_ring_index = 0x%x, " - "mailbox[5] = 0x%x\n", - ha->rsp_ring_index, - mailbox[5]); - dprintk(2, - "qla1280_isr: response packet data\n"); - qla1280_dump_buffer(2, (char *)pkt, - RESPONSE_ENTRY_SIZE); - } - - if (pkt->entry_type == STATUS_TYPE - || pkt->entry_status) { - if (pkt->entry_type == STATUS_TYPE) - qla1280_status_entry(ha, - (sts_entry_t *) pkt, - done_q_first, - done_q_last); - else - qla1280_error_entry(ha, pkt, - done_q_first, - done_q_last); - - /* Adjust ring index. */ - ha->rsp_ring_index++; - if (ha->rsp_ring_index == - RESPONSE_ENTRY_CNT) { - ha->rsp_ring_index = 0; - ha->response_ring_ptr = - ha->response_ring; - } else - ha->response_ring_ptr++; - WRT_REG_WORD(®->mailbox5, - ha->rsp_ring_index); - } -#if QLA1280_TARGET_MODE_SUPPORT - else { - pkt = &response_entry; - - /* Copy packet. */ - dptr1 = - (uint32_t *)ha->response_ring_ptr; - dptr2 = (uint32_t *) pkt; - for (index = 0; - index < RESPONSE_ENTRY_SIZE / 4; - index++) - *dptr2++ = *dptr1++; - - /* Adjust ring index. */ - ha->rsp_ring_index++; - if (ha->rsp_ring_index == - RESPONSE_ENTRY_CNT) { - ha->rsp_ring_index = 0; - ha->response_ring_ptr = - ha->response_ring; - } else - ha->response_ring_ptr++; - WRT_REG_WORD(®->mailbox5, - ha->rsp_ring_index); - - switch (pkt->entry_type) { - case ACCEPT_TGT_IO_TYPE: - qla1280_atio_entry(ha, - (atio_entry_t *) pkt); - break; - case IMMED_NOTIFY_TYPE: - qla1280_notify_entry(ha, - (notify_entry_t *) pkt); - break; - case CTIO_RET_TYPE: - qla1280_accept_io(ha, - (ctio_ret_entry_t *) pkt); - break; - default: - break; - } - } -#endif + )) { + dprintk(2, "qla1280_isr: Response pointer Error\n"); + goto out; + } + + if (mailbox[5] >= RESPONSE_ENTRY_CNT) + goto out; + + while (ha->rsp_ring_index != mailbox[5]) { + pkt = ha->response_ring_ptr; + + dprintk(5, "qla1280_isr: ha->rsp_ring_index = 0x%x, mailbox[5]" + " = 0x%x\n", ha->rsp_ring_index, mailbox[5]); + dprintk(5,"qla1280_isr: response packet data\n"); + qla1280_dump_buffer(5, (char *)pkt, RESPONSE_ENTRY_SIZE); + + if (pkt->entry_type == STATUS_TYPE) { + if ((le16_to_cpu(pkt->scsi_status) & 0xff) + || pkt->comp_status || pkt->entry_status) { + dprintk(2, "qla1280_isr: ha->rsp_ring_index = " + "0x%x mailbox[5] = 0x%x, comp_status " + "= 0x%x, scsi_status = 0x%x\n", + ha->rsp_ring_index, mailbox[5], + le16_to_cpu(pkt->comp_status), + le16_to_cpu(pkt->scsi_status)); } } else { - ha->flags.isp_abort_needed = TRUE; - dprintk(2, "qla1280_isr: Response pointer Error\n"); + dprintk(2, "qla1280_isr: ha->rsp_ring_index = " + "0x%x, mailbox[5] = 0x%x\n", + ha->rsp_ring_index, mailbox[5]); + dprintk(2, "qla1280_isr: response packet data\n"); + qla1280_dump_buffer(2, (char *)pkt, + RESPONSE_ENTRY_SIZE); } - } + if (pkt->entry_type == STATUS_TYPE || pkt->entry_status) { + dprintk(2, "status: Cmd %p, handle %i\n", + ha->outstanding_cmds[pkt->handle]->cmd, + pkt->handle); + if (pkt->entry_type == STATUS_TYPE) + qla1280_status_entry(ha, pkt, done_q_first, + done_q_last); + else + qla1280_error_entry(ha, pkt, done_q_first, + done_q_last); + + /* Adjust ring index. */ + ha->rsp_ring_index++; + if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) { + ha->rsp_ring_index = 0; + ha->response_ring_ptr = ha->response_ring; + } else + ha->response_ring_ptr++; + WRT_REG_WORD(®->mailbox5, ha->rsp_ring_index); + } + } + + out: LEAVE("qla1280_isr"); } @@ -4923,42 +4482,22 @@ static void qla1280_rst_aen(struct scsi_qla_host *ha) { -#if QL1280_TARGET_MODE_SUPPORT - notify_entry_t nentry; -#endif uint8_t bus; ENTER("qla1280_rst_aen"); if (ha->flags.online && !ha->flags.reset_active && !ha->flags.abort_isp_active) { - ha->flags.reset_active = TRUE; + ha->flags.reset_active = 1; while (ha->flags.reset_marker) { /* Issue marker command. */ - ha->flags.reset_marker = FALSE; + ha->flags.reset_marker = 0; for (bus = 0; bus < ha->ports && !ha->flags.reset_marker; bus++) { if (ha->bus_settings[bus].reset_marker) { - ha->bus_settings[bus].reset_marker = - FALSE; + ha->bus_settings[bus].reset_marker = 0; qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL); - - if (!ha->flags.reset_marker) { -#if QL1280_TARGET_MODE_SUPPORT - /* Issue notify acknowledgement command. */ - memset(&nentry, 0, - sizeof(notify_entry_t)); - - nentry.initiator_id = - nentry.target_id = - bus ? ha->bus_settings[bus].id | BIT_7 : - ha->bus_settings[bus].id; - qla1280_notify_entry(ha, - &nentry); -#endif - /* Asynchronous event notification */ - } } } } @@ -4967,432 +4506,50 @@ LEAVE("qla1280_rst_aen"); } -#if QL1280_TARGET_MODE_SUPPORT -/* - * qla1280_atio_entry - * Processes received ISP accept target I/O entry. - * - * Input: - * ha = adapter block pointer. - * pkt = entry pointer. - */ -static void -qla1280_atio_entry(struct scsi_qla_host *ha, atio_entry_t * pkt) -{ - uint64_t *a64; - uint64_t *end_a64; - paddr32_t phy_addr[2]; - paddr32_t end_addr[2]; - uint32_t len; - uint32_t offset; - uint8_t t; - uint8_t *sense_ptr; - - dprintk(3, "qla1280_atio_entry: entered\n"); - - t = pkt->initiator_id; - sense_ptr = ha->tsense + t * TARGET_SENSE_SIZE; - a64 = (uint64_t *)&phy_addr[0]; - end_a64 = (uint64_t *)&end_addr[0]; - - switch (pkt->status & ~BIT_7) { - case 7: /* Path invalid */ - dprintk(2, "qla1280_atio_entry: Path invalid\n"); - break; - - case 0x14: /* Target Bus Phase Sequence Failure */ - dprintk(2, "qla1280_atio_entry: Target Bus Phase " - "Sequence Failure\n"); - - if (pkt->status & BIT_7) { - memcpy(sense_ptr, &pkt->sense_data, TARGET_SENSE_SIZE); - } else { - memset(sense_ptr, 0, TARGET_SENSE_SIZE); - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_HARDERR; - *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_SELFAIL; - } - pkt->scsi_status = S_CKCON; - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) - if (ha->flags.enable_64bit_addressing) - qla1280_64bit_continue_io(ha, pkt, 0, 0); - else -#endif - qla1280_32bit_continue_io(ha, pkt, 0, 0); - break; - - case 0x16: /* Requested Capability Not Available */ - dprintk(2, "qla1280_atio_entry: Target Bus Phase " - "Sequence Failure\n"); - break; - - case 0x17: /* Bus Device Reset Message Received */ - dprintk(2, "qla1280_atio_entry: Target Bus Phase " - "Sequence Failure\n"); - break; - - case 0x3D: /* CDB Received */ - - /* Check for invalid LUN */ - if (pkt->lun && pkt->cdb[0] != SS_INQUIR && - pkt->cdb[0] != SS_REQSEN) - pkt->cdb[0] = SS_TEST; - - switch (pkt->cdb[0]) { - case SS_TEST: - dprintk(3, "qla1280_atio_entry: SS_TEST\n"); - - memset(sense_ptr, 0, TARGET_SENSE_SIZE); - len = 0; - if (pkt->lun == 0) - pkt->scsi_status = S_GOOD; - else { - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_INVLUN; - pkt->scsi_status = S_CKCON; - } - - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA); - break; - - case SS_REQSEN: - dprintk(3, "qla1280_atio_entry: SS_REQSEN\n"); - - phy_addr[0] = ha->tsense_dma; - phy_addr[1] = 0; - *a64 += t * TARGET_SENSE_SIZE; - if (pkt->cdb[4] > TARGET_SENSE_SIZE) - len = TARGET_SENSE_SIZE; - else - len = pkt->cdb[4]; - pkt->scsi_status = S_GOOD; - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_DATA_IN); - break; - - case SS_INQUIR: - dprintk(3, "qla1280_atio_entry: SS_INQUIR\n"); - - memset(sense_ptr, 0, TARGET_SENSE_SIZE); - phy_addr[0] = ha->tbuf_dma; - phy_addr[1] = 0; - *a64 += TARGET_INQ_OFFSET; - - if (pkt->lun == 0) { - ha->tbuf->inq.id_type = ID_PROCESOR; - ha->tbuf->inq.id_pqual = ID_QOK; - } else { - ha->tbuf->inq.id_type = ID_NODEV; - ha->tbuf->inq.id_pqual = ID_QNOLU; - } - - if (pkt->cdb[4] > sizeof(struct ident)) - len = sizeof(struct ident); - else - len = pkt->cdb[4]; - pkt->scsi_status = S_GOOD; - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_DATA_IN); - break; - - case SM_WRDB: - memset(sense_ptr, 0, TARGET_SENSE_SIZE); - offset = pkt->cdb[5]; - offset |= pkt->cdb[4] << 8; - offset |= pkt->cdb[3] << 16; - len = pkt->cdb[8]; - len |= pkt->cdb[7] << 8; - len |= pkt->cdb[6] << 16; - end_addr[0] = phy_addr[0] = ha->tbuf_dma; - end_addr[1] = phy_addr[1] = 0; - *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE; - switch (pkt->cdb[1] & 7) { - case RW_BUF_HDATA: - dprintk(3, "qla1280_atio_entry: SM_WRDB, " - "RW_BUF_HDATA\n"); - - if (len > TARGET_DATA_SIZE + 4) { - dprintk(2, - "qla1280_atio_entry: SM_WRDB, " - "length > buffer size\n"); - - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = - TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_ILLCDB; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - len = 0; - } else if (len) { - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_DATA_OUT); - dprintk(3, - "qla1280_atio_entry: Issuing " - "SDI_TARMOD_WRCOMP\n"); - - sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr, - pkt->target_id, pkt->lun, 0, - offset); - } else { - dprintk(2, - "qla1280_atio_entry: SM_WRDB, " - "zero length\n"); - - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } - - break; - case RW_BUF_DATA: - dprintk(3, "qla1280_atio_entry: SM_WRDB, " - "RW_BUF_DATA\n"); - - *a64 += offset + TARGET_DATA_OFFSET; - if (pkt->cdb[2] != 0 || *a64 >= *end_a64 || - *a64 + len > *end_a64) { - dprintk(2, - "qla1280_atio_entry: SM_WRDB, " - "RW_BUF_DATA BAD\n"); - dprintk(2, "buf_id=0x%x, offset=0x%x, " - "length=0x%x\n", pkt->cdb[2], - offset, len); - - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = - TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } else if (len) { - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_DATA_OUT); - dprintk(3, - "qla1280_atio_entry: Issuing " - "SDI_TARMOD_WRCOMP\n"); - - sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr, - pkt->target_id, pkt->lun, 0, - offset); - } else { - dprintk(2, - "qla1280_atio_entry: SM_WRDB, " - "zero length\n"); - - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } - break; - - default: - dprintk(2, "qla1280_atio_entry: SM_WRDB " - "unknown mode\n"); - - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA); - break; - } - break; - - case SM_RDDB: - memset(sense_ptr, 0, TARGET_SENSE_SIZE); - offset = pkt->cdb[5]; - offset |= pkt->cdb[4] << 8; - offset |= pkt->cdb[3] << 16; - len = pkt->cdb[8]; - len |= pkt->cdb[7] << 8; - len |= pkt->cdb[6] << 16; - end_addr[0] = phy_addr[0] = ha->tbuf_dma; - end_addr[1] = phy_addr[1] = 0; - *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE; - switch (pkt->cdb[1] & 7) { - case RW_BUF_HDATA: - dprintk(3, "qla1280_atio_entry: SM_RDDB, " - "RW_BUF_HDATA\n"); - - if (len) { - ha->tbuf->hdr[0] = 0; - ha->tbuf->hdr[1] = - (TARGET_DATA_SIZE >> 16) & 0xff; - ha->tbuf->hdr[2] = - (TARGET_DATA_SIZE >> 8) & 0xff; - ha->tbuf->hdr[3] = - TARGET_DATA_SIZE & 0xff; - if (len > TARGET_DATA_SIZE + 4) - len = TARGET_DATA_SIZE + 4; - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_DATA_IN); - } else { - dprintk(2, - "qla1280_atio_entry: SM_RDDB, " - "zero length\n"); - - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } - break; - case RW_BUF_DATA: - dprintk(3, "qla1280_atio_entry: SM_RDDB, " - "RW_BUF_DATA\n"); - - *a64 += offset + TARGET_DATA_OFFSET; - if (pkt->cdb[2] != 0 || *a64 >= *end_a64) { - dprintk(2, - "qla1280_atio_entry: SM_RDDB, " - "RW_BUF_DATA BAD\n"); - dprintk(2, "buf_id=0x%x, offset=0x%x\n" - pkt->cdb[2], offset); - - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = - TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } else { - if (*a64 + len > *end_a64) - len = *end_a64 - *a64; - if (len) { - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - (OF_SSTS | OF_DATA_IN); - } else { - dprintk(2, - "qla1280_atio_entry: SM_RDDB, " - "zero length\n"); - - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } - } - break; - case RW_BUF_DESC: - dprintk(3, "qla1280_atio_entry: SM_RDDB, " - "RW_BUF_DESC\n"); - - if (len) { - if (len > 4) - len = 4; - - ha->tbuf->hdr[0] = 0; - if (pkt->cdb[2] != 0) { - ha->tbuf->hdr[1] = 0; - ha->tbuf->hdr[2] = 0; - ha->tbuf->hdr[3] = 0; - } else { - ha->tbuf->hdr[1] = - (TARGET_DATA_SIZE >> 16) & - 0xff; - ha->tbuf->hdr[2] = - (TARGET_DATA_SIZE >> 8) & - 0xff; - ha->tbuf->hdr[3] = - TARGET_DATA_SIZE & 0xff; - } - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_DATA_IN); - } else { - dprintk(2, - "qla1280_atio_entry: SM_RDDB," - " zero length\n"); - - pkt->scsi_status = S_GOOD; - pkt->option_flags |= - cpu_to_le32(OF_SSTS | OF_NO_DATA); - } - break; - default: - dprintk(2, "qla1280_atio_entry: SM_RDDB " - "unknown mode\n"); - - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_ILLCDB; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA); - break; - } - break; - - default: - dprintk(2, - "qla1280_atio_entry: Unknown SCSI command\n"); - qla1280_dump_buffer(2, &pkt->cdb[0], pkt->cdb_len); - - memset(sense_ptr, 0, TARGET_SENSE_SIZE); - *sense_ptr = 0x70; - *(sense_ptr + 2) = SD_ILLREQ; - *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8; - *(sense_ptr + 12) = SC_INVOPCODE; - len = 0; - pkt->scsi_status = S_CKCON; - pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA); - break; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) - if (ha->flags.enable_64bit_addressing) - qla1280_64bit_continue_io(ha, pkt, len, - (paddr32_t *)&phy_addr); - else -#endif - qla1280_32bit_continue_io(ha, pkt, len, - (paddr32_t *)&phy_addr); - break; - - default: - break; - } - - dprintk(3, "qla1280_atio_entry: exiting normally\n"); -} +#if LINUX_VERSION_CODE < 0x020500 /* - * qla1280_notify_entry - * Processes received ISP immediate notify entry. * - * Input: - * ha = adapter block pointer. - * pkt = entry pointer. */ -static void -qla1280_notify_entry(struct scsi_qla_host *ha, notify_entry_t * pkt) +void +qla1280_get_target_options(struct scsi_cmnd *cmd, struct scsi_qla_host *ha) { - dprintk(3, "qla1280_notify_entry: entered\n"); + unsigned char *result; + struct nvram *n; + int bus, target, lun; - /* Acknowledge immediate notify */ - qla1280_notify_ack(ha, pkt); + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); - /* Issue notify entry to increment resource count */ - qla1280_immed_notify(ha, pkt); + /* + * Make sure to not touch anything if someone is using the + * sg interface. + */ + if (cmd->use_sg || (CMD_RESULT(cmd) >> 16) != DID_OK || lun) + return; + + result = cmd->request_buffer; + n = &ha->nvram; - dprintk(3, "qla1280_notify_entry: exiting normally\n"); + n->bus[bus].target[target].parameter.f.enable_wide = 0; + n->bus[bus].target[target].parameter.f.enable_sync = 0; + n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; + + if (result[7] & 0x60) + n->bus[bus].target[target].parameter.f.enable_wide = 1; + if (result[7] & 0x10) + n->bus[bus].target[target].parameter.f.enable_sync = 1; + if ((result[2] >= 3) && (result[4] + 5 > 56) && + (result[56] & 0x4)) + n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1; + + dprintk(2, "get_target_options(): wide %i, sync %i, ppr %i\n", + n->bus[bus].target[target].parameter.f.enable_wide, + n->bus[bus].target[target].parameter.f.enable_sync, + n->bus[bus].target[target].ppr_1x160.flags.enable_ppr); } -#endif /* QLA1280_TARGET_MODE_SUPPORT */ +#endif /* * qla1280_status_entry @@ -5405,13 +4562,12 @@ * done_q_last = done queue last pointer. */ static void -qla1280_status_entry(struct scsi_qla_host *ha, sts_entry_t * pkt, - srb_t ** done_q_first, srb_t ** done_q_last) +qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt, + struct srb **done_q_first, struct srb **done_q_last) { unsigned int bus, target, lun; int sense_sz; - srb_t *sp; - scsi_lu_t *q; + struct srb *sp; Scsi_Cmnd *cmd; uint32_t handle = le32_to_cpu(pkt->handle); uint16_t scsi_status = le16_to_cpu(pkt->scsi_status); @@ -5423,73 +4579,73 @@ if (handle < MAX_OUTSTANDING_COMMANDS) sp = ha->outstanding_cmds[handle]; else - sp = 0; + sp = NULL; - if (sp) { - /* Free outstanding command slot. */ - ha->outstanding_cmds[handle] = 0; + if (!sp) { + printk(KERN_WARNING "qla1280: Status Entry invalid handle\n"); + goto out; + } - cmd = sp->cmd; + /* Free outstanding command slot. */ + ha->outstanding_cmds[handle] = 0; - /* Generate LU queue on cntrl, target, LUN */ - bus = SCSI_BUS_32(cmd); - target = SCSI_TCN_32(cmd); - lun = SCSI_LUN_32(cmd); - q = LU_Q(ha, bus, target, lun); + cmd = sp->cmd; - if (comp_status || scsi_status) { - dprintk(1, "scsi: comp_status = 0x%x, scsi_status = " - "0x%x, handle = 0x%lx\n", comp_status, - scsi_status, handle); - } + /* Generate LU queue on cntrl, target, LUN */ + bus = SCSI_BUS_32(cmd); + target = SCSI_TCN_32(cmd); + lun = SCSI_LUN_32(cmd); - /* Target busy */ - if (scsi_status & SS_BUSY_CONDITION && - scsi_status != SS_RESERVE_CONFLICT) { - CMD_RESULT(cmd) = - DID_BUS_BUSY << 16 | (scsi_status & 0xff); - } else { + if (comp_status || scsi_status) { + dprintk(3, "scsi: comp_status = 0x%x, scsi_status = " + "0x%x, handle = 0x%x\n", comp_status, + scsi_status, handle); + } - /* Save ISP completion status */ - CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd); + /* Target busy */ + if (scsi_status & SS_BUSY_CONDITION && + scsi_status != SS_RESERVE_CONFLICT) { + CMD_RESULT(cmd) = + DID_BUS_BUSY << 16 | (scsi_status & 0xff); + } else { - if (scsi_status & SS_CHECK_CONDITION) { - if (comp_status != CS_ARS_FAILED) { - uint16_t req_sense_length = - le16_to_cpu(pkt->req_sense_length); - if (req_sense_length < - CMD_SNSLEN(cmd)) - sense_sz = req_sense_length; - else - /* - * Scsi_Cmnd->sense_buffer is - * 64 bytes, why only copy 63? - * This looks wrong! /Jes - */ - sense_sz = CMD_SNSLEN(cmd) - 1; + /* Save ISP completion status */ + CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd); - memcpy(cmd->sense_buffer, - &pkt->req_sense_data, sense_sz); - } else - sense_sz = 0; - memset(cmd->sense_buffer + sense_sz, 0, - sizeof(cmd->sense_buffer) - sense_sz); - - dprintk(2, "qla1280_status_entry: Check " - "condition Sense data, b %i, t %i, " - "l %i\n", bus, target, lun); - if (sense_sz) - qla1280_dump_buffer(2, (char *)cmd->sense_buffer, - sense_sz); - } + if (scsi_status & SS_CHECK_CONDITION) { + if (comp_status != CS_ARS_FAILED) { + uint16_t req_sense_length = + le16_to_cpu(pkt->req_sense_length); + if (req_sense_length < CMD_SNSLEN(cmd)) + sense_sz = req_sense_length; + else + /* + * Scsi_Cmnd->sense_buffer is + * 64 bytes, why only copy 63? + * This looks wrong! /Jes + */ + sense_sz = CMD_SNSLEN(cmd) - 1; + + memcpy(cmd->sense_buffer, + &pkt->req_sense_data, sense_sz); + } else + sense_sz = 0; + memset(cmd->sense_buffer + sense_sz, 0, + sizeof(cmd->sense_buffer) - sense_sz); + + dprintk(2, "qla1280_status_entry: Check " + "condition Sense data, b %i, t %i, " + "l %i\n", bus, target, lun); + if (sense_sz) + qla1280_dump_buffer(2, + (char *)cmd->sense_buffer, + sense_sz); } - /* Place command on done queue. */ - qla1280_done_q_put(sp, done_q_first, done_q_last); - } else { - printk(KERN_WARNING "qla1280: Status Entry invalid handle\n"); - ha->flags.isp_abort_needed = TRUE; } + /* Place command on done queue. */ + qla1280_done_q_put(sp, done_q_first, done_q_last); + out: LEAVE("qla1280_status_entry"); } @@ -5504,10 +4660,10 @@ * done_q_last = done queue last pointer. */ static void -qla1280_error_entry(struct scsi_qla_host *ha, response_t * pkt, - srb_t ** done_q_first, srb_t ** done_q_last) +qla1280_error_entry(struct scsi_qla_host *ha, struct response * pkt, + struct srb ** done_q_first, struct srb ** done_q_last) { - srb_t *sp; + struct srb *sp; uint32_t handle = le32_to_cpu(pkt->handle); ENTER("qla1280_error_entry"); @@ -5548,7 +4704,6 @@ #ifdef QLA_64BIT_PTR else if (pkt->entry_type == COMMAND_A64_TYPE) { printk(KERN_WARNING "!qla1280: Error Entry invalid handle"); - ha->flags.isp_abort_needed = TRUE; } #endif @@ -5568,49 +4723,39 @@ static int qla1280_abort_isp(struct scsi_qla_host *ha) { -#if 0 - struct device_reg *reg = ha->iobase; -#endif - srb_t *sp; - scsi_lu_t *q; + struct srb *sp; int status = 0; int cnt; - int bus, target, lun; + int bus; ENTER("qla1280_abort_isp"); - ha->flags.isp_abort_needed = FALSE; if (!ha->flags.abort_isp_active && ha->flags.online) { - ha->flags.abort_isp_active = TRUE; + struct device_reg *reg = ha->iobase; + ha->flags.abort_isp_active = 1; /* Disable ISP interrupts. */ qla1280_disable_intrs(ha); + WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC); + RD_REG_WORD(®->id_l); + printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n", + ha->host_no); /* Dequeue all commands in outstanding command list. */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { + Scsi_Cmnd *cmd; sp = ha->outstanding_cmds[cnt]; if (sp) { - ha->outstanding_cmds[cnt] = 0; - - /* Generate LU queue on controller, target, LUN */ - bus = SCSI_BUS_32(sp->cmd); - target = SCSI_TCN_32(sp->cmd); - lun = SCSI_LUN_32(sp->cmd); - q = LU_Q(ha, bus, target, lun); + cmd = sp->cmd; + CMD_RESULT(cmd) = DID_RESET << 16; - /* Reset outstanding command count. */ - q->q_outcnt = 0; - q->q_flag &= ~QLA1280_QBUSY; - q->q_flag = 0; + sp->cmd = NULL; + ha->outstanding_cmds[cnt] = NULL; - /* Adjust watchdog timer for command. */ - /* if (sp->flags & SRB_WATCHDOG) - sp->timeout += 2; */ + (*cmd->scsi_done)(cmd); - /* Place request back on top of device queue. */ sp->flags = 0; - qla1280_putq_t(q, sp); } } @@ -5629,38 +4774,21 @@ for (bus = 0; bus < ha->ports; bus++) { qla1280_bus_reset(ha, bus); } - do { - /* Issue marker command. */ - ha->flags.reset_marker = FALSE; - for (bus = 0; bus < ha->ports; bus++) { - ha->bus_settings[bus]. - reset_marker = FALSE; - qla1280_marker(ha, bus, 0, 0, - MK_SYNC_ALL); - } - } while (ha->flags.reset_marker); - - /* Enable host adapter target mode. */ + /* + * qla1280_bus_reset() will do the marker + * dance - no reason to repeat here! + */ +#if 0 + /* Issue marker command. */ + ha->flags.reset_marker = 0; for (bus = 0; bus < ha->ports; bus++) { - if (! - (status = - qla1280_enable_tgt(ha, bus))) { - for (cnt = 0; cnt < MAX_LUNS; - cnt++) { - /* qla1280_enable_lun(ha, bus, cnt); */ - qla1280_poll(ha); - } - } else - break; - } - - if (!status) { - /* Enable ISP interrupts. */ - qla1280_enable_intrs(ha); - ha->flags.abort_isp_active = FALSE; - /* Restart queues that may have been stopped. */ - qla1280_restart_queues(ha); + ha->bus_settings[bus]. + reset_marker = 0; + qla1280_marker(ha, bus, 0, 0, + MK_SYNC_ALL); } +#endif + ha->flags.abort_isp_active = 0; } } } @@ -5669,8 +4797,6 @@ printk(KERN_WARNING "qla1280: ISP error recovery failed, board disabled"); qla1280_reset_adapter(ha); - qla1280_abort_queues(ha); - dprintk(2, "qla1280_abort_isp: **** FAILED ****\n"); } @@ -5678,86 +4804,6 @@ return status; } -/* - * qla1280_restart_queues - * Restart all device queues. - * - * Input: - * ha = adapter block pointer. - */ -static void -qla1280_restart_queues(struct scsi_qla_host *ha) -{ - scsi_lu_t *q; - int bus, target, lun; - - ENTER("qla1280_restart_queues"); - - for (bus = 0; bus < ha->ports; bus++) - for (target = 0; target < MAX_TARGETS; target++) - for (lun = 0; lun < MAX_LUNS; lun++) { - q = LU_Q(ha, bus, target, lun); - if (q != NULL) { - if (q->q_first) - qla1280_next(ha, q, bus); - } - } - dprintk(3, "qla1280_restart_queues: exiting normally\n"); -} - -/* - * qla1280_abort_queue_single - * Abort all commands on a device queues. - * - * Input: - * ha = adapter block pointer. - */ -static void -qla1280_abort_queue_single(struct scsi_qla_host *ha, int bus, - int target, int lun, uint32_t stat) -{ - scsi_lu_t *q; - srb_t *sp, *sp_next; - - ENTER("qla1280_abort_queue_single"); - q = LU_Q(ha, bus, target, lun); - if (q != NULL) { - sp = q->q_first; - q->q_first = q->q_last = NULL; - - while (sp) { - sp_next = sp->s_next; - CMD_RESULT(sp->cmd) = stat; - qla1280_done_q_put(sp, &ha->done_q_first, - &ha->done_q_last); - sp = sp_next; - } - } - LEAVE("qla1280_abort_queue_single"); -} - -/* - * qla1280_abort_queues - * Abort all commands on device queues. - * - * Input: - * ha = adapter block pointer. - */ -static void -qla1280_abort_queues(struct scsi_qla_host *ha) -{ - uint32_t bus, target, lun; - - ENTER("qla1280_abort_queues"); - - for (bus = 0; bus < ha->ports; bus++) - for (target = 0; target < MAX_TARGETS; target++) - for (lun = 0; lun < MAX_LUNS; lun++) - qla1280_abort_queue_single(ha, bus, target, - lun, DID_RESET); - - LEAVE("qla1280_abort_queues"); -} /* * qla1280_debounce_register @@ -5790,27 +4836,11 @@ return ret; } -static Scsi_Host_Template driver_template = { - .proc_info = qla1280_proc_info, - .name = "Qlogic ISP 1280/12160", - .detect = qla1280_detect, - .release = qla1280_release, - .info = qla1280_info, - .queuecommand = qla1280_queuecommand, - .eh_abort_handler = qla1280_eh_abort, - .eh_device_reset_handler = qla1280_eh_device_reset, - .eh_bus_reset_handler = qla1280_eh_bus_reset, - .eh_host_reset_handler = qla1280_eh_adapter_reset, - .slave_configure = qla1280_slave_configure, - .bios_param = qla1280_biosparam, - .can_queue = 255, - .this_id = -1, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 3, - .use_clustering = ENABLE_CLUSTERING, \ -}; + +static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE; #include "scsi_module.c" + /************************************************************************ * qla1280_check_for_dead_scsi_bus * * * @@ -5823,18 +4853,7 @@ { uint16_t config_reg, scsi_control; struct device_reg *reg = ha->iobase; -#if 0 - unsigned int bus; - Scsi_Cmnd *cp; - /* - * If SCSI Bus is Dead because of bad termination, - * we will return a status of Selection timeout. - */ - - cp = sp->cmd; - bus = SCSI_BUS_32(cp); -#endif if (ha->bus_settings[bus].scsi_bus_dead) { WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC); config_reg = RD_REG_WORD(®->cfg_1); @@ -5844,218 +4863,82 @@ WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); if (scsi_control == SCSI_PHASE_INVALID) { - ha->bus_settings[bus].scsi_bus_dead = TRUE; + ha->bus_settings[bus].scsi_bus_dead = 1; #if 0 CMD_RESULT(cp) = DID_NO_CONNECT << 16; - CMD_HANDLE(cp) = NULL; + CMD_HANDLE(cp) = INVALID_HANDLE; /* ha->actthreads--; */ (*(cp)->scsi_done)(cp); #endif - return TRUE; /* bus is dead */ + return 1; /* bus is dead */ } else { - ha->bus_settings[bus].scsi_bus_dead = FALSE; + ha->bus_settings[bus].scsi_bus_dead = 0; ha->bus_settings[bus].failed_reset_count = 0; } } - return FALSE; /* bus is not dead */ + return 0; /* bus is not dead */ } static void -qla12160_get_target_parameters(struct scsi_qla_host *ha, uint32_t bus, - uint32_t target, uint32_t lun) +qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device) { uint16_t mb[MAILBOX_REGISTER_COUNT]; + int bus, target, lun; + + bus = device->channel; + target = device->id; + lun = device->lun; + mb[0] = MBC_GET_TARGET_PARAMETERS; mb[1] = (uint16_t) (bus ? target | BIT_7 : target); mb[1] <<= 8; qla1280_mailbox_command(ha, BIT_6 | BIT_3 | BIT_2 | BIT_1 | BIT_0, &mb[0]); - if (mb[3] != 0) { - printk(KERN_INFO - "scsi(%ld:%d:%d:%d): Synchronous transfer at period " - "%d, offset %d. \n", ha->host_no, bus, target, lun, - (mb[3] & 0xff), (mb[3] >> 8)); - } - - if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2) { - printk(KERN_INFO - "scsi(%ld:%d:%d:%d): Dual Transition enabled.\n", - ha->host_no, bus, target, lun); - } -} - -#ifdef QL_DEBUG_ROUTINES -/****************************************************************************/ -/* Driver Debug Functions. */ -/****************************************************************************/ - -/* - * Get byte from I/O port - */ -static u8 -qla1280_getbyte (u8 * port) -{ - u8 ret; -#if MEMORY_MAPPED_IO - ret = readb((unsigned long) port); -#else - ret = inb((unsigned long) port); -#endif - - if (ql_debug_print) - printk(KERN_DEBUG - "qla1280_getbyte: address = 0x%p, data = 0x%x", port, - ret); + printk(KERN_INFO "scsi(%li:%d:%d:%d):", ha->host_no, bus, target, lun); - return ret; -} - -/* - * Get word from I/O port - */ -static u16 -qla1280_getword (u16 * port) -{ - u16 ret; - -#if MEMORY_MAPPED_IO - ret = readw(unsigned long) port; -#else - ret = inw((unsigned long) port); -#endif - - if (ql_debug_print) - printk(KERN_DEBUG - "qla1280_getbyte: address = 0x%p, data = 0x%x", port, - ret); - - return ret; -} - -/* - * Get double word from I/O port - */ -static u32 -qla1280_getdword (u32 * port) -{ - u32 ret; - -#if MEMORY_MAPPED_IO - ret = readl((unsigned long) port); -#else - ret = inl((unsigned long) port); -#endif - - if (ql_debug_print) - printk(KERN_DEBUG - "qla1280_getbyte: address = 0x%p, data = 0x%x", port, - ret); - - return ret; -} - -/* - * Send byte to I/O port - */ -static void -qla1280_putbyte(u8 * port, u8 data) -{ -#if MEMORY_MAPPED_IO - writeb(data, (unsigned long) port); -#else - outb(data, (unsigned long) port); -#endif - - if (ql_debug_print) - printk(KERN_DEBUG - "qla1280_getbyte: address = 0x%p, data = 0x%x", port, - data); -} - -/* - * Send word to I/O port - */ -static void -qla1280_putword(u16 * port, u16 data) -{ -#if MEMORY_MAPPED_IO - writew(data, (unsigned long) port); -#else - outw(data, (unsigned long) port); -#endif - - if (ql_debug_print) - printk(KERN_DEBUG - "qla1280_getbyte: address = 0x%p, data = 0x%x", port, - data); -} - -/* - * Send double word to I/O port - */ -static void -qla1280_putdword(u32 * port, u32 data) -{ -#if MEMORY_MAPPED_IO - writel(data, (unsigned long) port); -#else - outl(data, (unsigned long) port); -#endif + if (mb[3] != 0) { + printk(" Sync: period %d, offset %d", + (mb[3] & 0xff), (mb[3] >> 8)); + if (mb[2] & BIT_13) + printk(", Wide"); + if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2) + printk(", DT"); + } else + printk(" Async"); - if (ql_debug_print) - printk(KERN_DEBUG - "qla1280_getbyte: address = 0x%p, data = 0x%x", port, - data); + if (device->tagged_queue) + printk(", Tagged queuing: depth %d", device->queue_depth); + printk("\n"); } -/* - * Dummy function to prevent warnings for - * declared and unused debug functions - */ -static void -qla1280_debug(void) -{ - qla1280_getbyte(0); - qla1280_getword(0); - qla1280_getdword(0); - qla1280_putbyte(0, 0); - qla1280_putword(0, 0); - qla1280_putdword(0, 0); -} +#if DEBUG_QLA1280 static void __qla1280_dump_buffer(char *b, int size) { int cnt; u8 c; - if (ql_debug_print) { - printk(KERN_DEBUG - " 0 1 2 3 4 5 6 7 8 9 Ah " - "Bh Ch Dh Eh Fh\n"); - printk(KERN_DEBUG - "---------------------------------------------" - "------------------\n"); - - for (cnt = 0; cnt < size;) { - c = *b++; - if (c < 16) - printk(' '); - printk("0x%x", c); - cnt++; - if (!(cnt % 16)) - printk("\n"); - else if (c < 10) - printk(" "); - else - printk(' '); - } - if (cnt % 16) + printk(KERN_DEBUG " 0 1 2 3 4 5 6 7 8 9 Ah " + "Bh Ch Dh Eh Fh\n"); + printk(KERN_DEBUG "---------------------------------------------" + "------------------\n"); + + for (cnt = 0; cnt < size;) { + c = *b++; + + printk("0x%02x", c); + cnt++; + if (!(cnt % 16)) printk("\n"); + else + printk(" "); } + if (cnt % 16) + printk("\n"); } /************************************************************************** @@ -6063,20 +4946,21 @@ * **************************************************************************/ static void -qla1280_print_scsi_cmd(Scsi_Cmnd * cmd) +__qla1280_print_scsi_cmd(Scsi_Cmnd * cmd) { struct scsi_qla_host *ha; - struct Scsi_Host *host = cmd->host; - srb_t *sp; + struct Scsi_Host *host = CMD_HOST(cmd); + struct srb *sp; /* struct scatterlist *sg; */ int i; ha = (struct scsi_qla_host *)host->hostdata; - sp = (srb_t *)CMD_SP(cmd); + sp = (struct srb *)CMD_SP(cmd); printk("SCSI Command @= 0x%p, Handle=0x%p\n", cmd, CMD_HANDLE(cmd)); printk(" chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", - cmd->channel, cmd->target, cmd->lun, cmd->cmd_len); + SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd), + CMD_CDBLEN(cmd)); printk(" CDB = "); for (i = 0; i < cmd->cmd_len; i++) { printk("0x%02x ", cmd->cmnd[i]); @@ -6093,8 +4977,8 @@ printk(" tag=%d, flags=0x%x, transfersize=0x%x \n", cmd->tag, cmd->flags, cmd->transfersize); printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd)); - printk(" underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n", - cmd->underflow, sp->dir, cmd->request->cmd); + printk(" underflow size = 0x%x, direction=0x%x\n", + cmd->underflow, sp->dir); } /************************************************************************** @@ -6106,104 +4990,139 @@ { Scsi_Cmnd *cp; - srb_t *sp; + struct srb *sp; int i; - if (ql_debug_print) { - printk(KERN_DEBUG "Outstanding Commands on controller:\n"); - for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { - if ((sp = ha->outstanding_cmds[i]) == NULL) - continue; - if ((cp = sp->cmd) == NULL) - continue; - qla1280_print_scsi_cmd(1, cp); - } + printk(KERN_DEBUG "Outstanding Commands on controller:\n"); + + for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { + if ((sp = ha->outstanding_cmds[i]) == NULL) + continue; + if ((cp = sp->cmd) == NULL) + continue; + qla1280_print_scsi_cmd(1, cp); } } #endif -#if STOP_ON_ERROR -/************************************************************************** - * ql1280_panic - * - **************************************************************************/ -static void -qla1280_panic(char *cp, struct Scsi_Host *host) + +enum tokens { + TOKEN_NVRAM, + TOKEN_SYNC, + TOKEN_WIDE, + TOKEN_PPR, + TOKEN_VERBOSE, + TOKEN_DEBUG, +}; + +struct setup_tokens { + char *token; + int val; +}; + +static struct setup_tokens setup_token[] __initdata = { - struct scsi_qla_host *ha; - long *fp; + { "nvram", TOKEN_NVRAM }, + { "sync", TOKEN_SYNC }, + { "wide", TOKEN_WIDE }, + { "ppr", TOKEN_PPR }, + { "verbose", TOKEN_VERBOSE }, + { "debug", TOKEN_DEBUG }, +}; - ha = (struct scsi_qla_host *)host->hostdata; - printk(KERN_ERR "qla1280 - PANIC: %s\n", cp); - printk(KERN_ERR "Current time=0x%lx\n", jiffies); - printk(KERN_ERR "Number of pending commands =0x%lx\n", ha->actthreads); - printk(KERN_ERR "Number of SCSI queued commands =0x%lx\n", - ha->qthreads); - printk(KERN_ERR "Number of free entries = (%d)\n", ha->req_q_cnt); - printk(KERN_ERR "Request Queue @ 0x%lx, Response Queue @ 0x%lx\n", - ha->request_dma, ha->response_dma); - printk(KERN_ERR "Request In Ptr %d\n", ha->req_ring_index); - fp = (long *) &ha->flags; - printk(KERN_ERR "HA flags =0x%lx\n", *fp); - if (ql_debug_level >= 2) { - ql_debug_print = 1; -#if 0 - ql1280_dump_device((struct scsi_qla_host *)host->hostdata); -#endif - } - sti(); - panic("Ooops"); - /* cli(); - for(;;) - { - barrier(); - sti(); - } - */ -} -#endif -#ifdef MODULE /************************************************************************** * qla1280_setup * - * Handle Linux boot parameters. This routine allows for assigning a value - * to a parameter with a ':' between the parameter and the value. - * ie. qla1280=max_reqs:0x0A,verbose + * Handle boot parameters. This really needs to be changed so one + * can specify per adapter parameters. **************************************************************************/ -void -qla1280_setup(char *s, int *dummy) +int __init +qla1280_setup(char *s) { - char *end, *str, *cp; + char *cp, *ptr; + unsigned long val; + int toke; + + cp = s; + + while (cp && (ptr = strchr(cp, ':'))) { + ptr++; + if (!strcmp(ptr, "yes")) { + val = 0x10000; + ptr += 3; + } else if (!strcmp(ptr, "no")) { + val = 0; + ptr += 2; + } else + val = simple_strtoul(ptr, &ptr, 0); + + switch ((toke = qla1280_get_token(cp))) { + case TOKEN_NVRAM: + if (!val) + driver_setup.no_nvram = 1; + break; + case TOKEN_SYNC: + if (!val) + driver_setup.no_sync = 1; + else if (val != 0x10000) + driver_setup.sync_mask = val; + break; + case TOKEN_WIDE: + if (!val) + driver_setup.no_wide = 1; + else if (val != 0x10000) + driver_setup.wide_mask = val; + break; + case TOKEN_PPR: + if (!val) + driver_setup.no_ppr = 1; + else if (val != 0x10000) + driver_setup.ppr_mask = val; + break; + case TOKEN_VERBOSE: + qla1280_verbose = val; + break; + default: + printk(KERN_INFO "qla1280: unknown boot option %s\n", + cp); + } - printk(KERN_INFO "scsi: Processing Option str = %s\n", s); - end = strchr (s, '\0'); - /* locate command */ - str = s; - for (cp = s; *cp && cp != end; cp++) { - cp = qla1280_get_token(cp, str); - printk(KERN_INFO "scsi: token str = %s\n", str); - /* if found execute routine */ + cp = strchr(ptr, ';'); + if (cp) + cp++; + else { + break; + } } + return 1; } -static char * -qla1280_get_token(char *cmdline, char *str) -{ - register char *cp = cmdline; - - /* skip preceeding spaces */ - while (strchr (cp, ' ')) - ++cp; - /* symbol starts here */ - str = cp; - /* skip char if not a space or : */ - while (*cp && !(strchr (cp, ' ') || strchr (cp, ':'))) - cp++; - *cp = '\0'; - return cp; + +static int +qla1280_get_token(char *str) +{ + char *sep; + long ret = -1; + int i, len; + + len = sizeof(setup_token)/sizeof(struct setup_tokens); + + sep = strchr(str, ':'); + + if (sep) { + for (i = 0; i < len; i++){ + + if (!strncmp(setup_token[i].token, str, (sep - str))) { + ret = setup_token[i].val; + break; + } + } + } + + return ret; } -#endif + /* * Overrides for Emacs so that we almost follow Linus's tabbing style. diff -Nru a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h --- a/drivers/scsi/qla1280.h Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/qla1280.h Mon Aug 18 22:21:06 2003 @@ -21,18 +21,6 @@ #define _IO_HBA_QLA1280_H /* subject to change without notice */ #ifndef HOSTS_C /* included in hosts.c */ -/* - * Enable define statement to ignore Data Underrun Errors, - * remove define statement to enable detection. - */ -/* #define DATA_UNDERRUN_ERROR_DISABLE */ - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif /* * Data bit definitions. @@ -70,48 +58,13 @@ #define BIT_30 0x40000000 #define BIT_31 0x80000000 -/* - * Local Macro Definitions. - */ -#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \ - defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \ - defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \ - defined(QL_DEBUG_LEVEL_7) -#define QL_DEBUG_ROUTINES -#endif - -/* - * I/O port macros -*/ -/* #define MEMORY_MAPPED_IO *//* Enable memory mapped I/O */ -#undef MEMORY_MAPPED_IO /* Disable memory mapped I/O */ - -#ifdef QL_DEBUG_LEVEL_1 -#define RD_REG_BYTE(addr) qla1280_getbyte((u8 *)addr) -#define RD_REG_WORD(addr) qla1280_getword((u16 *)addr) -#define RD_REG_DWORD(addr) qla1280_getdword((u32 *)addr) -#define WRT_REG_BYTE(addr, data) qla1280_putbyte((u8 *)addr, data) -#define WRT_REG_WORD(addr, data) qla1280_putword((u16 *)addr, data) -#define WRT_REG_DWORD(addr, data) qla1280_putdword((u32 *)addr, data) -#else /* QL_DEBUG_LEVEL_1 */ - -#ifdef MEMORY_MAPPED_IO -#define RD_REG_BYTE(addr) readb(addr) +#if MEMORY_MAPPED_IO #define RD_REG_WORD(addr) readw(addr) -#define RD_REG_DWORD(addr) readl(addr) -#define WRT_REG_BYTE(addr, data) writeb(data, addr) #define WRT_REG_WORD(addr, data) writew(data, addr) -#define WRT_REG_DWORD(addr, data) writel(data, addr) #else /* MEMORY_MAPPED_IO */ -#define RD_REG_BYTE(addr) inb((unsigned long)addr) #define RD_REG_WORD(addr) inw((unsigned long)addr) -#define RD_REG_DWORD(addr) inl((unsigned long)addr) -/* Parameters are reversed in Linux */ -#define WRT_REG_BYTE(addr, data) outb(data, (unsigned long)addr) #define WRT_REG_WORD(addr, data) outw(data, (unsigned long)addr) -#define WRT_REG_DWORD(addr, data) outl(data, (unsigned long)addr) #endif /* MEMORY_MAPPED_IO */ -#endif /* QL_DEBUG_LEVEL_1 */ /* * Host adapter default definitions. @@ -133,16 +86,14 @@ /* Command retry count (0-65535) */ #define COMMAND_RETRY_COUNT 255 -/* Maximum outstanding commands in ISP queues (1-65535) */ +/* Maximum outstanding commands in ISP queues */ #define MAX_OUTSTANDING_COMMANDS 512 +#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 2) /* ISP request and response entry counts (37-65535) */ #define REQUEST_ENTRY_CNT 256 /* Number of request entries. */ #define RESPONSE_ENTRY_CNT 16 /* Number of response entries. */ -/* Maximum equipage per controller */ -#define MAX_EQ (MAX_BUSES * MAX_TARGETS * MAX_LUNS) - /* Number of segments 1 - 65535 */ #define SG_SEGMENTS 32 /* Cmd entry + 6 continuations */ @@ -150,20 +101,20 @@ * SCSI Request Block structure (sp) that is placed * on cmd->SCp location of every I/O */ -typedef struct srb { +struct srb { Scsi_Cmnd *cmd; /* (4/8) SCSI command block */ struct srb *s_next; /* (4/8) Next block on LU queue */ struct srb *s_prev; /* (4/8) Previous block on LU queue */ uint8_t flags; /* (1) Status flags. */ uint8_t dir; /* direction of transfer */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + /* + * This should be moved around to save space. + */ dma_addr_t saved_dma_handle; /* for unmap of single transfers */ /* NOTE: the sp->cmd will be NULL when this completion is * called, so you should know the scsi_cmnd when using this */ struct completion *wait; -#endif - -} srb_t; +}; /* * SRB flag definitions @@ -176,9 +127,9 @@ /* * Logical Unit Queue structure */ -typedef struct scsi_lu { - srb_t *q_first; /* First block on LU queue */ - srb_t *q_last; /* Last block on LU queue */ +struct scsi_lu { + struct srb *q_first; /* First block on LU queue */ + struct srb *q_last; /* Last block on LU queue */ uint8_t q_flag; /* LU queue state flags */ uint8_t q_sense[16]; /* sense data */ unsigned long io_cnt; /* total xfer count */ @@ -187,12 +138,7 @@ unsigned long w_cnt; /* total writes */ unsigned long r_cnt; /* total reads */ uint16_t q_outcnt; /* Pending jobs for this LU */ -#if QL1280_TARGET_MODE_SUPPORT - void (*q_func)(); /* Target driver event handler */ - int32_t q_param; /* Target driver event param */ - uint8_t q_lock; /* Device Queue Lock */ -#endif -} scsi_lu_t; +}; /* * Logical Unit flags @@ -317,44 +263,47 @@ /* * ISP mailbox commands */ -#define MBC_NOP 0 /* No Operation. */ -#define MBC_LOAD_RAM 1 /* Load RAM. */ -#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware. */ -#define MBC_DUMP_RAM 3 /* Dump RAM contents */ -#define MBC_WRITE_RAM_WORD 4 /* Write ram word. */ -#define MBC_READ_RAM_WORD 5 /* Read ram word. */ -#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */ -#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum. */ -#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision. */ -#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue. */ -#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue. */ -#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command. */ -#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */ -#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */ -#define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */ -#define MBC_BUS_RESET 0x18 /* SCSI bus reset. */ -#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay. */ -#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters. */ -#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID. */ -#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout. */ -#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay. */ -#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit. */ -#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate. */ -#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state. */ -#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time. */ -#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters. */ -#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters. */ -#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */ -#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word. */ -#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word. */ -#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */ -#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64. */ -#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode. */ +#define MBC_NOP 0 /* No Operation */ +#define MBC_LOAD_RAM 1 /* Load RAM */ +#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware */ +#define MBC_DUMP_RAM 3 /* Dump RAM contents */ +#define MBC_WRITE_RAM_WORD 4 /* Write ram word */ +#define MBC_READ_RAM_WORD 5 /* Read ram word */ +#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */ +#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum */ +#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision */ +#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue */ +#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue */ +#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command */ +#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command */ +#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN) */ +#define MBC_ABORT_TARGET 0x17 /* Abort target (ID) */ +#define MBC_BUS_RESET 0x18 /* SCSI bus reset */ +#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay */ +#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters */ +#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID */ +#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout */ +#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay */ +#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit */ +#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate */ +#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state */ +#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time */ +#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters */ +#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters */ +#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */ +#define MBC_SET_RESET_DELAY_PARAMETERS 0x3A /* Set reset delay parameters */ +#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word */ +#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word */ +#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */ +#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64 */ +#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode */ +#define MBC_SET_DATA_OVERRUN_RECOVERY 0x5A /* Set data overrun recovery mode */ /* * ISP Get/Set Target Parameters mailbox command control flags. */ -#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */ +#define TP_PPR BIT_5 /* PPR */ +#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */ #define TP_STOP_QUEUE BIT_9 /* Stop que on check condition */ #define TP_AUTO_REQUEST_SENSE BIT_10 /* Automatic request sense. */ #define TP_TAGGED_QUEUE BIT_11 /* Tagged queuing. */ @@ -374,167 +323,9 @@ #define NV_DELAY_COUNT 10 /* - * QLogic ISP1280 NVRAM structure definition. - * - * NOTE: the firmware structure is byte reversed on big-endian systems - * because it is read a word at a time from the chip, so the in-memory - * representation becomes correct + * QLogic ISP1280/ISP12160 NVRAM structure definition. */ -typedef struct { -#if defined(__BIG_ENDIAN) - uint8_t id1; /* 1 */ - uint8_t id0; /* 0 */ - - uint8_t id3; /* 3 */ - uint8_t id2; /* 2 */ - - struct { - uint8_t bios_configuration_mode:2; - uint8_t bios_disable:1; - uint8_t selectable_scsi_boot_enable:1; - uint8_t cd_rom_boot_enable:1; - uint8_t disable_loading_risc_code:1; - uint8_t enable_64bit_addressing:1; - uint8_t unused_7:1; - } cntr_flags_1; /* 5 */ - uint8_t version; /* 4 */ - - struct { - uint8_t boot_lun_number:5; - uint8_t scsi_bus_number:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - uint8_t boot_target_number:4; - uint8_t unused_12:1; - uint8_t unused_13:1; - uint8_t unused_14:1; - uint8_t unused_15:1; - } cntr_flags_2; /* 6, 7 */ - - uint16_t unused_8; /* 8, 9 */ - uint16_t unused_10; /* 10, 11 */ - uint16_t unused_12; /* 12, 13 */ - uint16_t unused_14; /* 14, 15 */ - - /* Termination - * 0 = Disable, 1 = high only, 3 = Auto term - */ - union { - uint8_t c; - struct { - uint8_t scsi_bus_1_control:2; - uint8_t scsi_bus_0_control:2; - uint8_t unused_0:1; - uint8_t unused_1:1; - uint8_t unused_2:1; - uint8_t auto_term_support:1; - } f; - } termination; /* 17 */ - union { - uint8_t c; - struct { - uint8_t reserved:2; - uint8_t burst_enable:1; - uint8_t reserved_1:1; - uint8_t fifo_threshold:4; - } f; - } isp_config; /* 16 */ - - - uint16_t isp_parameter; /* 18, 19 */ - - union { - uint16_t w; - struct { - uint16_t enable_fast_posting:1; - uint16_t report_lvd_bus_transition:1; - uint16_t unused_2:1; - uint16_t unused_3:1; - uint16_t unused_4:1; - uint16_t unused_5:1; - uint16_t unused_6:1; - uint16_t unused_7:1; - uint16_t unused_8:1; - uint16_t unused_9:1; - uint16_t unused_10:1; - uint16_t unused_11:1; - uint16_t unused_12:1; - uint16_t unused_13:1; - uint16_t unused_14:1; - uint16_t unused_15:1; - } f; - } firmware_feature; /* 20, 21 */ - - uint16_t unused_22; /* 22, 23 */ - - struct { - uint8_t bus_reset_delay; /* 25 */ - struct { - uint8_t initiator_id:4; - uint8_t scsi_reset_disable:1; - uint8_t scsi_bus_size:1; - uint8_t scsi_bus_type:1; - uint8_t unused_7:1; - } config_1; /* 24 */ - - uint8_t retry_delay; /* 27 */ - uint8_t retry_count; /* 26 */ - - uint8_t unused_29; /* 29 */ - struct { - uint8_t async_data_setup_time:4; - uint8_t req_ack_active_negation:1; - uint8_t data_line_active_negation:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } config_2; /* 28 */ - - - uint16_t selection_timeout; /* 30, 31 */ - uint16_t max_queue_depth; /* 32, 33 */ - - uint16_t unused_34; /* 34, 35 */ - uint16_t unused_36; /* 36, 37 */ - uint16_t unused_38; /* 38, 39 */ - - struct { - uint8_t execution_throttle; /* 41 */ - union { - uint8_t c; - struct { - uint8_t renegotiate_on_error:1; - uint8_t stop_queue_on_check:1; - uint8_t auto_request_sense:1; - uint8_t tag_queuing:1; - uint8_t sync_data_transfers:1; - uint8_t wide_data_transfers:1; - uint8_t parity_checking:1; - uint8_t disconnect_allowed:1; - } f; - } parameter; /* 40 */ - - struct { - uint8_t sync_offset:4; - uint8_t device_enable:1; - uint8_t lun_disable:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } flags; /* 43 */ - uint8_t sync_period; /* 42 */ - - - uint16_t unused_44; /* 44, 45 */ - } target[MAX_TARGETS]; - } bus[MAX_BUSES]; - - uint16_t unused_248; /* 248, 249 */ - - uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ - - uint8_t chksum; /* 255 */ - uint8_t unused_254; /* 254 */ - -#elif defined(__LITTLE_ENDIAN) +struct nvram { uint8_t id0; /* 0 */ uint8_t id1; /* 1 */ uint8_t id2; /* 2 */ @@ -552,174 +343,6 @@ } cntr_flags_1; /* 5 */ struct { - uint8_t boot_lun_number:5; - uint8_t scsi_bus_number:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - uint8_t boot_target_number:4; - uint8_t unused_12:1; - uint8_t unused_13:1; - uint8_t unused_14:1; - uint8_t unused_15:1; - } cntr_flags_2; /* 6, 7 */ - - uint16_t unused_8; /* 8, 9 */ - uint16_t unused_10; /* 10, 11 */ - uint16_t unused_12; /* 12, 13 */ - uint16_t unused_14; /* 14, 15 */ - - union { - uint8_t c; - struct { - uint8_t reserved:2; - uint8_t burst_enable:1; - uint8_t reserved_1:1; - uint8_t fifo_threshold:4; - } f; - } isp_config; /* 16 */ - - /* Termination - * 0 = Disable, 1 = high only, 3 = Auto term - */ - union { - uint8_t c; - struct { - uint8_t scsi_bus_1_control:2; - uint8_t scsi_bus_0_control:2; - uint8_t unused_0:1; - uint8_t unused_1:1; - uint8_t unused_2:1; - uint8_t auto_term_support:1; - } f; - } termination; /* 17 */ - - uint16_t isp_parameter; /* 18, 19 */ - - union { - uint16_t w; - struct { - uint8_t enable_fast_posting:1; - uint8_t report_lvd_bus_transition:1; - uint8_t unused_2:1; - uint8_t unused_3:1; - uint8_t unused_4:1; - uint8_t unused_5:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - uint8_t unused_8:1; - uint8_t unused_9:1; - uint8_t unused_10:1; - uint8_t unused_11:1; - uint8_t unused_12:1; - uint8_t unused_13:1; - uint8_t unused_14:1; - uint8_t unused_15:1; - } f; - } firmware_feature; /* 20, 21 */ - - uint16_t unused_22; /* 22, 23 */ - - struct { - struct { - uint8_t initiator_id:4; - uint8_t scsi_reset_disable:1; - uint8_t scsi_bus_size:1; - uint8_t scsi_bus_type:1; - uint8_t unused_7:1; - } config_1; /* 24 */ - - uint8_t bus_reset_delay; /* 25 */ - uint8_t retry_count; /* 26 */ - uint8_t retry_delay; /* 27 */ - - struct { - uint8_t async_data_setup_time:4; - uint8_t req_ack_active_negation:1; - uint8_t data_line_active_negation:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } config_2; /* 28 */ - - uint8_t unused_29; /* 29 */ - - uint16_t selection_timeout; /* 30, 31 */ - uint16_t max_queue_depth; /* 32, 33 */ - - uint16_t unused_34; /* 34, 35 */ - uint16_t unused_36; /* 36, 37 */ - uint16_t unused_38; /* 38, 39 */ - - struct { - union { - uint8_t c; - struct { - uint8_t renegotiate_on_error:1; - uint8_t stop_queue_on_check:1; - uint8_t auto_request_sense:1; - uint8_t tag_queuing:1; - uint8_t sync_data_transfers:1; - uint8_t wide_data_transfers:1; - uint8_t parity_checking:1; - uint8_t disconnect_allowed:1; - } f; - } parameter; /* 40 */ - - uint8_t execution_throttle; /* 41 */ - uint8_t sync_period; /* 42 */ - - struct { - uint8_t sync_offset:4; - uint8_t device_enable:1; - uint8_t lun_disable:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } flags; /* 43 */ - - uint16_t unused_44; /* 44, 45 */ - } target[MAX_TARGETS]; - } bus[MAX_BUSES]; - - uint16_t unused_248; /* 248, 249 */ - - uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ - - uint8_t unused_254; /* 254 */ - - uint8_t chksum; /* 255 */ -#else -#error neither __BIG_ENDIAN nor __LITTLE_ENDIAN is defined -#endif -} nvram_t; - -/* - * QLogic ISP12160 NVRAM structure definition. - * - * NOTE: the firmware structure is byte reversed on big-endian systems - * because it is read a word at a time from the chip, so the in-memory - * representation becomes correct - */ -typedef struct { -#if defined(__BIG_ENDIAN) - uint8_t id1; /* 1 */ - uint8_t id0; /* 0 */ - - uint8_t id3; /* 3 */ - uint8_t id2; /* 2 */ - - /* Host/Bios Flags */ - struct { - uint8_t bios_configuration_mode:2; - uint8_t bios_disable:1; - uint8_t selectable_scsi_boot_enable:1; - uint8_t cd_rom_boot_enable:1; - uint8_t disable_loading_risc_code:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } cntr_flags_1; /* 5 */ - uint8_t version; /* 4 */ - - /* Selectable Boot Support */ - struct { uint16_t boot_lun_number:5; uint16_t scsi_bus_number:1; uint16_t unused_6:1; @@ -736,167 +359,6 @@ uint16_t unused_12; /* 12, 13 */ uint16_t unused_14; /* 14, 15 */ - /* Termination - * 0 = Disable, 1 = high only, 3 = Auto term - */ - union { - uint8_t c; - struct { - uint8_t scsi_bus_1_control:2; - uint8_t scsi_bus_0_control:2; - uint8_t unused_0:1; - uint8_t unused_1:1; - uint8_t unused_2:1; - uint8_t auto_term_support:1; - } f; - } termination; /* 17 */ - /* Auto Term - 3 */ - /* High Only - 1 (GPIO2 = 1 & GPIO3 = 0) */ - /* Disable - 0 (GPIO2 = 0 & GPIO3 = X) */ - /* ISP Config Parameters */ - union { - uint8_t c; - struct { - uint8_t reserved:2; - uint8_t burst_enable:1; - uint8_t reserved_1:1; - uint8_t fifo_threshold:4; - } f; - } isp_config; /* 16 */ - - uint16_t isp_parameter; /* 18, 19 */ - - union { - uint16_t w; - struct { - uint16_t enable_fast_posting:1; - uint16_t report_lvd_bus_transition:1; - uint16_t unused_2:1; - uint16_t unused_3:1; - uint16_t unused_4:1; - uint16_t unused_5:1; - uint16_t unused_6:1; - uint16_t unused_7:1; - uint16_t unused_8:1; - uint16_t unused_9:1; - uint16_t unused_10:1; - uint16_t unused_11:1; - uint16_t unused_12:1; - uint16_t unused_13:1; - uint16_t unused_14:1; - uint16_t unused_15:1; - } f; - } firmware_feature; /* 20, 21 */ - - uint16_t unused_22; /* 22, 23 */ - - struct { - uint8_t bus_reset_delay; /* 25 */ - struct { - uint8_t initiator_id:4; - uint8_t scsi_reset_disable:1; - uint8_t scsi_bus_size:1; - uint8_t scsi_bus_type:1; - uint8_t unused_7:1; - } config_1; /* 24 */ - - uint8_t retry_delay; /* 27 */ - uint8_t retry_count; /* 26 */ - - uint8_t unused_29; /* 29 */ - /* Adapter Capabilities bits */ - struct { - uint8_t async_data_setup_time:4; - uint8_t req_ack_active_negation:1; - uint8_t data_line_active_negation:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } config_2; /* 28 */ - - uint16_t selection_timeout; /* 30, 31 */ - uint16_t max_queue_depth; /* 32, 33 */ - - uint16_t unused_34; /* 34, 35 */ - uint16_t unused_36; /* 36, 37 */ - uint16_t unused_38; /* 38, 39 */ - - struct { - uint8_t execution_throttle; /* 41 */ - union { - uint8_t c; - struct { - uint8_t renegotiate_on_error:1; - uint8_t stop_queue_on_check:1; - uint8_t auto_request_sense:1; - uint8_t tag_queuing:1; - uint8_t sync_data_transfers:1; - uint8_t wide_data_transfers:1; - uint8_t parity_checking:1; - uint8_t disconnect_allowed:1; - } f; - } parameter; /* 40 */ - - struct { - uint8_t sync_offset:5; - uint8_t device_enable:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } flags1; /* 43 */ - uint8_t sync_period; /* 42 */ - - uint8_t unused_45; /* 45 */ - struct { - uint8_t ppr_options:4; - uint8_t ppr_bus_width:2; - uint8_t unused_8:1; - uint8_t enable_ppr:1; - } flags2; /* 44 */ - - } target[MAX_TARGETS]; - } bus[MAX_BUSES]; - - uint16_t unused_248; /* 248, 249 */ - - uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ - - uint8_t chksum; /* 255 */ - uint8_t System_Id_Pointer; /* 254 */ - -#elif defined(__LITTLE_ENDIAN) - uint8_t id0; /* 0 */ - uint8_t id1; /* 1 */ - uint8_t id2; /* 2 */ - uint8_t id3; /* 3 */ - uint8_t version; /* 4 */ - /* Host/Bios Flags */ - struct { - uint8_t bios_configuration_mode:2; - uint8_t bios_disable:1; - uint8_t selectable_scsi_boot_enable:1; - uint8_t cd_rom_boot_enable:1; - uint8_t disable_loading_risc_code:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } cntr_flags_1; /* 5 */ - /* Selectable Boot Support */ - struct { - uint16_t boot_lun_number:5; - uint16_t scsi_bus_number:1; - uint16_t unused_6:1; - uint16_t unused_7:1; - uint16_t boot_target_number:4; - uint16_t unused_12:1; - uint16_t unused_13:1; - uint16_t unused_14:1; - uint16_t unused_15:1; - } cntr_flags_2; /* 6, 7 */ - - uint16_t unused_8; /* 8, 9 */ - uint16_t unused_10; /* 10, 11 */ - uint16_t unused_12; /* 12, 13 */ - uint16_t unused_14; /* 14, 15 */ - - /* ISP Config Parameters */ union { uint8_t c; struct { @@ -921,9 +383,6 @@ uint8_t auto_term_support:1; } f; } termination; /* 17 */ - /* Auto Term - 3 */ - /* High Only - 1 (GPIO2 = 1 & GPIO3 = 0) */ - /* Disable - 0 (GPIO2 = 0 & GPIO3 = X) */ uint16_t isp_parameter; /* 18, 19 */ @@ -934,11 +393,11 @@ uint16_t report_lvd_bus_transition:1; uint16_t unused_2:1; uint16_t unused_3:1; - uint16_t unused_4:1; - uint16_t unused_5:1; + uint16_t disable_iosbs_with_bus_reset_status:1; + uint16_t disable_synchronous_backoff:1; uint16_t unused_6:1; - uint16_t unused_7:1; - uint16_t unused_8:1; + uint16_t synchronous_backoff_reporting:1; + uint16_t disable_reselection_fairness:1; uint16_t unused_9:1; uint16_t unused_10:1; uint16_t unused_11:1; @@ -963,7 +422,7 @@ uint8_t bus_reset_delay; /* 25 */ uint8_t retry_count; /* 26 */ uint8_t retry_delay; /* 27 */ - /* Adapter Capabilities bits */ + struct { uint8_t async_data_setup_time:4; uint8_t req_ack_active_negation:1; @@ -989,8 +448,8 @@ uint8_t stop_queue_on_check:1; uint8_t auto_request_sense:1; uint8_t tag_queuing:1; - uint8_t sync_data_transfers:1; - uint8_t wide_data_transfers:1; + uint8_t enable_sync:1; + uint8_t enable_wide:1; uint8_t parity_checking:1; uint8_t disconnect_allowed:1; } f; @@ -999,20 +458,31 @@ uint8_t execution_throttle; /* 41 */ uint8_t sync_period; /* 42 */ - struct { - uint8_t sync_offset:5; - uint8_t device_enable:1; - uint8_t unused_6:1; - uint8_t unused_7:1; - } flags1; /* 43 */ - - struct { - uint8_t ppr_options:4; - uint8_t ppr_bus_width:2; - uint8_t unused_8:1; - uint8_t enable_ppr:1; - } flags2; /* 43 */ - + union { /* 43 */ + uint8_t flags_43; + struct { + uint8_t sync_offset:4; + uint8_t device_enable:1; + uint8_t lun_disable:1; + uint8_t unused_6:1; + uint8_t unused_7:1; + } flags1x80; + struct { + uint8_t sync_offset:5; + uint8_t device_enable:1; + uint8_t unused_6:1; + uint8_t unused_7:1; + } flags1x160; + } flags; + union { /* PPR flags for the 1x160 controllers */ + uint8_t unused_44; + struct { + uint8_t ppr_options:4; + uint8_t ppr_bus_width:2; + uint8_t unused_8:1; + uint8_t enable_ppr:1; + } flags; /* 44 */ + } ppr_1x160; uint8_t unused_45; /* 45 */ } target[MAX_TARGETS]; } bus[MAX_BUSES]; @@ -1021,19 +491,19 @@ uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ - uint8_t System_Id_Pointer; /* 254 */ + union { /* 254 */ + uint8_t unused_254; + uint8_t system_id_pointer; + } sysid_1x160; uint8_t chksum; /* 255 */ -#else -#error neither __BIG_ENDIAN nor __LITTLE_ENDIAN is defined -#endif -} nvram160_t; +}; /* * ISP queue - command entry structure definition. */ #define MAX_CMDSZ 12 /* SCSI maximum CDB size. */ -typedef struct { +struct cmd_entry { uint8_t entry_type; /* Entry type. */ #define COMMAND_TYPE 1 /* Command entry */ uint8_t entry_count; /* Entry count. */ @@ -1056,12 +526,12 @@ uint32_t dseg_2_length; /* Data segment 2 length. */ uint32_t dseg_3_address; /* Data segment 3 address. */ uint32_t dseg_3_length; /* Data segment 3 length. */ -} cmd_entry_t; +}; /* * ISP queue - continuation entry structure definition. */ -typedef struct { +struct cont_entry { uint8_t entry_type; /* Entry type. */ #define CONTINUE_TYPE 2 /* Continuation entry. */ uint8_t entry_count; /* Entry count. */ @@ -1082,12 +552,12 @@ uint32_t dseg_5_length; /* Data segment 5 length. */ uint32_t dseg_6_address; /* Data segment 6 address. */ uint32_t dseg_6_length; /* Data segment 6 length. */ -} cont_entry_t; +}; /* * ISP queue - status entry structure definition. */ -typedef struct { +struct response { uint8_t entry_type; /* Entry type. */ #define STATUS_TYPE 3 /* Status entry. */ uint8_t entry_count; /* Entry count. */ @@ -1114,12 +584,12 @@ uint32_t residual_length; /* Residual transfer length. */ uint16_t reserved[4]; uint8_t req_sense_data[32]; /* Request sense data. */ -} sts_entry_t, response_t; +}; /* * ISP queue - marker entry structure definition. */ -typedef struct { +struct mrk_entry { uint8_t entry_type; /* Entry type. */ #define MARKER_TYPE 4 /* Marker entry. */ uint8_t entry_count; /* Entry count. */ @@ -1133,12 +603,14 @@ #define MK_SYNC_ID 1 /* Synchronize ID */ #define MK_SYNC_ALL 2 /* Synchronize all ID/LUN */ uint8_t reserved_1[53]; -} mrk_entry_t; +}; /* * ISP queue - extended command entry structure definition. + * + * Unused by the driver! */ -typedef struct { +struct ecmd_entry { uint8_t entry_type; /* Entry type. */ #define EXTENDED_CMD_TYPE 5 /* Extended command entry. */ uint8_t entry_count; /* Entry count. */ @@ -1153,7 +625,7 @@ uint16_t timeout; /* Command timeout. */ uint16_t dseg_count; /* Data segment count. */ uint8_t scsi_cdb[88]; /* SCSI command words. */ -} ecmd_entry_t; +}; /* * ISP queue - 64-Bit addressing, command entry structure definition. @@ -1183,7 +655,7 @@ /* * ISP queue - 64-Bit addressing, continuation entry structure definition. */ -typedef struct { +struct cont_a64_entry { uint8_t entry_type; /* Entry type. */ #define CONTINUE_A64_TYPE 0xA /* Continuation A64 entry. */ uint8_t entry_count; /* Entry count. */ @@ -1199,12 +671,12 @@ uint32_t dseg_3_length; /* Data segment 3 length. */ uint32_t dseg_4_address[2]; /* Data segment 4 address. */ uint32_t dseg_4_length; /* Data segment 4 length. */ -} cont_a64_entry_t; +}; /* * ISP queue - enable LUN entry structure definition. */ -typedef struct { +struct elun_entry { uint8_t entry_type; /* Entry type. */ #define ENABLE_LUN_TYPE 0xB /* Enable LUN entry. */ uint8_t entry_count; /* Entry count. */ @@ -1225,12 +697,14 @@ /* commands (2-26). */ uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ uint16_t reserved_6[20]; -} elun_entry_t; +}; /* * ISP queue - modify LUN entry structure definition. + * + * Unused by the driver! */ -typedef struct { +struct modify_lun_entry { uint8_t entry_type; /* Entry type. */ #define MODIFY_LUN_TYPE 0xC /* Modify LUN entry. */ uint8_t entry_count; /* Entry count. */ @@ -1250,12 +724,12 @@ uint16_t reserved_6; uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ uint16_t reserved_7[20]; -} modify_lun_entry_t; +}; /* * ISP queue - immediate notify entry structure definition. */ -typedef struct { +struct notify_entry { uint8_t entry_type; /* Entry type. */ #define IMMED_NOTIFY_TYPE 0xD /* Immediate notify entry. */ uint8_t entry_count; /* Entry count. */ @@ -1276,12 +750,12 @@ uint8_t scsi_msg[8]; /* SCSI message not handled by ISP */ uint16_t reserved_5[8]; uint8_t sense_data[18]; -} notify_entry_t; +}; /* * ISP queue - notify acknowledge entry structure definition. */ -typedef struct { +struct nack_entry { uint8_t entry_type; /* Entry type. */ #define NOTIFY_ACK_TYPE 0xE /* Notify acknowledge entry. */ uint8_t entry_count; /* Entry count. */ @@ -1297,12 +771,12 @@ uint8_t event; uint16_t seq_id; uint16_t reserved_4[22]; -} nack_entry_t; +}; /* * ISP queue - Accept Target I/O (ATIO) entry structure definition. */ -typedef struct { +struct atio_entry { uint8_t entry_type; /* Entry type. */ #define ACCEPT_TGT_IO_TYPE 6 /* Accept target I/O entry. */ uint8_t entry_count; /* Entry count. */ @@ -1320,12 +794,12 @@ uint8_t tag_type; /* Received queue tag message type */ uint8_t cdb[26]; uint8_t sense_data[18]; -} atio_entry_t; +}; /* * ISP queue - Continue Target I/O (CTIO) entry structure definition. */ -typedef struct { +struct ctio_entry { uint8_t entry_type; /* Entry type. */ #define CONTINUE_TGT_IO_TYPE 7 /* CTIO entry */ uint8_t entry_count; /* Entry count. */ @@ -1353,12 +827,12 @@ uint32_t dseg_2_length; /* Data segment 2 length. */ uint32_t dseg_3_address; /* Data segment 3 address. */ uint32_t dseg_3_length; /* Data segment 3 length. */ -} ctio_entry_t; +}; /* * ISP queue - CTIO returned entry structure definition. */ -typedef struct { +struct ctio_ret_entry { uint8_t entry_type; /* Entry type. */ #define CTIO_RET_TYPE 7 /* CTIO return entry */ uint8_t entry_count; /* Entry count. */ @@ -1383,12 +857,12 @@ uint32_t dseg_1_address; /* Data segment 1 address. */ uint16_t dseg_1_length; /* Data segment 1 length. */ uint8_t sense_data[18]; -} ctio_ret_entry_t; +}; /* * ISP queue - CTIO A64 entry structure definition. */ -typedef struct { +struct ctio_a64_entry { uint8_t entry_type; /* Entry type. */ #define CTIO_A64_TYPE 0xF /* CTIO A64 entry */ uint8_t entry_count; /* Entry count. */ @@ -1413,12 +887,12 @@ uint32_t dseg_0_length; /* Data segment 0 length. */ uint32_t dseg_1_address[2]; /* Data segment 1 address. */ uint32_t dseg_1_length; /* Data segment 1 length. */ -} ctio_a64_entry_t; +}; /* * ISP queue - CTIO returned entry structure definition. */ -typedef struct { +struct ctio_a64_ret_entry { uint8_t entry_type; /* Entry type. */ #define CTIO_A64_RET_TYPE 0xF /* CTIO A64 returned entry */ uint8_t entry_count; /* Entry count. */ @@ -1440,12 +914,12 @@ uint16_t dseg_count; /* Data segment count. */ uint16_t reserved_4[7]; uint8_t sense_data[18]; -} ctio_a64_ret_entry_t; +}; /* * ISP request and response queue entry sizes */ -#define RESPONSE_ENTRY_SIZE (sizeof(response_t)) +#define RESPONSE_ENTRY_SIZE (sizeof(struct response)) #define REQUEST_ENTRY_SIZE (sizeof(request_t)) /* @@ -1508,27 +982,11 @@ #define OF_FORCE_DISC BIT_30 /* Disconnects mandatory */ #define OF_SSTS BIT_31 /* Send SCSI status */ -#if QL1280_TARGET_MODE_SUPPORT -/* - * Target Read/Write buffer structure. - */ -#define TARGET_DATA_OFFSET 4 -#define TARGET_DATA_SIZE 0x2000 /* 8K */ -#define TARGET_INQ_OFFSET (TARGET_DATA_OFFSET + TARGET_DATA_SIZE) -#define TARGET_SENSE_SIZE 18 -#define TARGET_BUF_SIZE 36 - -typedef struct { - uint8_t hdr[4]; - uint8_t data[TARGET_DATA_SIZE]; - struct ident inq; -} tgt_t; -#endif /* - * BUS parameters/settings structure + * BUS parameters/settings structure - UNUSED */ -typedef struct { +struct bus_param { uint8_t id; /* Host adapter SCSI id */ uint8_t bus_reset_delay; /* SCSI bus reset delay. */ uint8_t failed_reset_count; /* number of time reset failed */ @@ -1540,8 +998,19 @@ uint8_t reset_marker:1; uint8_t disable_scsi_reset:1; uint8_t scsi_bus_dead:1; /* SCSI Bus is Dead, when 5 back to back resets failed */ +}; + + +struct qla_driver_setup { + uint32_t no_sync:1; + uint32_t no_wide:1; + uint32_t no_ppr:1; + uint32_t no_nvram:1; + uint16_t sync_mask; + uint16_t wide_mask; + uint16_t ppr_mask; +}; -} bus_param_t; /* * Linux Host Adapter structure @@ -1551,35 +1020,32 @@ struct Scsi_Host *host; /* pointer to host data */ struct scsi_qla_host *next; struct device_reg *iobase; /* Base Memory-mapped I/O address */ - uint8_t pci_bus; - uint8_t pci_device_fn; - uint8_t devnum; - struct pci_dev *pdev; - volatile unsigned char *mmpbase; /* memory mapped address */ + unsigned char *mmpbase; /* memory mapped address */ unsigned long host_no; unsigned long instance; + struct pci_dev *pdev; + uint32_t device_id; + uint8_t pci_bus; + uint8_t pci_device_fn; + uint8_t devnum; uint8_t revision; uint8_t ports; unsigned long actthreads; - unsigned long qthreads; unsigned long isr_count; /* Interrupt count */ unsigned long spurious_int; - uint32_t device_id; - /* Outstandings ISP commands. */ - srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; + struct srb *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; /* BUS configuration data */ - bus_param_t bus_settings[MAX_BUSES]; - - /* Device LUN queues. */ - struct scsi_lu *dev[MAX_EQ]; /* Logical unit queues */ + struct bus_param bus_settings[MAX_BUSES]; +#if 0 /* bottom half run queue */ - struct work_struct run_qla_bh; + struct tq_struct run_qla_bh; +#endif /* Received ISP mailbox data. */ volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; @@ -1595,49 +1061,43 @@ uint16_t req_q_cnt; /* Number of available entries. */ dma_addr_t response_dma; /* Physical address. */ - response_t *response_ring; /* Base virtual address */ - response_t *response_ring_ptr; /* Current address. */ + struct response *response_ring; /* Base virtual address */ + struct response *response_ring_ptr; /* Current address. */ uint16_t rsp_ring_index; /* Current index. */ -#if QL1280_TARGET_MODE_SUPPORT - /* Target buffer and sense data. */ - dma_addr_t tbuf_dma; /* Physical address. */ - dma_addr_t tsense_dma; /* Physical address. */ - tgt_t *tbuf; - uint8_t *tsense; -#endif - #if WATCHDOGTIMER /* Watchdog queue, lock and total timer */ uint8_t watchdog_q_lock; /* Lock for watchdog queue */ - srb_t *wdg_q_first; /* First job on watchdog queue */ - srb_t *wdg_q_last; /* Last job on watchdog queue */ + struct srb *wdg_q_first; /* First job on watchdog queue */ + struct srb *wdg_q_last; /* Last job on watchdog queue */ uint32_t total_timeout; /* Total timeout (quantum count) */ uint32_t watchdogactive; #endif - srb_t *done_q_first; /* First job on done queue */ - srb_t *done_q_last; /* Last job on done queue */ + struct srb *done_q_first; /* First job on done queue */ + struct srb *done_q_last; /* Last job on done queue */ + + struct completion *mailbox_wait; volatile struct { - uint32_t mbox_int:1; /* 0 */ - uint32_t mbox_busy:1; /* 1 */ - uint32_t online:1; /* 2 */ - uint32_t reset_marker:1; /* 3 */ - uint32_t isp_abort_needed:1; /* 4 */ - uint32_t disable_host_adapter:1; /* 5 */ - uint32_t reset_active:1; /* 6 */ - uint32_t abort_isp_active:1; /* 7 */ - uint32_t disable_risc_code_load:1; /* 8 */ - uint32_t enable_64bit_addressing:1; /* 9 */ - uint32_t in_reset:1; /* 10 */ + uint32_t mbox_busy:1; /* 0 */ + uint32_t online:1; /* 1 */ + uint32_t reset_marker:1; /* 2 */ + uint32_t disable_host_adapter:1; /* 4 */ + uint32_t reset_active:1; /* 5 */ + uint32_t abort_isp_active:1; /* 6 */ + uint32_t disable_risc_code_load:1; /* 7 */ + uint32_t enable_64bit_addressing:1; /* 8 */ + uint32_t in_reset:1; /* 9 */ uint32_t ints_enabled:1; + uint32_t ignore_nvram:1; +#ifdef __ia64__ + uint32_t use_pci_vchannel:1; +#endif } flags; - /* needed holders for PCI ordered list of hosts */ - unsigned long io_port; - uint32_t irq; - + struct nvram nvram; + int nvram_valid; }; /* @@ -1651,16 +1111,62 @@ /* * Linux - SCSI Driver Interface Function Prototypes. */ +#if LINUX_VERSION_CODE < 0x020600 +int qla1280_proc_info(char *, char **, off_t, int, int, int); +#else +int qla1280_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); +#endif const char *qla1280_info(struct Scsi_Host *host); int qla1280_detect(Scsi_Host_Template *); int qla1280_release(struct Scsi_Host *); int qla1280_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); -int qla1280_abort(Scsi_Cmnd *); -int qla1280_reset(Scsi_Cmnd *, unsigned int); +#if LINUX_VERSION_CODE < 0x020545 +int qla1280_biosparam(Disk *, kdev_t, int[]); +#else int qla1280_biosparam(struct scsi_device *, struct block_device *, - sector_t, int[]); -static int qla1280_slave_configure(Scsi_Device *); -irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *); -void qla1280_setup(char *s, int *dummy); + sector_t, int *); +#endif +int __init qla1280_setup(char *s); +int qla1280_eh_abort(struct scsi_cmnd * cmd); +int qla1280_eh_device_reset(struct scsi_cmnd *cmd); +int qla1280_eh_bus_reset(struct scsi_cmnd *cmd); +int qla1280_eh_adapter_reset(struct scsi_cmnd *cmd); + +#if LINUX_VERSION_CODE < 0x020545 +#define USE_NEW_EH .use_new_eh_code= 1 +#else +#define USE_NEW_EH +#endif + +/* + * Scsi_Host_template (see hosts.h) + * Device driver Interfaces to mid-level SCSI driver. + */ + +#define QLA1280_LINUX_TEMPLATE { \ + .module = NULL, \ + .proc_dir = NULL, \ + .proc_info = qla1280_proc_info, \ + .name = "Qlogic ISP 1280/12160", \ + .detect = qla1280_detect, \ + .release = qla1280_release, \ + .info = qla1280_info, \ + .queuecommand = qla1280_queuecommand, \ + .eh_strategy_handler = NULL, \ + .eh_abort_handler = qla1280_eh_abort, \ + .eh_device_reset_handler = qla1280_eh_device_reset, \ + .eh_bus_reset_handler = qla1280_eh_bus_reset, \ + .eh_host_reset_handler = qla1280_eh_adapter_reset, \ + .bios_param = qla1280_biosparam, \ + .can_queue = 255, /* max simultaneous cmds */\ + .this_id = -1, /* scsi id of host adapter */\ + .sg_tablesize = SG_ALL, /* max scatter-gather cmds */\ + .cmd_per_lun = 3, /* cmds per lun (linked cmds) */\ + .present = 0, /* number of 1280's present */\ + .unchecked_isa_dma = 0, /* no memory DMA restrictions */\ + .use_clustering = ENABLE_CLUSTERING, \ + .emulated = 0, \ + USE_NEW_EH \ +} #endif /* _IO_HBA_QLA1280_H */ diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c --- a/drivers/scsi/qlogicfc.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/qlogicfc.c Mon Aug 18 22:21:04 2003 @@ -738,7 +738,6 @@ if (!hostdata->res){ printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hosts); - pci_free_consistent(pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr); scsi_unregister(host); continue; } @@ -1283,8 +1282,7 @@ } } else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) { struct page *page = virt_to_page(Cmnd->request_buffer); - unsigned long offset = ((unsigned long)Cmnd->request_buffer & - ~PAGE_MASK); + unsigned long offset = offset_in_page(Cmnd->request_buffer); dma_addr_t busaddr = pci_map_page(hostdata->pci_dev, page, offset, Cmnd->request_bufflen, @@ -1927,8 +1925,7 @@ */ busaddr = pci_map_page(hostdata->pci_dev, virt_to_page(&hostdata->control_block), - ((unsigned long) &hostdata->control_block & - ~PAGE_MASK), + offset_in_page(&hostdata->control_block), sizeof(hostdata->control_block), PCI_DMA_BIDIRECTIONAL); @@ -2235,6 +2232,5 @@ .sg_tablesize = QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN), .cmd_per_lun = QLOGICFC_CMD_PER_LUN, .use_clustering = ENABLE_CLUSTERING, - .highmem_io = 1, }; #include "scsi_module.c" diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c --- a/drivers/scsi/qlogicpti.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/qlogicpti.c Mon Aug 18 22:21:04 2003 @@ -1550,10 +1550,6 @@ .sg_tablesize = QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN), .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, -/* Sparc32's iommu code cannot handle highmem pages yet. */ -#ifdef CONFIG_SPARC64 - .highmem_io = 1, -#endif }; diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c --- a/drivers/scsi/scsi.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/scsi.c Mon Aug 18 22:21:03 2003 @@ -370,7 +370,7 @@ struct Scsi_Host *host = cmd->device->host; unsigned long flags = 0; unsigned long timeout; - int rtn = 1; + int rtn = 0; /* Assign a unique nonzero serial_number. */ /* XXX(hch): this is racy */ @@ -444,7 +444,12 @@ host->hostt->queuecommand)); spin_lock_irqsave(host->host_lock, flags); - rtn = host->hostt->queuecommand(cmd, scsi_done); + if (unlikely(test_bit(SHOST_CANCEL, &host->shost_state))) { + cmd->result = (DID_NO_CONNECT << 16); + scsi_done(cmd); + } else { + rtn = host->hostt->queuecommand(cmd, scsi_done); + } spin_unlock_irqrestore(host->host_lock, flags); if (rtn) { scsi_queue_insert(cmd, @@ -888,33 +893,65 @@ int scsi_device_get(struct scsi_device *sdev) { - if (!try_module_get(sdev->host->hostt->module)) - return -ENXIO; + struct class *class = class_get(&sdev_class); + int error = -ENXIO; - sdev->access_count++; - return 0; + if (class) { + down_write(&class->subsys.rwsem); + if (!test_bit(SDEV_DEL, &sdev->sdev_state)) + if (try_module_get(sdev->host->hostt->module)) + if (get_device(&sdev->sdev_gendev)) { + sdev->access_count++; + error = 0; + } + up_write(&class->subsys.rwsem); + class_put(&sdev_class); + } + + return error; } void scsi_device_put(struct scsi_device *sdev) { - sdev->access_count--; + struct class *class = class_get(&sdev_class); + + if (!class) + return; + + down_write(&class->subsys.rwsem); module_put(sdev->host->hostt->module); + if (--sdev->access_count == 0) { + if (test_bit(SDEV_DEL, &sdev->sdev_state)) + device_del(&sdev->sdev_gendev); + } + put_device(&sdev->sdev_gendev); + up_write(&class->subsys.rwsem); + + class_put(&sdev_class); +} + +int scsi_device_cancel_cb(struct device *dev, void *data) +{ + struct scsi_device *sdev = to_scsi_device(dev); + int recovery = *(int *)data; + + return scsi_device_cancel(sdev, recovery); } /** - * scsi_set_device_offline - set scsi_device offline - * @sdev: pointer to struct scsi_device to offline. + * scsi_device_cancel - cancel outstanding IO to this device + * @sdev: pointer to struct scsi_device + * @data: pointer to cancel value. * - * Locks: host_lock held on entry. **/ -void scsi_set_device_offline(struct scsi_device *sdev) +int scsi_device_cancel(struct scsi_device *sdev, int recovery) { struct scsi_cmnd *scmd; LIST_HEAD(active_list); struct list_head *lh, *lh_sf; unsigned long flags; - sdev->online = 0; + set_bit(SDEV_CANCEL, &sdev->sdev_state); spin_lock_irqsave(&sdev->list_lock, flags); list_for_each_entry(scmd, &sdev->cmd_list, list) { @@ -934,11 +971,17 @@ if (!list_empty(&active_list)) { list_for_each_safe(lh, lh_sf, &active_list) { scmd = list_entry(lh, struct scsi_cmnd, eh_entry); - scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD); + list_del_init(lh); + if (recovery) { + scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD); + } else { + scmd->result = (DID_ABORT << 16); + scsi_finish_command(scmd); + } } - } else { - /* FIXME: Send online state change hotplug event */ } + + return 0; } MODULE_DESCRIPTION("SCSI core"); @@ -960,9 +1003,12 @@ error = scsi_init_devinfo(); if (error) goto cleanup_procfs; - error = scsi_sysfs_register(); + error = scsi_init_hosts(); if (error) goto cleanup_devlist; + error = scsi_sysfs_register(); + if (error) + goto cleanup_hosts; for (i = 0; i < NR_CPUS; i++) INIT_LIST_HEAD(&done_q[i]); @@ -972,6 +1018,8 @@ printk(KERN_NOTICE "SCSI subsystem initialized\n"); return 0; +cleanup_hosts: + scsi_exit_hosts(); cleanup_devlist: scsi_exit_devinfo(); cleanup_procfs: @@ -986,6 +1034,7 @@ static void __exit exit_scsi(void) { scsi_sysfs_unregister(); + scsi_exit_hosts(); scsi_exit_devinfo(); devfs_remove("scsi"); scsi_exit_procfs(); diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c --- a/drivers/scsi/scsi_debug.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/scsi_debug.c Mon Aug 18 22:21:04 2003 @@ -1566,7 +1566,6 @@ module_exit(scsi_debug_exit); static struct device pseudo_primary = { - .name = "Host/Pseudo Bridge", .bus_id = "pseudo_0", }; @@ -1630,7 +1629,6 @@ sdbg_host->dev.bus = &pseudo_lld_bus; sdbg_host->dev.parent = &pseudo_primary; sdbg_host->dev.release = &sdebug_release_adapter; - sprintf(sdbg_host->dev.name, "scsi debug adapter"); sprintf(sdbg_host->dev.bus_id, "adapter%d", scsi_debug_add_host); error = device_register(&sdbg_host->dev); @@ -1722,10 +1720,7 @@ return -ENODEV; } - if (scsi_remove_host(sdbg_host->shost)) { - printk(KERN_ERR "%s: scsi_remove_host failed\n", __FUNCTION__); - return -EBUSY; - } + scsi_remove_host(sdbg_host->shost); list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) { sdbg_devinfo = list_entry(lh, struct sdebug_dev_info, diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c Mon Aug 18 22:21:00 2003 +++ b/drivers/scsi/scsi_error.c Mon Aug 18 22:21:00 2003 @@ -84,7 +84,7 @@ */ scmd->serial_number_at_timeout = scmd->serial_number; list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q); - shost->in_recovery = 1; + set_bit(SHOST_RECOVERY, &shost->shost_state); shost->host_failed++; scsi_eh_wakeup(shost); spin_unlock_irqrestore(shost->host_lock, flags); @@ -187,7 +187,7 @@ **/ int scsi_block_when_processing_errors(struct scsi_device *sdev) { - wait_event(sdev->host->host_wait, (sdev->host->in_recovery == 0)); + wait_event(sdev->host->host_wait, (!test_bit(SHOST_RECOVERY, &sdev->host->shost_state))); SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __FUNCTION__, sdev->online)); @@ -1285,7 +1285,12 @@ maybe_retry: - if ((++scmd->retries) < scmd->allowed) { + /* we requeue for retry because the error was retryable, and + * the request was not marked fast fail. Note that above, + * even if the request is marked fast fail, we still requeue + * for queue congestion conditions (QUEUE_FULL or BUSY) */ + if ((++scmd->retries) < scmd->allowed + && !blk_noretry_request(scmd->request)) { return NEEDS_RETRY; } else { /* @@ -1389,7 +1394,7 @@ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", __FUNCTION__)); - shost->in_recovery = 0; + clear_bit(SHOST_RECOVERY, &shost->shost_state); wake_up(&shost->host_wait); @@ -1599,7 +1604,6 @@ * that's fine. If the user sent a signal to this thing, we are * potentially in real danger. */ - shost->in_recovery = 0; shost->eh_active = 0; shost->ehandler = NULL; diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c --- a/drivers/scsi/scsi_ioctl.c Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/scsi_ioctl.c Mon Aug 18 22:21:06 2003 @@ -367,7 +367,7 @@ if (!dev) return -ENXIO; - return copy_to_user(arg, dev->bus_id, sizeof(dev->bus_id)); + return copy_to_user(arg, dev->bus_id, sizeof(dev->bus_id))? -EFAULT: 0; } diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/scsi_lib.c Mon Aug 18 22:21:03 2003 @@ -318,7 +318,8 @@ spin_lock_irqsave(shost->host_lock, flags); shost->host_busy--; - if (unlikely(shost->in_recovery && shost->host_failed)) + if (unlikely(test_bit(SHOST_RECOVERY, &shost->shost_state) && + shost->host_failed)) scsi_eh_wakeup(shost); spin_unlock(shost->host_lock); spin_lock(&sdev->sdev_lock); @@ -501,14 +502,22 @@ * to queue the remainder of them. */ if (end_that_request_first(req, uptodate, sectors)) { - if (requeue) { - /* - * Bleah. Leftovers again. Stick the leftovers in - * the front of the queue, and goose the queue again. - */ - scsi_requeue_command(q, cmd); + int leftover = req->hard_nr_sectors - sectors; + + /* kill remainder if no retrys */ + if (!uptodate && blk_noretry_request(req)) + end_that_request_first(req, 0, leftover); + else { + if (requeue) + /* + * Bleah. Leftovers again. Stick the + * leftovers in the front of the + * queue, and goose the queue again. + */ + scsi_requeue_command(q, cmd); + + return cmd; } - return cmd; } add_disk_randomness(req->rq_disk); @@ -1066,7 +1075,7 @@ struct Scsi_Host *shost, struct scsi_device *sdev) { - if (shost->in_recovery) + if (test_bit(SHOST_RECOVERY, &shost->shost_state)) return 0; if (shost->host_busy == 0 && shost->host_blocked) { /* @@ -1207,21 +1216,20 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) { - if (shost->highmem_io) { - struct device *host_dev = scsi_get_device(shost); + struct device *host_dev; - if (PCI_DMA_BUS_IS_PHYS && host_dev && host_dev->dma_mask) - return *host_dev->dma_mask; - - /* - * Platforms with virtual-DMA translation - * hardware have no practical limit. - */ - return BLK_BOUNCE_ANY; - } else if (shost->unchecked_isa_dma) + if (shost->unchecked_isa_dma) return BLK_BOUNCE_ISA; - return BLK_BOUNCE_HIGH; + host_dev = scsi_get_device(shost); + if (PCI_DMA_BUS_IS_PHYS && host_dev && host_dev->dma_mask) + return *host_dev->dma_mask; + + /* + * Platforms with virtual-DMA translation + * hardware have no practical limit. + */ + return BLK_BOUNCE_ANY; } struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) @@ -1239,6 +1247,7 @@ blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); blk_queue_max_sectors(q, shost->max_sectors); blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); + blk_queue_segment_boundary(q, shost->dma_boundary); if (!shost->use_clustering) clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); diff -Nru a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c --- a/drivers/scsi/scsi_module.c Mon Aug 18 22:21:02 2003 +++ b/drivers/scsi/scsi_module.c Mon Aug 18 22:21:02 2003 @@ -33,7 +33,7 @@ INIT_LIST_HEAD(&sht->legacy_hosts); sht->detect(sht); - if (!sht->present) + if (list_empty(&sht->legacy_hosts)) return -ENODEV; list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) { diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h --- a/drivers/scsi/scsi_priv.h Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/scsi_priv.h Mon Aug 18 22:21:04 2003 @@ -42,6 +42,12 @@ (((scmd)->sense_buffer[0] & 0x70) == 0x70) /* + * Special value for scanning to specify scanning or rescanning of all + * possible channels, (target) ids, or luns on a given shost. + */ +#define SCAN_WILD_CARD ~0 + +/* * scsi_target: representation of a scsi target, for now, this is only * used for single_lun devices. If no one has active IO to the target, * starget_sdev_user is NULL, else it points to the active sdev. @@ -51,6 +57,9 @@ unsigned int starget_refcnt; }; +/* hosts.c */ +extern int scsi_init_hosts(void); +extern void scsi_exit_hosts(void); /* scsi.c */ extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); @@ -90,11 +99,15 @@ /* scsi_proc.c */ #ifdef CONFIG_PROC_FS +extern void scsi_proc_hostdir_add(struct scsi_host_template *); +extern void scsi_proc_hostdir_rm(struct scsi_host_template *); extern void scsi_proc_host_add(struct Scsi_Host *); extern void scsi_proc_host_rm(struct Scsi_Host *); extern int scsi_init_procfs(void); extern void scsi_exit_procfs(void); #else +# define scsi_proc_hostdir_add(sht) do { } while (0) +# define scsi_proc_hostdir_rm(sht) do { } while (0) # define scsi_proc_host_add(shost) do { } while (0) # define scsi_proc_host_rm(shost) do { } while (0) # define scsi_init_procfs() (0) @@ -102,21 +115,19 @@ #endif /* CONFIG_PROC_FS */ /* scsi_scan.c */ +int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int, + unsigned int, int); extern void scsi_forget_host(struct Scsi_Host *); extern void scsi_free_sdev(struct scsi_device *); -extern void scsi_free_shost(struct Scsi_Host *); extern void scsi_rescan_device(struct device *); /* scsi_sysfs.c */ extern int scsi_device_register(struct scsi_device *); -extern void scsi_device_unregister(struct scsi_device *); -extern void scsi_sysfs_init_host(struct Scsi_Host *); -extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *); -extern void scsi_sysfs_remove_host(struct Scsi_Host *); +extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); -extern struct class shost_class; +extern struct class sdev_class; extern struct bus_type scsi_bus_type; #endif /* _SCSI_PRIV_H */ diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c --- a/drivers/scsi/scsi_proc.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/scsi_proc.c Mon Aug 18 22:21:01 2003 @@ -41,6 +41,8 @@ struct proc_dir_entry *proc_scsi; EXPORT_SYMBOL(proc_scsi); +/* Protect sht->present and sht->proc_dir */ +static DECLARE_MUTEX(global_host_template_sem); static int proc_scsi_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) @@ -77,16 +79,13 @@ return ret; } -void scsi_proc_host_add(struct Scsi_Host *shost) +void scsi_proc_hostdir_add(struct scsi_host_template *sht) { - struct scsi_host_template *sht = shost->hostt; - struct proc_dir_entry *p; - char name[10]; - if (!sht->proc_info) return; - if (!sht->proc_dir) { + down(&global_host_template_sem); + if (!sht->present++) { sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi); if (!sht->proc_dir) { printk(KERN_ERR "%s: proc_mkdir failed for %s\n", @@ -95,6 +94,30 @@ } sht->proc_dir->owner = sht->module; } + up(&global_host_template_sem); +} + +void scsi_proc_hostdir_rm(struct scsi_host_template *sht) +{ + if (!sht->proc_info) + return; + + down(&global_host_template_sem); + if (!--sht->present && sht->proc_dir) { + remove_proc_entry(sht->proc_name, proc_scsi); + sht->proc_dir = NULL; + } + up(&global_host_template_sem); +} + +void scsi_proc_host_add(struct Scsi_Host *shost) +{ + struct scsi_host_template *sht = shost->hostt; + struct proc_dir_entry *p; + char name[10]; + + if (!sht->proc_dir) + return; sprintf(name,"%d", shost->host_no); p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, @@ -107,20 +130,18 @@ } p->write_proc = proc_scsi_write_proc; - p->owner = shost->hostt->module; + p->owner = sht->module; } void scsi_proc_host_rm(struct Scsi_Host *shost) { - struct scsi_host_template *sht = shost->hostt; char name[10]; - if (sht->proc_info) { - sprintf(name,"%d", shost->host_no); - remove_proc_entry(name, sht->proc_dir); - if (!sht->present) - remove_proc_entry(sht->proc_name, proc_scsi); - } + if (!shost->hostt->proc_dir) + return; + + sprintf(name,"%d", shost->host_no); + remove_proc_entry(name, shost->hostt->proc_dir); } static int proc_print_scsidevice(struct device *dev, void *data) @@ -174,21 +195,13 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun) { struct Scsi_Host *shost; - struct scsi_device *sdev; - int error = -ENODEV; + int error = -ENXIO; shost = scsi_host_lookup(host); - if (!shost) - return -ENODEV; - - if (!scsi_find_device(shost, channel, id, lun)) { - sdev = scsi_add_device(shost, channel, id, lun); - if (IS_ERR(sdev)) - error = PTR_ERR(sdev); - else - error = 0; - } + if (IS_ERR(shost)) + return PTR_ERR(shost); + error = scsi_scan_host_selected(shost, channel, id, lun, 1); scsi_host_put(shost); return error; } @@ -197,18 +210,19 @@ { struct scsi_device *sdev; struct Scsi_Host *shost; - int error = -ENODEV; + int error = -ENXIO; shost = scsi_host_lookup(host); - if (!shost) - return -ENODEV; + if (IS_ERR(shost)) + return PTR_ERR(shost); sdev = scsi_find_device(shost, channel, id, lun); if (!sdev) goto out; if (sdev->access_count) goto out; - error = scsi_remove_device(sdev); + scsi_remove_device(sdev); + error = 0; out: scsi_host_put(shost); return error; diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c Mon Aug 18 22:21:05 2003 +++ b/drivers/scsi/scsi_scan.c Mon Aug 18 22:21:05 2003 @@ -288,8 +288,6 @@ if (sdev->request_queue) scsi_free_queue(sdev->request_queue); - if (sdev->host->hostt->slave_destroy) - sdev->host->hostt->slave_destroy(sdev); if (sdev->inquiry) kfree(sdev->inquiry); spin_lock_irqsave(sdev->host->host_lock, flags); @@ -449,24 +447,6 @@ return; } -static void scsi_set_name(struct scsi_device *sdev, char *inq_result) -{ - int i; - char type[72]; - - i = inq_result[0] & 0x1f; - if (i < MAX_SCSI_DEVICE_CODE) - strcpy(type, scsi_device_types[i]); - else - strcpy(type, "Unknown"); - - i = strlen(type) - 1; - while (i >= 0 && type[i] == ' ') - type[i--] = '\0'; - - snprintf(sdev->sdev_gendev.name, DEVICE_NAME_SIZE, "SCSI %s", type); -} - /** * scsi_add_lun - allocate and fully initialze a Scsi_Device * @sdevscan: holds information to be stored in the new Scsi_Device @@ -541,8 +521,6 @@ printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type); } - scsi_set_name(sdev, inq_result); - print_inquiry(inq_result); /* @@ -678,13 +656,32 @@ **/ static int scsi_probe_and_add_lun(struct Scsi_Host *host, uint channel, uint id, uint lun, int *bflagsp, - struct scsi_device **sdevp) + struct scsi_device **sdevp, int rescan) { struct scsi_device *sdev; struct scsi_request *sreq; unsigned char *result; int bflags, res = SCSI_SCAN_NO_RESPONSE; + /* + * The rescan flag is used as an optimization, the first scan of a + * host adapter calls into here with rescan == 0. + */ + if (rescan) { + sdev = scsi_find_device(host, channel, id, lun); + if (sdev) { + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO + "scsi scan: device exists on <%d:%d:%d:%d>\n", + host->host_no, channel, id, lun)); + if (sdevp) + *sdevp = sdev; + if (bflagsp) + *bflagsp = scsi_get_device_flags(sdev->vendor, + sdev->model); + return SCSI_SCAN_LUN_PRESENT; + } + } + sdev = scsi_alloc_sdev(host, channel, id, lun); if (!sdev) goto out; @@ -759,7 +756,7 @@ * Modifies sdevscan->lun. **/ static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel, - uint id, int bflags, int lun0_res, int scsi_level) + uint id, int bflags, int lun0_res, int scsi_level, int rescan) { unsigned int sparse_lun, lun, max_dev_lun; @@ -828,7 +825,8 @@ */ for (lun = 1; lun < max_dev_lun; ++lun) if ((scsi_probe_and_add_lun(shost, channel, id, lun, - NULL, NULL) != SCSI_SCAN_LUN_PRESENT) && !sparse_lun) + NULL, NULL, rescan) != SCSI_SCAN_LUN_PRESENT) && + !sparse_lun) return; } @@ -879,7 +877,8 @@ * 0: scan completed (or no memory, so further scanning is futile) * 1: no report lun scan, or not configured **/ -static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags) +static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, + int rescan) { char devname[64]; unsigned char scsi_cmd[MAX_COMMAND_SIZE]; @@ -1033,7 +1032,7 @@ int res; res = scsi_probe_and_add_lun(sdev->host, sdev->channel, - sdev->id, lun, NULL, NULL); + sdev->id, lun, NULL, NULL, rescan); if (res == SCSI_SCAN_NO_RESPONSE) { /* * Got some results, but now none, abort. @@ -1059,7 +1058,7 @@ return 0; } #else -# define scsi_report_lun_scan(sdev, blags) (1) +# define scsi_report_lun_scan(sdev, blags, rescan) (1) #endif /* CONFIG_SCSI_REPORT_LUNS */ struct scsi_device *scsi_add_device(struct Scsi_Host *shost, @@ -1068,18 +1067,12 @@ struct scsi_device *sdev; int res; - res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev); + res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1); if (res != SCSI_SCAN_LUN_PRESENT) sdev = ERR_PTR(-ENODEV); return sdev; } -int scsi_remove_device(struct scsi_device *sdev) -{ - scsi_device_unregister(sdev); - return 0; -} - void scsi_rescan_device(struct device *dev) { struct scsi_driver *drv = to_scsi_driver(dev->driver); @@ -1111,7 +1104,7 @@ * sequential scan of LUNs on the target id. **/ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel, - unsigned int id) + unsigned int id, unsigned int lun, int rescan) { int bflags = 0; int res; @@ -1123,19 +1116,29 @@ */ return; + if (lun != SCAN_WILD_CARD) { + /* + * Scan for a specific host/chan/id/lun. + */ + scsi_probe_and_add_lun(shost, channel, id, lun, NULL, NULL, + rescan); + return; + } + /* * Scan LUN 0, if there is some response, scan further. Ideally, we * would not configure LUN 0 until all LUNs are scanned. */ - res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev); + res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev, + rescan); if (res == SCSI_SCAN_LUN_PRESENT) { - if (scsi_report_lun_scan(sdev, bflags) != 0) + if (scsi_report_lun_scan(sdev, bflags, rescan) != 0) /* * The REPORT LUN did not scan the target, * do a sequential scan. */ scsi_sequential_lun_scan(shost, channel, id, bflags, - res, sdev->scsi_level); + res, sdev->scsi_level, rescan); } else if (res == SCSI_SCAN_TARGET_PRESENT) { /* * There's a target here, but lun 0 is offline so we @@ -1144,37 +1147,26 @@ * a default scsi level of SCSI_2 */ scsi_sequential_lun_scan(shost, channel, id, BLIST_SPARSELUN, - SCSI_SCAN_TARGET_PRESENT, SCSI_2); + SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan); } } -/** - * scsi_scan_host - scan the given adapter - * @shost: adapter to scan - * - * Description: - * Iterate and call scsi_scan_target to scan all possible target id's - * on all possible channels. - **/ -void scsi_scan_host(struct Scsi_Host *shost) +static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, + unsigned int id, unsigned int lun, int rescan) { - uint channel, id, order_id; + uint order_id; - /* - * The sdevscan host, channel, id and lun are filled in as - * needed to scan. - */ - for (channel = 0; channel <= shost->max_channel; channel++) { - /* - * XXX adapter drivers when possible (FCP, iSCSI) - * could modify max_id to match the current max, - * not the absolute max. - * - * XXX add a shost id iterator, so for example, - * the FC ID can be the same as a target id - * without a huge overhead of sparse id's. - */ + if (id == SCAN_WILD_CARD) for (id = 0; id < shost->max_id; ++id) { + /* + * XXX adapter drivers when possible (FCP, iSCSI) + * could modify max_id to match the current max, + * not the absolute max. + * + * XXX add a shost id iterator, so for example, + * the FC ID can be the same as a target id + * without a huge overhead of sparse id's. + */ if (shost->reverse_ordering) /* * Scan from high to low id. @@ -1182,9 +1174,39 @@ order_id = shost->max_id - id - 1; else order_id = id; - scsi_scan_target(shost, channel, order_id); + scsi_scan_target(shost, channel, order_id, lun, rescan); } - } + else + scsi_scan_target(shost, channel, id, lun, rescan); +} + +int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, + unsigned int id, unsigned int lun, int rescan) +{ + SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n", + __FUNCTION__, shost->host_no, channel, id, lun)); + + if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || + ((id != SCAN_WILD_CARD) && (id > shost->max_id)) || + ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) + return -EINVAL; + + if (channel == SCAN_WILD_CARD) + for (channel = 0; channel <= shost->max_channel; channel++) + scsi_scan_channel(shost, channel, id, lun, rescan); + else + scsi_scan_channel(shost, channel, id, lun, rescan); + return 0; +} + +/** + * scsi_scan_host - scan the given adapter + * @shost: adapter to scan + **/ +void scsi_scan_host(struct Scsi_Host *shost) +{ + scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, + SCAN_WILD_CARD, 0); } void scsi_forget_host(struct Scsi_Host *shost) diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c --- a/drivers/scsi/scsi_syms.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/scsi_syms.c Mon Aug 18 22:21:03 2003 @@ -86,7 +86,7 @@ EXPORT_SYMBOL(scsi_device_put); EXPORT_SYMBOL(scsi_add_device); EXPORT_SYMBOL(scsi_remove_device); -EXPORT_SYMBOL(scsi_set_device_offline); +EXPORT_SYMBOL(scsi_device_cancel); EXPORT_SYMBOL(__scsi_mode_sense); EXPORT_SYMBOL(scsi_mode_sense); diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c --- a/drivers/scsi/scsi_sysfs.c Mon Aug 18 22:21:01 2003 +++ b/drivers/scsi/scsi_sysfs.c Mon Aug 18 22:21:01 2003 @@ -15,6 +15,43 @@ #include "hosts.h" #include "scsi_priv.h" +#include "scsi_logging.h" + +static int check_set(unsigned int *val, char *src) +{ + char *last; + + if (strncmp(src, "-", 20) == 0) { + *val = SCAN_WILD_CARD; + } else { + /* + * Doesn't check for int overflow + */ + *val = simple_strtoul(src, &last, 0); + if (*last != '\0') + return 1; + } + return 0; +} + +static int scsi_scan(struct Scsi_Host *shost, const char *str) +{ + char s1[15], s2[15], s3[15], junk; + unsigned int channel, id, lun; + int res; + + res = sscanf(str, "%10s %10s %10s %c", s1, s2, s3, &junk); + if (res != 3) + return -EINVAL; + if (check_set(&channel, s1)) + return -EINVAL; + if (check_set(&id, s2)) + return -EINVAL; + if (check_set(&lun, s3)) + return -EINVAL; + res = scsi_scan_host_selected(shost, channel, id, lun, 1); + return res; +} /* * shost_show_function: macro to create an attr function that can be used to @@ -39,6 +76,20 @@ /* * Create the actual show/store functions and data structures. */ + +static ssize_t store_scan(struct class_device *class_dev, const char *buf, + size_t count) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + int res; + + res = scsi_scan(shost, buf); + if (res == 0) + res = count; + return res; +}; +static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); + shost_rd_attr(unique_id, "%u\n"); shost_rd_attr(host_busy, "%hu\n"); shost_rd_attr(cmd_per_lun, "%hd\n"); @@ -51,15 +102,32 @@ &class_device_attr_cmd_per_lun, &class_device_attr_sg_tablesize, &class_device_attr_unchecked_isa_dma, + &class_device_attr_scan, NULL }; -struct class shost_class = { - .name = "scsi_host", -}; +static void scsi_device_cls_release(struct class_device *class_dev) +{ + struct scsi_device *sdev; + + sdev = class_to_sdev(class_dev); + put_device(&sdev->sdev_gendev); +} + +static void scsi_device_dev_release(struct device *dev) +{ + struct scsi_device *sdev; + struct device *parent; + + parent = dev->parent; + sdev = to_scsi_device(dev); + scsi_free_sdev(sdev); + put_device(parent); +} -static struct class sdev_class = { +struct class sdev_class = { .name = "scsi_device", + .release = scsi_device_cls_release, }; /* all probing is done in the individual ->probe routines */ @@ -73,33 +141,23 @@ .match = scsi_bus_match, }; - int scsi_sysfs_register(void) { int error; error = bus_register(&scsi_bus_type); - if (error) - return error; - error = class_register(&shost_class); - if (error) - goto bus_unregister; - error = class_register(&sdev_class); - if (error) - goto class_unregister; - return 0; + if (!error) { + error = class_register(&sdev_class); + if (error) + bus_unregister(&scsi_bus_type); + } - class_unregister: - class_unregister(&shost_class); - bus_unregister: - bus_unregister(&scsi_bus_type); return error; } void scsi_sysfs_unregister(void) { class_unregister(&sdev_class); - class_unregister(&shost_class); bus_unregister(&scsi_bus_type); } @@ -109,7 +167,7 @@ */ #define sdev_show_function(field, format_string) \ static ssize_t \ -show_##field (struct device *dev, char *buf) \ +sdev_show_##field (struct device *dev, char *buf) \ { \ struct scsi_device *sdev; \ sdev = to_scsi_device(dev); \ @@ -122,7 +180,7 @@ */ #define sdev_rd_attr(field, format_string) \ sdev_show_function(field, format_string) \ -static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) +static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL) /* @@ -140,7 +198,7 @@ snscanf (buf, 20, format_string, &sdev->field); \ return count; \ } \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, sdev_store_##field) +static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field) /* * sdev_rd_attr: create a function and attribute variable for a @@ -162,7 +220,7 @@ } \ return ret; \ } \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, sdev_store_##field) +static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field) /* * scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1", @@ -203,6 +261,24 @@ static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field) +static ssize_t sdev_store_delete(struct device *dev, const char *buf, + size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + int res = count; + + if (sdev->access_count) + /* + * FIXME and scsi_proc.c: racey use of access_count, + * possibly add a new arg to scsi_remove_device. + */ + res = -EBUSY; + else + scsi_remove_device(sdev); + return res; +}; +static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); + /* Default template for device attributes. May NOT be modified */ static struct device_attribute *scsi_sysfs_sdev_attrs[] = { &dev_attr_device_blocked, @@ -215,18 +291,10 @@ &dev_attr_rev, &dev_attr_online, &dev_attr_rescan, + &dev_attr_delete, NULL }; -static void scsi_device_release(struct device *dev) -{ - struct scsi_device *sdev; - - sdev = to_scsi_device(dev); - if (!sdev) - return; - scsi_free_sdev(sdev); -} static struct device_attribute *attr_overridden( struct device_attribute **attrs, @@ -275,12 +343,13 @@ { int error = 0, i; + set_bit(SDEV_ADD, &sdev->sdev_state); device_initialize(&sdev->sdev_gendev); sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->sdev_gendev.parent = &sdev->host->shost_gendev; sdev->sdev_gendev.bus = &scsi_bus_type; - sdev->sdev_gendev.release = scsi_device_release; + sdev->sdev_gendev.release = scsi_device_dev_release; class_device_initialize(&sdev->sdev_classdev); sdev->sdev_classdev.dev = &sdev->sdev_gendev; @@ -293,19 +362,24 @@ printk(KERN_INFO "error 1\n"); return error; } + + get_device(sdev->sdev_gendev.parent); + error = class_device_add(&sdev->sdev_classdev); if (error) { printk(KERN_INFO "error 2\n"); - device_unregister(&sdev->sdev_gendev); + goto clean_device; return error; } + get_device(&sdev->sdev_gendev); + if (sdev->host->hostt->sdev_attrs) { for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { error = attr_add(&sdev->sdev_gendev, sdev->host->hostt->sdev_attrs[i]); if (error) - scsi_device_unregister(sdev); + scsi_remove_device(sdev); } } @@ -315,21 +389,40 @@ error = device_create_file(&sdev->sdev_gendev, scsi_sysfs_sdev_attrs[i]); if (error) - scsi_device_unregister(sdev); + scsi_remove_device(sdev); } } return error; + +clean_device: + device_del(&sdev->sdev_gendev); + put_device(&sdev->sdev_gendev); + return error; + } /** - * scsi_device_unregister - unregister a device from the scsi bus + * scsi_remove_device - unregister a device from the scsi bus * @sdev: scsi_device to unregister **/ -void scsi_device_unregister(struct scsi_device *sdev) +void scsi_remove_device(struct scsi_device *sdev) { + struct class *class = class_get(&sdev_class); + class_device_unregister(&sdev->sdev_classdev); - device_unregister(&sdev->sdev_gendev); + + if (class) { + down_write(&class->subsys.rwsem); + set_bit(SDEV_DEL, &sdev->sdev_state); + if (sdev->access_count == 0) + device_del(&sdev->sdev_gendev); + up_write(&class->subsys.rwsem); + } + + put_device(&sdev->sdev_gendev); + + class_put(&sdev_class); } int scsi_register_driver(struct device_driver *drv) @@ -346,32 +439,6 @@ return class_interface_register(intf); } -static void scsi_host_release(struct device *dev) -{ - struct Scsi_Host *shost; - - shost = dev_to_shost(dev); - if (!shost) - return; - - scsi_free_shost(shost); -} - -void scsi_sysfs_init_host(struct Scsi_Host *shost) -{ - device_initialize(&shost->shost_gendev); - snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d", - shost->host_no); - snprintf(shost->shost_gendev.name, DEVICE_NAME_SIZE, "%s", - shost->hostt->proc_name); - shost->shost_gendev.release = scsi_host_release; - - class_device_initialize(&shost->shost_classdev); - shost->shost_classdev.dev = &shost->shost_gendev; - shost->shost_classdev.class = &shost_class; - snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", - shost->host_no); -} static struct class_device_attribute *class_attr_overridden( struct class_device_attribute **attrs, @@ -415,27 +482,16 @@ * @shost: scsi host struct to add to subsystem * @dev: parent struct device pointer **/ -int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev) +int scsi_sysfs_add_host(struct Scsi_Host *shost) { int error, i; - if (!shost->shost_gendev.parent) - shost->shost_gendev.parent = dev ? dev : &legacy_bus; - - error = device_add(&shost->shost_gendev); - if (error) - return error; - - error = class_device_add(&shost->shost_classdev); - if (error) - goto clean_device; - if (shost->hostt->shost_attrs) { for (i = 0; shost->hostt->shost_attrs[i]; i++) { error = class_attr_add(&shost->shost_classdev, shost->hostt->shost_attrs[i]); if (error) - goto clean_class; + return error; } } @@ -445,26 +501,9 @@ error = class_device_create_file(&shost->shost_classdev, scsi_sysfs_shost_attrs[i]); if (error) - goto clean_class; + return error; } } - return error; - -clean_class: - class_device_del(&shost->shost_classdev); -clean_device: - device_del(&shost->shost_gendev); - - return error; -} - -/** - * scsi_sysfs_remove_host - remove scsi host from subsystem - * @shost: scsi host to remove from subsystem - **/ -void scsi_sysfs_remove_host(struct Scsi_Host *shost) -{ - class_device_del(&shost->shost_classdev); - device_del(&shost->shost_gendev); + return 0; } diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c --- a/drivers/scsi/sd.c Mon Aug 18 22:21:05 2003 +++ b/drivers/scsi/sd.c Mon Aug 18 22:21:05 2003 @@ -308,6 +308,8 @@ SCpnt->cmnd[4] = (unsigned char) this_count; SCpnt->cmnd[5] = 0; } + SCpnt->request_bufflen = SCpnt->bufflen = + this_count * sdp->sector_size; /* * We shouldn't disconnect in the middle of a sector, so with a dumb @@ -651,9 +653,11 @@ /* An error occurred */ if (driver_byte(result) != 0 && /* An error occurred */ - SCpnt->sense_buffer[0] == 0xF0) { /* Sense data is valid */ + (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */ switch (SCpnt->sense_buffer[2]) { case MEDIUM_ERROR: + if (!(SCpnt->sense_buffer[0] & 0x80)) + break; error_sector = (SCpnt->sense_buffer[3] << 24) | (SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[5] << 8) | @@ -696,7 +700,7 @@ * hard error. */ print_sense("sd", SCpnt); - result = 0; + SCpnt->result = 0; SCpnt->sense_buffer[0] = 0x0; good_sectors = this_count; break; @@ -1351,9 +1355,13 @@ static void sd_shutdown(struct device *dev) { struct scsi_device *sdp = to_scsi_device(dev); - struct scsi_disk *sdkp = dev_get_drvdata(dev); + struct scsi_disk *sdkp; struct scsi_request *sreq; int retries, res; + + sdkp = dev_get_drvdata(dev); + if (!sdkp) + return; /* this can happen */ if (!sdp->online || !sdkp->WCE) return; diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c --- a/drivers/scsi/sg.c Mon Aug 18 22:21:03 2003 +++ b/drivers/scsi/sg.c Mon Aug 18 22:21:03 2003 @@ -954,7 +954,8 @@ if (sdp->detached) return -ENODEV; if (filp->f_flags & O_NONBLOCK) { - if (sdp->device->host->in_recovery) + if (test_bit(SHOST_RECOVERY, + &sdp->device->host->shost_state)) return -EBUSY; } else if (!scsi_block_when_processing_errors(sdp->device)) return -EBUSY; @@ -1813,7 +1814,7 @@ break; } sclp->page = virt_to_page(p); - sclp->offset = (unsigned long) p & ~PAGE_MASK; + sclp->offset = offset_in_page(p); sclp->length = ret_sz; SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n", diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c --- a/drivers/scsi/sim710.c Mon Aug 18 22:21:05 2003 +++ b/drivers/scsi/sim710.c Mon Aug 18 22:21:05 2003 @@ -100,7 +100,7 @@ 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: %s\n", dev->bus_id); printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n", irq, clock, base_addr, scsi_id); @@ -255,7 +255,7 @@ } else { return -ENODEV; } - strlcpy(dev->name, name, sizeof(dev->name)); + mca_device_set_name(mca_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); @@ -304,7 +304,7 @@ scsi_id = ffs(val) - 1; if(scsi_id > 7 || (val & ~(1<name); + printk(KERN_ERR "sim710.c, EISA card %s has incorrect scsi_id, setting to 7\n", dev->bus_id); scsi_id = 7; } } else { diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c --- a/drivers/scsi/sr.c Mon Aug 18 22:21:02 2003 +++ b/drivers/scsi/sr.c Mon Aug 18 22:21:02 2003 @@ -181,6 +181,7 @@ int this_count = SCpnt->bufflen >> 9; int good_sectors = (result == 0 ? this_count : 0); int block_sectors = 0; + long error_sector; struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); #ifdef DEBUG @@ -194,33 +195,57 @@ * memcpy's that could be avoided. */ if (driver_byte(result) != 0 && /* An error occurred */ - SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */ - (SCpnt->sense_buffer[2] == MEDIUM_ERROR || - SCpnt->sense_buffer[2] == VOLUME_OVERFLOW || - SCpnt->sense_buffer[2] == ILLEGAL_REQUEST)) { - long error_sector = (SCpnt->sense_buffer[3] << 24) | - (SCpnt->sense_buffer[4] << 16) | - (SCpnt->sense_buffer[5] << 8) | - SCpnt->sense_buffer[6]; - if (SCpnt->request->bio != NULL) - block_sectors = bio_sectors(SCpnt->request->bio); - if (block_sectors < 4) - block_sectors = 4; - if (cd->device->sector_size == 2048) - error_sector <<= 2; - error_sector &= ~(block_sectors - 1); - good_sectors = error_sector - SCpnt->request->sector; - if (good_sectors < 0 || good_sectors >= this_count) - good_sectors = 0; - /* - * The SCSI specification allows for the value returned by READ - * CAPACITY to be up to 75 2K sectors past the last readable - * block. Therefore, if we hit a medium error within the last - * 75 2K sectors, we decrease the saved size value. - */ - if (error_sector < get_capacity(cd->disk) && - cd->capacity - error_sector < 4 * 75) - set_capacity(cd->disk, error_sector); + (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */ + switch (SCpnt->sense_buffer[2]) { + case MEDIUM_ERROR: + case VOLUME_OVERFLOW: + case ILLEGAL_REQUEST: + if (!(SCpnt->sense_buffer[0] & 0x90)) + break; + error_sector = (SCpnt->sense_buffer[3] << 24) | + (SCpnt->sense_buffer[4] << 16) | + (SCpnt->sense_buffer[5] << 8) | + SCpnt->sense_buffer[6]; + if (SCpnt->request->bio != NULL) + block_sectors = + bio_sectors(SCpnt->request->bio); + if (block_sectors < 4) + block_sectors = 4; + if (cd->device->sector_size == 2048) + error_sector <<= 2; + error_sector &= ~(block_sectors - 1); + good_sectors = error_sector - SCpnt->request->sector; + if (good_sectors < 0 || good_sectors >= this_count) + good_sectors = 0; + /* + * The SCSI specification allows for the value + * returned by READ CAPACITY to be up to 75 2K + * sectors past the last readable block. + * Therefore, if we hit a medium error within the + * last 75 2K sectors, we decrease the saved size + * value. + */ + if (error_sector < get_capacity(cd->disk) && + cd->capacity - error_sector < 4 * 75) + set_capacity(cd->disk, error_sector); + break; + + case RECOVERED_ERROR: + + /* + * An error occured, but it recovered. Inform the + * user, but make sure that it's not treated as a + * hard error. + */ + print_sense("sr", SCpnt); + SCpnt->result = 0; + SCpnt->sense_buffer[0] = 0x0; + good_sectors = this_count; + break; + + default: + break; + } } /* @@ -315,6 +340,20 @@ return 0; } + { + struct scatterlist *sg = SCpnt->request_buffer; + int i, size = 0; + for (i = 0; i < SCpnt->use_sg; i++) + size += sg[i].length; + + if (size != SCpnt->request_bufflen && SCpnt->use_sg) { + printk(KERN_ERR "sr: mismatch count %d, bytes %d\n", + size, SCpnt->request_bufflen); + if (SCpnt->request_bufflen > size) + SCpnt->request_bufflen = SCpnt->bufflen = size; + } + } + /* * request doesn't start on hw block boundary, add scatter pads */ @@ -336,8 +375,11 @@ SCpnt->cmnd[1] = 0; block = (unsigned int)SCpnt->request->sector / (s_size >> 9); - if (this_count > 0xffff) + if (this_count > 0xffff) { this_count = 0xffff; + SCpnt->request_bufflen = SCpnt->bufflen = + this_count * s_size; + } SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; @@ -364,18 +406,6 @@ * of capability to this function. */ SCpnt->done = rw_intr; - - { - struct scatterlist *sg = SCpnt->request_buffer; - int i, size = 0; - for (i = 0; i < SCpnt->use_sg; i++) - size += sg[i].length; - - if (size != SCpnt->request_bufflen && SCpnt->use_sg) { - printk("sr: mismatch count %d, bytes %d\n", size, SCpnt->request_bufflen); - SCpnt->request_bufflen = size; - } - } /* * This indicates that the command is ready from our end to be diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/st.c Mon Aug 18 22:21:04 2003 @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static char *verstr = "20030622"; +static char *verstr = "20030811"; #include @@ -1312,6 +1312,19 @@ } +/* Can be called more than once after each setup_buffer() */ +static void release_buffering(Scsi_Tape *STp) +{ + ST_buffer *STbp; + + STbp = STp->buffer; + if (STbp->do_dio) { + sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, FALSE); + STbp->do_dio = 0; + } +} + + /* Write command */ static ssize_t st_write(struct file *filp, const char *buf, size_t count, loff_t * ppos) @@ -1589,11 +1602,7 @@ out: if (SRpnt != NULL) scsi_release_request(SRpnt); - STbp = STp->buffer; - if (STbp->do_dio) { - sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, FALSE); - STbp->do_dio = 0; - } + release_buffering(STp); up(&STp->lock); return retval; @@ -1601,7 +1610,10 @@ /* Read data from the tape. Returns zero in the normal case, one if the eof status has changed, and the negative error code in case of a - fatal error. Otherwise updates the buffer and the eof state. */ + fatal error. Otherwise updates the buffer and the eof state. + + Does release user buffer mapping if it is set. +*/ static long read_tape(Scsi_Tape *STp, long count, Scsi_Request ** aSRpnt) { int transfer, blks, bytes; @@ -1647,6 +1659,7 @@ SRpnt = *aSRpnt; SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, SCSI_DATA_READ, STp->timeout, MAX_RETRIES, TRUE); + release_buffering(STp); *aSRpnt = SRpnt; if (!SRpnt) return STbp->syscall_result; @@ -1788,7 +1801,7 @@ ssize_t total; ssize_t retval = 0; ssize_t i, transfer; - int special; + int special, do_dio = 0; Scsi_Request *SRpnt = NULL; Scsi_Tape *STp = filp->private_data; ST_mode *STm; @@ -1826,6 +1839,7 @@ retval = setup_buffering(STp, buf, count, TRUE); if (retval) goto out; + do_dio = STbp->do_dio; if (STbp->buffer_bytes == 0 && STps->eof >= ST_EOD_1) { @@ -1838,7 +1852,7 @@ goto out; } - if (!STbp->do_dio) { + if (do_dio) { /* Check the buffer writability before any tape movement. Don't alter buffer data. */ if (copy_from_user(&i, buf, 1) != 0 || @@ -1876,7 +1890,7 @@ ) /* end DEB */ transfer = STbp->buffer_bytes < count - total ? STbp->buffer_bytes : count - total; - if (!STbp->do_dio) { + if (!do_dio) { i = from_buffer(STbp, buf, transfer); if (i) { retval = i; @@ -1917,9 +1931,8 @@ scsi_release_request(SRpnt); SRpnt = NULL; } - if (STbp->do_dio) { - sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, TRUE); - STbp->do_dio = 0; + if (do_dio) { + release_buffering(STp); STbp->buffer_bytes = 0; } up(&STp->lock); @@ -2348,6 +2361,7 @@ int datalen = 0, direction = SCSI_DATA_NONE; char *name = tape_name(STp); + WARN_ON(STp->buffer->do_dio != 0); if (STp->ready != ST_READY) { if (STp->ready == ST_NO_TAPE) return (-ENOMEDIUM); diff -Nru a/drivers/scsi/st.h b/drivers/scsi/st.h --- a/drivers/scsi/st.h Mon Aug 18 22:21:05 2003 +++ b/drivers/scsi/st.h Mon Aug 18 22:21:05 2003 @@ -11,7 +11,7 @@ typedef struct { unsigned char in_use; unsigned char dma; /* DMA-able buffer */ - unsigned char do_dio; + unsigned char do_dio; /* direct i/o set up? */ int buffer_size; int buffer_blocks; int buffer_bytes; diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c --- a/drivers/scsi/sym53c8xx.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/sym53c8xx.c Mon Aug 18 22:21:04 2003 @@ -1162,8 +1162,7 @@ mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), - ((unsigned long)cmd->request_buffer & - ~PAGE_MASK), + offset_in_page(cmd->request_buffer), cmd->request_bufflen, dma_dir); __data_mapped(cmd) = 1; __data_mapping(cmd) = mapping; @@ -14720,6 +14719,5 @@ .cmd_per_lun = SCSI_NCR_CMD_PER_LUN, .max_sectors = MAX_HW_SEGMENTS*8, .use_clustering = DISABLE_CLUSTERING, - .highmem_io = 1 }; #include "scsi_module.c" 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 Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Mon Aug 18 22:21:06 2003 @@ -57,35 +57,6 @@ #define NAME53C "sym53c" #define NAME53C8XX "sym53c8xx" -/* - * Simple Wrapper to kernel PCI bus interface. - */ - -typedef struct pci_dev *pcidev_t; -#define PCIDEV_NULL (0) -#define PciBusNumber(d) (d)->bus->number -#define PciDeviceFn(d) (d)->devfn -#define PciVendorId(d) (d)->vendor -#define PciDeviceId(d) (d)->device -#define PciIrqLine(d) (d)->irq - -static u_long __init -pci_get_base_cookie(struct pci_dev *pdev, int index) -{ - u_long base; - -#if LINUX_VERSION_CODE > LinuxVersionCode(2,3,12) - base = pdev->resource[index].start; -#else - base = pdev->base_address[index]; -#if BITS_PER_LONG > 32 - if ((base & 0x7) == 0x4) - base |= (((u_long)pdev->base_address[++index]) << 32); -#endif -#endif - return (base & ~0x7ul); -} - static int __init pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) { @@ -95,7 +66,7 @@ pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp); *base = tmp; ++index; - if ((tmp & 0x7) == 0x4) { + if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) { #if BITS_PER_LONG > 32 pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp); *base |= (((u_long)tmp) << 32); @@ -106,14 +77,6 @@ #undef PCI_BAR_OFFSET } -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) -#define pci_enable_device(pdev) (0) -#endif - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4) -#define scsi_set_pci_device(inst, pdev) do { ;} while (0) -#endif - /* * Insert a delay in micro-seconds and milli-seconds. */ @@ -235,53 +198,8 @@ */ static struct Scsi_Host *first_host = NULL; -/* - * /proc directory entry and proc_info. - */ -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27) -static struct proc_dir_entry proc_scsi_sym53c8xx = { - PROC_SCSI_SYM53C8XX, 9, NAME53C8XX, - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; -#endif - -/* - * Transfer direction - * - * Until some linux kernel version near 2.3.40, low-level scsi - * drivers were not told about data transfer direction. - */ -#if LINUX_VERSION_CODE > LinuxVersionCode(2, 3, 40) - #define scsi_data_direction(cmd) (cmd->sc_data_direction) -#else - -static __inline__ int scsi_data_direction(Scsi_Cmnd *cmd) -{ - int direction; - - switch((int) cmd->cmnd[0]) { - case 0x08: /* READ(6) 08 */ - case 0x28: /* READ(10) 28 */ - case 0xA8: /* READ(12) A8 */ - direction = SCSI_DATA_READ; - break; - case 0x0A: /* WRITE(6) 0A */ - case 0x2A: /* WRITE(10) 2A */ - case 0xAA: /* WRITE(12) AA */ - direction = SCSI_DATA_WRITE; - break; - default: - direction = SCSI_DATA_UNKNOWN; - break; - } - - return direction; -} - -#endif - /* * Driver host data structure. */ @@ -305,7 +223,7 @@ struct sym_eh_wait { struct semaphore sem; struct timer_list timer; - void (*old_done)(Scsi_Cmnd *); + void (*old_done)(struct scsi_cmnd *); int to_do; int timed_out; }; @@ -325,7 +243,7 @@ typedef struct sym_ucmd *ucmd_p; #define SYM_UCMD_PTR(cmd) ((ucmd_p)(&(cmd)->SCp)) -#define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, Scsi_Cmnd, SCp) +#define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, struct scsi_cmnd, SCp) #define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->device->host->hostdata)->ncb) /* @@ -367,7 +285,7 @@ #define bus_sg_dma_address(sc) sg_dma_address(sc) #define bus_sg_dma_len(sc) sg_dma_len(sc) -static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd) +static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) { int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); @@ -383,7 +301,7 @@ SYM_UCMD_PTR(cmd)->data_mapped = 0; } -static bus_addr_t __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd) +static bus_addr_t __map_scsi_single_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) { bus_addr_t mapping; int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); @@ -398,7 +316,7 @@ return mapping; } -static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd) +static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) { int use_sg; int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); @@ -412,7 +330,7 @@ return use_sg; } -static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd) +static void __sync_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) { int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); @@ -441,14 +359,14 @@ /* * Complete a pending CAM CCB. */ -void sym_xpt_done(hcb_p np, Scsi_Cmnd *ccb) +void sym_xpt_done(hcb_p np, struct scsi_cmnd *ccb) { sym_remque(&SYM_UCMD_PTR(ccb)->link_cmdq); unmap_scsi_data(np, ccb); ccb->scsi_done(ccb); } -void sym_xpt_done2(hcb_p np, Scsi_Cmnd *ccb, int cam_status) +void sym_xpt_done2(hcb_p np, struct scsi_cmnd *ccb, int cam_status) { sym_set_cam_status(ccb, cam_status); sym_xpt_done(np, ccb); @@ -460,7 +378,7 @@ */ void sym_print_addr (ccb_p cp) { - Scsi_Cmnd *cmd = cp->cam_ccb; + struct scsi_cmnd *cmd = cp->cam_ccb; if (cmd) printf("%s:%d:%d:", sym_name(SYM_SOFTC_PTR(cmd)), cmd->device->id,cmd->device->lun); @@ -521,7 +439,7 @@ */ void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid) { - Scsi_Cmnd *csio = cp->cam_ccb; + struct scsi_cmnd *csio = cp->cam_ccb; u_int cam_status, scsi_status, drv_status; drv_status = 0; @@ -581,9 +499,7 @@ */ cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status); } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,99) csio->resid = resid; -#endif csio->result = (drv_status << 24) + (cam_status << 16) + scsi_status; } @@ -591,7 +507,7 @@ /* * Called on successfull INQUIRY response. */ -void sym_sniff_inquiry(hcb_p np, Scsi_Cmnd *cmd, int resid) +void sym_sniff_inquiry(hcb_p np, struct scsi_cmnd *cmd, int resid) { int retv; @@ -612,7 +528,7 @@ * Build the scatter/gather array for an I/O. */ -static int sym_scatter_no_sglist(hcb_p np, ccb_p cp, Scsi_Cmnd *cmd) +static int sym_scatter_no_sglist(hcb_p np, ccb_p cp, struct scsi_cmnd *cmd) { struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1]; int segment; @@ -634,7 +550,7 @@ return segment; } -static int sym_scatter(hcb_p np, ccb_p cp, Scsi_Cmnd *cmd) +static int sym_scatter(hcb_p np, ccb_p cp, struct scsi_cmnd *cmd) { int segment; int use_sg = (int) cmd->use_sg; @@ -671,9 +587,9 @@ /* * Queue a SCSI command. */ -static int sym_queue_command(hcb_p np, Scsi_Cmnd *ccb) +static int sym_queue_command(hcb_p np, struct scsi_cmnd *ccb) { -/* Scsi_Device *device = ccb->device; */ +/* struct scsi_device *device = ccb->device; */ tcb_p tp; lcb_p lp; ccb_p cp; @@ -736,7 +652,7 @@ /* * Setup buffers and pointers that address the CDB. */ -static int __inline sym_setup_cdb(hcb_p np, Scsi_Cmnd *ccb, ccb_p cp) +static int __inline sym_setup_cdb(hcb_p np, struct scsi_cmnd *ccb, ccb_p cp) { u32 cmd_ba; int cmd_len; @@ -762,7 +678,7 @@ /* * Setup pointers that address the data and start the I/O. */ -int sym_setup_data_and_start(hcb_p np, Scsi_Cmnd *csio, ccb_p cp) +int sym_setup_data_and_start(hcb_p np, struct scsi_cmnd *csio, ccb_p cp) { int dir; tcb_p tp = &np->target[cp->target]; @@ -841,20 +757,6 @@ { u_long thistime = ktime_get(0); -#if LINUX_VERSION_CODE < LinuxVersionCode(2, 4, 0) - /* - * If release process in progress, let's go - * Set the release stage from 1 to 2 to synchronize - * with the release process. - */ - - if (np->s.release_stage) { - if (np->s.release_stage == 1) - np->s.release_stage = 2; - return; - } -#endif - /* * Restart the timer. */ @@ -933,7 +835,7 @@ */ static void sym_requeue_awaiting_cmds(hcb_p np) { - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; ucmd_p ucp = SYM_UCMD_PTR(cmd); SYM_QUEHEAD tmp_cmdq; int sts; @@ -954,7 +856,7 @@ /* * Linux entry point of the queuecommand() function */ -int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +int sym53c8xx_queue_command (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { hcb_p np = SYM_SOFTC_PTR(cmd); ucmd_p ucp = SYM_UCMD_PTR(cmd); @@ -1066,7 +968,7 @@ /* * Our general completion handler. */ -static void __sym_eh_done(Scsi_Cmnd *cmd, int timed_out) +static void __sym_eh_done(struct scsi_cmnd *cmd, int timed_out) { struct sym_eh_wait *ep = SYM_UCMD_PTR(cmd)->eh_wait; if (!ep) @@ -1091,18 +993,18 @@ /* * scsi_done() alias when error recovery is in progress. */ -static void sym_eh_done(Scsi_Cmnd *cmd) { __sym_eh_done(cmd, 0); } +static void sym_eh_done(struct scsi_cmnd *cmd) { __sym_eh_done(cmd, 0); } /* * Some timeout handler to avoid waiting too long. */ -static void sym_eh_timeout(u_long p) { __sym_eh_done((Scsi_Cmnd *)p, 1); } +static void sym_eh_timeout(u_long p) { __sym_eh_done((struct scsi_cmnd *)p, 1); } /* * Generic method for our eh processing. * The 'op' argument tells what we have to do. */ -static int sym_eh_handler(int op, char *opname, Scsi_Cmnd *cmd) +static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) { hcb_p np = SYM_SOFTC_PTR(cmd); SYM_QUEHEAD *qp; @@ -1147,11 +1049,7 @@ goto finish; break; case SYM_EH_DO_WAIT: -#if LINUX_VERSION_CODE > LinuxVersionCode(2,3,0) init_MUTEX_LOCKED(&ep->sem); -#else - ep->sem = MUTEX_LOCKED; -#endif /* fall through */ case SYM_EH_DO_COMPLETE: ep->old_done = cmd->scsi_done; @@ -1219,22 +1117,22 @@ /* * Error handlers called from the eh thread (one thread per HBA). */ -int sym53c8xx_eh_abort_handler(Scsi_Cmnd *cmd) +int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) { return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); } -int sym53c8xx_eh_device_reset_handler(Scsi_Cmnd *cmd) +int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd) { return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); } -int sym53c8xx_eh_bus_reset_handler(Scsi_Cmnd *cmd) +int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd) { return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); } -int sym53c8xx_eh_host_reset_handler(Scsi_Cmnd *cmd) +int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) { return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); } @@ -1331,7 +1229,7 @@ * Linux entry point for device queue sizing. */ int -sym53c8xx_slave_configure(Scsi_Device *device) +sym53c8xx_slave_configure(struct scsi_device *device) { struct Scsi_Host *host = device->host; hcb_p np; @@ -1853,10 +1751,6 @@ #ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING static int sym_setup_bus_dma_mask(hcb_p np) { -#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,3) - if (!pci_dma_supported(np->s.device, 0xffffffffUL)) - goto out_err32; -#else #if SYM_CONF_DMA_ADDRESSING_MODE == 0 if (pci_set_dma_mask(np->s.device, 0xffffffffUL)) goto out_err32; @@ -1879,7 +1773,6 @@ } #undef PciDmaMask #endif -#endif return 0; out_err32: @@ -1899,7 +1792,7 @@ * start the timer daemon. */ static int __init -sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev) +sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev) { struct host_data *host_data; hcb_p np = 0; @@ -1934,7 +1827,7 @@ /* * Allocate host_data structure */ - if (!(instance = scsi_register(tpnt, sizeof(*host_data)))) + if (!(instance = scsi_host_alloc(tpnt, sizeof(*host_data)))) goto attach_failed; host_data = (struct host_data *) instance->hostdata; @@ -1960,6 +1853,8 @@ host_data->ncb = np; np->s.host = instance; + pci_set_drvdata(dev->pdev, np); + SYM_INIT_LOCK_HCB(np); /* @@ -2106,11 +2001,7 @@ instance->max_id = np->maxwide ? 16 : 8; instance->max_lun = SYM_CONF_MAX_LUN; #ifndef SYM_CONF_IOMAPPED -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,29) instance->base = (unsigned long) np->s.mmio_va; -#else - instance->base = (char *) np->s.mmio_va; -#endif #endif instance->irq = np->s.irq; instance->unique_id = np->s.io_port; @@ -2120,27 +2011,25 @@ instance->cmd_per_lun = SYM_CONF_MAX_TAG; instance->can_queue = (SYM_CONF_MAX_START-2); instance->sg_tablesize = SYM_CONF_MAX_SG; -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) instance->max_cmd_len = 16; -#endif - instance->highmem_io = 1; SYM_UNLOCK_HCB(np, flags); - scsi_set_device(instance, &dev->pdev->dev); - /* * Now let the generic SCSI driver * look for the SCSI devices on the bus .. */ + scsi_add_host(instance, &dev->pdev->dev); /* XXX: handle failure */ + scsi_scan_host(instance); return 0; attach_failed: - if (!instance) return -1; + if (!instance) + return -1; printf_info("%s: giving up ...\n", sym_name(np)); if (np) sym_free_resources(np); - scsi_unregister(instance); + scsi_host_put(instance); return -1; } @@ -2371,60 +2260,9 @@ return 1; } -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13) #ifndef MODULE __setup("sym53c8xx=", sym53c8xx_setup); #endif -#endif - -#ifdef SYM_CONF_PQS_PDS_SUPPORT -/* - * Detect all NCR PQS/PDS boards and keep track of their bus nr. - * - * The NCR PQS or PDS card is constructed as a DEC bridge - * behind which sit a proprietary NCR memory controller and - * four or two 53c875s as separate devices. In its usual mode - * of operation, the 875s are slaved to the memory controller - * for all transfers. We can tell if an 875 is part of a - * PQS/PDS or not since if it is, it will be on the same bus - * as the memory controller. To operate with the Linux - * driver, the memory controller is disabled and the 875s - * freed to function independently. The only wrinkle is that - * the preset SCSI ID (which may be zero) must be read in from - * a special configuration space register of the 875 - */ -#ifndef SYM_CONF_MAX_PQS_BUS -#define SYM_CONF_MAX_PQS_BUS 16 -#endif -static int pqs_bus[SYM_CONF_MAX_PQS_BUS] __initdata = { 0 }; - -static void __init sym_detect_pqs_pds(void) -{ - short index; - pcidev_t dev = PCIDEV_NULL; - - for(index=0; index < SYM_CONF_MAX_PQS_BUS; index++) { - u_char tmp; - - dev = pci_find_device(0x101a, 0x0009, dev); - if (dev == PCIDEV_NULL) { - pqs_bus[index] = -1; - break; - } - printf_info(NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", PciBusNumber(dev)); - pci_read_config_byte(dev, 0x44, &tmp); - /* bit 1: allow individual 875 configuration */ - tmp |= 0x2; - pci_write_config_byte(dev, 0x44, tmp); - pci_read_config_byte(dev, 0x45, &tmp); - /* bit 2: drive individual 875 interrupts to the bus */ - tmp |= 0x4; - pci_write_config_byte(dev, 0x45, tmp); - - pqs_bus[index] = PciBusNumber(dev); - } -} -#endif /* SYM_CONF_PQS_PDS_SUPPORT */ /* * Read and check the PCI configuration for any detected NCR @@ -2432,7 +2270,7 @@ * been detected. */ static int __init -sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device) +sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device) { u_short vendor_id, device_id, command, status_reg; u_char cache_line_size; @@ -2440,34 +2278,30 @@ u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP; u_char revision; u_int irq; - u_long base, base_2, base_io; + u_long base, base_2; u_long base_c, base_2_c, io_port; int i; sym_chip *chip; /* Choose some short name for this device */ - sprintf(device->s.inst_name, "sym.%d.%d.%d", - PciBusNumber(pdev), - (int) (PciDeviceFn(pdev) & 0xf8) >> 3, - (int) (PciDeviceFn(pdev) & 7)); + sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); /* * Read needed minimal info from the PCI config space. */ - vendor_id = PciVendorId(pdev); - device_id = PciDeviceId(pdev); - irq = PciIrqLine(pdev); + vendor_id = pdev->vendor; + device_id = pdev->device; + irq = pdev->irq; - i = pci_get_base_address(pdev, 0, &base_io); - io_port = pci_get_base_cookie(pdev, 0); + io_port = pdev->resource[0].start; - base_c = pci_get_base_cookie(pdev, i); - i = pci_get_base_address(pdev, i, &base); + base_c = pdev->resource[1].start; + i = pci_get_base_address(pdev, 1, &base); - base_2_c = pci_get_base_cookie(pdev, i); - (void) pci_get_base_address(pdev, i, &base_2); + base_2_c = pdev->resource[i].start; + pci_get_base_address(pdev, i, &base_2); - io_port &= PCI_BASE_ADDRESS_IO_MASK; base &= PCI_BASE_ADDRESS_MEM_MASK; base_2 &= PCI_BASE_ADDRESS_MEM_MASK; @@ -2476,9 +2310,9 @@ /* * If user excluded this chip, donnot initialize it. */ - if (base_io) { + if (io_port) { for (i = 0 ; i < 8 ; i++) { - if (sym_driver_setup.excludes[i] == base_io) + if (sym_driver_setup.excludes[i] == io_port) return -1; } } @@ -2640,8 +2474,8 @@ * Initialise device structure with items required by sym_attach. */ device->pdev = pdev; - device->s.bus = PciBusNumber(pdev); - device->s.device_fn = PciDeviceFn(pdev); + device->s.bus = pdev->bus->number; + device->s.device_fn = pdev->devfn; device->s.base = base; device->s.base_2 = base_2; device->s.base_c = base_c; @@ -2653,26 +2487,7 @@ return 0; } -/* - * List of supported NCR chip ids - */ -static u_short sym_chip_ids[] __initdata = { - PCI_ID_SYM53C810, - PCI_ID_SYM53C815, - PCI_ID_SYM53C825, - PCI_ID_SYM53C860, - PCI_ID_SYM53C875, - PCI_ID_SYM53C875_2, - PCI_ID_SYM53C885, - PCI_ID_SYM53C875A, - PCI_ID_SYM53C895, - PCI_ID_SYM53C896, - PCI_ID_SYM53C895A, - PCI_ID_LSI53C1510D, - PCI_ID_LSI53C1010, - PCI_ID_LSI53C1010_2 -}; - +#if 0 /* * Detect all 53c8xx hosts and then attach them. * @@ -2683,9 +2498,9 @@ * If no NVRAM is found or data appears invalid attach boards in * the order they are detected. */ -int __init sym53c8xx_detect(Scsi_Host_Template *tpnt) +int __init sym53c8xx_detect(struct scsi_host_template *tpnt) { - pcidev_t pcidev; + struct pci_dev *pcidev; int i, j, chips, hosts, count; int attach_count = 0; sym_device *devtbl, *devp; @@ -2737,7 +2552,7 @@ #endif j = 0; count = 0; - pcidev = PCIDEV_NULL; + pcidev = NULL; while (1) { char *msg = ""; if (count >= hosts) @@ -2747,7 +2562,7 @@ i = sym_driver_setup.reverse_probe ? chips - 1 - j : j; pcidev = pci_find_device(PCI_VENDOR_ID_NCR, sym_chip_ids[i], pcidev); - if (pcidev == PCIDEV_NULL) { + if (pcidev == NULL) { ++j; continue; } @@ -2756,8 +2571,7 @@ continue; devp = &devtbl[count]; devp->host_id = SYM_SETUP_HOST_ID; - devp->attach_done = 0; - if (sym53c8xx_pci_init(tpnt, pcidev, devp)) { + if (sym53c8xx_pci_init(pcidev, devp)) { continue; } ++count; @@ -2789,7 +2603,7 @@ */ for(i = 0; i < SYM_CONF_MAX_PQS_BUS && pqs_bus[i] != -1; i++) { u_char tmp; - if (pqs_bus[i] == PciBusNumber(pcidev)) { + if (pqs_bus[i] == pcidev->bus->number) { pci_read_config_byte(pcidev, 0x84, &tmp); devp->pqs_pds = 1; devp->host_id = tmp; @@ -2868,7 +2682,7 @@ return attach_count; } - +#endif /* @@ -2883,32 +2697,7 @@ { printk("%s: detaching ...\n", sym_name(np)); - /* - * Try to delete the timer. - * In the unlikely situation where this failed, - * try to synchronize with the timer handler. - */ -#if LINUX_VERSION_CODE < LinuxVersionCode(2, 4, 0) - np->s.release_stage = 1; - if (!del_timer(&np->s.timer)) { - int i = 1000; - int k = 1; - while (1) { - u_long flags; - SYM_LOCK_HCB(np, flags); - k = np->s.release_stage; - SYM_UNLOCK_HCB(np, flags); - if (k == 2 || !--i) - break; - MDELAY(5); - } - if (!i) - printk("%s: failed to kill timer!\n", sym_name(np)); - } - np->s.release_stage = 2; -#else - (void)del_timer_sync(&np->s.timer); -#endif + del_timer_sync(&np->s.timer); /* * Reset NCR chip. @@ -2928,27 +2717,27 @@ return 1; } +#if 0 int sym53c8xx_release(struct Scsi_Host *host) { sym_detach(((struct host_data *) host->hostdata)->ncb); return 0; } +#endif -/* - * For bigots to keep silent. :) - */ -#ifdef MODULE_LICENSE MODULE_LICENSE("Dual BSD/GPL"); -#endif /* * Driver host template. */ -static Scsi_Host_Template driver_template = { +static struct scsi_host_template sym2_template = { + .module = THIS_MODULE, .name = "sym53c8xx", +#if 0 .detect = sym53c8xx_detect, .release = sym53c8xx_release, +#endif .info = sym53c8xx_info, .queuecommand = sym53c8xx_queue_command, .slave_configure = sym53c8xx_slave_configure, @@ -2958,14 +2747,181 @@ .eh_host_reset_handler = sym53c8xx_eh_host_reset_handler, .this_id = 7, .use_clustering = DISABLE_CLUSTERING, - .highmem_io = 1, #ifdef SYM_LINUX_PROC_INFO_SUPPORT .proc_info = sym53c8xx_proc_info, -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27) - .proc_dir = &proc_scsi_sym53c8xx, -#else .proc_name = NAME53C8XX, #endif +}; + +#ifdef _SYM_CONF_PQS_PDS_SUPPORT +#if 0 +/* + * Detect all NCR PQS/PDS boards and keep track of their bus nr. + * + * The NCR PQS or PDS card is constructed as a DEC bridge + * behind which sit a proprietary NCR memory controller and + * four or two 53c875s as separate devices. In its usual mode + * of operation, the 875s are slaved to the memory controller + * for all transfers. We can tell if an 875 is part of a + * PQS/PDS or not since if it is, it will be on the same bus + * as the memory controller. To operate with the Linux + * driver, the memory controller is disabled and the 875s + * freed to function independently. The only wrinkle is that + * the preset SCSI ID (which may be zero) must be read in from + * a special configuration space register of the 875 + */ +#ifndef SYM_CONF_MAX_PQS_BUS +#define SYM_CONF_MAX_PQS_BUS 16 +#endif +static int pqs_bus[SYM_CONF_MAX_PQS_BUS] __initdata = { 0 }; + +static void __init sym_detect_pqs_pds(void) +{ + short index; + struct pci_dev *dev = NULL; + + for(index=0; index < SYM_CONF_MAX_PQS_BUS; index++) { + u_char tmp; + + dev = pci_find_device(0x101a, 0x0009, dev); + if (dev == NULL) { + pqs_bus[index] = -1; + break; + } + printf_info(NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", dev->bus->number); + pci_read_config_byte(dev, 0x44, &tmp); + /* bit 1: allow individual 875 configuration */ + tmp |= 0x2; + pci_write_config_byte(dev, 0x44, tmp); + pci_read_config_byte(dev, 0x45, &tmp); + /* bit 2: drive individual 875 interrupts to the bus */ + tmp |= 0x4; + pci_write_config_byte(dev, 0x45, tmp); + + pqs_bus[index] = dev->bus->number; + } +} +#endif + +static int pqs_probe() +{ +} + +static void pqs_remove() +{ +} + +static struct pci_device_id pqs_id_table[] __devinitdata = { + { 0x101a, 0x0009, }, +}; + +MODULE_DEVICE_TABLE(pci, pqs_id_table); + +static struct pci_driver pqs_driver = { + .name = NAME53C8XX " (PQS)", + .id_table = pqs_id_table, + .probe = pqs_probe, + .remove = __devexit_p(pqs_remove), +}; +#endif /* PQS */ + +static int attach_count; + +static int __devinit sym2_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + sym_device sym_dev; + sym_nvram nvram; + + memset(&sym_dev, 0, sizeof(sym_dev)); + memset(&nvram, 0, sizeof(nvram)); + + sym_dev.host_id = SYM_SETUP_HOST_ID; + if (sym53c8xx_pci_init(pdev, &sym_dev)) + return -ENODEV; + printk(KERN_INFO "%s: 53c%s detected\n", sym_name(&sym_dev), sym_dev.chip.name); + + sym_dev.nvram = &nvram; + nvram.type = 0; +#if SYM_CONF_NVRAM_SUPPORT + sym_get_nvram(&sym_dev, &nvram); #endif + + if (sym_attach(&sym2_template, attach_count, &sym_dev)) + return -ENODEV; + + attach_count++; + return 0; +} + +static void __devexit sym2_remove(struct pci_dev *pdev) +{ + sym_detach(pci_get_drvdata(pdev)); + attach_count--; +} + +static struct pci_device_id sym2_id_table[] __devinitdata = { + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C810, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C820, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */ + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C825, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C815, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C810AP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */ + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C860, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1510, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C896, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C895, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C885, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C875, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C1510, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */ + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C895A, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C875A, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1010_33, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1010_66, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C875J, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, }; -#include "../scsi_module.c" + +MODULE_DEVICE_TABLE(pci, sym2_id_table); + +static struct pci_driver sym2_driver = { + .name = NAME53C8XX, + .id_table = sym2_id_table, + .probe = sym2_probe, + .remove = __devexit_p(sym2_remove), +}; + +static int __init sym2_init(void) +{ +#ifdef _SYM_CONF_PQS_PDS_SUPPORT + pci_register_driver(&pqs_driver); +#endif + pci_register_driver(&sym2_driver); + return 0; +} + +static void __exit sym2_exit(void) +{ + pci_unregister_driver(&sym2_driver); +#ifdef _SYM_CONF_PQS_PDS_SUPPORT + pci_unregister_driver(&pqs_driver); +#endif +} + +module_init(sym2_init); +module_exit(sym2_exit); 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 Mon Aug 18 22:21:06 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h Mon Aug 18 22:21:06 2003 @@ -57,20 +57,10 @@ #define SYM_CONF_DMA_ADDRESSING_MODE 2 #endif -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) -#include -#if LINUX_VERSION_CODE < LinuxVersionCode(2, 2, 0) -#error "This driver requires a kernel version not lower than 2.2.0" -#endif - #include #include #include -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17) #include -#else -#include -#endif #include #include #include @@ -91,29 +81,11 @@ #endif #include -#ifndef __init -#define __init -#endif -#ifndef __initdata -#define __initdata -#endif - #include "../scsi.h" #include "../hosts.h" #include -/* - * Define BITS_PER_LONG for earlier linux versions. - */ -#ifndef BITS_PER_LONG -#if (~0UL) == 0xffffffffUL -#define BITS_PER_LONG 32 -#else -#define BITS_PER_LONG 64 -#endif -#endif - typedef u_long vm_offset_t; #ifndef bcopy @@ -139,9 +111,7 @@ /* * Configuration addendum for Linux. */ -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,47) #define SYM_LINUX_DYNAMIC_DMA_MAPPING -#endif #define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2) @@ -472,9 +442,6 @@ u_long lasttime; u_long settle_time; /* Resetting the SCSI BUS */ u_char settle_time_valid; -#if LINUX_VERSION_CODE < LinuxVersionCode(2, 4, 0) - u_char release_stage; /* Synchronisation on release */ -#endif }; /* @@ -647,9 +614,7 @@ { Scsi_Cmnd *cmd = cp->cam_ccb; -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,99) cmd->resid = resid; -#endif cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f)); } void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid); diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c Mon Aug 18 22:21:00 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c Mon Aug 18 22:21:00 2003 @@ -5942,14 +5942,7 @@ */ return 0; - /* - * We have failed. - * We will try to free all the resources we have - * allocated, but if we are a boot device, this - * will not help that much.;) - */ attach_failed: - sym_hcb_free(np); return -ENXIO; } diff -Nru a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c --- a/drivers/scsi/zalon.c Mon Aug 18 22:21:04 2003 +++ b/drivers/scsi/zalon.c Mon Aug 18 22:21:04 2003 @@ -135,11 +135,9 @@ if(!host) goto fail; - strlcpy(dev->dev.name, "zalon7xx", sizeof(dev->dev.name)); - - if(request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.name, host)) { + if(request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.bus_id, host)) { printk(KERN_ERR "%s: irq problem with %d, detaching\n ", - dev->dev.name, irq); + dev->dev.bus_id, irq); goto fail; } diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c --- a/drivers/serial/8250_pnp.c Mon Aug 18 22:21:00 2003 +++ b/drivers/serial/8250_pnp.c Mon Aug 18 22:21:00 2003 @@ -369,7 +369,7 @@ */ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) { - if (!(check_name(dev->dev.name) || (dev->card && check_name(dev->card->dev.name)))) + if (!(check_name(pnp_dev_name(dev)) || (dev->card && check_name(dev->card->name)))) return -ENODEV; if (check_resources(dev->independent)) diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c --- a/drivers/serial/sunsu.c Mon Aug 18 22:21:01 2003 +++ b/drivers/serial/sunsu.c Mon Aug 18 22:21:01 2003 @@ -1326,7 +1326,7 @@ up->serio.type |= SERIO_SUNKBD; up->serio.name = "sukbd"; } else { - up->serio.type |= SERIO_SUN; + up->serio.type |= (SERIO_SUN | (1 << 16)); up->serio.name = "sums"; } up->serio.phys = (i == 0 ? "su/serio0" : "su/serio1"); diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c --- a/drivers/serial/sunzilog.c Mon Aug 18 22:21:06 2003 +++ b/drivers/serial/sunzilog.c Mon Aug 18 22:21:06 2003 @@ -1559,7 +1559,7 @@ up->serio.type |= SERIO_SUNKBD; up->serio.name = "zskbd"; } else { - up->serio.type |= SERIO_SUN; + up->serio.type |= (SERIO_SUN | (1 << 16)); up->serio.name = "zsms"; } up->serio.phys = (channel == KEYBOARD_LINE ? diff -Nru a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c --- a/drivers/telephony/ixj_pcmcia.c Mon Aug 18 22:21:05 2003 +++ b/drivers/telephony/ixj_pcmcia.c Mon Aug 18 22:21:05 2003 @@ -38,7 +38,7 @@ static dev_link_t *ixj_attach(void); static void ixj_detach(dev_link_t *); static void ixj_config(dev_link_t * link); -static void ixj_cs_release(u_long arg); +static void ixj_cs_release(dev_link_t * link); static int ixj_event(event_t event, int priority, event_callback_args_t * args); static dev_info_t dev_info = "ixj_cs"; static dev_link_t *dev_list = NULL; @@ -54,9 +54,6 @@ 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; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; @@ -97,10 +94,9 @@ break; if (*linkp == NULL) return; - del_timer_sync(&link->release); link->state &= ~DEV_RELEASE_PENDING; if (link->state & DEV_CONFIG) - ixj_cs_release((u_long) link); + ixj_cs_release(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); if (ret != CS_SUCCESS) @@ -251,12 +247,11 @@ return; cs_failed: cs_error(link->handle, last_fn, last_ret); - ixj_cs_release((u_long) link); + ixj_cs_release(link); } -static void ixj_cs_release(u_long arg) +static void ixj_cs_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *) arg; ixj_info_t *info = link->priv; DEBUG(0, "ixj_cs_release(0x%p)\n", link); info->ndev = 0; @@ -274,9 +269,8 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { - link->release.expires = jiffies + (HZ / 20); link->state |= DEV_RELEASE_PENDING; - add_timer(&link->release); + ixj_cs_release(link); } break; case CS_EVENT_CARD_INSERTION: diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c --- a/drivers/usb/class/cdc-acm.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/class/cdc-acm.c Mon Aug 18 22:21:04 2003 @@ -593,7 +593,14 @@ epwrite = &ifdata->endpoint[0].desc; } - usb_set_configuration(dev, cfacm->desc.bConfigurationValue); + /* FIXME don't scan every config. it's either correct + * when we probe(), or some other task must fix this. + */ + if (dev->actconfig != cfacm) { + err("need inactive config #%d", + cfacm->desc.bConfigurationValue); + return -ENODEV; + } for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (acm_table[minor]) { diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c Mon Aug 18 22:21:01 2003 +++ b/drivers/usb/class/usblp.c Mon Aug 18 22:21:01 2003 @@ -626,12 +626,6 @@ } } remove_wait_queue(&usblp->wait, &wait); - if (!timeout) { - /* we timed out and need to bail out cleanly */ - usb_unlink_urb(usblp->writeurb); - return writecount ? writecount : -EIO; - } - } down (&usblp->sem); diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c --- a/drivers/usb/core/devio.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/core/devio.c Mon Aug 18 22:21:03 2003 @@ -762,9 +762,7 @@ if (get_user(u, (unsigned int __user *)arg)) return -EFAULT; - if (usb_set_configuration(ps->dev, u) < 0) - return -EINVAL; - return 0; + return usb_set_configuration(ps->dev, u); } static int proc_submiturb(struct dev_state *ps, void __user *arg) diff -Nru a/drivers/usb/core/file.c b/drivers/usb/core/file.c --- a/drivers/usb/core/file.c Mon Aug 18 22:21:06 2003 +++ b/drivers/usb/core/file.c Mon Aug 18 22:21:06 2003 @@ -66,8 +66,15 @@ .open = usb_open, }; +static void release_usb_class_dev(struct class_device *class_dev) +{ + dbg("%s - %s", __FUNCTION__, class_dev->class_id); + kfree(class_dev); +} + static struct class usb_class = { - .name = "usb", + .name = "usb", + .release = &release_usb_class_dev, }; int usb_major_init(void) @@ -91,9 +98,8 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf) { - struct usb_interface *intf = class_dev_to_usb_interface(class_dev); - dev_t dev = MKDEV(USB_MAJOR, intf->minor); - return print_dev_t(buf, dev); + int minor = (int)class_get_devdata(class_dev); + return print_dev_t(buf, MKDEV(USB_MAJOR, minor)); } static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); @@ -124,6 +130,7 @@ int minor_base = class_driver->minor_base; int minor = 0; char name[DEVICE_ID_SIZE]; + struct class_device *class_dev; char *temp; #ifdef CONFIG_USB_DYNAMIC_MINORS @@ -163,18 +170,23 @@ devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name); /* create a usb class device for this usb interface */ - memset(&intf->class_dev, 0x00, sizeof(struct class_device)); - intf->class_dev.class = &usb_class; - intf->class_dev.dev = &intf->dev; - - temp = strrchr(name, '/'); - if (temp && (temp[1] != 0x00)) - ++temp; - else - temp = name; - snprintf(intf->class_dev.class_id, BUS_ID_SIZE, "%s", temp); - class_device_register(&intf->class_dev); - class_device_create_file (&intf->class_dev, &class_device_attr_dev); + class_dev = kmalloc(sizeof(*class_dev), GFP_KERNEL); + if (class_dev) { + memset(class_dev, 0x00, sizeof(struct class_device)); + class_dev->class = &usb_class; + class_dev->dev = &intf->dev; + + temp = strrchr(name, '/'); + if (temp && (temp[1] != 0x00)) + ++temp; + else + temp = name; + snprintf(class_dev->class_id, BUS_ID_SIZE, "%s", temp); + class_set_devdata(class_dev, (void *)intf->minor); + class_device_register(class_dev); + class_device_create_file(class_dev, &class_device_attr_dev); + intf->class_dev = class_dev; + } exit: return retval; } @@ -217,7 +229,10 @@ snprintf(name, DEVICE_ID_SIZE, class_driver->name, intf->minor - minor_base); devfs_remove (name); - class_device_unregister(&intf->class_dev); + if (intf->class_dev) { + class_device_unregister(intf->class_dev); + intf->class_dev = NULL; + } intf->minor = -1; } EXPORT_SYMBOL(usb_deregister_dev); diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c --- a/drivers/usb/core/hcd-pci.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/core/hcd-pci.c Mon Aug 18 22:21:03 2003 @@ -257,33 +257,6 @@ #ifdef CONFIG_PM -/* - * Some "sleep" power levels imply updating struct usb_driver - * to include a callback asking hcds to do their bit by checking - * if all the drivers can suspend. Gets involved with remote wakeup. - * - * If there are pending urbs, then HCs will need to access memory, - * causing extra power drain. New sleep()/wakeup() PM calls might - * be needed, beyond PCI suspend()/resume(). The root hub timer - * still be accessing memory though ... - * - * FIXME: USB should have some power budgeting support working with - * all kinds of hubs. - * - * FIXME: This assumes only D0->D3 suspend and D3->D0 resume. - * D1 and D2 states should do something, yes? - * - * FIXME: Should provide generic enable_wake(), calling pci_enable_wake() - * for all supported states, so that USB remote wakeup can work for any - * devices that support it (and are connected via powered hubs). - * - * FIXME: resume doesn't seem to work right any more... - */ - - -// 2.4 kernels have issued concurrent resumes (w/APM) -// we defend against that error; PCI doesn't yet. - /** * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD * @dev: USB Host Controller being suspended @@ -294,20 +267,29 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state) { struct usb_hcd *hcd; - int retval; + int retval = 0; hcd = pci_get_drvdata(dev); - dev_info (hcd->controller, "suspend to state %d\n", state); - - pci_save_state (dev, hcd->pci_state); - - // FIXME for all connected devices, leaf-to-root: - // driver->suspend() - // proposed "new 2.5 driver model" will automate that - - /* driver may want to disable DMA etc */ - retval = hcd->driver->suspend (hcd, state); - hcd->state = USB_STATE_SUSPENDED; + switch (hcd->state) { + case USB_STATE_HALT: + dev_dbg (hcd->controller, "halted; hcd not suspended\n"); + break; + case USB_STATE_SUSPENDED: + dev_dbg (hcd->controller, "suspend D%d --> D%d\n", + dev->current_state, state); + break; + default: + dev_dbg (hcd->controller, "suspend to state %d\n", state); + + /* remote wakeup needs hub->suspend() cooperation */ + // pci_enable_wake (dev, 3, 1); + + pci_save_state (dev, hcd->pci_state); + + /* driver may want to disable DMA etc */ + retval = hcd->driver->suspend (hcd, state); + hcd->state = USB_STATE_SUSPENDED; + } pci_set_power_state (dev, state); return retval; @@ -326,39 +308,24 @@ int retval; hcd = pci_get_drvdata(dev); - dev_info (hcd->controller, "resume\n"); - - /* guard against multiple resumes (APM bug?) */ - atomic_inc (&hcd->resume_count); - if (atomic_read (&hcd->resume_count) != 1) { - dev_err (hcd->controller, "concurrent PCI resumes\n"); - retval = 0; - goto done; - } - - retval = -EBUSY; if (hcd->state != USB_STATE_SUSPENDED) { dev_dbg (hcd->controller, "can't resume, not suspended!\n"); - goto done; + return -EL3HLT; } hcd->state = USB_STATE_RESUMING; pci_set_power_state (dev, 0); pci_restore_state (dev, hcd->pci_state); + /* remote wakeup needs hub->suspend() cooperation */ + // pci_enable_wake (dev, 3, 0); + retval = hcd->driver->resume (hcd); if (!HCD_IS_RUNNING (hcd->state)) { dev_dbg (hcd->controller, "resume fail, retval %d\n", retval); usb_hc_died (hcd); -// FIXME: recover, reset etc. - } else { - // FIXME for all connected devices, root-to-leaf: - // driver->resume (); - // proposed "new 2.5 driver model" will automate that } -done: - atomic_dec (&hcd->resume_count); return retval; } EXPORT_SYMBOL (usb_hcd_pci_resume); diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/core/hcd.c Mon Aug 18 22:21:04 2003 @@ -1494,8 +1494,16 @@ static void hcd_panic (void *_hcd) { - struct usb_hcd *hcd = _hcd; - hcd->driver->stop (hcd); + struct usb_hcd *hcd = _hcd; + struct usb_device *hub = hcd->self.root_hub; + unsigned i; + + /* hc's root hub is removed later removed in hcd->stop() */ + hub->state = USB_STATE_NOTATTACHED; + for (i = 0; i < hub->maxchild; i++) { + if (hub->children [i]) + usb_disconnect (&hub->children [i]); + } } /** @@ -1508,29 +1516,9 @@ */ void usb_hc_died (struct usb_hcd *hcd) { - struct list_head *devlist, *urblist; - struct hcd_dev *dev; - struct urb *urb; - unsigned long flags; - - /* flag every pending urb as done */ - spin_lock_irqsave (&hcd_data_lock, flags); - list_for_each (devlist, &hcd->dev_list) { - dev = list_entry (devlist, struct hcd_dev, dev_list); - list_for_each (urblist, &dev->urb_list) { - urb = list_entry (urblist, struct urb, urb_list); - dev_dbg (hcd->controller, "shutdown %s urb %p pipe %x, current status %d\n", - hcd->self.bus_name, urb, urb->pipe, urb->status); - if (urb->status == -EINPROGRESS) - urb->status = -ESHUTDOWN; - } - } - urb = (struct urb *) hcd->rh_timer.data; - if (urb) - urb->status = -ESHUTDOWN; - spin_unlock_irqrestore (&hcd_data_lock, flags); + dev_err (hcd->controller, "HC died; cleaning up\n"); - /* hcd->stop() needs a task context */ + /* clean up old urbs and devices; needs a task context */ INIT_WORK (&hcd->work, hcd_panic, hcd); (void) schedule_work (&hcd->work); } diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/core/hcd.h Mon Aug 18 22:21:02 2003 @@ -82,7 +82,6 @@ #ifdef CONFIG_PCI int region; /* pci region for regs */ u32 pci_state [16]; /* for PM state save */ - atomic_t resume_count; /* multiple resumes issue */ #endif #define HCD_BUFFER_POOLS 4 @@ -220,11 +219,8 @@ extern void usb_hcd_pci_remove (struct pci_dev *dev); #ifdef CONFIG_PM -// FIXME: see Documentation/power/pci.txt (2.4.6 and later?) -// extern int usb_hcd_pci_save_state (struct pci_dev *dev, u32 state); extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state); extern int usb_hcd_pci_resume (struct pci_dev *dev); -// extern int usb_hcd_pci_enable_wake (struct pci_dev *dev, u32 state, int flg); #endif /* CONFIG_PM */ #endif /* CONFIG_PCI */ diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/core/hub.c Mon Aug 18 22:21:03 2003 @@ -1335,7 +1335,10 @@ kfree(descriptor); - ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue); + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, + dev->actconfig->desc.bConfigurationValue, 0, + NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); if (ret < 0) { err("failed to set dev %s active configuration (error=%d)", dev->devpath, ret); diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/core/message.c Mon Aug 18 22:21:02 2003 @@ -16,77 +16,66 @@ #include #include #include +#include #include #include "hcd.h" /* for usbcore internals */ #include "usb.h" -struct usb_api_data { - wait_queue_head_t wqh; - int done; -}; - static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs) { - struct usb_api_data *awd = (struct usb_api_data *)urb->context; + complete((struct completion *)urb->context); +} + + +static void timeout_kill(unsigned long data) +{ + struct urb *urb = (struct urb *) data; - awd->done = 1; - wmb(); - wake_up(&awd->wqh); + dev_warn(&urb->dev->dev, "%s timeout on ep%d%s\n", + usb_pipecontrol(urb->pipe) ? "control" : "bulk", + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out"); + usb_unlink_urb(urb); } // Starts urb and waits for completion or timeout +// note that this call is NOT interruptible, while +// many device driver i/o requests should be interruptible static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) { - DECLARE_WAITQUEUE(wait, current); - struct usb_api_data awd; - int status; - - init_waitqueue_head(&awd.wqh); - awd.done = 0; - - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&awd.wqh, &wait); - - urb->context = &awd; - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - // something went wrong - usb_free_urb(urb); - set_current_state(TASK_RUNNING); - remove_wait_queue(&awd.wqh, &wait); - return status; - } - - while (timeout && !awd.done) - { - timeout = schedule_timeout(timeout); - set_current_state(TASK_UNINTERRUPTIBLE); - rmb(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&awd.wqh, &wait); - - if (!timeout && !awd.done) { - if (urb->status != -EINPROGRESS) { /* No callback?!! */ - printk(KERN_ERR "usb: raced timeout, " - "pipe 0x%x status %d time left %d\n", - urb->pipe, urb->status, timeout); - status = urb->status; - } else { - warn("usb_control/bulk_msg: timeout"); - usb_unlink_urb(urb); // remove urb safely - status = -ETIMEDOUT; + struct completion done; + struct timer_list timer; + int status; + + init_completion(&done); + urb->context = &done; + urb->transfer_flags |= URB_ASYNC_UNLINK; + urb->actual_length = 0; + status = usb_submit_urb(urb, GFP_NOIO); + + if (status == 0) { + if (timeout > 0) { + init_timer(&timer); + timer.expires = jiffies + timeout; + timer.data = (unsigned long)urb; + timer.function = timeout_kill; + /* grr. timeout _should_ include submit delays. */ + add_timer(&timer); } - } else + wait_for_completion(&done); status = urb->status; + /* note: HCDs return ETIMEDOUT for other reasons too */ + if (status == -ECONNRESET) + status = -ETIMEDOUT; + if (timeout > 0) + del_timer_sync(&timer); + } if (actual_length) *actual_length = urb->actual_length; - usb_free_urb(urb); - return status; + return status; } /*-------------------------------------------------------------------*/ @@ -964,6 +953,55 @@ } /** + * usb_reset_configuration - lightweight device reset + * @dev: the device whose configuration is being reset + * + * This issues a standard SET_CONFIGURATION request to the device using + * the current configuration. The effect is to reset most USB-related + * state in the device, including interface altsettings (reset to zero), + * endpoint halts (cleared), and data toggle (only for bulk and interrupt + * endpoints). Other usbcore state is unchanged, including bindings of + * usb device drivers to interfaces. + * + * Because this affects multiple interfaces, avoid using this with composite + * (multi-interface) devices. Instead, the driver for each interface may + * use usb_set_interface() on the interfaces it claims. Resetting the whole + * configuration would affect other drivers' interfaces. + * + * Returns zero on success, else a negative error code. + */ +int usb_reset_configuration(struct usb_device *dev) +{ + int i, retval; + struct usb_host_config *config; + + for (i = 1; i < 16; ++i) { + usb_disable_endpoint(dev, i); + usb_disable_endpoint(dev, i + USB_DIR_IN); + } + + config = dev->actconfig; + retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, + config->desc.bConfigurationValue, 0, + NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); + if (retval < 0) + return retval; + + dev->toggle[0] = dev->toggle[1] = 0; + dev->halted[0] = dev->halted[1] = 0; + + /* re-init hc/hcd interface/endpoint state */ + for (i = 0; i < config->desc.bNumInterfaces; i++) { + struct usb_interface *intf = config->interface[i]; + + intf->act_altsetting = 0; + usb_enable_interface(dev, intf); + } + return 0; +} + +/** * usb_set_configuration - Makes a particular device setting be current * @dev: the device whose configuration is being updated * @configuration: the configuration being chosen. @@ -1136,7 +1174,10 @@ EXPORT_SYMBOL(usb_get_status); EXPORT_SYMBOL(usb_get_string); EXPORT_SYMBOL(usb_string); + +// synchronous calls that also maintain usbcore state EXPORT_SYMBOL(usb_clear_halt); +EXPORT_SYMBOL(usb_reset_configuration); EXPORT_SYMBOL(usb_set_configuration); EXPORT_SYMBOL(usb_set_interface); diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/core/usb.c Mon Aug 18 22:21:03 2003 @@ -261,24 +261,28 @@ * * Few drivers should need to use this routine, since the most natural * way to bind to an interface is to return the private data from - * the driver's probe() method. Any driver that does use this must - * first be sure that no other driver has claimed the interface, by - * checking with usb_interface_claimed(). + * the driver's probe() method. */ -void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv) +int usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv) { if (!iface || !driver) - return; + return -EINVAL; - // FIXME change API to report an error in this case - if (iface->driver) - err ("%s driver booted %s off interface %p", - driver->name, iface->driver->name, iface); - else + /* this is mainly to lock against usbfs */ + lock_kernel(); + if (iface->driver) { + unlock_kernel(); + err ("%s driver booted %s off interface %p", + driver->name, iface->driver->name, iface); + return -EBUSY; + } else { dbg("%s driver claimed interface %p", driver->name, iface); + } iface->driver = driver; usb_set_intfdata(iface, priv); + unlock_kernel(); + return 0; } /** @@ -324,11 +328,11 @@ if (iface->driver && iface->driver != driver) return; - iface->driver = NULL; - usb_set_intfdata(iface, NULL); usb_set_interface(interface_to_usbdev(iface), iface->altsetting[0].desc.bInterfaceNumber, 0); + usb_set_intfdata(iface, NULL); + iface->driver = NULL; } /** diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c --- a/drivers/usb/host/ehci-q.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/host/ehci-q.c Mon Aug 18 22:21:05 2003 @@ -794,6 +794,10 @@ qh->hw_info1 = cpu_to_le32 (info); } } + + /* usb_reset_device() briefly reverts to address 0 */ + if (usb_pipedevice (urb->pipe) == 0) + qh->hw_info1 &= cpu_to_le32(~0x7f); } /* usb_clear_halt() means qh data toggle gets reset */ diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c --- a/drivers/usb/media/dabusb.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/media/dabusb.c Mon Aug 18 22:21:04 2003 @@ -747,8 +747,8 @@ s->usbdev = usbdev; s->devnum = intf->minor; - if (usb_set_configuration (usbdev, usbdev->config[0].desc.bConfigurationValue) < 0) { - err("set_configuration failed"); + if (usb_reset_configuration (usbdev) < 0) { + err("reset_configuration failed"); goto reject; } if (usbdev->descriptor.idProduct == 0x2131) { @@ -800,7 +800,7 @@ } static struct usb_device_id dabusb_ids [] = { - { USB_DEVICE(0x0547, 0x2131) }, + // { USB_DEVICE(0x0547, 0x2131) }, /* An2131 chip, no boot ROM */ { USB_DEVICE(0x0547, 0x9999) }, { } /* Terminating entry */ }; diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c --- a/drivers/usb/media/ov511.c Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/media/ov511.c Mon Aug 18 22:21:02 2003 @@ -38,16 +38,14 @@ #include #include #include -#include #include #include -#include #include #include -#include #include #include #include +#include #if defined (__i386__) #include @@ -295,7 +293,6 @@ { -1, NULL } }; -#if defined(CONFIG_VIDEO_PROC_FS) static struct symbolic_list senlist[] = { { SEN_OV76BE, "OV76BE" }, { SEN_OV7610, "OV7610" }, @@ -311,7 +308,6 @@ { SEN_SAA7111A, "SAA7111A" }, { -1, NULL } }; -#endif /* URB error codes: */ static struct symbolic_list urb_errlist[] = { @@ -382,270 +378,6 @@ } /********************************************************************** - * /proc interface - * Based on the CPiA driver version 0.7.4 -claudio - **********************************************************************/ - -#if defined(CONFIG_VIDEO_PROC_FS) - -static struct proc_dir_entry *ov511_proc_entry = NULL; -extern struct proc_dir_entry *video_proc_entry; - -/* Prototypes */ -static void ov51x_clear_snapshot(struct usb_ov511 *); -static int sensor_get_picture(struct usb_ov511 *, struct video_picture *); -static int sensor_get_exposure(struct usb_ov511 *, unsigned char *); -static int ov51x_check_snapshot(struct usb_ov511 *); -static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); - -static struct file_operations ov511_control_fops = { - .owner = THIS_MODULE, - .ioctl = ov51x_control_ioctl, -}; - -#define YES_NO(x) ((x) ? "yes" : "no") - -/* /proc/video/ov511//info */ -static int -ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - char *out = page; - int i, len; - struct usb_ov511 *ov = data; - struct video_picture p; - unsigned char exp; - - if (!ov || !ov->dev) - return -ENODEV; - - sensor_get_picture(ov, &p); - sensor_get_exposure(ov, &exp); - - /* IMPORTANT: This output MUST be kept under PAGE_SIZE - * or we need to get more sophisticated. */ - - out += sprintf(out, "driver_version : %s\n", DRIVER_VERSION); - out += sprintf(out, "custom_id : %d\n", ov->customid); - out += sprintf(out, "model : %s\n", ov->desc); - out += sprintf(out, "streaming : %s\n", YES_NO(ov->streaming)); - out += sprintf(out, "grabbing : %s\n", YES_NO(ov->grabbing)); - out += sprintf(out, "compress : %s\n", YES_NO(ov->compress)); - out += sprintf(out, "subcapture : %s\n", YES_NO(ov->sub_flag)); - out += sprintf(out, "sub_size : %d %d %d %d\n", - ov->subx, ov->suby, ov->subw, ov->subh); - out += sprintf(out, "brightness : %d\n", p.brightness >> 8); - out += sprintf(out, "colour : %d\n", p.colour >> 8); - out += sprintf(out, "contrast : %d\n", p.contrast >> 8); - out += sprintf(out, "hue : %d\n", p.hue >> 8); - out += sprintf(out, "exposure : %d\n", exp); - out += sprintf(out, "num_frames : %d\n", OV511_NUMFRAMES); - for (i = 0; i < OV511_NUMFRAMES; i++) { - out += sprintf(out, "frame : %d\n", i); - out += sprintf(out, " depth : %d\n", - ov->frame[i].depth); - out += sprintf(out, " size : %d %d\n", - ov->frame[i].width, ov->frame[i].height); - out += sprintf(out, " format : %s\n", - symbolic(v4l1_plist, ov->frame[i].format)); - out += sprintf(out, " data_buffer : 0x%p\n", - ov->frame[i].data); - } - out += sprintf(out, "snap_enabled : %s\n", YES_NO(ov->snap_enabled)); - out += sprintf(out, "bridge : %s\n", - symbolic(brglist, ov->bridge)); - out += sprintf(out, "sensor : %s\n", - symbolic(senlist, ov->sensor)); - out += sprintf(out, "packet_size : %d\n", ov->packet_size); - out += sprintf(out, "framebuffer : 0x%p\n", ov->fbuf); - out += sprintf(out, "packet_numbering: %d\n", ov->packet_numbering); - out += sprintf(out, "topology : %s\n", ov->usb_path); - - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - - *start = page + off; - - return len; -} - -/* /proc/video/ov511//button - * - * When the camera's button is pressed, the output of this will change from a - * 0 to a 1 (ASCII). It will retain this value until it is read, after which - * it will reset to zero. - * - * SECURITY NOTE: Since reading this file can change the state of the snapshot - * status, it is important for applications that open it to keep it locked - * against access by other processes, using flock() or a similar mechanism. No - * locking is provided by this driver. - */ -static int -ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - char *out = page; - int len, status; - struct usb_ov511 *ov = data; - - if (!ov || !ov->dev) - return -ENODEV; - - status = ov51x_check_snapshot(ov); - out += sprintf(out, "%d", status); - - if (status) - ov51x_clear_snapshot(ov); - - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else { - len = count; - } - - *start = page + off; - - return len; -} - -static void -create_proc_ov511_cam(struct usb_ov511 *ov) -{ - char dirname[10]; - - if (!ov511_proc_entry || !ov) - return; - - /* Create per-device directory */ - snprintf(dirname, 10, "%d", ov->vdev.minor); - PDEBUG(4, "creating /proc/video/ov511/%s/", dirname); - ov->proc_devdir = create_proc_entry(dirname, S_IFDIR, ov511_proc_entry); - if (!ov->proc_devdir) - return; - ov->proc_devdir->owner = THIS_MODULE; - - /* Create "info" entry (human readable device information) */ - PDEBUG(4, "creating /proc/video/ov511/%s/info", dirname); - ov->proc_info = create_proc_read_entry("info", S_IFREG|S_IRUGO|S_IWUSR, - ov->proc_devdir, ov511_read_proc_info, ov); - if (!ov->proc_info) - return; - ov->proc_info->owner = THIS_MODULE; - - /* Don't create it if old snapshot mode on (would cause race cond.) */ - if (!snapshot) { - /* Create "button" entry (snapshot button status) */ - PDEBUG(4, "creating /proc/video/ov511/%s/button", dirname); - ov->proc_button = create_proc_read_entry("button", - S_IFREG|S_IRUGO|S_IWUSR, ov->proc_devdir, - ov511_read_proc_button, ov); - if (!ov->proc_button) - return; - ov->proc_button->owner = THIS_MODULE; - } - - /* Create "control" entry (ioctl() interface) */ - PDEBUG(4, "creating /proc/video/ov511/%s/control", dirname); - lock_kernel(); - ov->proc_control = create_proc_entry("control", S_IFREG|S_IRUGO|S_IWUSR, - ov->proc_devdir); - if (!ov->proc_control) { - unlock_kernel(); - return; - } - ov->proc_control->owner = THIS_MODULE; - ov->proc_control->data = ov; - ov->proc_control->proc_fops = &ov511_control_fops; - unlock_kernel(); -} - -static void -destroy_proc_ov511_cam(struct usb_ov511 *ov) -{ - char dirname[10]; - - if (!ov || !ov->proc_devdir) - return; - - snprintf(dirname, 10, "%d", ov->vdev.minor); - - /* Destroy "control" entry */ - if (ov->proc_control) { - PDEBUG(4, "destroying /proc/video/ov511/%s/control", dirname); - remove_proc_entry("control", ov->proc_devdir); - ov->proc_control = NULL; - } - - /* Destroy "button" entry */ - if (ov->proc_button) { - PDEBUG(4, "destroying /proc/video/ov511/%s/button", dirname); - remove_proc_entry("button", ov->proc_devdir); - ov->proc_button = NULL; - } - - /* Destroy "info" entry */ - if (ov->proc_info) { - PDEBUG(4, "destroying /proc/video/ov511/%s/info", dirname); - remove_proc_entry("info", ov->proc_devdir); - ov->proc_info = NULL; - } - - /* Destroy per-device directory */ - PDEBUG(4, "destroying /proc/video/ov511/%s/", dirname); - remove_proc_entry(dirname, ov511_proc_entry); - ov->proc_devdir = NULL; -} - -static void -proc_ov511_create(void) -{ - /* No current standard here. Alan prefers /proc/video/ as it keeps - * /proc "less cluttered than /proc/randomcardifoundintheshed/" - * -claudio - */ - if (video_proc_entry == NULL) { - err("Error: /proc/video/ does not exist"); - return; - } - - ov511_proc_entry = create_proc_entry("ov511", S_IFDIR, - video_proc_entry); - - if (ov511_proc_entry) - ov511_proc_entry->owner = THIS_MODULE; - else - err("Unable to create /proc/video/ov511"); -} - -static void -proc_ov511_destroy(void) -{ - PDEBUG(3, "removing /proc/video/ov511"); - - if (ov511_proc_entry == NULL) - return; - - remove_proc_entry("ov511", video_proc_entry); -} -#else -static inline void create_proc_ov511_cam(struct usb_ov511 *ov) { } -static inline void destroy_proc_ov511_cam(struct usb_ov511 *ov) { } -static inline void proc_ov511_create(void) { } -static inline void proc_ov511_destroy(void) { } -#endif /* #ifdef CONFIG_VIDEO_PROC_FS */ - -/********************************************************************** * * Register I/O * @@ -1399,7 +1131,7 @@ } } -#if defined(CONFIG_VIDEO_PROC_FS) +#if 0 /* Checks the status of the snapshot button. Returns 1 if it was pressed since * it was last cleared, and zero in all other cases (including errors) */ static int @@ -2098,7 +1830,7 @@ return 0; } -#if defined(CONFIG_VIDEO_PROC_FS) +#if 0 // FIXME: Exposure range is only 0x00-0x7f in interlace mode /* Sets current exposure for sensor. This only has an effect if auto-exposure * is off */ @@ -2143,6 +1875,7 @@ return rc; } +#endif /* Gets current exposure level from sensor, regardless of whether it is under * manual control. */ @@ -2180,7 +1913,6 @@ return 0; } -#endif /* CONFIG_VIDEO_PROC_FS */ /* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */ static void @@ -4309,7 +4041,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) { struct video_device *vdev = video_devdata(file); - struct usb_ov511 *ov = vdev->priv; + struct usb_ov511 *ov = video_get_drvdata(vdev); int err, i; PDEBUG(4, "opening"); @@ -4366,7 +4098,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) { struct video_device *vdev = file->private_data; - struct usb_ov511 *ov = vdev->priv; + struct usb_ov511 *ov = video_get_drvdata(vdev); PDEBUG(4, "ov511_close"); @@ -4408,7 +4140,7 @@ unsigned int cmd, void *arg) { struct video_device *vdev = file->private_data; - struct usb_ov511 *ov = vdev->priv; + struct usb_ov511 *ov = video_get_drvdata(vdev); PDEBUG(5, "IOCtl: 0x%X", cmd); if (!ov->dev) @@ -4809,7 +4541,7 @@ memset(vu, 0, sizeof(struct video_unit)); - vu->video = ov->vdev.minor; + vu->video = ov->vdev->minor; vu->vbi = VIDEO_NO_UNIT; vu->radio = VIDEO_NO_UNIT; vu->audio = VIDEO_NO_UNIT; @@ -4848,7 +4580,7 @@ unsigned int cmd, unsigned long arg) { struct video_device *vdev = file->private_data; - struct usb_ov511 *ov = vdev->priv; + struct usb_ov511 *ov = video_get_drvdata(vdev); int rc; if (down_interruptible(&ov->lock)) @@ -4866,7 +4598,7 @@ struct video_device *vdev = file->private_data; int noblock = file->f_flags&O_NONBLOCK; unsigned long count = cnt; - struct usb_ov511 *ov = vdev->priv; + struct usb_ov511 *ov = video_get_drvdata(vdev); int i, rc = 0, frmx = -1; struct ov511_frame *frame; @@ -5020,7 +4752,7 @@ struct video_device *vdev = file->private_data; unsigned long start = vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start; - struct usb_ov511 *ov = vdev->priv; + struct usb_ov511 *ov = video_get_drvdata(vdev); unsigned long page, pos; if (ov->dev == NULL) @@ -5072,227 +4804,10 @@ .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_OV511, .fops = &ov511_fops, + .release = video_device_release, + .minor = -1, }; -#if defined(CONFIG_VIDEO_PROC_FS) -static int -ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long ularg) -{ - struct proc_dir_entry *pde = PDE(inode); - struct usb_ov511 *ov; - void *arg = (void *) ularg; - int rc = 0; - - if (!pde) - return -ENOENT; - - ov = pde->data; - if (!ov) - return -ENODEV; - - if (!ov->dev) - return -EIO; - - /* Should we pass through standard V4L IOCTLs? */ - - switch (cmd) { - case OV511IOC_GINTVER: - { - int ver = OV511_INTERFACE_VER; - - PDEBUG(4, "Get interface version: %d", ver); - if (copy_to_user(arg, &ver, sizeof(ver))) - rc = -EFAULT; - break; - } - case OV511IOC_GUSHORT: - { - struct ov511_ushort_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) { - rc = -EFAULT; - break; - } - - switch (opt.optnum) { - case OV511_USOPT_BRIGHT: - rc = sensor_get_brightness(ov, &(opt.val)); - break; - case OV511_USOPT_SAT: - rc = sensor_get_saturation(ov, &(opt.val)); - break; - case OV511_USOPT_HUE: - rc = sensor_get_hue(ov, &(opt.val)); - break; - case OV511_USOPT_CONTRAST: - rc = sensor_get_contrast(ov, &(opt.val)); - break; - default: - err("Invalid get short option number"); - rc = -EINVAL; - } - - if (rc < 0) - break; - if (copy_to_user(arg, &opt, sizeof(opt))) - rc = -EFAULT; - break; - } - case OV511IOC_SUSHORT: - { - struct ov511_ushort_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) { - rc = -EFAULT; - break; - } - - switch (opt.optnum) { - case OV511_USOPT_BRIGHT: - rc = sensor_set_brightness(ov, opt.val); - break; - case OV511_USOPT_SAT: - rc = sensor_set_saturation(ov, opt.val); - break; - case OV511_USOPT_HUE: - rc = sensor_set_hue(ov, opt.val); - break; - case OV511_USOPT_CONTRAST: - rc = sensor_set_contrast(ov, opt.val); - break; - default: - err("Invalid set short option number"); - rc = -EINVAL; - } - - break; - } - case OV511IOC_GUINT: - { - struct ov511_uint_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) { - rc = -EFAULT; - break; - } - - switch (opt.optnum) { - case OV511_UIOPT_POWER_FREQ: - opt.val = ov->lightfreq; - break; - case OV511_UIOPT_BFILTER: - opt.val = ov->bandfilt; - break; - case OV511_UIOPT_LED: - opt.val = ov->led_policy; - break; - case OV511_UIOPT_DEBUG: - opt.val = debug; - break; - case OV511_UIOPT_COMPRESS: - opt.val = ov->compress; - break; - default: - err("Invalid get int option number"); - rc = -EINVAL; - } - - if (rc < 0) - break; - if (copy_to_user(arg, &opt, sizeof(opt))) - rc = -EFAULT; - - break; - } - case OV511IOC_SUINT: - { - struct ov511_uint_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) { - rc = -EFAULT; - break; - } - - switch (opt.optnum) { - case OV511_UIOPT_POWER_FREQ: - rc = sensor_set_light_freq(ov, opt.val); - break; - case OV511_UIOPT_BFILTER: - rc = sensor_set_banding_filter(ov, opt.val); - break; - case OV511_UIOPT_LED: - if (opt.val <= 2) { - ov->led_policy = opt.val; - if (ov->led_policy == LED_OFF) - ov51x_led_control(ov, 0); - else if (ov->led_policy == LED_ON) - ov51x_led_control(ov, 1); - } else - rc = -EINVAL; - break; - case OV511_UIOPT_DEBUG: - if (opt.val <= 5) - debug = opt.val; - else - rc = -EINVAL; - break; - case OV511_UIOPT_COMPRESS: - ov->compress = opt.val; - if (ov->compress) { - if (ov->bclass == BCL_OV511) - ov511_init_compression(ov); - else if (ov->bclass == BCL_OV518) - ov518_init_compression(ov); - } - break; - default: - err("Invalid get int option number"); - rc = -EINVAL; - } - - break; - } - case OV511IOC_WI2C: - { - struct ov511_i2c_struct w; - - if (copy_from_user(&w, arg, sizeof(w))) { - rc = -EFAULT; - break; - } - - rc = i2c_w_slave(ov, w.slave, w.reg, w.value, w.mask); - break; - } - case OV511IOC_RI2C: - { - struct ov511_i2c_struct r; - - if (copy_from_user(&r, arg, sizeof(r))) { - rc = -EFAULT; - break; - } - - rc = i2c_r_slave(ov, r.slave, r.reg); - if (rc < 0) - break; - - r.value = rc; - - if (copy_to_user(arg, &r, sizeof(r))) - rc = -EFAULT; - - break; - } - default: - rc = -EINVAL; - } /* end switch */ - - return rc; -} -#endif - /**************************************************************************** * * OV511 and sensor configuration @@ -6162,9 +5677,118 @@ } /**************************************************************************** - * + * sysfs + ***************************************************************************/ + +static inline struct usb_ov511 *cd_to_ov(struct class_device *cd) +{ + struct video_device *vdev = to_video_device(cd); + return video_get_drvdata(vdev); +} + +static ssize_t show_custom_id(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%d\n", ov->customid); +} +static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL); + +static ssize_t show_model(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", ov->desc); +} +static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL); + +static ssize_t show_bridge(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge)); +} +static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL); + +static ssize_t show_sensor(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor)); +} +static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL); + +static ssize_t show_brightness(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_brightness(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); + +static ssize_t show_saturation(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_saturation(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); + +static ssize_t show_contrast(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_contrast(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); + +static ssize_t show_hue(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_hue(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); + +static ssize_t show_exposure(struct class_device *cd, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned char exp; + + if (!ov->dev) + return -ENODEV; + sensor_get_exposure(ov, &exp); + return sprintf(buf, "%d\n", exp >> 8); +} +static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); + +static void ov_create_sysfs(struct video_device *vdev) +{ + video_device_create_file(vdev, &class_device_attr_custom_id); + video_device_create_file(vdev, &class_device_attr_model); + video_device_create_file(vdev, &class_device_attr_bridge); + video_device_create_file(vdev, &class_device_attr_sensor); + video_device_create_file(vdev, &class_device_attr_brightness); + video_device_create_file(vdev, &class_device_attr_saturation); + video_device_create_file(vdev, &class_device_attr_contrast); + video_device_create_file(vdev, &class_device_attr_hue); + video_device_create_file(vdev, &class_device_attr_exposure); +} + +/**************************************************************************** * USB routines - * ***************************************************************************/ static int @@ -6174,7 +5798,6 @@ struct usb_interface_descriptor *idesc; struct usb_ov511 *ov; int i; - int registered = 0; PDEBUG(1, "probing for device..."); @@ -6234,7 +5857,7 @@ break; default: err("Unknown product ID 0x%04x", dev->descriptor.idProduct); - goto error_dealloc; + goto error; } info("USB %s video device found", symbolic(brglist, ov->bridge)); @@ -6251,7 +5874,7 @@ if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) { err("usb_make_path error"); - goto error_dealloc; + goto error; } /* Allocate control transfer buffer. */ @@ -6293,38 +5916,47 @@ } #endif - memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template)); - ov->vdev.priv = ov; + ov->vdev = video_device_alloc(); + if (!ov->vdev) + goto error; + + memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); + ov->vdev->dev = &dev->dev; + video_set_drvdata(ov->vdev, ov); for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { /* Minor 0 cannot be specified; assume user wants autodetect */ if (unit_video[i] == 0) break; - if (video_register_device(&ov->vdev, VFL_TYPE_GRABBER, + if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, unit_video[i]) >= 0) { - registered = 1; break; } } /* Use the next available one */ - if (!registered && - video_register_device(&ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { + if ((ov->vdev->minor == -1) && + video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { err("video_register_device failed"); goto error; } info("Device at %s registered to minor %d", ov->usb_path, - ov->vdev.minor); - - create_proc_ov511_cam(ov); + ov->vdev->minor); - usb_set_intfdata (intf, ov); + usb_set_intfdata(intf, ov); + ov_create_sysfs(ov->vdev); return 0; error: - destroy_proc_ov511_cam(ov); + if (ov->vdev) { + if (-1 == ov->vdev->minor) + video_device_release(ov->vdev); + else + video_unregister_device(ov->vdev); + ov->vdev = NULL; + } if (ov->cbuf) { down(&ov->cbuf_lock); @@ -6333,7 +5965,6 @@ up(&ov->cbuf_lock); } -error_dealloc: if (ov) { kfree(ov); ov = NULL; @@ -6347,7 +5978,7 @@ static void ov51x_disconnect(struct usb_interface *intf) { - struct usb_ov511 *ov = usb_get_intfdata (intf); + struct usb_ov511 *ov = usb_get_intfdata(intf); int n; PDEBUG(3, ""); @@ -6357,9 +5988,8 @@ if (!ov) return; - video_unregister_device(&ov->vdev); - if (ov->user) - PDEBUG(3, "Device open...deferring video_unregister_device"); + if (ov->vdev) + video_unregister_device(ov->vdev); for (n = 0; n < OV511_NUMFRAMES; n++) ov->frame[n].grabstate = FRAME_ERROR; @@ -6375,8 +6005,6 @@ ov->streaming = 0; ov51x_unlink_isoc(ov); - destroy_proc_ov511_cam(ov); - ov->dev = NULL; /* Free the memory */ @@ -6487,7 +6115,6 @@ static int __init usb_ov511_init(void) { - proc_ov511_create(); if (usb_register(&ov511_driver) < 0) return -1; @@ -6503,7 +6130,6 @@ usb_deregister(&ov511_driver); info("driver deregistered"); - proc_ov511_destroy(); } module_init(usb_ov511_init); diff -Nru a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h --- a/drivers/usb/media/ov511.h Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/media/ov511.h Mon Aug 18 22:21:02 2003 @@ -321,35 +321,6 @@ RAWFMT_GBR422, }; -/* Unsigned short option numbers */ -enum { - OV511_USOPT_INVALID, - OV511_USOPT_BRIGHT, - OV511_USOPT_SAT, - OV511_USOPT_HUE, - OV511_USOPT_CONTRAST, -}; - -/* Unsigned int option numbers */ -enum { - OV511_UIOPT_INVALID, - OV511_UIOPT_POWER_FREQ, - OV511_UIOPT_BFILTER, - OV511_UIOPT_LED, - OV511_UIOPT_DEBUG, - OV511_UIOPT_COMPRESS, -}; - -struct ov511_ushort_opt { - int optnum; /* Specific option number */ - unsigned short val; -}; - -struct ov511_uint_opt { - int optnum; /* Specific option number */ - unsigned int val; -}; - struct ov511_i2c_struct { unsigned char slave; /* Write slave ID (read ID - 1) */ unsigned char reg; /* Index of register */ @@ -358,15 +329,6 @@ }; /* ioctls */ -#define OV511IOC_GINTVER _IOR('v', BASE_VIDIOCPRIVATE + 0, int) -#define OV511IOC_GUSHORT _IOWR('v', BASE_VIDIOCPRIVATE + 1, \ - struct ov511_ushort_opt) -#define OV511IOC_SUSHORT _IOW('v', BASE_VIDIOCPRIVATE + 2, \ - struct ov511_ushort_opt) -#define OV511IOC_GUINT _IOWR('v', BASE_VIDIOCPRIVATE + 3, \ - struct ov511_uint_opt) -#define OV511IOC_SUINT _IOW('v', BASE_VIDIOCPRIVATE + 4, \ - struct ov511_uint_opt) #define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \ struct ov511_i2c_struct) #define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \ @@ -445,9 +407,7 @@ }; struct usb_ov511 { - struct video_device vdev; - - /* Device structure */ + struct video_device *vdev; struct usb_device *dev; int customid; @@ -514,12 +474,6 @@ int packet_numbering; /* Is ISO frame numbering enabled? */ struct semaphore param_lock; /* params lock for this camera */ - - /* /proc entries, relative to /proc/video/ov511/ */ - struct proc_dir_entry *proc_devdir; /* Per-device proc directory */ - struct proc_dir_entry *proc_info; /* /info entry */ - struct proc_dir_entry *proc_button; /* /button entry */ - struct proc_dir_entry *proc_control; /* /control entry */ /* Framebuffer/sbuf management */ int buf_state; diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c --- a/drivers/usb/media/stv680.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/media/stv680.c Mon Aug 18 22:21:04 2003 @@ -225,8 +225,9 @@ static int stv_set_config (struct usb_stv *dev, int configuration, int interface, int alternate) { - if (usb_set_configuration (dev->udev, configuration) < 0) { - PDEBUG (1, "STV(e): FAILED to set configuration %i", configuration); + if (configuration != dev->udev->actconfig->desc.bConfigurationValue + || usb_reset_configuration (dev->udev) < 0) { + PDEBUG (1, "STV(e): FAILED to reset configuration %i", configuration); return -1; } if (usb_set_interface (dev->udev, interface, alternate) < 0) { diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c --- a/drivers/usb/media/usbvideo.c Mon Aug 18 22:21:06 2003 +++ b/drivers/usb/media/usbvideo.c Mon Aug 18 22:21:06 2003 @@ -777,7 +777,7 @@ const struct usb_device_id *id_table) { struct usbvideo *cams; - int i, base_size; + int i, base_size, result; /* Check parameters for sanity */ if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) { @@ -846,9 +846,13 @@ up->user_size = num_cams * num_extra; up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL); if (up->user_data == NULL) { - up->user_size = 0; err("%s: Failed to allocate user_data (%d. bytes)", __FUNCTION__, up->user_size); + while (i) { + up = &cams->cam[--i]; + kfree(up->user_data); + } + kfree(cams); return -ENOMEM; } dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)", @@ -878,9 +882,16 @@ * If the handle is not yet updated then the probe() will fail. */ *pCams = cams; - usb_register(&cams->usbdrv); + result = usb_register(&cams->usbdrv); + if (result) { + for (i = 0; i < num_cams; i++) { + struct uvd *up = &cams->cam[i]; + kfree(up->user_data); + } + kfree(cams); + } - return 0; + return result; } EXPORT_SYMBOL(usbvideo_register); diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c --- a/drivers/usb/misc/tiglusb.c Mon Aug 18 22:21:00 2003 +++ b/drivers/usb/misc/tiglusb.c Mon Aug 18 22:21:00 2003 @@ -57,7 +57,7 @@ static inline int clear_device (struct usb_device *dev) { - if (usb_set_configuration (dev, dev->config[0].desc.bConfigurationValue) < 0) { + if (usb_reset_configuration (dev) < 0) { err ("clear_device failed"); return -1; } @@ -343,8 +343,10 @@ && (dev->descriptor.idVendor != 0x451)) return -ENODEV; - if (usb_set_configuration (dev, dev->config[0].desc.bConfigurationValue) < 0) { - err ("tiglusb_probe: set_configuration failed"); + // NOTE: it's already in this config, this shouldn't be needed. + // is this working around some hardware bug? + if (usb_reset_configuration (dev) < 0) { + err ("tiglusb_probe: reset_configuration failed"); return -ENODEV; } diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c --- a/drivers/usb/misc/usbtest.c Mon Aug 18 22:21:06 2003 +++ b/drivers/usb/misc/usbtest.c Mon Aug 18 22:21:06 2003 @@ -271,7 +271,7 @@ /* kmalloc pages are always physically contiguous! */ sg [i].page = virt_to_page (buf); - sg [i].offset = ((unsigned) buf) & ~PAGE_MASK; + sg [i].offset = offset_in_page (buf); sg [i].length = size; if (vary) { diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c --- a/drivers/usb/net/usbnet.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/net/usbnet.c Mon Aug 18 22:21:03 2003 @@ -600,7 +600,9 @@ /* claim data interface and set it up ... with side effects. * network traffic can't flow until an altsetting is enabled. */ - usb_driver_claim_interface (&usbnet_driver, info->data, dev); + status = usb_driver_claim_interface (&usbnet_driver, info->data, dev); + if (status < 0) + return status; status = get_endpoints (dev, info->data); if (status < 0) { usb_driver_release_interface (&usbnet_driver, info->data); @@ -984,6 +986,8 @@ skb2 = skb_copy_expand (skb, (4 + 4*1) , padlen, flags); dev_kfree_skb_any (skb); skb = skb2; + if (!skb) + return NULL; } // attach the packet count to the header @@ -2338,7 +2342,7 @@ if (!((skb->len + sizeof *trailer) & 0x01)) *skb_put (skb, 1) = PAD_BYTE; trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer); - } else + } #endif /* CONFIG_USB_NET1080 */ usb_fill_bulk_urb (urb, dev->udev, dev->out, diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c --- a/drivers/usb/serial/belkin_sa.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/serial/belkin_sa.c Mon Aug 18 22:21:04 2003 @@ -189,8 +189,8 @@ priv->bad_flow_control = (dev->descriptor.bcdDevice <= 0x0206) ? 1 : 0; info("bcdDevice: %04x, bfc: %d", dev->descriptor.bcdDevice, priv->bad_flow_control); - init_waitqueue_head(&serial->port->write_wait); - usb_set_serial_port_data(serial->port, priv); + init_waitqueue_head(&serial->port[0]->write_wait); + usb_set_serial_port_data(serial->port[0], priv); return (0); } @@ -206,7 +206,7 @@ /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { /* My special items, the standard routines free my urbs */ - priv = usb_get_serial_port_data(&serial->port[i]); + priv = usb_get_serial_port_data(serial->port[i]); if (priv) kfree(priv); } diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/serial/cyberjack.c Mon Aug 18 22:21:05 2003 @@ -123,9 +123,9 @@ priv->rdtodo = 0; priv->wrfilled = 0; priv->wrsent = 0; - usb_set_serial_port_data(serial->port, priv); + usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port->write_wait); + init_waitqueue_head(&serial->port[0]->write_wait); return( 0 ); } @@ -138,8 +138,8 @@ for (i=0; i < serial->num_ports; ++i) { /* My special items, the standard routines free my urbs */ - kfree(usb_get_serial_port_data(&serial->port[i])); - usb_set_serial_port_data(&serial->port[i], NULL); + kfree(usb_get_serial_port_data(serial->port[i])); + usb_set_serial_port_data(serial->port[i], NULL); } } diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c --- a/drivers/usb/serial/digi_acceleport.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/serial/digi_acceleport.c Mon Aug 18 22:21:03 2003 @@ -1675,7 +1675,7 @@ /* set USB_DISABLE_SPD flag for write bulk urbs */ for( i=0; itype->num_ports+1; i++ ) { - port = &serial->port[i]; + port = serial->port[i]; port->write_urb->dev = port->serial->dev; @@ -1711,7 +1711,7 @@ GFP_KERNEL ); if( priv == (struct digi_port *)0 ) { while( --i >= 0 ) - kfree( usb_get_serial_port_data(&serial->port[i]) ); + kfree( usb_get_serial_port_data(serial->port[i]) ); return( 1 ); /* error */ } @@ -1734,9 +1734,9 @@ (void *)(&serial->port[i])); /* initialize write wait queue for this port */ - init_waitqueue_head( &serial->port[i].write_wait ); + init_waitqueue_head( &serial->port[i]->write_wait ); - usb_set_serial_port_data(&serial->port[i], priv); + usb_set_serial_port_data(serial->port[i], priv); } /* allocate serial private structure */ @@ -1744,14 +1744,14 @@ GFP_KERNEL ); if( serial_priv == (struct digi_serial *)0 ) { for( i=0; itype->num_ports+1; i++ ) - kfree( usb_get_serial_port_data(&serial->port[i]) ); + kfree( usb_get_serial_port_data(serial->port[i]) ); return( 1 ); /* error */ } /* initialize serial private structure */ spin_lock_init( &serial_priv->ds_serial_lock ); serial_priv->ds_oob_port_num = serial->type->num_ports; - serial_priv->ds_oob_port = &serial->port[serial_priv->ds_oob_port_num]; + serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; serial_priv->ds_device_started = 0; usb_set_serial_data(serial, serial_priv); @@ -1770,14 +1770,14 @@ /* stop reads and writes on all ports */ for( i=0; itype->num_ports+1; i++ ) { - usb_unlink_urb( serial->port[i].read_urb ); - usb_unlink_urb( serial->port[i].write_urb ); + usb_unlink_urb( serial->port[i]->read_urb ); + usb_unlink_urb( serial->port[i]->write_urb ); } /* free the private data structures for all ports */ /* number of regular ports + 1 for the out-of-band port */ for( i=0; itype->num_ports+1; i++ ) - kfree( usb_get_serial_port_data(&serial->port[i]) ); + kfree( usb_get_serial_port_data(serial->port[i]) ); kfree( usb_get_serial_data(serial) ); } @@ -1980,7 +1980,7 @@ if( status != 0 || line >= serial->type->num_ports ) continue; - port = &serial->port[line]; + port = serial->port[line]; if( port_paranoia_check( port, __FUNCTION__ ) || (priv=usb_get_serial_port_data(port)) == NULL ) diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c --- a/drivers/usb/serial/empeg.c Mon Aug 18 22:21:06 2003 +++ b/drivers/usb/serial/empeg.c Mon Aug 18 22:21:06 2003 @@ -464,8 +464,13 @@ dbg("%s", __FUNCTION__); - dbg("%s - Set config to 1", __FUNCTION__); - r = usb_set_configuration (serial->dev, 1); + if (serial->dev->actconfig->desc.bConfigurationValue != 1) { + err("active config #%d != 1 ??", + serial->dev->actconfig->desc.bConfigurationValue); + return -ENODEV; + } + dbg("%s - reset config", __FUNCTION__); + r = usb_reset_configuration (serial->dev); /* continue on with initialization */ return r; diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/serial/ftdi_sio.c Mon Aug 18 22:21:05 2003 @@ -981,7 +981,7 @@ /* Called from ftdi_SIO_startup, etc. */ static int ftdi_common_startup (struct usb_serial *serial) { - struct usb_serial_port *port = &serial->port[0]; + struct usb_serial_port *port = serial->port[0]; struct ftdi_private *priv; dbg("%s",__FUNCTION__); @@ -1022,7 +1022,7 @@ port->bulk_out_buffer = NULL; } - usb_set_serial_port_data(serial->port, priv); + usb_set_serial_port_data(serial->port[0], priv); return (0); } @@ -1042,7 +1042,7 @@ return (err); } - priv = usb_get_serial_port_data(serial->port); + priv = usb_get_serial_port_data(serial->port[0]); priv->chip_type = SIO; priv->baud_base = 12000000 / 16; priv->write_offset = 1; @@ -1063,7 +1063,7 @@ return (err); } - priv = usb_get_serial_port_data(serial->port); + priv = usb_get_serial_port_data(serial->port[0]); priv->chip_type = FT8U232AM; priv->baud_base = 48000000 / 2; /* Would be / 16, but FTDI supports 0.125, 0.25 and 0.5 divisor fractions! */ @@ -1083,7 +1083,7 @@ return (err); } - priv = usb_get_serial_port_data(serial->port); + priv = usb_get_serial_port_data(serial->port[0]); priv->chip_type = FT232BM; priv->baud_base = 48000000 / 2; /* Would be / 16, but FT232BM supports multiple of 0.125 divisor fractions! */ @@ -1103,7 +1103,7 @@ return (err); } - priv = usb_get_serial_port_data(serial->port); + priv = usb_get_serial_port_data(serial->port[0]); priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 77; priv->force_baud = B38400; @@ -1124,7 +1124,7 @@ return (err); } - priv = usb_get_serial_port_data(serial->port); + priv = usb_get_serial_port_data(serial->port[0]); priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 240; priv->force_baud = B38400; @@ -1146,7 +1146,7 @@ static void ftdi_shutdown (struct usb_serial *serial) { /* ftdi_shutdown */ - struct usb_serial_port *port = serial->port; + struct usb_serial_port *port = serial->port[0]; struct ftdi_private *priv = usb_get_serial_port_data(port); dbg("%s", __FUNCTION__); diff -Nru a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c --- a/drivers/usb/serial/generic.c Mon Aug 18 22:21:01 2003 +++ b/drivers/usb/serial/generic.c Mon Aug 18 22:21:01 2003 @@ -300,7 +300,7 @@ /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { - generic_cleanup (&serial->port[i]); + generic_cleanup(serial->port[i]); } } diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c --- a/drivers/usb/serial/io_edgeport.c Mon Aug 18 22:21:01 2003 +++ b/drivers/usb/serial/io_edgeport.c Mon Aug 18 22:21:01 2003 @@ -824,7 +824,7 @@ while ((position < length) && (portNumber < edge_serial->serial->num_ports)) { txCredits = data[position] | (data[position+1] << 8); if (txCredits) { - port = &edge_serial->serial->port[portNumber]; + port = edge_serial->serial->port[portNumber]; if (port_paranoia_check (port, __FUNCTION__) == 0) { edge_port = usb_get_serial_port_data(port); if (edge_port->open) { @@ -1031,7 +1031,7 @@ return -ENODEV; } if (edge_serial->interrupt_in_buffer == NULL) { - struct usb_serial_port *port0 = &serial->port[0]; + struct usb_serial_port *port0 = serial->port[0]; /* not set up yet, so do it now */ edge_serial->interrupt_in_buffer = port0->interrupt_in_buffer; @@ -2065,7 +2065,7 @@ /* spit this data back into the tty driver if this port is open */ if (rxLen) { - port = &edge_serial->serial->port[edge_serial->rxPort]; + port = edge_serial->serial->port[edge_serial->rxPort]; if (port_paranoia_check (port, __FUNCTION__) == 0) { edge_port = usb_get_serial_port_data(port); if (edge_port->open) { @@ -2118,7 +2118,7 @@ __u8 code = edge_serial->rxStatusCode; /* switch the port pointer to the one being currently talked about */ - port = &edge_serial->serial->port[edge_serial->rxPort]; + port = edge_serial->serial->port[edge_serial->rxPort]; if (port_paranoia_check (port, __FUNCTION__)) { return; } @@ -3018,8 +3018,8 @@ return -ENOMEM; } memset (edge_port, 0, sizeof(struct edgeport_port)); - edge_port->port = &serial->port[i]; - usb_set_serial_port_data(&serial->port[i], edge_port); + edge_port->port = serial->port[i]; + usb_set_serial_port_data(serial->port[i], edge_port); } return 0; @@ -3039,8 +3039,8 @@ /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { - kfree (usb_get_serial_port_data(&serial->port[i])); - usb_set_serial_port_data(&serial->port[i], NULL); + kfree (usb_get_serial_port_data(serial->port[i])); + usb_set_serial_port_data(serial->port[i], NULL); } kfree (usb_get_serial_data(serial)); usb_set_serial_data(serial, NULL); diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c --- a/drivers/usb/serial/io_ti.c Mon Aug 18 22:21:06 2003 +++ b/drivers/usb/serial/io_ti.c Mon Aug 18 22:21:06 2003 @@ -924,7 +924,7 @@ status = usb_bulk_msg (serial->dev, usb_sndbulkpipe(serial->dev, - serial->port[0].bulk_out_endpointAddress), + serial->port[0]->bulk_out_endpointAddress), buffer, length, num_sent, @@ -1682,7 +1682,7 @@ function = TIUMP_GET_FUNC_FROM_CODE (data[0]); dbg ("%s - port_number %d, function %d, info 0x%x", __FUNCTION__, port_number, function, data[1]); - port = &edge_serial->serial->port[port_number]; + port = edge_serial->serial->port[port_number]; if (port_paranoia_check (port, __FUNCTION__)) { dbg ("%s - change found for port that is not present", __FUNCTION__); @@ -1945,7 +1945,7 @@ edge_serial = edge_port->edge_serial; if (edge_serial->num_ports_open == 0) { /* we are the first port to be opened, let's post the interrupt urb */ - urb = edge_serial->serial->port[0].interrupt_in_urb; + urb = edge_serial->serial->port[0]->interrupt_in_urb; if (!urb) { dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __FUNCTION__); return -EINVAL; @@ -2034,7 +2034,7 @@ --edge_port->edge_serial->num_ports_open; if (edge_port->edge_serial->num_ports_open <= 0) { /* last port is now closed, let's shut down our interrupt urb */ - usb_unlink_urb (serial->port[0].interrupt_in_urb); + usb_unlink_urb (serial->port[0]->interrupt_in_urb); edge_port->edge_serial->num_ports_open = 0; } edge_port->close_pending = 0; @@ -2603,9 +2603,9 @@ return -ENOMEM; } memset (edge_port, 0, sizeof(struct edgeport_port)); - edge_port->port = &serial->port[i]; + edge_port->port = serial->port[i]; edge_port->edge_serial = edge_serial; - usb_set_serial_port_data(&serial->port[i], edge_port); + usb_set_serial_port_data(serial->port[i], edge_port); } return 0; @@ -2618,8 +2618,8 @@ dbg ("%s", __FUNCTION__); for (i=0; i < serial->num_ports; ++i) { - kfree (usb_get_serial_port_data(&serial->port[i])); - usb_set_serial_port_data(&serial->port[i], NULL); + kfree (usb_get_serial_port_data(serial->port[i])); + usb_set_serial_port_data(serial->port[i], NULL); } kfree (usb_get_serial_data(serial)); usb_set_serial_data(serial, NULL); diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/serial/ipaq.c Mon Aug 18 22:21:05 2003 @@ -555,8 +555,12 @@ static int ipaq_startup(struct usb_serial *serial) { dbg("%s", __FUNCTION__); - usb_set_configuration(serial->dev, 1); - return 0; + if (serial->dev->actconfig->desc.bConfigurationValue != 1) { + err("active config #%d != 1 ??", + serial->dev->actconfig->desc.bConfigurationValue); + return -ENODEV; + } + return usb_reset_configuration (serial->dev); } static void ipaq_shutdown(struct usb_serial *serial) diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c --- a/drivers/usb/serial/keyspan.c Mon Aug 18 22:21:01 2003 +++ b/drivers/usb/serial/keyspan.c Mon Aug 18 22:21:01 2003 @@ -523,7 +523,7 @@ dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port); goto exit; } - port = &serial->port[msg->port]; + port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); /* Update handshaking pin state information */ @@ -658,7 +658,7 @@ dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port); goto exit; } - port = &serial->port[msg->port]; + port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); /* Update handshaking pin state information */ @@ -701,7 +701,7 @@ serial = (struct usb_serial *) urb->context; for (i = 0; i < serial->num_ports; ++i) { - port = &serial->port[i]; + port = serial->port[i]; p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { @@ -750,7 +750,7 @@ dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->portNumber); goto exit; } - port = &serial->port[msg->portNumber]; + port = serial->port[msg->portNumber]; p_priv = usb_get_serial_port_data(port); /* Update handshaking pin state information */ @@ -1188,7 +1188,7 @@ /* Setup endpoints for each port specific thing */ for (i = 0; i < d_details->num_ports; i ++) { - port = &serial->port[i]; + port = serial->port[i]; p_priv = usb_get_serial_port_data(port); /* Do indat endpoints first, once for each flip */ @@ -1893,7 +1893,7 @@ /* Now setup per port private data */ for (i = 0; i < serial->num_ports; i++) { - port = &serial->port[i]; + port = serial->port[i]; p_priv = kmalloc(sizeof(struct keyspan_port_private), GFP_KERNEL); if (!p_priv) { dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __FUNCTION__, i); @@ -1929,7 +1929,7 @@ stop_urb(s_priv->instat_urb); stop_urb(s_priv->glocont_urb); for (i = 0; i < serial->num_ports; ++i) { - port = &serial->port[i]; + port = serial->port[i]; p_priv = usb_get_serial_port_data(port); stop_urb(p_priv->inack_urb); stop_urb(p_priv->outcont_urb); @@ -1945,7 +1945,7 @@ if (s_priv->glocont_urb) usb_free_urb(s_priv->glocont_urb); for (i = 0; i < serial->num_ports; ++i) { - port = &serial->port[i]; + port = serial->port[i]; p_priv = usb_get_serial_port_data(port); if (p_priv->inack_urb) usb_free_urb(p_priv->inack_urb); @@ -1965,7 +1965,7 @@ /* dbg("Freeing port->private."); */ /* Now free per port private data */ for (i = 0; i < serial->num_ports; i++) { - port = &serial->port[i]; + port = serial->port[i]; kfree(usb_get_serial_port_data(port)); } } diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c --- a/drivers/usb/serial/keyspan_pda.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/serial/keyspan_pda.c Mon Aug 18 22:21:04 2003 @@ -264,7 +264,7 @@ case 0: /* rest of message is rx data */ if (urb->actual_length) { - tty = serial->port[0].tty; + tty = serial->port[0]->tty; for (i = 1; i < urb->actual_length ; ++i) { tty_insert_flip_char(tty, data[i], 0); } @@ -278,7 +278,7 @@ case 1: /* modemline change */ break; case 2: /* tx unthrottle interrupt */ - tty = serial->port[0].tty; + tty = serial->port[0]->tty; priv->tx_throttled = 0; /* queue up a wakeup at scheduler time */ schedule_work(&priv->wakeup_work); @@ -801,8 +801,8 @@ priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); if (!priv) return (1); /* error */ - usb_set_serial_port_data(&serial->port[0], priv); - init_waitqueue_head(&serial->port[0].write_wait); + usb_set_serial_port_data(serial->port[0], priv); + init_waitqueue_head(&serial->port[0]->write_wait); INIT_WORK(&priv->wakeup_work, (void *)keyspan_pda_wakeup_write, (void *)(&serial->port[0])); INIT_WORK(&priv->unthrottle_work, @@ -815,7 +815,7 @@ { dbg("%s", __FUNCTION__); - kfree(usb_get_serial_port_data(&serial->port[0])); + kfree(usb_get_serial_port_data(serial->port[0])); } #ifdef KEYSPAN diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c --- a/drivers/usb/serial/kl5kusb105.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/serial/kl5kusb105.c Mon Aug 18 22:21:04 2003 @@ -290,7 +290,7 @@ priv->bytes_in = 0; priv->bytes_out = 0; - usb_set_serial_port_data(&serial->port[i], priv); + usb_set_serial_port_data(serial->port[i], priv); spin_lock_init (&priv->lock); for (i=0; itermios is left uninitalized until port opening */ - init_waitqueue_head(&serial->port[i].write_wait); + init_waitqueue_head(&serial->port[i]->write_wait); } return (0); @@ -327,7 +327,7 @@ /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { - struct klsi_105_private *priv = usb_get_serial_port_data(&serial->port[i]); + struct klsi_105_private *priv = usb_get_serial_port_data(serial->port[i]); unsigned long flags; if (priv) { @@ -354,7 +354,7 @@ spin_unlock_irqrestore (&priv->lock, flags); kfree(priv); - usb_set_serial_port_data(&serial->port[i], NULL); + usb_set_serial_port_data(serial->port[i], NULL); } } } /* klsi_105_shutdown */ diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c --- a/drivers/usb/serial/kobil_sct.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/serial/kobil_sct.c Mon Aug 18 22:21:05 2003 @@ -177,7 +177,7 @@ printk(KERN_DEBUG "KOBIL KAAN SIM detected\n"); break; } - usb_set_serial_port_data(serial->port, priv); + usb_set_serial_port_data(serial->port[0], priv); // search for the necessary endpoints pdev = serial->dev; @@ -206,14 +206,14 @@ static void kobil_shutdown (struct usb_serial *serial) { int i; - dbg("%s - port %d", __FUNCTION__, serial->port->number); + dbg("%s - port %d", __FUNCTION__, serial->port[0]->number); for (i=0; i < serial->num_ports; ++i) { - while (serial->port[i].open_count > 0) { - kobil_close (&serial->port[i], NULL); + while (serial->port[i]->open_count > 0) { + kobil_close (serial->port[i], NULL); } - kfree(usb_get_serial_port_data(&serial->port[i])); - usb_set_serial_port_data(&serial->port[i], NULL); + kfree(usb_get_serial_port_data(serial->port[i])); + usb_set_serial_port_data(serial->port[i], NULL); } } diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c --- a/drivers/usb/serial/mct_u232.c Mon Aug 18 22:21:04 2003 +++ b/drivers/usb/serial/mct_u232.c Mon Aug 18 22:21:04 2003 @@ -320,9 +320,9 @@ priv->control_state = 0; priv->last_lsr = 0; priv->last_msr = 0; - usb_set_serial_port_data(serial->port, priv); + usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port->write_wait); + init_waitqueue_head(&serial->port[0]->write_wait); return (0); } /* mct_u232_startup */ @@ -337,7 +337,7 @@ for (i=0; i < serial->num_ports; ++i) { /* My special items, the standard routines free my urbs */ - priv = usb_get_serial_port_data(&serial->port[i]); + priv = usb_get_serial_port_data(serial->port[i]); if (priv) kfree(priv); } @@ -393,7 +393,7 @@ { /* Puh, that's dirty */ struct usb_serial_port *rport; - rport = &serial->port[1]; + rport = serial->port[1]; rport->tty = port->tty; usb_set_serial_port_data(rport, usb_get_serial_port_data(port)); port->read_urb = rport->interrupt_in_urb; diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c --- a/drivers/usb/serial/omninet.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/serial/omninet.c Mon Aug 18 22:21:05 2003 @@ -170,7 +170,7 @@ } usb_set_serial_port_data(port, od); - wport = &serial->port[1]; + wport = serial->port[1]; wport->tty = port->tty; /* Start reading from the device */ @@ -201,7 +201,7 @@ return; if (serial->dev) { - wport = &serial->port[1]; + wport = serial->port[1]; usb_unlink_urb (wport->write_urb); usb_unlink_urb (port->read_urb); } @@ -271,7 +271,7 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; - struct usb_serial_port *wport = &serial->port[1]; + struct usb_serial_port *wport = serial->port[1]; struct omninet_data *od = usb_get_serial_port_data(port); struct omninet_header *header = (struct omninet_header *) wport->write_urb->transfer_buffer; @@ -326,7 +326,7 @@ static int omninet_write_room (struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - struct usb_serial_port *wport = &serial->port[1]; + struct usb_serial_port *wport = serial->port[1]; int room = 0; // Default: no room diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/serial/pl2303.c Mon Aug 18 22:21:03 2003 @@ -186,7 +186,7 @@ return -ENOMEM; memset (priv, 0x00, sizeof (struct pl2303_private)); spin_lock_init(&priv->lock); - usb_set_serial_port_data(&serial->port[i], priv); + usb_set_serial_port_data(serial->port[i], priv); } return 0; } @@ -592,8 +592,8 @@ dbg("%s", __FUNCTION__); for (i = 0; i < serial->num_ports; ++i) { - kfree (usb_get_serial_port_data(&serial->port[i])); - usb_set_serial_port_data(&serial->port[i], NULL); + kfree (usb_get_serial_port_data(serial->port[i])); + usb_set_serial_port_data(serial->port[i], NULL); } } diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c Mon Aug 18 22:21:03 2003 +++ b/drivers/usb/serial/usb-serial.c Mon Aug 18 22:21:03 2003 @@ -466,7 +466,7 @@ /* set up our port structure making the tty driver remember our port object, and us it */ portNumber = tty->index - serial->minor; - port = &serial->port[portNumber]; + port = serial->port[portNumber]; tty->driver_data = port; port->tty = tty; @@ -482,10 +482,7 @@ if (port->open_count == 1) { /* only call the device specific open if this * is the first time the port is opened */ - if (serial->type->open) - retval = serial->type->open(port, filp); - else - retval = usb_serial_generic_open(port, filp); + retval = serial->type->open(port, filp); if (retval) { port->open_count = 0; module_put(serial->type->owner); @@ -507,10 +504,7 @@ if (port->open_count <= 0) { /* only call the device specific close if this * port is being closed by the last owner */ - if (port->serial->type->close) - port->serial->type->close(port, filp); - else - usb_serial_generic_close(port, filp); + port->serial->type->close(port, filp); port->open_count = 0; } @@ -552,11 +546,8 @@ goto exit; } - /* pass on to the driver specific version of this function if it is available */ - if (serial->type->write) - retval = serial->type->write(port, from_user, buf, count); - else - retval = usb_serial_generic_write(port, from_user, buf, count); + /* pass on to the driver specific version of this function */ + retval = serial->type->write(port, from_user, buf, count); exit: return retval; @@ -578,11 +569,8 @@ goto exit; } - /* pass on to the driver specific version of this function if it is available */ - if (serial->type->write_room) - retval = serial->type->write_room(port); - else - retval = usb_serial_generic_write_room(port); + /* pass on to the driver specific version of this function */ + retval = serial->type->write_room(port); exit: return retval; @@ -604,11 +592,8 @@ goto exit; } - /* pass on to the driver specific version of this function if it is available */ - if (serial->type->chars_in_buffer) - retval = serial->type->chars_in_buffer(port); - else - retval = usb_serial_generic_chars_in_buffer(port); + /* pass on to the driver specific version of this function */ + retval = serial->type->chars_in_buffer(port); exit: return retval; @@ -736,10 +721,7 @@ { dbg ("%s", __FUNCTION__); - if (serial->type->shutdown) - serial->type->shutdown(serial); - else - usb_serial_generic_shutdown(serial); + serial->type->shutdown(serial); } static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) @@ -863,13 +845,13 @@ struct usb_serial_port *port; int i; - dbg ("%s", __FUNCTION__); + dbg ("%s - %s", __FUNCTION__, kobj->name); serial = to_usb_serial(kobj); /* fail all future close/read/write/ioctl/etc calls */ for (i = 0; i < serial->num_ports; ++i) { - port = &serial->port[i]; + port = serial->port[i]; if (port->tty != NULL) { port->tty->driver_data = NULL; while (port->open_count > 0) { @@ -881,41 +863,41 @@ serial_shutdown (serial); + /* return the minor range that this device had */ + return_serial(serial); + for (i = 0; i < serial->num_ports; ++i) - device_unregister(&serial->port[i].dev); + serial->port[i]->open_count = 0; + /* the ports are cleaned up and released in port_release() */ for (i = 0; i < serial->num_ports; ++i) - serial->port[i].open_count = 0; + device_unregister(&serial->port[i]->dev); - for (i = 0; i < serial->num_bulk_in; ++i) { - port = &serial->port[i]; - if (port->read_urb) { - usb_unlink_urb (port->read_urb); - usb_free_urb (port->read_urb); - } - if (port->bulk_in_buffer) - kfree (port->bulk_in_buffer); - } - for (i = 0; i < serial->num_bulk_out; ++i) { - port = &serial->port[i]; - if (port->write_urb) { - usb_unlink_urb (port->write_urb); - usb_free_urb (port->write_urb); - } - if (port->bulk_out_buffer) - kfree (port->bulk_out_buffer); - } - for (i = 0; i < serial->num_interrupt_in; ++i) { - port = &serial->port[i]; - if (port->interrupt_in_urb) { - usb_unlink_urb (port->interrupt_in_urb); - usb_free_urb (port->interrupt_in_urb); + /* If this is a "fake" port, we have to clean it up here, as it will + * not get cleaned up in port_release() as it was never registered with + * the driver core */ + if (serial->num_ports < serial->num_port_pointers) { + for (i = serial->num_ports; i < serial->num_port_pointers; ++i) { + port = serial->port[i]; + if (!port) + continue; + if (port->read_urb) { + usb_unlink_urb(port->read_urb); + usb_free_urb(port->read_urb); + } + if (port->write_urb) { + usb_unlink_urb(port->write_urb); + usb_free_urb(port->write_urb); + } + if (port->interrupt_in_urb) { + usb_unlink_urb(port->interrupt_in_urb); + usb_free_urb(port->interrupt_in_urb); + } + kfree(port->bulk_in_buffer); + kfree(port->bulk_out_buffer); + kfree(port->interrupt_in_buffer); } - if (port->interrupt_in_buffer) - kfree (port->interrupt_in_buffer); } - /* return the minor range that this device had */ - return_serial (serial); usb_put_dev(serial->dev); @@ -927,6 +909,29 @@ .release = destroy_serial, }; +static void port_release(struct device *dev) +{ + struct usb_serial_port *port = to_usb_serial_port(dev); + + dbg ("%s - %s", __FUNCTION__, dev->bus_id); + if (port->read_urb) { + usb_unlink_urb(port->read_urb); + usb_free_urb(port->read_urb); + } + if (port->write_urb) { + usb_unlink_urb(port->write_urb); + usb_free_urb(port->write_urb); + } + if (port->interrupt_in_urb) { + usb_unlink_urb(port->interrupt_in_urb); + usb_free_urb(port->interrupt_in_urb); + } + kfree(port->bulk_in_buffer); + kfree(port->bulk_out_buffer); + kfree(port->interrupt_in_buffer); + kfree(port); +} + static struct usb_serial * create_serial (struct usb_device *dev, struct usb_interface *interface, struct usb_serial_device_type *type) @@ -1124,10 +1129,29 @@ serial->num_bulk_out = num_bulk_out; serial->num_interrupt_in = num_interrupt_in; + /* create our ports, we need as many as the max endpoints */ + /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ + max_endpoints = max(num_bulk_in, num_bulk_out); + max_endpoints = max(max_endpoints, num_interrupt_in); + max_endpoints = max(max_endpoints, (int)serial->num_ports); + serial->num_port_pointers = max_endpoints; + dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); + for (i = 0; i < max_endpoints; ++i) { + port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL); + if (!port) + goto probe_error; + memset(port, 0x00, sizeof(struct usb_serial_port)); + port->number = i + serial->minor; + port->serial = serial; + port->magic = USB_SERIAL_PORT_MAGIC; + INIT_WORK(&port->work, usb_serial_port_softint, port); + serial->port[i] = port; + } + /* set up the endpoint information */ for (i = 0; i < num_bulk_in; ++i) { endpoint = bulk_in_endpoint[i]; - port = &serial->port[i]; + port = serial->port[i]; port->read_urb = usb_alloc_urb (0, GFP_KERNEL); if (!port->read_urb) { dev_err(&interface->dev, "No free urbs available\n"); @@ -1144,15 +1168,13 @@ usb_rcvbulkpipe (dev, endpoint->bEndpointAddress), port->bulk_in_buffer, buffer_size, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - usb_serial_generic_read_bulk_callback), + serial->type->read_bulk_callback, port); } for (i = 0; i < num_bulk_out; ++i) { endpoint = bulk_out_endpoint[i]; - port = &serial->port[i]; + port = serial->port[i]; port->write_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->write_urb) { dev_err(&interface->dev, "No free urbs available\n"); @@ -1170,15 +1192,13 @@ usb_sndbulkpipe (dev, endpoint->bEndpointAddress), port->bulk_out_buffer, buffer_size, - ((serial->type->write_bulk_callback) ? - serial->type->write_bulk_callback : - usb_serial_generic_write_bulk_callback), + serial->type->write_bulk_callback, port); } for (i = 0; i < num_interrupt_in; ++i) { endpoint = interrupt_in_endpoint[i]; - port = &serial->port[i]; + port = serial->port[i]; port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->interrupt_in_urb) { dev_err(&interface->dev, "No free urbs available\n"); @@ -1199,20 +1219,6 @@ endpoint->bInterval); } - /* initialize some parts of the port structures */ - /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ - max_endpoints = max(num_bulk_in, num_bulk_out); - max_endpoints = max(max_endpoints, num_interrupt_in); - max_endpoints = max(max_endpoints, (int)serial->num_ports); - dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); - for (i = 0; i < max_endpoints; ++i) { - port = &serial->port[i]; - port->number = i + serial->minor; - port->serial = serial; - port->magic = USB_SERIAL_PORT_MAGIC; - INIT_WORK(&port->work, usb_serial_port_softint, port); - } - /* if this device type has an attach function, call it */ if (type->attach) { if (!try_module_get(type->owner)) { @@ -1232,10 +1238,11 @@ /* register all of the individual ports with the driver core */ for (i = 0; i < num_ports; ++i) { - port = &serial->port[i]; + port = serial->port[i]; port->dev.parent = &serial->dev->dev; port->dev.driver = NULL; port->dev.bus = &usb_serial_bus_type; + port->dev.release = &port_release; snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number); dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id); @@ -1249,34 +1256,38 @@ usb_set_intfdata (interface, serial); return 0; - probe_error: for (i = 0; i < num_bulk_in; ++i) { - port = &serial->port[i]; + port = serial->port[i]; + if (!port) + continue; if (port->read_urb) usb_free_urb (port->read_urb); - if (port->bulk_in_buffer) - kfree (port->bulk_in_buffer); + kfree(port->bulk_in_buffer); } for (i = 0; i < num_bulk_out; ++i) { - port = &serial->port[i]; + port = serial->port[i]; + if (!port) + continue; if (port->write_urb) usb_free_urb (port->write_urb); - if (port->bulk_out_buffer) - kfree (port->bulk_out_buffer); + kfree(port->bulk_out_buffer); } for (i = 0; i < num_interrupt_in; ++i) { - port = &serial->port[i]; + port = serial->port[i]; + if (!port) + continue; if (port->interrupt_in_urb) usb_free_urb (port->interrupt_in_urb); - if (port->interrupt_in_buffer) - kfree (port->interrupt_in_buffer); + kfree(port->interrupt_in_buffer); } /* return the minor range that this device had */ return_serial (serial); /* free up any memory that we allocated */ + for (i = 0; i < serial->num_port_pointers; ++i) + kfree(serial->port[i]); kfree (serial); return -EIO; } @@ -1396,10 +1407,32 @@ module_init(usb_serial_init); module_exit(usb_serial_exit); +#define set_to_generic_if_null(type, function) \ + do { \ + if (!type->function) { \ + type->function = usb_serial_generic_##function; \ + dbg("Had to override the " #function \ + " usb serial operation with the generic one.");\ + } \ + } while (0) + +static void fixup_generic(struct usb_serial_device_type *device) +{ + set_to_generic_if_null(device, open); + set_to_generic_if_null(device, write); + set_to_generic_if_null(device, close); + set_to_generic_if_null(device, write_room); + set_to_generic_if_null(device, chars_in_buffer); + set_to_generic_if_null(device, read_bulk_callback); + set_to_generic_if_null(device, write_bulk_callback); + set_to_generic_if_null(device, shutdown); +} int usb_serial_register(struct usb_serial_device_type *new_device) { int retval; + + fixup_generic(new_device); /* Add this device to our list of devices */ list_add(&new_device->driver_list, &usb_serial_driver_list); diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h --- a/drivers/usb/serial/usb-serial.h Mon Aug 18 22:21:06 2003 +++ b/drivers/usb/serial/usb-serial.h Mon Aug 18 22:21:06 2003 @@ -156,12 +156,13 @@ struct usb_interface * interface; unsigned char minor; unsigned char num_ports; + unsigned char num_port_pointers; char num_interrupt_in; char num_bulk_in; char num_bulk_out; __u16 vendor; __u16 product; - struct usb_serial_port port[MAX_NUM_PORTS]; + struct usb_serial_port * port[MAX_NUM_PORTS]; struct kobject kobj; void * private; }; diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/serial/visor.c Mon Aug 18 22:21:02 2003 @@ -763,8 +763,14 @@ dbg("%s", __FUNCTION__); - dbg("%s - Set config to 1", __FUNCTION__); - usb_set_configuration (serial->dev, 1); + if (serial->dev->actconfig->desc.bConfigurationValue != 1) { + err("active config #%d != 1 ??", + serial->dev->actconfig->desc.bConfigurationValue); + return -ENODEV; + } + dbg("%s - reset config", __FUNCTION__); + retval = usb_reset_configuration (serial->dev); + if (id->driver_info) { startup = (void *)id->driver_info; @@ -844,25 +850,25 @@ * "virtual serial port". So let's force the endpoints to be * where we want them to be. */ for (i = serial->num_bulk_in; i < serial->num_ports; ++i) { - port = &serial->port[i]; - port->read_urb = serial->port[0].read_urb; - port->bulk_in_endpointAddress = serial->port[0].bulk_in_endpointAddress; - port->bulk_in_buffer = serial->port[0].bulk_in_buffer; + port = serial->port[i]; + port->read_urb = serial->port[0]->read_urb; + port->bulk_in_endpointAddress = serial->port[0]->bulk_in_endpointAddress; + port->bulk_in_buffer = serial->port[0]->bulk_in_buffer; } for (i = serial->num_bulk_out; i < serial->num_ports; ++i) { - port = &serial->port[i]; - port->write_urb = serial->port[0].write_urb; - port->bulk_out_size = serial->port[0].bulk_out_size; - port->bulk_out_endpointAddress = serial->port[0].bulk_out_endpointAddress; - port->bulk_out_buffer = serial->port[0].bulk_out_buffer; + port = serial->port[i]; + port->write_urb = serial->port[0]->write_urb; + port->bulk_out_size = serial->port[0]->bulk_out_size; + port->bulk_out_endpointAddress = serial->port[0]->bulk_out_endpointAddress; + port->bulk_out_buffer = serial->port[0]->bulk_out_buffer; } for (i = serial->num_interrupt_in; i < serial->num_ports; ++i) { - port = &serial->port[i]; - port->interrupt_in_urb = serial->port[0].interrupt_in_urb; - port->interrupt_in_endpointAddress = serial->port[0].interrupt_in_endpointAddress; - port->interrupt_in_buffer = serial->port[0].interrupt_in_buffer; + port = serial->port[i]; + port->interrupt_in_urb = serial->port[0]->interrupt_in_urb; + port->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; + port->interrupt_in_buffer = serial->port[0]->interrupt_in_buffer; } return 0; diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c --- a/drivers/usb/serial/whiteheat.c Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/serial/whiteheat.c Mon Aug 18 22:21:02 2003 @@ -361,7 +361,7 @@ struct whiteheat_urb_wrap *wrap; struct list_head *tmp; - command_port = &serial->port[COMMAND_PORT]; + command_port = serial->port[COMMAND_PORT]; pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress); /* @@ -400,7 +400,7 @@ DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev); for (i = 0; i < serial->num_ports; i++) { - port = &serial->port[i]; + port = serial->port[i]; info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); if (info == NULL) { @@ -496,7 +496,7 @@ no_command_private: for (i = serial->num_ports - 1; i >= 0; i--) { - port = &serial->port[i]; + port = serial->port[i]; info = usb_get_serial_port_data(port); for (j = urb_pool_size - 1; j >= 0; j--) { tmp = list_first(&info->tx_urbs_free); @@ -543,11 +543,11 @@ dbg("%s", __FUNCTION__); /* free up our private data for our command port */ - command_port = &serial->port[COMMAND_PORT]; + command_port = serial->port[COMMAND_PORT]; kfree (usb_get_serial_port_data(command_port)); for (i = 0; i < serial->num_ports; i++) { - port = &serial->port[i]; + port = serial->port[i]; info = usb_get_serial_port_data(port); list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) { list_del(tmp); @@ -1119,7 +1119,7 @@ dbg("%s - command %d", __FUNCTION__, command); - command_port = &port->serial->port[COMMAND_PORT]; + command_port = port->serial->port[COMMAND_PORT]; command_info = usb_get_serial_port_data(command_port); spin_lock_irqsave(&command_info->lock, flags); command_info->command_finished = FALSE; @@ -1323,7 +1323,7 @@ unsigned long flags; int retval = 0; - command_port = &serial->port[COMMAND_PORT]; + command_port = serial->port[COMMAND_PORT]; command_info = usb_get_serial_port_data(command_port); spin_lock_irqsave(&command_info->lock, flags); if (!command_info->port_running) { @@ -1351,7 +1351,7 @@ struct whiteheat_command_private *command_info; unsigned long flags; - command_port = &serial->port[COMMAND_PORT]; + command_port = serial->port[COMMAND_PORT]; command_info = usb_get_serial_port_data(command_port); spin_lock_irqsave(&command_info->lock, flags); command_info->port_running--; diff -Nru a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c --- a/drivers/usb/storage/sddr09.c Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/storage/sddr09.c Mon Aug 18 22:21:05 2003 @@ -1127,7 +1127,7 @@ char *vaddr = kmalloc(alloc_req, GFP_NOIO); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,3) sg[i].page = virt_to_page(vaddr); - sg[i].offset = ((unsigned long)vaddr & ~PAGE_MASK); + sg[i].offset = offset_in_page(vaddr); #else sg[i].address = vaddr; #endif diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h Mon Aug 18 22:21:05 2003 +++ b/drivers/usb/storage/unusual_devs.h Mon Aug 18 22:21:05 2003 @@ -388,6 +388,12 @@ US_FL_SINGLE_LUN ), #endif +/* Submitted by Benny Sjostrand */ +UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001, + "Minolta", + "Dimage F300", + US_SC_SCSI, US_PR_BULK, NULL, 0 ), + UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara", "FlashGate SmartMedia", diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c Mon Aug 18 22:21:02 2003 +++ b/drivers/usb/storage/usb.c Mon Aug 18 22:21:02 2003 @@ -921,9 +921,14 @@ if (us->protocol == US_PR_EUSB_SDDR09 || us->protocol == US_PR_DPCM_USB) { /* set the configuration -- STALL is an acceptable response here */ - result = usb_set_configuration(us->pusb_dev, 1); + if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { + US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev + ->actconfig->desc.bConfigurationValue); + goto BadDevice; + } + result = usb_reset_configuration(us->pusb_dev); - US_DEBUGP("Result from usb_set_configuration is %d\n", result); + US_DEBUGP("Result of usb_reset_configuration is %d\n", result); if (result == -EPIPE) { US_DEBUGP("-- stall on control interface\n"); } else if (result != 0) { @@ -978,16 +983,9 @@ static void storage_disconnect(struct usb_interface *intf) { struct us_data *us = usb_get_intfdata(intf); - struct scsi_device *sdev; US_DEBUGP("storage_disconnect() called\n"); - /* Set devices offline -- need host lock for this */ - scsi_lock(us->host); - list_for_each_entry(sdev, &us->host->my_devices, siblings) - sdev->online = 0; - scsi_unlock(us->host); - /* Prevent new USB transfers and stop the current command */ set_bit(US_FLIDX_DISCONNECTING, &us->flags); usb_stor_stop_transport(us); @@ -995,12 +993,7 @@ /* Dissociate from the USB device */ dissociate_dev(us); - /* Begin the SCSI host removal sequence */ - if (scsi_remove_host(us->host)) { - US_DEBUGP("-- SCSI refused to remove the host\n"); - BUG(); - return; - } + scsi_remove_host(us->host); /* TODO: somehow, wait for the device to * be 'idle' (tasklet completion) */ diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c --- a/drivers/video/cfbimgblt.c Mon Aug 18 22:21:03 2003 +++ b/drivers/video/cfbimgblt.c Mon Aug 18 22:21:03 2003 @@ -325,7 +325,7 @@ else slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index); - } else if (image->depth == bpp) + } else if (image->depth <= bpp) color_imageblit(image, p, dst1, start_index, pitch_index); } diff -Nru a/drivers/video/cg14.c b/drivers/video/cg14.c --- a/drivers/video/cg14.c Mon Aug 18 22:21:06 2003 +++ b/drivers/video/cg14.c Mon Aug 18 22:21:06 2003 @@ -34,6 +34,7 @@ static int cg14_mmap(struct fb_info *, struct file *, struct vm_area_struct *); static int cg14_ioctl(struct inode *, struct file *, unsigned int, unsigned long, struct fb_info *); +static int cg14_pan_display(struct fb_var_screeninfo *, struct fb_info *); /* * Frame buffer operations @@ -42,6 +43,7 @@ static struct fb_ops cg14_ops = { .owner = THIS_MODULE, .fb_setcolreg = cg14_setcolreg, + .fb_pan_display = cg14_pan_display, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, @@ -213,6 +215,23 @@ val = sbus_readb(®s->mcr); val &= ~(CG14_MCR_PIXMODE_MASK); sbus_writeb(val, ®s->mcr); +} + +static int cg14_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct cg14_par *par = (struct cg14_par *) info->par; + unsigned long flags; + + /* We just use this to catch switches out of + * graphics mode. + */ + spin_lock_irqsave(&par->lock, flags); + __cg14_reset(par); + spin_unlock_irqrestore(&par->lock, flags); + + if (var->xoffset || var->yoffset || var->vmode) + return -EINVAL; + return 0; } /** diff -Nru a/drivers/video/ffb.c b/drivers/video/ffb.c --- a/drivers/video/ffb.c Mon Aug 18 22:21:06 2003 +++ b/drivers/video/ffb.c Mon Aug 18 22:21:06 2003 @@ -40,6 +40,7 @@ static int ffb_mmap(struct fb_info *, struct file *, struct vm_area_struct *); static int ffb_ioctl(struct inode *, struct file *, unsigned int, unsigned long, struct fb_info *); +static int ffb_pan_display(struct fb_var_screeninfo *, struct fb_info *); /* * Frame buffer operations @@ -49,6 +50,7 @@ .owner = THIS_MODULE, .fb_setcolreg = ffb_setcolreg, .fb_blank = ffb_blank, + .fb_pan_display = ffb_pan_display, .fb_fillrect = ffb_fillrect, .fb_copyarea = ffb_copyarea, .fb_imageblit = ffb_imageblit, @@ -481,6 +483,20 @@ upa_writel(par->bg_cache, &fbc->bg); FFBWait(par); spin_unlock_irqrestore(&par->lock, flags); +} + +static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct ffb_par *par = (struct ffb_par *) info->par; + + /* We just use this to catch switches out of + * graphics mode. + */ + ffb_switch_from_graph(par); + + if (var->xoffset || var->yoffset || var->vmode) + return -EINVAL; + return 0; } /** diff -Nru a/drivers/video/leo.c b/drivers/video/leo.c --- a/drivers/video/leo.c Mon Aug 18 22:21:05 2003 +++ b/drivers/video/leo.c Mon Aug 18 22:21:05 2003 @@ -35,6 +35,7 @@ static int leo_mmap(struct fb_info *, struct file *, struct vm_area_struct *); static int leo_ioctl(struct inode *, struct file *, unsigned int, unsigned long, struct fb_info *); +static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *); /* * Frame buffer operations @@ -44,6 +45,7 @@ .owner = THIS_MODULE, .fb_setcolreg = leo_setcolreg, .fb_blank = leo_blank, + .fb_pan_display = leo_pan_display, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, @@ -408,15 +410,14 @@ } -static void leo_init_hw(struct fb_info *info) +static void leo_switch_from_graph(struct fb_info *info) { struct leo_par *par = (struct leo_par *) info->par; struct leo_ld *ss = (struct leo_ld *) par->ld_ss0; + unsigned long flags; u32 val; - val = sbus_readl(&par->ld_ss1->ss1_misc); - val |= LEO_SS1_MISC_ENABLE; - sbus_writel(val, &par->ld_ss1->ss1_misc); + spin_lock_irqsave(&par->lock, flags); par->extent = ((info->var.xres - 1) | ((info->var.yres - 1) << 16)); @@ -437,6 +438,32 @@ do { val = sbus_readl(&par->lc_ss0_usr->csr); } while (val & 0x20000000); + + spin_unlock_irqrestore(&par->lock, flags); +} + +static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + /* We just use this to catch switches out of + * graphics mode. + */ + leo_switch_from_graph(info); + + if (var->xoffset || var->yoffset || var->vmode) + return -EINVAL; + return 0; +} + +static void leo_init_hw(struct fb_info *info) +{ + struct leo_par *par = (struct leo_par *) info->par; + u32 val; + + val = sbus_readl(&par->ld_ss1->ss1_misc); + val |= LEO_SS1_MISC_ENABLE; + sbus_writel(val, &par->ld_ss1->ss1_misc); + + leo_switch_from_graph(info); } static void leo_fixup_var_rgb(struct fb_var_screeninfo *var) diff -Nru a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c --- a/drivers/video/matrox/i2c-matroxfb.c Mon Aug 18 22:21:03 2003 +++ b/drivers/video/matrox/i2c-matroxfb.c Mon Aug 18 22:21:03 2003 @@ -111,7 +111,7 @@ b->mask.data = data; b->mask.clock = clock; b->adapter = matrox_i2c_adapter_template; - snprintf(b->adapter.dev.name, DEVICE_NAME_SIZE, name, + snprintf(b->adapter.name, DEVICE_NAME_SIZE, name, minfo->fbcon.node); i2c_set_adapdata(&b->adapter, b); b->adapter.algo_data = &b->bac; diff -Nru a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c --- a/drivers/video/matrox/matroxfb_maven.c Mon Aug 18 22:21:00 2003 +++ b/drivers/video/matrox/matroxfb_maven.c Mon Aug 18 22:21:00 2003 @@ -1255,7 +1255,7 @@ new_client->adapter = adapter; new_client->driver = &maven_driver; new_client->flags = 0; - strcpy(new_client->dev.name, "maven client"); + strcpy(new_client->name, "maven client"); if ((err = i2c_attach_client(new_client))) goto ERROR3; err = maven_init_client(new_client); diff -Nru a/fs/Kconfig b/fs/Kconfig --- a/fs/Kconfig Mon Aug 18 22:21:04 2003 +++ b/fs/Kconfig Mon Aug 18 22:21:04 2003 @@ -777,6 +777,10 @@ the material in , especially the file README there. + Note that devfs no longer manages /dev/pts! If you are using UNIX98 + ptys, you will also need to enable (and mount) the /dev/pts + filesystem (CONFIG_DEVPTS_FS). + If unsure, say N. config DEVFS_MOUNT @@ -823,9 +827,6 @@ mode of operation; you also need client programs that use the Unix98 API. Please read for more information about the Unix98 pty devices. - - Note that the experimental "/dev file system support" - (CONFIG_DEVFS_FS) is a more general facility. config DEVPTS_FS_XATTR bool "/dev/pts Extended Attributes" diff -Nru a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt --- a/fs/Kconfig.binfmt Mon Aug 18 22:21:06 2003 +++ b/fs/Kconfig.binfmt Mon Aug 18 22:21:06 2003 @@ -111,6 +111,9 @@ feature, and for information about how to include Java support. + To use binfmt_misc, you will need to mount it: + mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc + 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. If you don't know what to answer at this point, say Y. diff -Nru a/fs/Makefile b/fs/Makefile --- a/fs/Makefile Mon Aug 18 22:21:04 2003 +++ b/fs/Makefile Mon Aug 18 22:21:04 2003 @@ -81,11 +81,11 @@ obj-$(CONFIG_AFFS_FS) += affs/ obj-$(CONFIG_ROMFS_FS) += romfs/ obj-$(CONFIG_QNX4FS_FS) += qnx4/ -obj-$(CONFIG_UDF_FS) += udf/ obj-$(CONFIG_AUTOFS_FS) += autofs/ obj-$(CONFIG_AUTOFS4_FS) += autofs4/ obj-$(CONFIG_ADFS_FS) += adfs/ obj-$(CONFIG_REISERFS_FS) += reiserfs/ +obj-$(CONFIG_UDF_FS) += udf/ obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ obj-$(CONFIG_JFS_FS) += jfs/ obj-$(CONFIG_XFS_FS) += xfs/ diff -Nru a/fs/afs/super.c b/fs/afs/super.c --- a/fs/afs/super.c Mon Aug 18 22:21:03 2003 +++ b/fs/afs/super.c Mon Aug 18 22:21:03 2003 @@ -240,7 +240,7 @@ * - this function has been shamelessly adapted from the ext3 fs which shamelessly adapted it from * the msdos fs */ -static int afs_super_parse_options(struct afs_super_info *as, char *options, char **devname) +static int afs_super_parse_options(struct afs_super_info *as, char *options, const char ** devname) { char *key, *value; int ret; @@ -314,6 +314,11 @@ return ret; } /* end afs_super_parse_options() */ +struct fill_super_options { + const char *dev_name; + void *options; +}; + /*****************************************************************************/ /* * fill in the superblock @@ -324,8 +329,9 @@ struct dentry *root = NULL; struct inode *inode = NULL; afs_fid_t fid; - void **data = _data; - char *options, *devname; + struct fill_super_options *data = _data; + const char *devname; + char *options; int ret; _enter(""); @@ -334,8 +340,8 @@ _leave(" = -EINVAL"); return -EINVAL; } - devname = data[0]; - options = data[1]; + devname = data->dev_name; + options = data->options; if (options) options[PAGE_SIZE-1] = 0; @@ -413,7 +419,7 @@ const char *dev_name, void *options) { struct super_block *sb; - void *data[2] = { dev_name, options }; + struct fill_super_options data = { dev_name, options }; int ret; _enter(",,%s,%p",dev_name,options); @@ -426,7 +432,7 @@ } /* allocate a deviceless superblock */ - sb = get_sb_nodev(fs_type,flags,data,afs_fill_super); + sb = get_sb_nodev(fs_type, flags, &data, afs_fill_super); if (IS_ERR(sb)) { afscm_stop(); return sb; diff -Nru a/fs/afs/volume.c b/fs/afs/volume.c --- a/fs/afs/volume.c Mon Aug 18 22:21:00 2003 +++ b/fs/afs/volume.c Mon Aug 18 22:21:00 2003 @@ -43,7 +43,7 @@ * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W if not available * - Rule 3: If parent volume is R/W, then only mount R/W volume unless explicitly told otherwise */ -int afs_volume_lookup(char *name, int rwparent, afs_volume_t **_volume) +int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume) { afs_vlocation_t *vlocation = NULL; afs_voltype_t type; diff -Nru a/fs/afs/volume.h b/fs/afs/volume.h --- a/fs/afs/volume.h Mon Aug 18 22:21:05 2003 +++ b/fs/afs/volume.h Mon Aug 18 22:21:05 2003 @@ -79,7 +79,7 @@ struct rw_semaphore server_sem; /* lock for accessing current server */ }; -extern int afs_volume_lookup(char *name, int ro, afs_volume_t **_volume); +extern int afs_volume_lookup(const char *name, int ro, afs_volume_t **_volume); #define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0) diff -Nru a/fs/aio.c b/fs/aio.c --- a/fs/aio.c Mon Aug 18 22:21:03 2003 +++ b/fs/aio.c Mon Aug 18 22:21:03 2003 @@ -639,13 +639,13 @@ iocb->ki_user_data = res; if (iocb->ki_users == 1) { iocb->ki_users = 0; - return 1; + ret = 1; + } else { + spin_lock_irq(&ctx->ctx_lock); + iocb->ki_users--; + ret = (0 == iocb->ki_users); + spin_unlock_irq(&ctx->ctx_lock); } - spin_lock_irq(&ctx->ctx_lock); - iocb->ki_users--; - ret = (0 == iocb->ki_users); - spin_unlock_irq(&ctx->ctx_lock); - /* sync iocbs put the task here for us */ wake_up_process(iocb->ki_user_obj); return ret; diff -Nru a/fs/befs/btree.c b/fs/befs/btree.c --- a/fs/befs/btree.c Mon Aug 18 22:21:00 2003 +++ b/fs/befs/btree.c Mon Aug 18 22:21:00 2003 @@ -86,7 +86,7 @@ } befs_btree_node; /* local constants */ -static const befs_off_t befs_bt_inval = 0xffffffffffffffff; +static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; /* local functions */ static int befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c --- a/fs/binfmt_elf.c Mon Aug 18 22:21:03 2003 +++ b/fs/binfmt_elf.c Mon Aug 18 22:21:03 2003 @@ -1084,18 +1084,19 @@ jiffies_to_timeval(p->cstime, &prstatus->pr_cstime); } -static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p) +static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, + struct mm_struct *mm) { int i, len; /* first copy the parameters from user space */ memset(psinfo, 0, sizeof(struct elf_prpsinfo)); - len = p->mm->arg_end - p->mm->arg_start; + len = mm->arg_end - mm->arg_start; if (len >= ELF_PRARGSZ) len = ELF_PRARGSZ-1; copy_from_user(&psinfo->pr_psargs, - (const char *)p->mm->arg_start, len); + (const char *)mm->arg_start, len); for(i = 0; i < len; i++) if (psinfo->pr_psargs[i] == 0) psinfo->pr_psargs[i] = ' '; @@ -1280,7 +1281,7 @@ fill_note(notes +0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus); - fill_psinfo(psinfo, current->group_leader); + fill_psinfo(psinfo, current->group_leader, current->mm); fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo); fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current); diff -Nru a/fs/char_dev.c b/fs/char_dev.c --- a/fs/char_dev.c Mon Aug 18 22:21:02 2003 +++ b/fs/char_dev.c Mon Aug 18 22:21:02 2003 @@ -456,9 +456,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data) { - char name[30]; - sprintf(name, "char-major-%d", MAJOR(dev)); - request_module(name); + request_module("char-major-%d", MAJOR(dev)); return NULL; } diff -Nru a/fs/compat.c b/fs/compat.c --- a/fs/compat.c Mon Aug 18 22:21:03 2003 +++ b/fs/compat.c Mon Aug 18 22:21:03 2003 @@ -53,6 +53,19 @@ return do_utimes(filename, t ? tv : NULL); } +asmlinkage long compat_sys_utimes(char *filename, struct compat_timeval *t) +{ + struct timeval tv[2]; + + if (t) { + if (get_user(tv[0].tv_sec, &t[0].tv_sec) || + get_user(tv[0].tv_usec, &t[0].tv_usec) || + get_user(tv[1].tv_sec, &t[1].tv_sec) || + get_user(tv[1].tv_usec, &t[1].tv_usec)) + return -EFAULT; + } + return do_utimes(filename, t ? tv : NULL); +} asmlinkage long compat_sys_newstat(char * filename, struct compat_stat *statbuf) @@ -150,6 +163,64 @@ return error; } +static int put_compat_statfs64(struct compat_statfs64 *ubuf, struct kstatfs *kbuf) +{ + + if (sizeof ubuf->f_blocks == 4) { + if ((kbuf->f_blocks | kbuf->f_bfree | + kbuf->f_bavail | kbuf->f_files | kbuf->f_ffree) & + 0xffffffff00000000ULL) + return -EOVERFLOW; + } + if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || + __put_user(kbuf->f_type, &ubuf->f_type) || + __put_user(kbuf->f_bsize, &ubuf->f_bsize) || + __put_user(kbuf->f_blocks, &ubuf->f_blocks) || + __put_user(kbuf->f_bfree, &ubuf->f_bfree) || + __put_user(kbuf->f_bavail, &ubuf->f_bavail) || + __put_user(kbuf->f_files, &ubuf->f_files) || + __put_user(kbuf->f_ffree, &ubuf->f_ffree) || + __put_user(kbuf->f_namelen, &ubuf->f_namelen) || + __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || + __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || + __put_user(kbuf->f_frsize, &ubuf->f_frsize)) + return -EFAULT; + return 0; +} + +asmlinkage long compat_statfs64(const char *path, struct compat_statfs64 *buf) +{ + struct nameidata nd; + int error; + + error = user_path_walk(path, &nd); + if (!error) { + struct kstatfs tmp; + error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); + if (!error && put_compat_statfs64(buf, &tmp)) + error = -EFAULT; + path_release(&nd); + } + return error; +} + +asmlinkage long compat_fstatfs64(unsigned int fd, struct compat_statfs64 *buf) +{ + struct file * file; + struct kstatfs 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 && put_compat_statfs64(buf, &tmp)) + error = -EFAULT; + fput(file); +out: + return error; +} /* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64 */ diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c --- a/fs/devfs/base.c Mon Aug 18 22:21:01 2003 +++ b/fs/devfs/base.c Mon Aug 18 22:21:01 2003 @@ -1224,6 +1224,12 @@ { struct devfs_entry *de, *link; + if (!S_ISDIR (dir->mode)) + { + devfs_put (dir); + return NULL; + } + if ( ( de = _devfs_descend (dir, name, namelen, &next_pos) ) == NULL ) { devfs_put (dir); @@ -1697,13 +1703,13 @@ } error = _devfs_append_entry(dir, de, &old); - if (error == -EEXIST) { + if (error == -EEXIST && S_ISDIR(old->mode)) { /* * devfs_mk_dir() of an already-existing directory will * return success. */ error = 0; - devfs_put(old); + goto out_put; } else if (error) { PRINTK("(%s): could not append to dir: %p \"%s\"\n", buf, dir, dir->name); diff -Nru a/fs/exec.c b/fs/exec.c --- a/fs/exec.c Mon Aug 18 22:21:02 2003 +++ b/fs/exec.c Mon Aug 18 22:21:02 2003 @@ -341,6 +341,7 @@ struct vm_area_struct *mpnt; struct mm_struct *mm = current->mm; int i; + long arg_size; #ifdef CONFIG_STACK_GROWSUP /* Move the argument and environment strings to the bottom of the @@ -375,6 +376,7 @@ bprm->p = PAGE_SIZE * i - offset; stack_base = STACK_TOP - current->rlim[RLIMIT_STACK].rlim_max; mm->arg_start = stack_base; + arg_size = i << PAGE_SHIFT; /* zero pages that were copied above */ while (i < MAX_ARG_PAGES) @@ -382,6 +384,7 @@ #else stack_base = STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE; mm->arg_start = bprm->p + stack_base; + arg_size = STACK_TOP - (PAGE_MASK & (unsigned long) mm->arg_start); #endif bprm->p += stack_base; @@ -393,7 +396,7 @@ if (!mpnt) return -ENOMEM; - if (security_vm_enough_memory((STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) { + if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) { kmem_cache_free(vm_area_cachep, mpnt); return -ENOMEM; } diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c --- a/fs/hugetlbfs/inode.c Mon Aug 18 22:21:05 2003 +++ b/fs/hugetlbfs/inode.c Mon Aug 18 22:21:05 2003 @@ -48,7 +48,7 @@ struct inode *inode = file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb); - loff_t len; + loff_t len, vma_len; int ret; if (vma->vm_start & ~HPAGE_MASK) @@ -60,11 +60,11 @@ if (vma->vm_end - vma->vm_start < HPAGE_SIZE) return -EINVAL; - len = (loff_t)(vma->vm_end - vma->vm_start); + vma_len = (loff_t)(vma->vm_end - vma->vm_start); if (sbinfo->free_blocks >= 0) { /* Check if there is any size limit. */ spin_lock(&sbinfo->stat_lock); - if ((len >> HPAGE_SHIFT) <= sbinfo->free_blocks) { - sbinfo->free_blocks -= (len >> HPAGE_SHIFT); + if ((vma_len >> HPAGE_SHIFT) <= sbinfo->free_blocks) { + sbinfo->free_blocks -= (vma_len >> HPAGE_SHIFT); spin_unlock(&sbinfo->stat_lock); } else { spin_unlock(&sbinfo->stat_lock); @@ -78,8 +78,7 @@ vma->vm_flags |= VM_HUGETLB | VM_RESERVED; vma->vm_ops = &hugetlb_vm_ops; ret = hugetlb_prefault(mapping, vma); - len = (loff_t)(vma->vm_end - vma->vm_start) + - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); + len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); if (ret == 0 && inode->i_size < len) inode->i_size = len; up(&inode->i_sem); @@ -89,7 +88,7 @@ */ if ((ret != 0) && (sbinfo->free_blocks >= 0)) { spin_lock(&sbinfo->stat_lock); - sbinfo->free_blocks += (len >> HPAGE_SHIFT); + sbinfo->free_blocks += (vma_len >> HPAGE_SHIFT); spin_unlock(&sbinfo->stat_lock); } @@ -575,6 +574,16 @@ return 0; } +static void hugetlbfs_put_super(struct super_block *sb) +{ + struct hugetlbfs_sb_info *sbi = HUGETLBFS_SB(sb); + + if (sbi) { + sb->s_fs_info = NULL; + kfree(sbi); + } +} + static struct address_space_operations hugetlbfs_aops = { .readpage = hugetlbfs_readpage, .prepare_write = hugetlbfs_prepare_write, @@ -608,6 +617,7 @@ static struct super_operations hugetlbfs_ops = { .statfs = hugetlbfs_statfs, .drop_inode = hugetlbfs_drop_inode, + .put_super = hugetlbfs_put_super, }; static int @@ -709,19 +719,10 @@ return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super); } -static void hugetlbfs_kill_super(struct super_block *sb) -{ - if (sb) { - if(sb->s_fs_info) - kfree(sb->s_fs_info); - kill_litter_super(sb); - } -} - static struct file_system_type hugetlbfs_fs_type = { .name = "hugetlbfs", .get_sb = hugetlbfs_get_sb, - .kill_sb = hugetlbfs_kill_super + .kill_sb = kill_litter_super, }; static struct vfsmount *hugetlbfs_vfsmount; diff -Nru a/fs/inode.c b/fs/inode.c --- a/fs/inode.c Mon Aug 18 22:21:06 2003 +++ b/fs/inode.c Mon Aug 18 22:21:06 2003 @@ -1148,8 +1148,13 @@ void inode_update_time(struct inode *inode, int ctime_too) { - struct timespec now = current_kernel_time(); + struct timespec now; int sync_it = 0; + + if (IS_RDONLY(inode)) + return; + + now = current_kernel_time(); if (inode_times_differ(inode, &inode->i_mtime, &now)) sync_it = 1; diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c --- a/fs/jbd/journal.c Mon Aug 18 22:21:01 2003 +++ b/fs/jbd/journal.c Mon Aug 18 22:21:01 2003 @@ -278,9 +278,6 @@ * Bit 1 set == buffer copy-out performed (kfree the data after IO) */ -static inline unsigned long virt_to_offset(void *p) -{return ((unsigned long) p) & ~PAGE_MASK;} - int journal_write_metadata_buffer(transaction_t *transaction, struct journal_head *jh_in, struct journal_head **jh_out, @@ -318,10 +315,10 @@ if (jh_in->b_frozen_data) { done_copy_out = 1; new_page = virt_to_page(jh_in->b_frozen_data); - new_offset = virt_to_offset(jh_in->b_frozen_data); + new_offset = offset_in_page(jh_in->b_frozen_data); } else { new_page = jh2bh(jh_in)->b_page; - new_offset = virt_to_offset(jh2bh(jh_in)->b_data); + new_offset = offset_in_page(jh2bh(jh_in)->b_data); } mapped_data = kmap_atomic(new_page, KM_USER0); @@ -358,7 +355,7 @@ address kmapped so that we can clear the escaped magic number below. */ new_page = virt_to_page(tmp); - new_offset = virt_to_offset(tmp); + new_offset = offset_in_page(tmp); done_copy_out = 1; } diff -Nru a/fs/jbd/revoke.c b/fs/jbd/revoke.c --- a/fs/jbd/revoke.c Mon Aug 18 22:21:01 2003 +++ b/fs/jbd/revoke.c Mon Aug 18 22:21:01 2003 @@ -438,7 +438,7 @@ record = find_revoke_record(journal, bh->b_blocknr); if (record) { jbd_debug(4, "cancelled existing revoke on " - "blocknr %llu\n", (u64)bh->b_blocknr); + "blocknr %llu\n", (unsigned long long)bh->b_blocknr); spin_lock(&journal->j_revoke_lock); list_del(&record->hash); spin_unlock(&journal->j_revoke_lock); diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c --- a/fs/jffs/inode-v23.c Mon Aug 18 22:21:04 2003 +++ b/fs/jffs/inode-v23.c Mon Aug 18 22:21:04 2003 @@ -383,7 +383,7 @@ /* Get statistics of the file system. */ int -jffs_statfs(struct super_block *sb, struct statfs *buf) +jffs_statfs(struct super_block *sb, struct kstatfs *buf) { struct jffs_control *c = (struct jffs_control *) sb->s_fs_info; struct jffs_fmcontrol *fmc; diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c --- a/fs/lockd/svc.c Mon Aug 18 22:21:04 2003 +++ b/fs/lockd/svc.c Mon Aug 18 22:21:04 2003 @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -51,12 +53,23 @@ static DECLARE_WAIT_QUEUE_HEAD(lockd_exit); /* - * Currently the following can be set only at insmod time. - * Ideally, they would be accessible through the sysctl interface. + * These can be set at insmod time (useful for NFS as root filesystem), + * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 */ -unsigned long nlm_grace_period; -unsigned long nlm_timeout = LOCKD_DFLT_TIMEO; -unsigned long nlm_udpport, nlm_tcpport; +static unsigned long nlm_grace_period; +static unsigned long nlm_timeout = LOCKD_DFLT_TIMEO; +static int nlm_udpport, nlm_tcpport; + +/* + * Constants needed for the sysctl interface. + */ +static const unsigned long nlm_grace_period_min = 0; +static const unsigned long nlm_grace_period_max = 240; +static const unsigned long nlm_timeout_min = 3; +static const unsigned long nlm_timeout_max = 20; +static const int nlm_port_min = 0, nlm_port_max = 65535; + +static struct ctl_table_header * nlm_sysctl_table; static unsigned long set_grace_period(void) { @@ -302,52 +315,130 @@ up(&nlmsvc_sema); } -#ifdef MODULE -/* New module support in 2.1.18 */ +/* + * Sysctl parameters (same as module parameters, different interface). + */ + +/* Something that isn't CTL_ANY, CTL_NONE or a value that may clash. */ +#define CTL_UNNUMBERED -2 + +static ctl_table nlm_sysctls[] = { + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nlm_grace_period", + .data = &nlm_grace_period, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_doulongvec_minmax, + .extra1 = (unsigned long *) &nlm_grace_period_min, + .extra2 = (unsigned long *) &nlm_grace_period_max, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nlm_timeout", + .data = &nlm_timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_doulongvec_minmax, + .extra1 = (unsigned long *) &nlm_timeout_min, + .extra2 = (unsigned long *) &nlm_timeout_max, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nlm_udpport", + .data = &nlm_udpport, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = (int *) &nlm_port_min, + .extra2 = (int *) &nlm_port_max, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nlm_tcpport", + .data = &nlm_tcpport, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = (int *) &nlm_port_min, + .extra2 = (int *) &nlm_port_max, + }, + { .ctl_name = 0 } +}; + +static ctl_table nlm_sysctl_dir[] = { + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nfs", + .mode = 0555, + .child = nlm_sysctls, + }, + { .ctl_name = 0 } +}; + +static ctl_table nlm_sysctl_root[] = { + { + .ctl_name = CTL_FS, + .procname = "fs", + .mode = 0555, + .child = nlm_sysctl_dir, + }, + { .ctl_name = 0 } +}; + +/* + * Module (and driverfs) parameters. + */ + +#define param_set_min_max(name, type, which_strtol, min, max) \ +static int param_set_##name(const char *val, struct kernel_param *kp) \ +{ \ + char *endp; \ + __typeof__(type) num = which_strtol(val, &endp, 0); \ + if (endp == val || *endp || num < (min) || num > (max)) \ + return -EINVAL; \ + *((int *) kp->arg) = num; \ + return 0; \ +} + +param_set_min_max(port, int, simple_strtol, 0, 65535) +param_set_min_max(grace_period, unsigned long, simple_strtoul, + nlm_grace_period_min, nlm_grace_period_max) +param_set_min_max(timeout, unsigned long, simple_strtoul, + nlm_timeout_min, nlm_timeout_max) MODULE_AUTHOR("Olaf Kirch "); MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION "."); MODULE_LICENSE("GPL"); -MODULE_PARM(nlm_grace_period, "10-240l"); -MODULE_PARM(nlm_timeout, "3-20l"); -MODULE_PARM(nlm_udpport, "0-65535l"); -MODULE_PARM(nlm_tcpport, "0-65535l"); -int -init_module(void) -{ - /* Init the static variables */ - init_MUTEX(&nlmsvc_sema); - nlmsvc_users = 0; - nlmsvc_pid = 0; - return 0; -} +module_param_call(nlm_grace_period, param_set_grace_period, param_get_ulong, + &nlm_grace_period, 644); +module_param_call(nlm_timeout, param_set_timeout, param_get_ulong, + &nlm_timeout, 644); +module_param_call(nlm_udpport, param_set_port, param_get_int, + &nlm_udpport, 644); +module_param_call(nlm_tcpport, param_set_port, param_get_int, + &nlm_tcpport, 644); -void -cleanup_module(void) -{ - /* FIXME: delete all NLM clients */ - nlm_shutdown_hosts(); -} -#else -/* not a module, so process bootargs - * lockd.udpport and lockd.tcpport +/* + * Initialising and terminating the module. */ -static int __init udpport_set(char *str) +static int __init init_nlm(void) { - nlm_udpport = simple_strtoul(str, NULL, 0); - return 1; + nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root, 0); + return nlm_sysctl_table ? 0 : -ENOMEM; } -static int __init tcpport_set(char *str) + +static void __exit exit_nlm(void) { - nlm_tcpport = simple_strtoul(str, NULL, 0); - return 1; + /* FIXME: delete all NLM clients */ + nlm_shutdown_hosts(); + unregister_sysctl_table(nlm_sysctl_table); } -__setup("lockd.udpport=", udpport_set); -__setup("lockd.tcpport=", tcpport_set); -#endif +module_init(init_nlm); +module_exit(exit_nlm); /* * Define NLM program and procedures diff -Nru a/fs/minix/bitmap.c b/fs/minix/bitmap.c --- a/fs/minix/bitmap.c Mon Aug 18 22:21:05 2003 +++ b/fs/minix/bitmap.c Mon Aug 18 22:21:05 2003 @@ -116,7 +116,7 @@ if (!ino || ino > sbi->s_ninodes) { printk("Bad inode number on dev %s: %ld is out of range\n", - sb->s_id, ino); + sb->s_id, (long)ino); return NULL; } ino--; @@ -141,7 +141,7 @@ *bh = NULL; if (!ino || ino > sbi->s_ninodes) { printk("Bad inode number on dev %s: %ld is out of range\n", - sb->s_id, ino); + sb->s_id, (long)ino); return NULL; } ino--; diff -Nru a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c --- a/fs/nfs/nfs2xdr.c Mon Aug 18 22:21:02 2003 +++ b/fs/nfs/nfs2xdr.c Mon Aug 18 22:21:02 2003 @@ -90,7 +90,7 @@ { *p++ = htonl(timep->tv_sec); /* Convert nanoseconds into microseconds */ - *p++ = htonl(timep->tv_nsec / 1000); + *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0); return p; } diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c --- a/fs/nfsd/nfs3xdr.c Mon Aug 18 22:21:00 2003 +++ b/fs/nfsd/nfs3xdr.c Mon Aug 18 22:21:00 2003 @@ -4,6 +4,8 @@ * XDR support for nfsd/protocol version 3. * * Copyright (C) 1995, 1996, 1997 Olaf Kirch + * + * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()! */ #include @@ -43,7 +45,7 @@ static inline u32 * encode_time3(u32 *p, struct timespec *time) { - *p++ = htonl((u32) time->tv_sec); *p++ = htons(time->tv_nsec); + *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); return p; } diff -Nru a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c --- a/fs/nfsd/nfsxdr.c Mon Aug 18 22:21:00 2003 +++ b/fs/nfsd/nfsxdr.c Mon Aug 18 22:21:00 2003 @@ -123,13 +123,13 @@ if (tmp != (u32)-1 && tmp1 != (u32)-1) { iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET; iap->ia_atime.tv_sec = tmp; - iap->ia_atime.tv_nsec = tmp1; + iap->ia_atime.tv_nsec = tmp1 * 1000; } tmp = ntohl(*p++); tmp1 = ntohl(*p++); if (tmp != (u32)-1 && tmp1 != (u32)-1) { iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET; iap->ia_mtime.tv_sec = tmp; - iap->ia_mtime.tv_nsec = tmp1; + iap->ia_mtime.tv_nsec = tmp1 * 1000; } return p; } @@ -171,12 +171,12 @@ *p++ = htonl((u32) stat.dev); *p++ = htonl((u32) stat.ino); *p++ = htonl((u32) stat.atime.tv_sec); - *p++ = htons(stat.atime.tv_nsec); + *p++ = htonl(stat.atime.tv_nsec ? stat.atime.tv_nsec / 1000 : 0); lease_get_mtime(dentry->d_inode, &time); *p++ = htonl((u32) time.tv_sec); - *p++ = htons(time.tv_nsec); + *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); *p++ = htonl((u32) stat.ctime.tv_sec); - *p++ = htons(stat.ctime.tv_nsec); + *p++ = htonl(stat.ctime.tv_nsec ? stat.ctime.tv_nsec / 1000 : 0); return p; } diff -Nru a/fs/nls/Makefile b/fs/nls/Makefile --- a/fs/nls/Makefile Mon Aug 18 22:21:01 2003 +++ b/fs/nls/Makefile Mon Aug 18 22:21:01 2003 @@ -24,6 +24,7 @@ obj-$(CONFIG_NLS_CODEPAGE_936) += nls_cp936.o nls_gb2312.o obj-$(CONFIG_NLS_CODEPAGE_949) += nls_cp949.o nls_euc-kr.o obj-$(CONFIG_NLS_CODEPAGE_950) += nls_cp950.o nls_big5.o +obj-$(CONFIG_NLS_CODEPAGE_1250) += nls_cp1250.o obj-$(CONFIG_NLS_CODEPAGE_1251) += nls_cp1251.o obj-$(CONFIG_NLS_CODEPAGE_1255) += nls_cp1255.o obj-$(CONFIG_NLS_ISO8859_1) += nls_iso8859-1.o diff -Nru a/fs/partitions/acorn.c b/fs/partitions/acorn.c --- a/fs/partitions/acorn.c Mon Aug 18 22:21:04 2003 +++ b/fs/partitions/acorn.c Mon Aug 18 22:21:04 2003 @@ -517,7 +517,7 @@ const unsigned char *data; unsigned char buffer[256]; struct eesox_part *p; - u32 start = 0; + sector_t start = 0; int i, slot = 1; data = read_dev_sector(bdev, 7, §); @@ -533,22 +533,22 @@ put_dev_sector(sect); for (i = 0, p = (struct eesox_part *)buffer; i < 8; i++, p++) { - u32 next; + sector_t next; if (memcmp(p->magic, "Eesox", 6)) break; - next = le32_to_cpu(p->start) + first_sector; + next = le32_to_cpu(p->start); if (i) put_partition(state, slot++, start, next - start); start = next; } if (i != 0) { - unsigned long size; + sector_t size; - size = hd->part[minor(to_kdev_t(bdev->bd_dev))].nr_sects; - add_gd_partition(hd, minor++, start, size - start); + size = get_capacity(bdev->bd_disk); + put_partition(state, slot++, start, size - start); printk("\n"); } diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c --- a/fs/partitions/check.c Mon Aug 18 22:21:05 2003 +++ b/fs/partitions/check.c Mon Aug 18 22:21:05 2003 @@ -223,9 +223,8 @@ static ssize_t part_dev_read(struct hd_struct * p, char *page) { struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); - int part = p->partno; - dev_t base = MKDEV(disk->major, disk->first_minor); - return sprintf(page, "%04x\n", (unsigned)(base + part)); + dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno); + return print_dev_t(page, dev); } static ssize_t part_start_read(struct hd_struct * p, char *page) { diff -Nru a/fs/partitions/efi.h b/fs/partitions/efi.h --- a/fs/partitions/efi.h Mon Aug 18 22:21:04 2003 +++ b/fs/partitions/efi.h Mon Aug 18 22:21:04 2003 @@ -39,7 +39,7 @@ #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE #define GPT_BLOCK_SIZE 512 -#define GPT_HEADER_SIGNATURE 0x5452415020494645L +#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL #define GPT_HEADER_REVISION_V1 0x00010000 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1 diff -Nru a/fs/partitions/ldm.h b/fs/partitions/ldm.h --- a/fs/partitions/ldm.h Mon Aug 18 22:21:02 2003 +++ b/fs/partitions/ldm.h Mon Aug 18 22:21:02 2003 @@ -38,8 +38,8 @@ /* Magic numbers in CPU format. */ #define MAGIC_VMDB 0x564D4442 /* VMDB */ #define MAGIC_VBLK 0x56424C4B /* VBLK */ -#define MAGIC_PRIVHEAD 0x5052495648454144 /* PRIVHEAD */ -#define MAGIC_TOCBLOCK 0x544F43424C4F434B /* TOCBLOCK */ +#define MAGIC_PRIVHEAD 0x5052495648454144ULL /* PRIVHEAD */ +#define MAGIC_TOCBLOCK 0x544F43424C4F434BULL /* TOCBLOCK */ /* The defined vblk types. */ #define VBLK_VOL5 0x51 /* Volume, version 5 */ diff -Nru a/fs/pipe.c b/fs/pipe.c --- a/fs/pipe.c Mon Aug 18 22:21:03 2003 +++ b/fs/pipe.c Mon Aug 18 22:21:03 2003 @@ -208,10 +208,8 @@ wake_up_interruptible(PIPE_WAIT(*inode)); kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); } - if (ret > 0) { - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - mark_inode_dirty(inode); - } + if (ret > 0) + inode_update_time(inode, 1); /* mtime and ctime */ return ret; } diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c --- a/fs/proc/proc_misc.c Mon Aug 18 22:21:01 2003 +++ b/fs/proc/proc_misc.c Mon Aug 18 22:21:01 2003 @@ -362,7 +362,7 @@ int i, len; extern unsigned long total_forks; u64 jif; - unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0; + unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; struct timeval now; unsigned long seq; @@ -388,25 +388,31 @@ system += kstat_cpu(i).cpustat.system; idle += kstat_cpu(i).cpustat.idle; iowait += kstat_cpu(i).cpustat.iowait; + irq += kstat_cpu(i).cpustat.irq; + softirq += kstat_cpu(i).cpustat.softirq; for (j = 0 ; j < NR_IRQS ; j++) sum += kstat_cpu(i).irqs[j]; } - len = sprintf(page, "cpu %u %u %u %u %u\n", + len = sprintf(page, "cpu %u %u %u %u %u %u %u\n", jiffies_to_clock_t(user), jiffies_to_clock_t(nice), jiffies_to_clock_t(system), jiffies_to_clock_t(idle), - jiffies_to_clock_t(iowait)); + jiffies_to_clock_t(iowait), + jiffies_to_clock_t(irq), + jiffies_to_clock_t(softirq)); for (i = 0 ; i < NR_CPUS; i++){ if (!cpu_online(i)) continue; - len += sprintf(page + len, "cpu%d %u %u %u %u %u\n", + len += sprintf(page + len, "cpu%d %u %u %u %u %u %u %u\n", i, jiffies_to_clock_t(kstat_cpu(i).cpustat.user), jiffies_to_clock_t(kstat_cpu(i).cpustat.nice), jiffies_to_clock_t(kstat_cpu(i).cpustat.system), jiffies_to_clock_t(kstat_cpu(i).cpustat.idle), - jiffies_to_clock_t(kstat_cpu(i).cpustat.iowait)); + jiffies_to_clock_t(kstat_cpu(i).cpustat.iowait), + jiffies_to_clock_t(kstat_cpu(i).cpustat.irq), + jiffies_to_clock_t(kstat_cpu(i).cpustat.softirq)); } len += sprintf(page + len, "intr %u", sum); diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c --- a/fs/reiserfs/file.c Mon Aug 18 22:21:00 2003 +++ b/fs/reiserfs/file.c Mon Aug 18 22:21:00 2003 @@ -555,7 +555,6 @@ struct page *page = prepared_pages[i]; try_to_free_buffers(page); - kunmap(page); unlock_page(page); page_cache_release(page); } diff -Nru a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c --- a/fs/reiserfs/hashes.c Mon Aug 18 22:21:05 2003 +++ b/fs/reiserfs/hashes.c Mon Aug 18 22:21:05 2003 @@ -90,10 +90,6 @@ if (len >= 12) { - //assert(len < 16); - if (len >= 16) - BUG(); - a = (u32)msg[ 0] | (u32)msg[ 1] << 8 | (u32)msg[ 2] << 16| @@ -116,9 +112,6 @@ } else if (len >= 8) { - //assert(len < 12); - if (len >= 12) - BUG(); a = (u32)msg[ 0] | (u32)msg[ 1] << 8 | (u32)msg[ 2] << 16| @@ -137,9 +130,6 @@ } else if (len >= 4) { - //assert(len < 8); - if (len >= 8) - BUG(); a = (u32)msg[ 0] | (u32)msg[ 1] << 8 | (u32)msg[ 2] << 16| @@ -154,9 +144,6 @@ } else { - //assert(len < 4); - if (len >= 4) - BUG(); a = b = c = d = pad; for(i = 0; i < len; i++) { diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c --- a/fs/reiserfs/inode.c Mon Aug 18 22:21:02 2003 +++ b/fs/reiserfs/inode.c Mon Aug 18 22:21:02 2003 @@ -2236,6 +2236,10 @@ inode -> i_flags |= S_IMMUTABLE; else inode -> i_flags &= ~S_IMMUTABLE; + if( sd_attrs & REISERFS_APPEND_FL ) + inode -> i_flags |= S_APPEND; + else + inode -> i_flags &= ~S_APPEND; if( sd_attrs & REISERFS_NOATIME_FL ) inode -> i_flags |= S_NOATIME; else diff -Nru a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c --- a/fs/reiserfs/ioctl.c Mon Aug 18 22:21:02 2003 +++ b/fs/reiserfs/ioctl.c Mon Aug 18 22:21:02 2003 @@ -47,7 +47,7 @@ if (get_user(flags, (int *) arg)) return -EFAULT; - if ( ( flags & REISERFS_IMMUTABLE_FL ) && + if ( ( ( flags ^ REISERFS_I(inode) -> i_attrs) & ( REISERFS_IMMUTABLE_FL | REISERFS_APPEND_FL)) && !capable( CAP_LINUX_IMMUTABLE ) ) return -EPERM; diff -Nru a/fs/sysfs/Makefile b/fs/sysfs/Makefile --- a/fs/sysfs/Makefile Mon Aug 18 22:21:00 2003 +++ b/fs/sysfs/Makefile Mon Aug 18 22:21:00 2003 @@ -2,4 +2,5 @@ # Makefile for the sysfs virtual filesystem # -obj-y := inode.o file.o dir.o symlink.o mount.o bin.o +obj-y := inode.o file.o dir.o symlink.o mount.o bin.o \ + group.o diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c --- a/fs/sysfs/bin.c Mon Aug 18 22:21:03 2003 +++ b/fs/sysfs/bin.c Mon Aug 18 22:21:03 2003 @@ -47,7 +47,7 @@ return ret; count = ret; - if (copy_to_user(userbuf, buffer + offs, count)) + if (copy_to_user(userbuf, buffer, count)) return -EFAULT; pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count); @@ -83,7 +83,7 @@ count = size - offs; } - if (copy_from_user(buffer + offs, userbuf, count)) + if (copy_from_user(buffer, userbuf, count)) return -EFAULT; count = flush_write(dentry, buffer, offs, count); diff -Nru a/fs/sysfs/dir.c b/fs/sysfs/dir.c --- a/fs/sysfs/dir.c Mon Aug 18 22:21:03 2003 +++ b/fs/sysfs/dir.c Mon Aug 18 22:21:03 2003 @@ -20,6 +20,36 @@ return 0; } + +static struct dentry * +create_dir(struct kobject * k, struct dentry * p, const char * n) +{ + struct dentry * dentry; + + down(&p->d_inode->i_sem); + dentry = sysfs_get_dentry(p,n); + if (!IS_ERR(dentry)) { + int error = sysfs_create(dentry, + S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO, + init_dir); + if (!error) { + dentry->d_fsdata = k; + p->d_inode->i_nlink++; + } else { + dput(dentry); + dentry = ERR_PTR(error); + } + } + up(&p->d_inode->i_sem); + return dentry; +} + + +struct dentry * sysfs_create_subdir(struct kobject * k, const char * n) +{ + return create_dir(k,k->dentry,n); +} + /** * sysfs_create_dir - create a directory for an object. * @parent: parent parent object. @@ -42,23 +72,34 @@ else return -EFAULT; - down(&parent->d_inode->i_sem); - dentry = sysfs_get_dentry(parent,kobj->name); - if (!IS_ERR(dentry)) { - dentry->d_fsdata = (void *)kobj; + dentry = create_dir(kobj,parent,kobj->name); + if (!IS_ERR(dentry)) kobj->dentry = dentry; - error = sysfs_create(dentry,(S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO), - init_dir); - if (!error) - parent->d_inode->i_nlink++; - } else + else error = PTR_ERR(dentry); - up(&parent->d_inode->i_sem); - return error; } +static void remove_dir(struct dentry * d) +{ + struct dentry * parent = dget(d->d_parent); + down(&parent->d_inode->i_sem); + d_delete(d); + simple_rmdir(parent->d_inode,d); + + pr_debug(" o %s removing done (%d)\n",d->d_name.name, + atomic_read(&d->d_count)); + + up(&parent->d_inode->i_sem); + dput(parent); +} + +void sysfs_remove_subdir(struct dentry * d) +{ + remove_dir(d); +} + /** * sysfs_remove_dir - remove an object's directory. @@ -73,14 +114,11 @@ { struct list_head * node; struct dentry * dentry = dget(kobj->dentry); - struct dentry * parent; if (!dentry) return; pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); - parent = dget(dentry->d_parent); - down(&parent->d_inode->i_sem); down(&dentry->d_inode->i_sem); spin_lock(&dcache_lock); @@ -107,21 +145,15 @@ } spin_unlock(&dcache_lock); up(&dentry->d_inode->i_sem); - d_delete(dentry); - simple_rmdir(parent->d_inode,dentry); - - pr_debug(" o %s removing done (%d)\n",dentry->d_name.name, - atomic_read(&dentry->d_count)); + remove_dir(dentry); /** * Drop reference from dget() on entrance. */ dput(dentry); - up(&parent->d_inode->i_sem); - dput(parent); } -void sysfs_rename_dir(struct kobject * kobj, char *new_name) +void sysfs_rename_dir(struct kobject * kobj, const char *new_name) { struct dentry * new_dentry, * parent; diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c --- a/fs/sysfs/file.c Mon Aug 18 22:21:01 2003 +++ b/fs/sysfs/file.c Mon Aug 18 22:21:01 2003 @@ -344,36 +344,44 @@ .release = sysfs_release, }; -/** - * sysfs_create_file - create an attribute file for an object. - * @kobj: object we're creating for. - * @attr: atrribute descriptor. - */ -int sysfs_create_file(struct kobject * kobj, struct attribute * attr) +int sysfs_add_file(struct dentry * dir, const struct attribute * attr) { struct dentry * dentry; - struct dentry * parent; - int error = 0; + int error; - if (!kobj || !attr) - return -EINVAL; - - parent = kobj->dentry; - - down(&parent->d_inode->i_sem); - dentry = sysfs_get_dentry(parent,attr->name); + down(&dir->d_inode->i_sem); + dentry = sysfs_get_dentry(dir,attr->name); if (!IS_ERR(dentry)) { - dentry->d_fsdata = (void *)attr; error = sysfs_create(dentry,(attr->mode & S_IALLUGO) | S_IFREG,init_file); + if (!error) + dentry->d_fsdata = (void *)attr; + else { + dput(dentry); + dentry = ERR_PTR(error); + } } else error = PTR_ERR(dentry); - up(&parent->d_inode->i_sem); + up(&dir->d_inode->i_sem); return error; } /** + * sysfs_create_file - create an attribute file for an object. + * @kobj: object we're creating for. + * @attr: atrribute descriptor. + */ + +int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) +{ + if (kobj && attr) + return sysfs_add_file(kobj->dentry,attr); + return -EINVAL; +} + + +/** * sysfs_update_file - update the modified timestamp on an object attribute. * @kobj: object we're acting for. * @attr: attribute descriptor. @@ -381,7 +389,7 @@ * Also call dnotify for the dentry, which lots of userspace programs * use. */ -int sysfs_update_file(struct kobject * kobj, struct attribute * attr) +int sysfs_update_file(struct kobject * kobj, const struct attribute * attr) { struct dentry * dir = kobj->dentry; struct dentry * victim; @@ -422,7 +430,7 @@ * Hash the attribute name and kill the victim. */ -void sysfs_remove_file(struct kobject * kobj, struct attribute * attr) +void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) { sysfs_hash_and_remove(kobj->dentry,attr->name); } diff -Nru a/fs/sysfs/group.c b/fs/sysfs/group.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/fs/sysfs/group.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,81 @@ +/* + * fs/sysfs/group.c - Operations for adding/removing multiple files at once. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * + * This file is released undert the GPL v2. + * + */ + +#include +#include +#include +#include +#include "sysfs.h" + + +static void remove_files(struct dentry * dir, + const struct attribute_group * grp) +{ + struct attribute *const* attr; + + for (attr = grp->attrs; *attr; attr++) + sysfs_hash_and_remove(dir,(*attr)->name); +} + +static int create_files(struct dentry * dir, + const struct attribute_group * grp) +{ + struct attribute *const* attr; + int error = 0; + + for (attr = grp->attrs; *attr && !error; attr++) { + error = sysfs_add_file(dir,*attr); + } + if (error) + remove_files(dir,grp); + return error; +} + + +int sysfs_create_group(struct kobject * kobj, + const struct attribute_group * grp) +{ + struct dentry * dir; + int error; + + if (grp->name) { + dir = sysfs_create_subdir(kobj,grp->name); + if (IS_ERR(dir)) + return PTR_ERR(dir); + } else + dir = kobj->dentry; + dir = dget(dir); + if ((error = create_files(dir,grp))) { + if (grp->name) + sysfs_remove_subdir(dir); + dput(dir); + } + return error; +} + +void sysfs_remove_group(struct kobject * kobj, + const struct attribute_group * grp) +{ + struct dentry * dir; + + if (grp->name) + dir = sysfs_get_dentry(kobj->dentry,grp->name); + else + dir = kobj->dentry; + + remove_files(dir,grp); + dput(dir); + if (grp->name) + sysfs_remove_subdir(dir); +} + + +EXPORT_SYMBOL(sysfs_create_group); +EXPORT_SYMBOL(sysfs_remove_group); diff -Nru a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h --- a/fs/sysfs/sysfs.h Mon Aug 18 22:21:05 2003 +++ b/fs/sysfs/sysfs.h Mon Aug 18 22:21:05 2003 @@ -4,7 +4,10 @@ extern struct inode * sysfs_new_inode(mode_t mode); extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); -extern struct dentry * sysfs_get_dentry(struct dentry *, char *); +extern struct dentry * sysfs_get_dentry(struct dentry *, const char *); +extern int sysfs_add_file(struct dentry * dir, const struct attribute * attr); extern void sysfs_hash_and_remove(struct dentry * dir, const char * name); +extern struct dentry * sysfs_create_subdir(struct kobject *, const char *); +extern void sysfs_remove_subdir(struct dentry *); diff -Nru a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c --- a/fs/xfs/linux/xfs_aops.c Mon Aug 18 22:21:05 2003 +++ b/fs/xfs/linux/xfs_aops.c Mon Aug 18 22:21:05 2003 @@ -803,7 +803,7 @@ bh = bh->b_this_page; } while (offset < end_offset); - if (uptodate) + if (uptodate && bh == head) SetPageUptodate(page); if (startio) diff -Nru a/fs/xfs/linux/xfs_file.c b/fs/xfs/linux/xfs_file.c --- a/fs/xfs/linux/xfs_file.c Mon Aug 18 22:21:03 2003 +++ b/fs/xfs/linux/xfs_file.c Mon Aug 18 22:21:03 2003 @@ -262,7 +262,11 @@ uio.uio_iov = &iov; uio.uio_fmode = filp->f_mode; uio.uio_segflg = UIO_SYSSPACE; - curr_offset = uio.uio_offset = filp->f_pos; + curr_offset = filp->f_pos; + if (filp->f_pos != 0x7fffffff) + uio.uio_offset = filp->f_pos; + else + uio.uio_offset = 0xffffffff; while (!eof) { uio.uio_resid = iov.iov_len = rlen; @@ -283,13 +287,13 @@ namelen = strlen(dbp->d_name); if (filldir(dirent, dbp->d_name, namelen, - (loff_t) curr_offset, + (loff_t) curr_offset & 0x7fffffff, (ino_t) dbp->d_ino, DT_UNKNOWN)) { goto done; } size -= dbp->d_reclen; - curr_offset = (loff_t)dbp->d_off & 0x7fffffff; + curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */; dbp = nextdp(dbp); } } diff -Nru a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c --- a/fs/xfs/linux/xfs_iops.c Mon Aug 18 22:21:02 2003 +++ b/fs/xfs/linux/xfs_iops.c Mon Aug 18 22:21:02 2003 @@ -109,14 +109,20 @@ struct inode *ip; vattr_t va; vnode_t *vp = NULL, *dvp = LINVFS_GET_VP(dir); + xfs_acl_t *default_acl = NULL; xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS; - int have_default_acl = 0; - int error = EINVAL; + int error; - if (test_default_acl) - have_default_acl = test_default_acl(dvp); + if (test_default_acl && test_default_acl(dvp)) { + if (!_ACL_ALLOC(default_acl)) + return -ENOMEM; + if (!_ACL_GET_DEFAULT(dvp, default_acl)) { + _ACL_FREE(default_acl); + default_acl = NULL; + } + } - if (IS_POSIXACL(dir) && !have_default_acl && has_fs_struct(current)) + if (IS_POSIXACL(dir) && !default_acl && has_fs_struct(current)) mode &= ~current->fs->umask; memset(&va, 0, sizeof(va)); @@ -140,13 +146,36 @@ break; } + if (default_acl) { + if (!error) { + error = _ACL_INHERIT(vp, &va, default_acl); + if (!error) { + VMODIFY(vp); + } else { + struct dentry teardown = {}; + int err2; + + /* Oh, the horror. + * If we can't add the ACL we must back out. + * ENOSPC can hit here, among other things. + */ + teardown.d_inode = ip = LINVFS_GET_IP(vp); + teardown.d_name = dentry->d_name; + remove_inode_hash(ip); + make_bad_inode(ip); + if (S_ISDIR(mode)) + VOP_RMDIR(dvp, &teardown, NULL, err2); + else + VOP_REMOVE(dvp, &teardown, NULL, err2); + VN_RELE(vp); + } + } + _ACL_FREE(default_acl); + } + if (!error) { ASSERT(vp); ip = LINVFS_GET_IP(vp); - if (!ip) { - VN_RELE(vp); - return -ENOMEM; - } if (S_ISCHR(mode) || S_ISBLK(mode)) ip->i_rdev = to_kdev_t(rdev); @@ -154,19 +183,6 @@ validate_fields(ip); d_instantiate(dentry, ip); validate_fields(dir); - } - - if (!error && have_default_acl) { - _ACL_DECL (pdacl); - - if (!_ACL_ALLOC(pdacl)) { - error = -ENOMEM; - } else { - if (_ACL_GET_DEFAULT(dvp, pdacl)) - error = _ACL_INHERIT(vp, &va, pdacl); - VMODIFY(vp); - _ACL_FREE(pdacl); - } } return -error; } diff -Nru a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c --- a/fs/xfs/linux/xfs_super.c Mon Aug 18 22:21:05 2003 +++ b/fs/xfs/linux/xfs_super.c Mon Aug 18 22:21:05 2003 @@ -507,6 +507,24 @@ } STATIC int +linvfs_sync_super( + struct super_block *sb, + int wait) +{ + vfs_t *vfsp = LINVFS_GET_VFS(sb); + int error; + int flags = SYNC_FSDATA; + + if (wait) + flags |= SYNC_WAIT; + + VFS_SYNC(vfsp, flags, NULL, error); + sb->s_dirt = 0; + + return -error; +} + +STATIC int linvfs_statfs( struct super_block *sb, struct kstatfs *statp) @@ -798,6 +816,7 @@ .clear_inode = linvfs_clear_inode, .put_super = linvfs_put_super, .write_super = linvfs_write_super, + .sync_fs = linvfs_sync_super, .write_super_lockfs = linvfs_freeze_fs, .unlockfs = linvfs_unfreeze_fs, .statfs = linvfs_statfs, diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c --- a/fs/xfs/pagebuf/page_buf.c Mon Aug 18 22:21:01 2003 +++ b/fs/xfs/pagebuf/page_buf.c Mon Aug 18 22:21:01 2003 @@ -1114,10 +1114,10 @@ add_wait_queue(&pb->pb_waiters, &wait); for (;;) { current->state = TASK_UNINTERRUPTIBLE; - if (atomic_read(&pb->pb_pin_count) == 0) { + if (atomic_read(&pb->pb_pin_count) == 0) break; - } - pagebuf_run_queues(pb); + if (atomic_read(&pb->pb_io_remaining)) + blk_run_queues(); schedule(); } remove_wait_queue(&pb->pb_waiters, &wait); @@ -1224,26 +1224,27 @@ return status; } - pb->pb_flags &= - ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI|PBF_READ_AHEAD); - pb->pb_flags |= flags & - (PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_READ_AHEAD); + pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC | \ + PBF_DELWRI | PBF_READ_AHEAD | PBF_RUN_QUEUES); + pb->pb_flags |= flags & (PBF_READ | PBF_WRITE | PBF_ASYNC | \ + PBF_SYNC | PBF_READ_AHEAD | PBF_RUN_QUEUES); BUG_ON(pb->pb_bn == PAGE_BUF_DADDR_NULL); - /* For writes call internal function which checks for - * filesystem specific callout function and execute it. + /* For writes allow an alternate strategy routine to precede + * the actual I/O request (which may not be issued at all in + * a shutdown situation, for example). */ - if (flags & PBF_WRITE) { - status = __pagebuf_iorequest(pb); - } else { - status = pagebuf_iorequest(pb); - } + status = (flags & PBF_WRITE) ? + pagebuf_iostrategy(pb) : pagebuf_iorequest(pb); - /* Wait for I/O if we are not an async request */ - if ((status == 0) && (flags & PBF_ASYNC) == 0) { + /* Wait for I/O if we are not an async request. + * Note: async I/O request completion will release the buffer, + * and that can already be done by this point. So using the + * buffer pointer from here on, after async I/O, is invalid. + */ + if (!status && !(flags & PBF_ASYNC)) status = pagebuf_iowait(pb); - } return status; } @@ -1381,8 +1382,6 @@ nr_pages = total_nr_pages; bio = bio_alloc(GFP_NOIO, nr_pages); - - BUG_ON(bio == NULL); bio->bi_bdev = pb->pb_target->pbr_bdev; bio->bi_sector = sector; bio->bi_end_io = bio_end_io_pagebuf; @@ -1418,6 +1417,12 @@ } else { pagebuf_ioerror(pb, EIO); } + + if (pb->pb_flags & PBF_RUN_QUEUES) { + pb->pb_flags &= ~PBF_RUN_QUEUES; + if (atomic_read(&pb->pb_io_remaining) > 1) + blk_run_queues(); + } } /* @@ -1453,6 +1458,8 @@ _pagebuf_wait_unpin(pb); } + pagebuf_hold(pb); + /* Set the count to 1 initially, this will stop an I/O * completion callout which happens before we have started * all the I/O from calling pagebuf_iodone too early. @@ -1460,6 +1467,8 @@ atomic_set(&pb->pb_io_remaining, 1); _pagebuf_ioapply(pb); _pagebuf_iodone(pb, 0); + + pagebuf_rele(pb); return 0; } @@ -1475,7 +1484,8 @@ page_buf_t *pb) { PB_TRACE(pb, PB_TRACE_REC(iowait), 0); - pagebuf_run_queues(pb); + if (atomic_read(&pb->pb_io_remaining)) + blk_run_queues(); down(&pb->pb_iodonesema); PB_TRACE(pb, PB_TRACE_REC(iowaited), (int)pb->pb_error); return pb->pb_error; @@ -1554,6 +1564,7 @@ } } + /* * Pagebuf delayed write buffer handling */ @@ -1683,13 +1694,13 @@ pb->pb_flags &= ~PBF_DELWRI; pb->pb_flags |= PBF_WRITE; - __pagebuf_iorequest(pb); + pagebuf_iostrategy(pb); } if (as_list_len > 0) purge_addresses(); if (count) - pagebuf_run_queues(NULL); + blk_run_queues(); force_flush = 0; } while (pbd_active == 1); @@ -1756,9 +1767,9 @@ pb->pb_flags &= ~PBF_DELWRI; pb->pb_flags |= PBF_WRITE; - __pagebuf_iorequest(pb); + pagebuf_iostrategy(pb); if (++flush_cnt > 32) { - pagebuf_run_queues(NULL); + blk_run_queues(); flush_cnt = 0; } @@ -1767,7 +1778,7 @@ spin_unlock(&pbd_delwrite_lock); - pagebuf_run_queues(NULL); + blk_run_queues(); if (pinptr) *pinptr = pincount; diff -Nru a/fs/xfs/pagebuf/page_buf.h b/fs/xfs/pagebuf/page_buf.h --- a/fs/xfs/pagebuf/page_buf.h Mon Aug 18 22:21:04 2003 +++ b/fs/xfs/pagebuf/page_buf.h Mon Aug 18 22:21:04 2003 @@ -128,6 +128,7 @@ PBF_FORCEIO = (1 << 21), PBF_FLUSH = (1 << 22), /* flush disk write cache */ PBF_READ_AHEAD = (1 << 23), + PBF_RUN_QUEUES = (1 << 24), /* run block device task queue */ } page_buf_flags_t; @@ -239,10 +240,6 @@ } page_buf_t; -/* - * page_buf module entry points - */ - /* Finding and Reading Buffers */ extern page_buf_t *pagebuf_find( /* find buffer for block if */ @@ -276,12 +273,11 @@ size_t len, struct pb_target *); /* mount point "fake" inode */ -extern int pagebuf_associate_memory( +extern int pagebuf_associate_memory( page_buf_t *, void *, size_t); - extern void pagebuf_hold( /* increment reference count */ page_buf_t *); /* buffer to hold */ @@ -291,7 +287,7 @@ size_t, /* length of range */ page_buf_flags_t); /* additional read flags */ -/* Writing and Releasing Buffers */ +/* Releasing Buffers */ extern void pagebuf_free( /* deallocate a buffer */ page_buf_t *); /* buffer to deallocate */ @@ -314,11 +310,7 @@ extern void pagebuf_unlock( /* unlock buffer */ page_buf_t *); /* buffer to unlock */ -/* Buffer Utility Routines */ -static inline int pagebuf_geterror(page_buf_t *pb) -{ - return (pb ? pb->pb_error : ENOMEM); -} +/* Buffer Read and Write Routines */ extern void pagebuf_iodone( /* mark buffer I/O complete */ page_buf_t *, /* buffer to mark */ @@ -339,21 +331,9 @@ extern int pagebuf_iorequest( /* start real I/O */ page_buf_t *); /* buffer to convey to device */ - /* - * pagebuf_iorequest is the core I/O request routine. - * It assumes that the buffer is well-formed and - * mapped and ready for physical I/O, unlike - * pagebuf_iostart() and pagebuf_iophysio(). Those - * routines call the inode pagebuf_ioinitiate routine to start I/O, - * if it is present, or else call pagebuf_iorequest() - * directly if the inode pagebuf_ioinitiate routine is not present. - */ - extern int pagebuf_iowait( /* wait for buffer I/O done */ page_buf_t *); /* buffer to wait on */ -extern caddr_t pagebuf_offset(page_buf_t *, size_t); - extern void pagebuf_iomove( /* move data in/out of pagebuf */ page_buf_t *, /* buffer to manipulate */ size_t, /* starting buffer offset */ @@ -361,6 +341,22 @@ caddr_t, /* data pointer */ page_buf_rw_t); /* direction */ +static inline int pagebuf_iostrategy(page_buf_t *pb) +{ + return pb->pb_strat ? pb->pb_strat(pb) : pagebuf_iorequest(pb); +} + +static inline int pagebuf_geterror(page_buf_t *pb) +{ + return pb ? pb->pb_error : ENOMEM; +} + +/* Buffer Utility Routines */ + +extern caddr_t pagebuf_offset( /* pointer at offset in buffer */ + page_buf_t *, /* buffer to offset into */ + size_t); /* offset */ + /* Pinning Buffer Storage in Memory */ extern void pagebuf_pin( /* pin buffer in memory */ @@ -369,33 +365,24 @@ extern void pagebuf_unpin( /* unpin buffered data */ page_buf_t *); /* buffer to unpin */ -extern int pagebuf_ispin( page_buf_t *); /* check if pagebuf is pinned */ - -/* Reading and writing pages */ +extern int pagebuf_ispin( /* check if buffer is pinned */ + page_buf_t *); /* buffer to check */ -extern void pagebuf_delwri_dequeue(page_buf_t *); +/* Delayed Write Buffer Routines */ #define PBDF_WAIT 0x01 #define PBDF_TRYLOCK 0x02 extern void pagebuf_delwri_flush( - struct pb_target *, + pb_target_t *, unsigned long, int *); -extern int pagebuf_init(void); -extern void pagebuf_terminate(void); +extern void pagebuf_delwri_dequeue( + page_buf_t *); -static __inline__ int __pagebuf_iorequest(page_buf_t *pb) -{ - if (pb->pb_strat) - return pb->pb_strat(pb); - return pagebuf_iorequest(pb); -} +/* Buffer Daemon Setup Routines */ -static __inline__ void pagebuf_run_queues(page_buf_t *pb) -{ - if (!pb || atomic_read(&pb->pb_io_remaining)) - blk_run_queues(); -} +extern int pagebuf_init(void); +extern void pagebuf_terminate(void); #endif /* __PAGE_BUF_H__ */ diff -Nru a/fs/xfs/pagebuf/page_buf_locking.c b/fs/xfs/pagebuf/page_buf_locking.c --- a/fs/xfs/pagebuf/page_buf_locking.c Mon Aug 18 22:21:03 2003 +++ b/fs/xfs/pagebuf/page_buf_locking.c Mon Aug 18 22:21:03 2003 @@ -113,7 +113,8 @@ ASSERT(pb->pb_flags & _PBF_LOCKABLE); PB_TRACE(pb, PB_TRACE_REC(lock), 0); - pagebuf_run_queues(pb); + if (atomic_read(&pb->pb_io_remaining)) + blk_run_queues(); down(&pb->pb_sema); PB_SET_OWNER(pb); PB_TRACE(pb, PB_TRACE_REC(locked), 0); diff -Nru a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c --- a/fs/xfs/xfs_attr.c Mon Aug 18 22:21:04 2003 +++ b/fs/xfs/xfs_attr.c Mon Aug 18 22:21:04 2003 @@ -1718,6 +1718,7 @@ int i; state = xfs_da_state_alloc(); + state->holeok = 1; state->args = args; state->mp = args->dp->i_mount; state->blocksize = state->mp->m_sb.sb_blocksize; diff -Nru a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c --- a/fs/xfs/xfs_bmap.c Mon Aug 18 22:21:05 2003 +++ b/fs/xfs/xfs_bmap.c Mon Aug 18 22:21:05 2003 @@ -3810,7 +3810,7 @@ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_DEV: - ip->i_d.di_forkoff = roundup(sizeof(dev_t), 8) >> 3; + ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; break; case XFS_DINODE_FMT_UUID: ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3; diff -Nru a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h --- a/fs/xfs/xfs_buf.h Mon Aug 18 22:21:06 2003 +++ b/fs/xfs/xfs_buf.h Mon Aug 18 22:21:06 2003 @@ -215,21 +215,16 @@ static inline int xfs_bawrite(void *mp, page_buf_t *bp) { - int ret; - bp->pb_fspriv3 = mp; bp->pb_strat = xfs_bdstrat_cb; xfs_buf_undelay(bp); - if ((ret = pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC)) == 0) - pagebuf_run_queues(bp); - return ret; + return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | PBF_RUN_QUEUES); } static inline void xfs_buf_relse(page_buf_t *bp) { if ((bp->pb_flags & _PBF_LOCKABLE) && !bp->pb_relse) pagebuf_unlock(bp); - pagebuf_rele(bp); } @@ -263,23 +258,19 @@ static inline int XFS_bwrite(page_buf_t *pb) { - int sync = (pb->pb_flags & PBF_ASYNC) == 0; - int error; + int iowait = (pb->pb_flags & PBF_ASYNC) == 0; + int error = 0; pb->pb_flags |= PBF_SYNC; + if (!iowait) + pb->pb_flags |= PBF_RUN_QUEUES; xfs_buf_undelay(pb); - - __pagebuf_iorequest(pb); - - if (sync) { + pagebuf_iostrategy(pb); + if (iowait) { error = pagebuf_iowait(pb); xfs_buf_relse(pb); - } else { - pagebuf_run_queues(pb); - error = 0; } - return error; } @@ -320,4 +311,4 @@ #define xfs_buf_get_noaddr(len, target) pagebuf_get_no_daddr((len), (target)) #define xfs_buf_free(bp) pagebuf_free(bp) -#endif +#endif /* __XFS_BUF_H__ */ diff -Nru a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c --- a/fs/xfs/xfs_da_btree.c Mon Aug 18 22:21:05 2003 +++ b/fs/xfs/xfs_da_btree.c Mon Aug 18 22:21:05 2003 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -1141,10 +1141,13 @@ xfs_da_node_entry_t *btree; xfs_dablk_t blkno; int probe, span, max, error, retval; + xfs_daddr_t mappedbno; xfs_dahash_t hashval; xfs_da_args_t *args; args = state->args; + mappedbno = state->holeok ? -2 : -1; + /* * Descend thru the B-tree searching each level for the right * node to use, until the right hashval is found. @@ -1160,15 +1163,15 @@ * Read the next node down in the tree. */ blk->blkno = blkno; - error = xfs_da_read_buf(state->args->trans, state->args->dp, - blkno, -1, &blk->bp, - state->args->whichfork); + error = xfs_da_read_buf(args->trans, args->dp, blkno, + mappedbno, &blk->bp, args->whichfork); + if (!error && unlikely(state->holeok && !blk->bp)) + error = XFS_ERROR(ENOATTR); /* always attr here */ if (error) { blk->blkno = 0; state->path.active--; return(error); } - ASSERT(blk->bp != NULL); curr = blk->bp->data; ASSERT(INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC || INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) || @@ -1187,7 +1190,7 @@ */ max = INT_GET(node->hdr.count, ARCH_CONVERT); probe = span = max / 2; - hashval = state->args->hashval; + hashval = args->hashval; for (btree = &node->btree[probe]; span > 4; btree = &node->btree[probe]) { span /= 2; @@ -1250,22 +1253,22 @@ for (;;) { if (blk->magic == XFS_DIR_LEAF_MAGIC) { ASSERT(XFS_DIR_IS_V1(state->mp)); - retval = xfs_dir_leaf_lookup_int(blk->bp, state->args, + retval = xfs_dir_leaf_lookup_int(blk->bp, args, &blk->index); } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { ASSERT(XFS_DIR_IS_V2(state->mp)); - retval = xfs_dir2_leafn_lookup_int(blk->bp, state->args, + retval = xfs_dir2_leafn_lookup_int(blk->bp, args, &blk->index, state); } #ifdef __KERNEL__ else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { - retval = xfs_attr_leaf_lookup_int(blk->bp, state->args); - blk->index = state->args->index; - state->args->blkno = blk->blkno; + retval = xfs_attr_leaf_lookup_int(blk->bp, args); + blk->index = args->index; + args->blkno = blk->blkno; } #endif if (((retval == ENOENT) || (retval == ENOATTR)) && - (blk->hashval == state->args->hashval)) { + (blk->hashval == args->hashval)) { error = xfs_da_path_shift(state, &state->path, 1, 1, &retval); if (error) diff -Nru a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h --- a/fs/xfs/xfs_da_btree.h Mon Aug 18 22:21:03 2003 +++ b/fs/xfs/xfs_da_btree.h Mon Aug 18 22:21:03 2003 @@ -185,14 +185,14 @@ int index; /* index of attr of interest in blk */ xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ int rmtblkcnt; /* remote attr value block count */ - int rename; /* T/F: this is an atomic rename op */ xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ int index2; /* index of 2nd attr in blk */ xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ int rmtblkcnt2; /* remote attr value block count */ - int justcheck; /* check for ok with no space */ - int addname; /* T/F: this is an add operation */ - int oknoent; /* T/F: ok to return ENOENT, else die */ + int justcheck : 1; /* T/F: check for ok with no space */ + int rename : 1; /* T/F: this is an atomic rename op */ + int addname : 1; /* T/F: this is an add operation */ + int oknoent : 1; /* T/F: ok to return ENOENT, else die */ } xfs_da_args_t; /* @@ -253,6 +253,7 @@ xfs_da_state_path_t path; /* search/split paths */ xfs_da_state_path_t altpath; /* alternate path for join */ unsigned int inleaf : 1; /* insert into 1->lf, 0->splf */ + unsigned int holeok : 1; /* T/F: can deal with a hole */ unsigned int extravalid : 1; /* T/F: extrablk is in use */ unsigned int extraafter : 1; /* T/F: extrablk is after new */ xfs_da_state_blk_t extrablk; /* for double-splits on leafs */ diff -Nru a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h --- a/fs/xfs/xfs_dinode.h Mon Aug 18 22:21:04 2003 +++ b/fs/xfs/xfs_dinode.h Mon Aug 18 22:21:04 2003 @@ -72,7 +72,8 @@ __uint32_t di_gid; /* owner's group id */ __uint32_t di_nlink; /* number of links to file */ __uint16_t di_projid; /* owner's project id */ - __uint8_t di_pad[10]; /* unused, zeroed space */ + __uint8_t di_pad[8]; /* unused, zeroed space */ + __uint16_t di_flushiter; /* incremented on flush */ xfs_timestamp_t di_atime; /* time last accessed */ xfs_timestamp_t di_mtime; /* time last modified */ xfs_timestamp_t di_ctime; /* time created/inode modified */ @@ -88,6 +89,8 @@ __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ __uint32_t di_gen; /* generation number */ } xfs_dinode_core_t; + +#define DI_MAX_FLUSH 0xffff typedef struct xfs_dinode { diff -Nru a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h --- a/fs/xfs/xfs_dir2_leaf.h Mon Aug 18 22:21:01 2003 +++ b/fs/xfs/xfs_dir2_leaf.h Mon Aug 18 22:21:01 2003 @@ -64,7 +64,7 @@ * Offset in data space of a data entry. */ typedef __uint32_t xfs_dir2_dataptr_t; -#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0x7fffffff) +#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff) #define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0) /* diff -Nru a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c --- a/fs/xfs/xfs_dir_leaf.c Mon Aug 18 22:21:05 2003 +++ b/fs/xfs/xfs_dir_leaf.c Mon Aug 18 22:21:05 2003 @@ -560,14 +560,7 @@ */ if (sbp->seqno == 0 || sbp == sbuf) lastresid = uio->uio_resid; - /* - * NOTE! Linux "filldir" semantics require that the - * offset "cookie" be for this entry, not the - * next; all the actual shuffling to make it - * "look right" to the user is done in filldir. - */ - XFS_PUT_COOKIE(p.cook, mp, 0, sbp->seqno, sbp->hash); - + XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash); #if XFS_BIG_FILESYSTEMS p.ino = sbp->ino + mp->m_inoadd; #else @@ -575,9 +568,7 @@ #endif p.name = sbp->name; p.namelen = sbp->namelen; - retval = p.put(&p); - if (!p.done) { uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash); @@ -586,20 +577,12 @@ xfs_dir_trace_g_du("sf: E-O-B", dp, uio); return retval; } - sbp++; } - kmem_free(sbuf, sbsize); - - XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH); - uio->uio_offset = p.cook.o; - *eofp = 1; - xfs_dir_trace_g_du("sf: E-O-F", dp, uio); - return 0; } @@ -2070,16 +2053,6 @@ return XFS_ERROR(EFSCORRUPTED); } - thishash = INT_GET(entry->hashval, ARCH_CONVERT); - - /* - * NOTE! Linux "filldir" semantics require that the - * offset "cookie" be for this entry, not the - * next; all the actual shuffling to make it - * "look right" to the user is done in filldir. - */ - XFS_PUT_COOKIE(p.cook, mp, bno, entno, thishash); - xfs_dir_trace_g_duc("leaf: middle cookie ", dp, uio, p.cook.o); @@ -2090,17 +2063,19 @@ nextentno = entno + 1; else nextentno = 0; + XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash); + xfs_dir_trace_g_duc("leaf: middle cookie ", + dp, uio, p.cook.o); - } else if (INT_GET(leaf->hdr.info.forw, ARCH_CONVERT)) { + } else if ((thishash = INT_GET(leaf->hdr.info.forw, + ARCH_CONVERT))) { xfs_dabuf_t *bp2; xfs_dir_leafblock_t *leaf2; ASSERT(nextda != -1); - retval = xfs_da_read_buf(dp->i_transp, dp, - INT_GET(leaf->hdr.info.forw, - ARCH_CONVERT), nextda, - &bp2, XFS_DATA_FORK); + retval = xfs_da_read_buf(dp->i_transp, dp, thishash, + nextda, &bp2, XFS_DATA_FORK); if (retval) return(retval); @@ -2124,13 +2099,13 @@ nexthash = INT_GET(leaf2->entries[0].hashval, ARCH_CONVERT); nextentno = -1; - + XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash); xfs_da_brelse(dp->i_transp, bp2); xfs_dir_trace_g_duc("leaf: next blk cookie", dp, uio, p.cook.o); } else { nextentno = -1; - nexthash = XFS_DA_MAXHASH; + XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH); } /* @@ -2147,7 +2122,8 @@ * provided is big enough to handle it (see pv763517). */ #if (BITS_PER_LONG == 32) - if (INT_GET(entry->hashval, ARCH_CONVERT) != lasthash) { + if ((thishash = INT_GET(entry->hashval, ARCH_CONVERT)) + != lasthash) { XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); lastresid = uio->uio_resid; lasthash = thishash; @@ -2156,6 +2132,7 @@ dp, uio, p.cook.o); } #else + thishash = INT_GET(entry->hashval, ARCH_CONVERT); XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); lastresid = uio->uio_resid; #endif /* BITS_PER_LONG == 32 */ @@ -2186,8 +2163,6 @@ return(retval); } } - - XFS_PUT_COOKIE(p.cook, mp, 0, 0, nexthash); uio->uio_offset = p.cook.o; diff -Nru a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c --- a/fs/xfs/xfs_inode.c Mon Aug 18 22:21:06 2003 +++ b/fs/xfs/xfs_inode.c Mon Aug 18 22:21:06 2003 @@ -825,6 +825,8 @@ sizeof(buf_core->di_pad)); } + INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch); + INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec, dir, arch); INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec, @@ -956,6 +958,7 @@ ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT); ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT); ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT); + ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT); /* * Make sure to pull in the mode here as well in * case the inode is released without being used. @@ -3233,6 +3236,13 @@ goto corrupt_out; } /* + * bump the flush iteration count, used to detect flushes which + * postdate a log record during recovery. + */ + + ip->i_d.di_flushiter++; + + /* * Copy the dirty parts of the inode into the on-disk * inode. We always copy out the core of the inode, * because if the inode is dirty at all the core must @@ -3240,6 +3250,10 @@ */ xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1, ARCH_CONVERT); + + /* Wrap, we never let the log put out DI_MAX_FLUSH */ + if (ip->i_d.di_flushiter == DI_MAX_FLUSH) + ip->i_d.di_flushiter = 0; /* * If this is really an old format inode and the superblock version diff -Nru a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c --- a/fs/xfs/xfs_log_recover.c Mon Aug 18 22:21:03 2003 +++ b/fs/xfs/xfs_log_recover.c Mon Aug 18 22:21:03 2003 @@ -2326,6 +2326,26 @@ XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } + + /* Skip replay when the on disk inode is newer than the log one */ + if (dicp->di_flushiter < + INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)) { + /* + * Deal with the wrap case, DI_MAX_FLUSH is less + * than smaller numbers + */ + if ((INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT) + == DI_MAX_FLUSH) && + (dicp->di_flushiter < (DI_MAX_FLUSH>>1))) { + /* do nothing */ + } else { + xfs_buf_relse(bp); + return 0; + } + } + /* Take the opportunity to reset the flush iteration count */ + dicp->di_flushiter = 0; + if (unlikely((dicp->di_mode & IFMT) == IFREG)) { if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && (dicp->di_format != XFS_DINODE_FMT_BTREE)) { diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c --- a/fs/xfs/xfs_vfsops.c Mon Aug 18 22:21:01 2003 +++ b/fs/xfs/xfs_vfsops.c Mon Aug 18 22:21:01 2003 @@ -1506,7 +1506,7 @@ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = xfs_trans_commit(tp, 0, NULL); xfs_iunlock(ip, XFS_ILOCK_EXCL); - xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); + xfs_log_force(mp, (xfs_lsn_t)0, log_flags); } /* diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c --- a/fs/xfs/xfs_vnodeops.c Mon Aug 18 22:21:06 2003 +++ b/fs/xfs/xfs_vnodeops.c Mon Aug 18 22:21:06 2003 @@ -2813,7 +2813,6 @@ xfs_inode_t *cdp; /* inode of created dir */ vnode_t *cvp; /* vnode of created dir */ xfs_trans_t *tp; - xfs_dev_t rdev; xfs_mount_t *mp; int cancel_flags; int error; @@ -2912,10 +2911,9 @@ /* * create the directory inode. */ - rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; error = xfs_dir_ialloc(&tp, dp, MAKEIMODE(vap->va_type,vap->va_mode), 2, - rdev, credp, prid, resblks > 0, + 0, credp, prid, resblks > 0, &cdp, NULL); if (error) { if (error == ENOSPC) @@ -3336,7 +3334,6 @@ xfs_inode_t *ip; int error; int pathlen; - xfs_dev_t rdev; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; boolean_t dp_joined_to_trans; @@ -3479,10 +3476,8 @@ /* * Allocate an inode for the symlink. */ - rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; - error = xfs_dir_ialloc(&tp, dp, IFLNK | (vap->va_mode&~IFMT), - 1, rdev, credp, prid, resblks > 0, &ip, NULL); + 1, 0, credp, prid, resblks > 0, &ip, NULL); if (error) { if (error == ENOSPC) goto error_return; @@ -3730,9 +3725,7 @@ int flags) { xfs_inode_t *ip; - xfs_dinode_t *dip; xfs_mount_t *mp; - xfs_buf_t *bp; int error = 0; ip = XFS_BHVTOI(bdp); @@ -3778,44 +3771,30 @@ * now, they get caught later by xfs_sync. */ if (flags & FLUSH_INODE) { - if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { - if ((xfs_ipincount(ip) == 0) && xfs_iflock_nowait(ip)) { - int flush_flags; - -#if 0 - /* not turning this on until some - * performance analysis is done - */ - if (flags & FLUSH_SYNC) - flush_flags = XFS_IFLUSH_SYNC; - else -#endif - flush_flags = XFS_IFLUSH_DELWRI_ELSE_ASYNC; + int flush_flags; - xfs_ifunlock(ip); - xfs_iunlock(ip, XFS_ILOCK_SHARED); - error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0); - if (error) - return error; - xfs_buf_relse(bp); + if (xfs_ipincount(ip)) + return EAGAIN; - if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED) == 0) - return EAGAIN; - - if (xfs_ipincount(ip) || - !xfs_iflock_nowait(ip)) { - xfs_iunlock(ip, XFS_ILOCK_SHARED); - return EAGAIN; - } - - error = xfs_iflush(ip, flush_flags); - } else { - error = EAGAIN; + if (flags & FLUSH_SYNC) { + xfs_ilock(ip, XFS_ILOCK_SHARED); + xfs_iflock(ip); + } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { + if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) { + xfs_iunlock(ip, XFS_ILOCK_SHARED); + return EAGAIN; } - xfs_iunlock(ip, XFS_ILOCK_SHARED); } else { - error = EAGAIN; + return EAGAIN; } + + if (flags & FLUSH_SYNC) + flush_flags = XFS_IFLUSH_SYNC; + else + flush_flags = XFS_IFLUSH_ASYNC; + + error = xfs_iflush(ip, flush_flags); + xfs_iunlock(ip, XFS_ILOCK_SHARED); } return error; diff -Nru a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c --- a/fs/xfs/xfsidbg.c Mon Aug 18 22:21:05 2003 +++ b/fs/xfs/xfsidbg.c Mon Aug 18 22:21:05 2003 @@ -3033,11 +3033,12 @@ INT_GET(dip->di_format, convert), xfs_fmtformat( (xfs_dinode_fmt_t)INT_GET(dip->di_format, convert))); - kdb_printf("nlink 0x%x uid 0x%x gid 0x%x projid 0x%x\n", + kdb_printf("nlink %d uid %d gid %d projid %d flushiter %u\n", INT_GET(dip->di_nlink, convert), INT_GET(dip->di_uid, convert), INT_GET(dip->di_gid, convert), - (uint)INT_GET(dip->di_projid, convert)); + (uint)INT_GET(dip->di_projid, convert), + (uint)INT_GET(dip->di_flushiter, convert)); kdb_printf("atime 0x%x:%x mtime 0x%x:%x ctime 0x%x:%x\n", INT_GET(dip->di_atime.t_sec, convert), INT_GET(dip->di_atime.t_nsec, convert), diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h Mon Aug 18 22:21:05 2003 +++ b/include/acpi/acconfig.h Mon Aug 18 22:21:05 2003 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20030714 +#define ACPI_CA_VERSION 0x20030813 /* Maximum objects in the various object caches */ diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h --- a/include/acpi/acpi_drivers.h Mon Aug 18 22:21:04 2003 +++ b/include/acpi/acpi_drivers.h Mon Aug 18 22:21:04 2003 @@ -60,7 +60,7 @@ /* ACPI PCI Interrupt Link (pci_link.c) */ int acpi_pci_link_check (void); -int acpi_pci_link_get_irq (acpi_handle handle, int index); +int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low); /* ACPI PCI Interrupt Routing (pci_irq.c) */ diff -Nru a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h --- a/include/asm-alpha/smp.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-alpha/smp.h Mon Aug 18 22:21:06 2003 @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -44,27 +45,12 @@ #define hard_smp_processor_id() __hard_smp_processor_id() #define smp_processor_id() (current_thread_info()->cpu) -extern unsigned long cpu_present_mask; -extern volatile unsigned long cpu_online_map; +extern cpumask_t cpu_present_mask; +extern cpumask_t long cpu_online_map; extern int smp_num_cpus; -#define cpu_possible(cpu) (cpu_present_mask & (1UL << (cpu))) -#define cpu_online(cpu) (cpu_online_map & (1UL << (cpu))) - -static inline int -num_online_cpus(void) -{ - return hweight64(cpu_online_map); -} - -extern inline int -any_online_cpu(unsigned int mask) -{ - if (mask & cpu_online_map) - return __ffs(mask & cpu_online_map); - - return -1; -} +#define cpu_possible(cpu) cpu_isset(cpu, cpu_present_mask) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu); diff -Nru a/include/asm-generic/cpumask_arith.h b/include/asm-generic/cpumask_arith.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-generic/cpumask_arith.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,43 @@ +#ifndef __ASM_GENERIC_CPUMASK_ARITH_H +#define __ASM_GENERIC_CPUMASK_ARITH_H + +/* + * Arithmetic type -based cpu bitmaps. A single unsigned long is used + * to contain the whole cpu bitmap. + */ + +#define cpu_set(cpu, map) set_bit(cpu, &(map)) +#define cpu_clear(cpu, map) clear_bit(cpu, &(map)) +#define cpu_isset(cpu, map) test_bit(cpu, &(map)) +#define cpu_test_and_set(cpu, map) test_and_set_bit(cpu, &(map)) + +#define cpus_and(dst,src1,src2) do { dst = (src1) & (src2); } while (0) +#define cpus_or(dst,src1,src2) do { dst = (src1) | (src2); } while (0) +#define cpus_clear(map) do { map = 0; } while (0) +#define cpus_complement(map) do { map = ~(map); } while (0) +#define cpus_equal(map1, map2) ((map1) == (map2)) +#define cpus_empty(map) ((map) == 0) + +#if BITS_PER_LONG == 32 +#define cpus_weight(map) hweight32(map) +#elif BITS_PER_LONG == 64 +#define cpus_weight(map) hweight64(map) +#endif + +#define cpus_shift_right(dst, src, n) do { dst = (src) >> (n); } while (0) +#define cpus_shift_left(dst, src, n) do { dst = (src) << (n); } while (0) + +#define any_online_cpu(map) ({ (map) ? first_cpu(map) : NR_CPUS; }) + +#define CPU_MASK_ALL (~((cpumask_t)0) >> (8*sizeof(cpumask_t) - NR_CPUS)) +#define CPU_MASK_NONE ((cpumask_t)0) + +/* only ever use this for things that are _never_ used on large boxen */ +#define cpus_coerce(map) ((unsigned long)(map)) +#define cpus_promote(map) ({ map; }) +#define cpumask_of_cpu(cpu) ({ ((cpumask_t)1) << (cpu); }) + +#define first_cpu(map) __ffs(map) +#define next_cpu(cpu, map) find_next_bit(&(map), NR_CPUS, cpu + 1) + +#endif /* __ASM_GENERIC_CPUMASK_ARITH_H */ diff -Nru a/include/asm-generic/cpumask_array.h b/include/asm-generic/cpumask_array.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-generic/cpumask_array.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,47 @@ +#ifndef __ASM_GENERIC_CPUMASK_ARRAY_H +#define __ASM_GENERIC_CPUMASK_ARRAY_H + +/* + * Array-based cpu bitmaps. An array of unsigned longs is used to contain + * the bitmap, and then contained in a structure so it may be passed by + * value. + */ + +#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS) + +#define cpu_set(cpu, map) set_bit(cpu, (map).mask) +#define cpu_clear(cpu, map) clear_bit(cpu, (map).mask) +#define cpu_isset(cpu, map) test_bit(cpu, (map).mask) +#define cpu_test_and_set(cpu, map) test_and_set_bit(cpu, (map).mask) + +#define cpus_and(dst,src1,src2) bitmap_and((dst).mask,(src1).mask, (src2).mask, NR_CPUS) +#define cpus_or(dst,src1,src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS) +#define cpus_clear(map) bitmap_clear((map).mask, NR_CPUS) +#define cpus_complement(map) bitmap_complement((map).mask, NR_CPUS) +#define cpus_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, NR_CPUS) +#define cpus_empty(map) bitmap_empty(map.mask, NR_CPUS) +#define cpus_weight(map) bitmap_weight((map).mask, NR_CPUS) +#define cpus_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, NR_CPUS) +#define cpus_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, NR_CPUS) +#define first_cpu(map) find_first_bit((map).mask, NR_CPUS) +#define next_cpu(cpu, map) find_next_bit((map).mask, NR_CPUS, cpu + 1) + +/* only ever use this for things that are _never_ used on large boxen */ +#define cpus_coerce(map) ((map).mask[0]) +#define cpus_promote(map) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ + __cpu_mask.mask[0] = map; \ + __cpu_mask; \ + }) +#define cpumask_of_cpu(cpu) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ + cpu_set(cpu, __cpu_mask); \ + __cpu_mask; \ + }) +#define any_online_cpu(map) find_first_bit((map).mask, NR_CPUS) + +/* + * um, these need to be usable as static initializers + */ +#define CPU_MASK_ALL { {[0 ... CPU_ARRAY_SIZE-1] = ~0UL} } +#define CPU_MASK_NONE { {[0 ... CPU_ARRAY_SIZE-1] = 0UL} } + +#endif /* __ASM_GENERIC_CPUMASK_ARRAY_H */ diff -Nru a/include/asm-generic/cpumask_const_reference.h b/include/asm-generic/cpumask_const_reference.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-generic/cpumask_const_reference.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,29 @@ +#ifndef __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H +#define __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H + +struct cpumask_ref { + const cpumask_t *val; +}; + +typedef const struct cpumask_ref cpumask_const_t; + +#define mk_cpumask_const(map) ((cpumask_const_t){ &(map) }) +#define cpu_isset_const(cpu, map) cpu_isset(cpu, *(map).val) + +#define cpus_and_const(dst,src1,src2) cpus_and(dst,*(src1).val,*(src2).val) +#define cpus_or_const(dst,src1,src2) cpus_or(dst,*(src1).val,*(src2).val) + +#define cpus_equal_const(map1, map2) cpus_equal(*(map1).val, *(map2).val) + +#define cpus_copy_const(map1, map2) bitmap_copy((map1).mask, (map2).val->mask, NR_CPUS) + +#define cpus_empty_const(map) cpus_empty(*(map).val) +#define cpus_weight_const(map) cpus_weight(*(map).val) +#define first_cpu_const(map) first_cpu(*(map).val) +#define next_cpu_const(cpu, map) next_cpu(cpu, *(map).val) + +/* only ever use this for things that are _never_ used on large boxen */ +#define cpus_coerce_const(map) cpus_coerce(*(map).val) +#define any_online_cpu_const(map) any_online_cpu(*(map).val) + +#endif /* __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H */ diff -Nru a/include/asm-generic/cpumask_const_value.h b/include/asm-generic/cpumask_const_value.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-generic/cpumask_const_value.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,21 @@ +#ifndef __ASM_GENERIC_CPUMASK_CONST_VALUE_H +#define __ASM_GENERIC_CPUMASK_CONST_VALUE_H + +typedef const cpumask_t cpumask_const_t; + +#define mk_cpumask_const(map) ((cpumask_const_t)(map)) +#define cpu_isset_const(cpu, map) cpu_isset(cpu, map) +#define cpus_and_const(dst,src1,src2) cpus_and(dst, src1, src2) +#define cpus_or_const(dst,src1,src2) cpus_or(dst, src1, src2) +#define cpus_equal_const(map1, map2) cpus_equal(map1, map2) +#define cpus_empty_const(map) cpus_empty(map) +#define cpus_copy_const(map1, map2) do { map1 = (cpumask_t)map2; } while (0) +#define cpus_weight_const(map) cpus_weight(map) +#define first_cpu_const(map) first_cpu(map) +#define next_cpu_const(cpu, map) next_cpu(cpu, map) + +/* only ever use this for things that are _never_ used on large boxen */ +#define cpus_coerce_const(map) cpus_coerce(map) +#define any_online_cpu_const(map) any_online_cpu(map) + +#endif /* __ASM_GENERIC_CPUMASK_CONST_VALUE_H */ diff -Nru a/include/asm-generic/cpumask_up.h b/include/asm-generic/cpumask_up.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-generic/cpumask_up.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,58 @@ +#ifndef __ASM_GENERIC_CPUMASK_UP_H +#define __ASM_GENERIC_CPUMASK_UP_H + +#define cpus_coerce(map) (map) + +#define cpu_set(cpu, map) do { cpus_coerce(map) = 1UL; } while (0) +#define cpu_clear(cpu, map) do { cpus_coerce(map) = 0UL; } while (0) +#define cpu_isset(cpu, map) (cpus_coerce(map) != 0UL) +#define cpu_test_and_set(cpu, map) test_and_set_bit(0, (map).mask) + +#define cpus_and(dst, src1, src2) \ + do { \ + if (cpus_coerce(src1) && cpus_coerce(src2)) \ + cpus_coerce(dst) = 1UL; \ + else \ + cpus_coerce(dst) = 0UL; \ + } while (0) + +#define cpus_or(dst, src1, src2) \ + do { \ + if (cpus_coerce(src1) || cpus_coerce(src2)) \ + cpus_coerce(dst) = 1UL; \ + else \ + cpus_coerce(dst) = 0UL; \ + } while (0) + +#define cpus_clear(map) do { cpus_coerce(map) = 0UL; } while (0) + +#define cpus_complement(map) \ + do { \ + cpus_coerce(map) = !cpus_coerce(map); \ + } while (0) + +#define cpus_equal(map1, map2) (cpus_coerce(map1) == cpus_coerce(map2)) +#define cpus_empty(map) (cpus_coerce(map) == 0UL) +#define cpus_weight(map) (cpus_coerce(map) ? 1UL : 0UL) +#define cpus_shift_right(d, s, n) do { cpus_coerce(d) = 0UL; } while (0) +#define cpus_shift_left(d, s, n) do { cpus_coerce(d) = 0UL; } while (0) +#define first_cpu(map) (cpus_coerce(map) ? 0 : 1) +#define next_cpu(cpu, map) 1 + +/* only ever use this for things that are _never_ used on large boxen */ +#define cpus_promote(map) \ + ({ \ + cpumask_t __tmp__; \ + cpus_coerce(__tmp__) = map; \ + __tmp__; \ + }) +#define cpumask_of_cpu(cpu) cpus_promote(1) +#define any_online_cpu(map) (cpus_coerce(map) ? 0 : 1) + +/* + * um, these need to be usable as static initializers + */ +#define CPU_MASK_ALL 1UL +#define CPU_MASK_NONE 0UL + +#endif /* __ASM_GENERIC_CPUMASK_UP_H */ diff -Nru a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h --- a/include/asm-generic/tlb.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-generic/tlb.h Mon Aug 18 22:21:00 2003 @@ -99,7 +99,7 @@ } -/* void tlb_remove_page(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr) +/* tlb_remove_page * Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while * handling the additional races in SMP caused by other CPUs caching valid * mappings in their TLBs. diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h --- a/include/asm-i386/acpi.h Mon Aug 18 22:21:05 2003 +++ b/include/asm-i386/acpi.h Mon Aug 18 22:21:05 2003 @@ -106,30 +106,22 @@ :"0"(n_hi), "1"(n_lo)) -#ifdef CONFIG_ACPI_HT_ONLY -extern int acpi_lapic; -#define acpi_ioapic 0 +#if defined(CONFIG_ACPI_BOOT) && defined(CONFIG_X86_LOCAL_APIC) + extern int acpi_lapic; #else -#ifndef CONFIG_ACPI_BOOT -#define acpi_lapic 0 -#define acpi_ioapic 0 -#else -#ifdef CONFIG_X86_LOCAL_APIC -extern int acpi_lapic; -#else -#define acpi_lapic 0 + #define acpi_lapic 0 #endif -#ifdef CONFIG_X86_IO_APIC -extern int acpi_ioapic; + +#if defined(CONFIG_ACPI_BOOT) && defined(CONFIG_X86_IO_APIC) + extern int acpi_ioapic; #else -#define acpi_ioapic 0 -#endif + #define acpi_ioapic 0 #endif +#ifdef CONFIG_ACPI_BOOT /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ #define FIX_ACPI_PAGES 4 - -#endif /*CONFIG_ACPI_BOOT*/ +#endif #ifdef CONFIG_ACPI_SLEEP diff -Nru a/include/asm-i386/agp.h b/include/asm-i386/agp.h --- a/include/asm-i386/agp.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-i386/agp.h Mon Aug 18 22:21:00 2003 @@ -2,6 +2,7 @@ #define AGP_H 1 #include +#include /* * Functions to keep the agpgart mappings coherent with the MMU. diff -Nru a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h --- a/include/asm-i386/atomic.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-i386/atomic.h Mon Aug 18 22:21:02 2003 @@ -193,7 +193,7 @@ #define atomic_set_mask(mask, addr) \ __asm__ __volatile__(LOCK "orl %0,%1" \ -: : "r" (mask),"m" (*addr) : "memory") +: : "r" (mask),"m" (*(addr)) : "memory") /* Atomic operations are already serializing on x86 */ #define smp_mb__before_atomic_dec() barrier() diff -Nru a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h --- a/include/asm-i386/bitops.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/bitops.h Mon Aug 18 22:21:04 2003 @@ -270,7 +270,7 @@ * Returns the bit-number of the first zero bit, not the number of the byte * containing a bit. */ -static __inline__ int find_first_zero_bit(unsigned long * addr, unsigned size) +static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned size) { int d0, d1, d2; int res; @@ -302,7 +302,7 @@ * Returns the bit-number of the first set bit, not the number of the byte * containing a bit. */ -static __inline__ int find_first_bit(unsigned long * addr, unsigned size) +static __inline__ int find_first_bit(const unsigned long *addr, unsigned size) { int d0, d1; int res; @@ -328,7 +328,7 @@ * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -static __inline__ int find_next_zero_bit(unsigned long * addr, int size, int offset) +static __inline__ int find_next_zero_bit(const unsigned long *addr, int size, int offset) { unsigned long * p = ((unsigned long *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res; @@ -361,9 +361,9 @@ * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -static __inline__ int find_next_bit(unsigned long *addr, int size, int offset) +static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset) { - unsigned long * p = addr + (offset >> 5); + const unsigned long *p = addr + (offset >> 5); int set = 0, bit = offset & 31, res; if (bit) { @@ -430,7 +430,7 @@ * unlikely to be set. It's guaranteed that at least one of the 140 * bits is cleared. */ -static inline int sched_find_first_bit(unsigned long *b) +static inline int sched_find_first_bit(const unsigned long *b) { if (unlikely(b[0])) return __ffs(b[0]); diff -Nru a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h --- a/include/asm-i386/genapic.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/genapic.h Mon Aug 18 22:21:04 2003 @@ -1,13 +1,13 @@ #ifndef _ASM_GENAPIC_H #define _ASM_GENAPIC_H 1 -/* +/* * Generic APIC driver interface. - * - * An straight forward mapping of the APIC related parts of the + * + * An straight forward mapping of the APIC related parts of the * x86 subarchitecture interface to a dynamic object. - * - * This is used by the "generic" x86 subarchitecture. + * + * This is used by the "generic" x86 subarchitecture. * * Copyright 2003 Andi Kleen, SuSE Labs. */ @@ -22,23 +22,23 @@ int (*probe)(void); int (*apic_id_registered)(void); - unsigned long (*target_cpus)(void); + cpumask_t (*target_cpus)(void); int int_delivery_mode; int int_dest_mode; int apic_broadcast_id; int esr_disable; - unsigned long (*check_apicid_used)(unsigned long bitmap, int apicid); + unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid); unsigned long (*check_apicid_present)(int apicid); int no_balance_irq; void (*init_apic_ldr)(void); - unsigned long (*ioapic_phys_id_map)(unsigned long map); + physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); void (*clustered_apic_check)(void); int (*multi_timer_check)(int apic, int irq); int (*apicid_to_node)(int logical_apicid); int (*cpu_to_logical_apicid)(int cpu); int (*cpu_present_to_apicid)(int mps_cpu); - unsigned long (*apicid_to_cpu_present)(int phys_apicid); + physid_mask_t (*apicid_to_cpu_present)(int phys_apicid); int (*mpc_apic_id)(struct mpc_config_processor *m, struct mpc_config_translation *t); void (*setup_portio_remap)(void); @@ -59,11 +59,11 @@ int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id); unsigned (*get_apic_id)(unsigned long x); - unsigned long apic_id_mask; - unsigned int (*cpu_mask_to_apicid)(unsigned long cpumask); + unsigned long apic_id_mask; + unsigned int (*cpu_mask_to_apicid)(cpumask_const_t cpumask); /* ipi */ - void (*send_IPI_mask)(int mask, int vector); + void (*send_IPI_mask)(cpumask_t mask, int vector); void (*send_IPI_allbutself)(int vector); void (*send_IPI_all)(int vector); }; diff -Nru a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h --- a/include/asm-i386/highmem.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-i386/highmem.h Mon Aug 18 22:21:01 2003 @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -39,7 +40,11 @@ * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ +#if NR_CPUS <= 32 #define PKMAP_BASE (0xff800000UL) +#else +#define PKMAP_BASE (0xff600000UL) +#endif #ifdef CONFIG_X86_PAE #define LAST_PKMAP 512 #else diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h --- a/include/asm-i386/hw_irq.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-i386/hw_irq.h Mon Aug 18 22:21:06 2003 @@ -31,33 +31,33 @@ extern void (*interrupt[NR_IRQS])(void); #ifdef CONFIG_SMP -extern asmlinkage void reschedule_interrupt(void); -extern asmlinkage void invalidate_interrupt(void); -extern asmlinkage void call_function_interrupt(void); +asmlinkage void reschedule_interrupt(void); +asmlinkage void invalidate_interrupt(void); +asmlinkage void call_function_interrupt(void); #endif #ifdef CONFIG_X86_LOCAL_APIC -extern asmlinkage void apic_timer_interrupt(void); -extern asmlinkage void error_interrupt(void); -extern asmlinkage void spurious_interrupt(void); -extern asmlinkage void thermal_interrupt(struct pt_regs); +asmlinkage void apic_timer_interrupt(void); +asmlinkage void error_interrupt(void); +asmlinkage void spurious_interrupt(void); +asmlinkage void thermal_interrupt(struct pt_regs); #endif -extern void mask_irq(unsigned int irq); -extern void unmask_irq(unsigned int irq); -extern void disable_8259A_irq(unsigned int irq); -extern void enable_8259A_irq(unsigned int irq); -extern int i8259A_irq_pending(unsigned int irq); -extern void make_8259A_irq(unsigned int irq); -extern void init_8259A(int aeoi); -extern void FASTCALL(send_IPI_self(int vector)); -extern void init_VISWS_APIC_irqs(void); -extern void setup_IO_APIC(void); -extern void disable_IO_APIC(void); -extern void print_IO_APIC(void); -extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); -extern void send_IPI(int dest, int vector); -extern void setup_ioapic_dest(unsigned long mask); +void mask_irq(unsigned int irq); +void unmask_irq(unsigned int irq); +void disable_8259A_irq(unsigned int irq); +void enable_8259A_irq(unsigned int irq); +int i8259A_irq_pending(unsigned int irq); +void make_8259A_irq(unsigned int irq); +void init_8259A(int aeoi); +void FASTCALL(send_IPI_self(int vector)); +void init_VISWS_APIC_irqs(void); +void setup_IO_APIC(void); +void disable_IO_APIC(void); +void print_IO_APIC(void); +int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); +void send_IPI(int dest, int vector); +void setup_ioapic_dest(cpumask_t mask); extern unsigned long io_apic_irqs; diff -Nru a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h --- a/include/asm-i386/io_apic.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/io_apic.h Mon Aug 18 22:21:04 2003 @@ -170,7 +170,7 @@ extern int io_apic_get_unique_id (int ioapic, int apic_id); extern int io_apic_get_version (int ioapic); extern int io_apic_get_redir_entries (int ioapic); -extern int io_apic_set_pci_routing (int ioapic, int pin, int irq); +extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low); #endif /*CONFIG_ACPI_BOOT*/ #else /* !CONFIG_X86_IO_APIC */ diff -Nru a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h --- a/include/asm-i386/mach-bigsmp/mach_apic.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-i386/mach-bigsmp/mach_apic.h Mon Aug 18 22:21:06 2003 @@ -20,7 +20,7 @@ } #define APIC_DFR_VALUE (APIC_DFR_CLUSTER) -static inline unsigned long target_cpus(void) +static inline cpumask_t target_cpus(void) { return cpu_online_map; } @@ -29,14 +29,15 @@ #define INT_DELIVERY_MODE dest_LowestPrio #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ -#define APIC_BROADCAST_ID (0x0f) -static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) -{ +#define APIC_BROADCAST_ID (0xff) +static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) +{ return 0; -} +} + static inline unsigned long check_apicid_present(int bit) { - return (phys_cpu_present_map & (1 << bit)); + return physid_isset(bit, phys_cpu_present_map); } #define apicid_cluster(apicid) (apicid & 0xF0) @@ -88,12 +89,12 @@ return (int) bios_cpu_apicid[mps_cpu]; } -static inline unsigned long apicid_to_cpu_present(int phys_apicid) +static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) { - return (1ul << phys_apicid); + return physid_mask_of_physid(phys_apicid); } -extern volatile u8 cpu_2_logical_apicid[]; +extern u8 cpu_2_logical_apicid[]; /* Mapping from cpu number to logical apicid */ static inline int cpu_to_logical_apicid(int cpu) { @@ -108,13 +109,13 @@ (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, m->mpc_apicver); - return (m->mpc_apicid); + return m->mpc_apicid; } -static inline ulong ioapic_phys_id_map(ulong phys_map) +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) { /* For clustered we don't have a good way to do this yet - hack */ - return (0x0F); + return physids_promote(0xFUL); } #define WAKE_SECONDARY_VIA_INIT @@ -132,25 +133,25 @@ return (1); } -static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - num_bits_set = hweight32(cpumask); + num_bits_set = cpus_weight_const(cpumask); /* Return id to all */ - if (num_bits_set == 32) + if (num_bits_set == NR_CPUS) return (int) 0xFF; /* * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = ffs(cpumask)-1; + cpu = first_cpu_const(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpumask & (1 << cpu)) { + if (cpu_isset_const(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ diff -Nru a/include/asm-i386/mach-bigsmp/mach_ipi.h b/include/asm-i386/mach-bigsmp/mach_ipi.h --- a/include/asm-i386/mach-bigsmp/mach_ipi.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-i386/mach-bigsmp/mach_ipi.h Mon Aug 18 22:21:03 2003 @@ -1,18 +1,19 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -inline void send_IPI_mask_sequence(int mask, int vector); +inline void send_IPI_mask_sequence(cpumask_t mask, int vector); -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t mask, int vector) { send_IPI_mask_sequence(mask, vector); } static inline void send_IPI_allbutself(int vector) { - unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); - if (mask) + if (!cpus_empty(mask)) send_IPI_mask(mask, vector); } diff -Nru a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h --- a/include/asm-i386/mach-default/mach_apic.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-i386/mach-default/mach_apic.h Mon Aug 18 22:21:06 2003 @@ -5,12 +5,12 @@ #define APIC_DFR_VALUE (APIC_DFR_FLAT) -static inline unsigned long target_cpus(void) +static inline cpumask_t target_cpus(void) { #ifdef CONFIG_SMP return cpu_online_map; #else - return 1; + return cpumask_of_cpu(0); #endif } #define TARGET_CPUS (target_cpus()) @@ -21,16 +21,20 @@ #define INT_DELIVERY_MODE dest_LowestPrio #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ +/* + * this isn't really broadcast, just a (potentially inaccurate) upper + * bound for valid physical APIC id's + */ #define APIC_BROADCAST_ID 0x0F -static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) -{ - return (bitmap & (1UL << apicid)); -} +static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return physid_isset(apicid, bitmap); +} -static inline unsigned long check_apicid_present(int bit) +static inline unsigned long check_apicid_present(int bit) { - return (phys_cpu_present_map & (1UL << bit)); + return physid_isset(bit, phys_cpu_present_map); } /* @@ -50,7 +54,7 @@ apic_write_around(APIC_LDR, val); } -static inline unsigned long ioapic_phys_id_map(unsigned long phys_map) +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) { return phys_map; } @@ -82,9 +86,9 @@ return mps_cpu; } -static inline unsigned long apicid_to_cpu_present(int phys_apicid) +static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) { - return (1ul << phys_apicid); + return physid_mask_of_physid(phys_apicid); } static inline int mpc_apic_id(struct mpc_config_processor *m, @@ -104,18 +108,17 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) { - return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map); + return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); } static inline int apic_id_registered(void) { - return (test_bit(GET_APIC_ID(apic_read(APIC_ID)), - &phys_cpu_present_map)); + return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) { - return cpumask; + return cpus_coerce_const(cpumask); } static inline void enable_apic_mode(void) diff -Nru a/include/asm-i386/mach-default/mach_ipi.h b/include/asm-i386/mach-default/mach_ipi.h --- a/include/asm-i386/mach-default/mach_ipi.h Mon Aug 18 22:21:05 2003 +++ b/include/asm-i386/mach-default/mach_ipi.h Mon Aug 18 22:21:05 2003 @@ -1,10 +1,10 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -inline void send_IPI_mask_bitmask(int mask, int vector); +inline void send_IPI_mask_bitmask(cpumask_t mask, int vector); inline void __send_IPI_shortcut(unsigned int shortcut, int vector); -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t mask, int vector) { send_IPI_mask_bitmask(mask, vector); } diff -Nru a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h --- a/include/asm-i386/mach-es7000/mach_apic.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-i386/mach-es7000/mach_apic.h Mon Aug 18 22:21:00 2003 @@ -11,12 +11,12 @@ return (1); } -static inline unsigned long target_cpus(void) +static inline cpumask_t target_cpus(void) { #if defined CONFIG_ES7000_CLUSTERED_APIC - return (0xff); + return CPU_MASK_ALL; #else - return (bios_cpu_apicid[smp_processor_id()]); + return cpumask_of_cpu(bios_cpu_apicid[smp_processor_id()]); #endif } #define TARGET_CPUS (target_cpus()) @@ -40,13 +40,13 @@ #define APIC_BROADCAST_ID (0xff) -static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) +static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) { return 0; } static inline unsigned long check_apicid_present(int bit) { - return (phys_cpu_present_map & (1 << bit)); + return physid_isset(bit, phys_cpu_present_map); } #define apicid_cluster(apicid) (apicid & 0xF0) @@ -88,7 +88,7 @@ int apic = bios_cpu_apicid[smp_processor_id()]; printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", (apic_version[apic] == 0x14) ? - "Physical Cluster" : "Logical Cluster", nr_ioapics, TARGET_CPUS); + "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_coerce(TARGET_CPUS)); } static inline int multi_timer_check(int apic, int irq) @@ -110,20 +110,23 @@ return (int) bios_cpu_apicid[mps_cpu]; } -static inline unsigned long apicid_to_cpu_present(int phys_apicid) +static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) { - static int cpu = 0; - return (1ul << cpu++); + static int id = 0; + physid_mask_t mask; + mask = physid_mask_of_physid(id); + ++id; + return mask; } -extern volatile u8 cpu_2_logical_apicid[]; +extern u8 cpu_2_logical_apicid[]; /* Mapping from cpu number to logical apicid */ static inline int cpu_to_logical_apicid(int cpu) { return (int)cpu_2_logical_apicid[cpu]; } -static inline int mpc_apic_id(struct mpc_config_processor *m, int quad) +static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused) { printk("Processor #%d %ld:%ld APIC version %d\n", m->mpc_apicid, @@ -133,10 +136,10 @@ return (m->mpc_apicid); } -static inline ulong ioapic_phys_id_map(ulong phys_map) +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) { /* For clustered we don't have a good way to do this yet - hack */ - return (0xff); + return physids_promote(0xff); } @@ -151,32 +154,30 @@ return (1); } -static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - if (cpumask == TARGET_CPUS) - return cpumask; - num_bits_set = hweight32(cpumask); + num_bits_set = cpus_weight_const(cpumask); /* Return id to all */ - if (num_bits_set == 32) - return TARGET_CPUS; + if (num_bits_set == NR_CPUS) + return 0xFF; /* * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = ffs(cpumask)-1; + cpu = first_cpu_const(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpumask & (1 << cpu)) { + if (cpu_isset_const(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ printk ("%s: Not a valid mask!\n",__FUNCTION__); - return TARGET_CPUS; + return 0xFF; } apicid = new_apicid; cpus_found++; diff -Nru a/include/asm-i386/mach-es7000/mach_ipi.h b/include/asm-i386/mach-es7000/mach_ipi.h --- a/include/asm-i386/mach-es7000/mach_ipi.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-i386/mach-es7000/mach_ipi.h Mon Aug 18 22:21:02 2003 @@ -1,18 +1,19 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -static inline void send_IPI_mask_sequence(int mask, int vector); +static inline void send_IPI_mask_sequence(cpumask_t mask, int vector); -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t mask, int vector) { send_IPI_mask_sequence(mask, vector); } static inline void send_IPI_allbutself(int vector) { - unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); - - if (mask) + cpumask_t mask = cpumask_of_cpu(smp_processor_id()); + cpus_complement(mask); + cpus_and(mask, mask, cpu_online_map); + if (!cpus_empty(mask)) send_IPI_mask(mask, vector); } diff -Nru a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h --- a/include/asm-i386/mach-numaq/mach_apic.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-i386/mach-numaq/mach_apic.h Mon Aug 18 22:21:03 2003 @@ -6,7 +6,13 @@ #define APIC_DFR_VALUE (APIC_DFR_CLUSTER) -#define TARGET_CPUS (~0UL) +static inline cpumask_t target_cpus(void) +{ + cpumask_t tmp = CPU_MASK_ALL; + return tmp; +} + +#define TARGET_CPUS (target_cpus()) #define NO_BALANCE_IRQ (1) #define esr_disable (1) @@ -15,13 +21,13 @@ #define INT_DEST_MODE 0 /* physical delivery on LOCAL quad */ #define APIC_BROADCAST_ID 0x0F -#define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid))) -#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit)) +#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap) +#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map) #define apicid_cluster(apicid) (apicid & 0xF0) static inline int apic_id_registered(void) { - return (1); + return 1; } static inline void init_apic_ldr(void) @@ -41,17 +47,17 @@ */ static inline int multi_timer_check(int apic, int irq) { - return (apic != 0 && irq == 0); + return apic != 0 && irq == 0; } -static inline ulong ioapic_phys_id_map(ulong phys_map) +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) { /* We don't have a good way to do this yet - hack */ - return 0xf; + return physids_promote(0xFUL); } /* Mapping from cpu number to logical apicid */ -extern volatile u8 cpu_2_logical_apicid[]; +extern u8 cpu_2_logical_apicid[]; static inline int cpu_to_logical_apicid(int cpu) { return (int)cpu_2_logical_apicid[cpu]; @@ -59,22 +65,25 @@ static inline int cpu_present_to_apicid(int mps_cpu) { - return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) ); + return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3)); } static inline int generate_logical_apicid(int quad, int phys_apicid) { - return ( (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1) ); + return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); } static inline int apicid_to_node(int logical_apicid) { - return (logical_apicid >> 4); + return logical_apicid >> 4; } -static inline unsigned long apicid_to_cpu_present(int logical_apicid) +static inline physid_mask_t apicid_to_cpu_present(int logical_apicid) { - return ( (logical_apicid&0xf) << (4*apicid_to_node(logical_apicid)) ); + int node = apicid_to_node(logical_apicid); + int cpu = __ffs(logical_apicid & 0xf); + + return physid_mask_of_physid(cpu + 4*node); } static inline int mpc_apic_id(struct mpc_config_processor *m, @@ -115,7 +124,7 @@ * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ -static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) { return (int) 0xF; } diff -Nru a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h --- a/include/asm-i386/mach-numaq/mach_ipi.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/mach-numaq/mach_ipi.h Mon Aug 18 22:21:04 2003 @@ -1,18 +1,19 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -static inline void send_IPI_mask_sequence(int mask, int vector); +static inline void send_IPI_mask_sequence(cpumask_t, int vector); -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t mask, int vector) { send_IPI_mask_sequence(mask, vector); } static inline void send_IPI_allbutself(int vector) { - unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); - if (mask) + if (!cpus_empty(mask)) send_IPI_mask(mask, vector); } diff -Nru a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h --- a/include/asm-i386/mach-summit/mach_apic.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/mach-summit/mach_apic.h Mon Aug 18 22:21:04 2003 @@ -18,17 +18,18 @@ #define APIC_DFR_VALUE (APIC_DFR_CLUSTER) -static inline unsigned long target_cpus(void) +static inline cpumask_t target_cpus(void) { - return (~0UL); + cpumask_t tmp = CPU_MASK_ALL; + return tmp; } #define TARGET_CPUS (target_cpus()) #define INT_DELIVERY_MODE (dest_Fixed) #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ -#define APIC_BROADCAST_ID (0x0F) -static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) +#define APIC_BROADCAST_ID (0xFF) +static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) { return 0; } @@ -72,11 +73,11 @@ static inline int apicid_to_node(int logical_apicid) { - return (logical_apicid >> 5); /* 2 clusterids per CEC */ + return logical_apicid >> 5; /* 2 clusterids per CEC */ } /* Mapping from cpu number to logical apicid */ -extern volatile u8 cpu_2_logical_apicid[]; +extern u8 cpu_2_logical_apicid[]; static inline int cpu_to_logical_apicid(int cpu) { return (int)cpu_2_logical_apicid[cpu]; @@ -87,15 +88,15 @@ return (int) bios_cpu_apicid[mps_cpu]; } -static inline ulong ioapic_phys_id_map(ulong phys_map) +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_id_map) { /* For clustered we don't have a good way to do this yet - hack */ - return 0x0F; + return physids_promote(0x0F); } -static inline unsigned long apicid_to_cpu_present(int apicid) +static inline physid_mask_t apicid_to_cpu_present(int apicid) { - return 1; + return physid_mask_of_physid(0); } static inline int mpc_apic_id(struct mpc_config_processor *m, @@ -122,25 +123,25 @@ { } -static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - num_bits_set = hweight32(cpumask); + num_bits_set = cpus_weight_const(cpumask); /* Return id to all */ - if (num_bits_set == 32) + if (num_bits_set == NR_CPUS) return (int) 0xFF; /* * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = ffs(cpumask)-1; + cpu = first_cpu_const(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpumask & (1 << cpu)) { + if (cpu_isset_const(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ diff -Nru a/include/asm-i386/mach-summit/mach_ipi.h b/include/asm-i386/mach-summit/mach_ipi.h --- a/include/asm-i386/mach-summit/mach_ipi.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-i386/mach-summit/mach_ipi.h Mon Aug 18 22:21:01 2003 @@ -1,18 +1,19 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -inline void send_IPI_mask_sequence(int mask, int vector); +inline void send_IPI_mask_sequence(cpumask_t mask, int vector); -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t mask, int vector) { send_IPI_mask_sequence(mask, vector); } static inline void send_IPI_allbutself(int vector) { - unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); - if (mask) + if (!cpus_empty(mask)) send_IPI_mask(mask, vector); } diff -Nru a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h --- a/include/asm-i386/mach-summit/mach_mpparse.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-i386/mach-summit/mach_mpparse.h Mon Aug 18 22:21:03 2003 @@ -5,6 +5,12 @@ extern int use_cyclone; +#ifdef CONFIG_NUMA +extern void setup_summit(void); +#else /* !CONFIG_NUMA */ +#define setup_summit() {} +#endif /* CONFIG_NUMA */ + static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, struct mpc_config_translation *translation) { @@ -24,6 +30,7 @@ || !strncmp(productid, "EXA", 3) || !strncmp(productid, "RUTHLESS SMP", 12))){ use_cyclone = 1; /*enable cyclone-timer*/ + setup_summit(); return 1; } return 0; @@ -36,6 +43,7 @@ (!strncmp(oem_table_id, "SERVIGIL", 8) || !strncmp(oem_table_id, "EXA", 3))){ use_cyclone = 1; /*enable cyclone-timer*/ + setup_summit(); return 1; } return 0; diff -Nru a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h --- a/include/asm-i386/mach-visws/mach_apic.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-i386/mach-visws/mach_apic.h Mon Aug 18 22:21:00 2003 @@ -12,17 +12,16 @@ #ifdef CONFIG_SMP #define TARGET_CPUS cpu_online_map #else - #define TARGET_CPUS 0x01 + #define TARGET_CPUS cpumask_of_cpu(0) #endif #define APIC_BROADCAST_ID 0x0F -#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid)) -#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit)) +#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap) +#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map) static inline int apic_id_registered(void) { - return (test_bit(GET_APIC_ID(apic_read(APIC_ID)), - &phys_cpu_present_map)); + return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); } /* @@ -61,9 +60,9 @@ return mps_cpu; } -static inline unsigned long apicid_to_cpu_present(int apicid) +static inline physid_mask_t apicid_to_cpu_present(int apicid) { - return (1ul << apicid); + return physid_mask_of_physid(apicid); } #define WAKE_SECONDARY_VIA_INIT @@ -78,11 +77,11 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) { - return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map); + return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) { - return cpumask; + return cpus_coerce_const(cpumask); } #endif /* __ASM_MACH_APIC_H */ diff -Nru a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h --- a/include/asm-i386/mmu_context.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-i386/mmu_context.h Mon Aug 18 22:21:00 2003 @@ -31,12 +31,12 @@ if (likely(prev != next)) { /* stop flush ipis for the previous mm */ - clear_bit(cpu, &prev->cpu_vm_mask); + cpu_clear(cpu, prev->cpu_vm_mask); #ifdef CONFIG_SMP cpu_tlbstate[cpu].state = TLBSTATE_OK; cpu_tlbstate[cpu].active_mm = next; #endif - set_bit(cpu, &next->cpu_vm_mask); + cpu_set(cpu, next->cpu_vm_mask); /* Re-load page tables */ load_cr3(next->pgd); @@ -52,7 +52,7 @@ cpu_tlbstate[cpu].state = TLBSTATE_OK; BUG_ON(cpu_tlbstate[cpu].active_mm != next); - if (!test_and_set_bit(cpu, &next->cpu_vm_mask)) { + if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled * tlb flush IPI delivery. We must reload %cr3. */ diff -Nru a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h --- a/include/asm-i386/mpspec.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-i386/mpspec.h Mon Aug 18 22:21:00 2003 @@ -1,6 +1,7 @@ #ifndef __ASM_MPSPEC_H #define __ASM_MPSPEC_H +#include #include #include @@ -11,7 +12,6 @@ extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; -extern unsigned long phys_cpu_present_map; extern int smp_found_config; extern void find_smp_config (void); extern void get_smp_config (void); @@ -40,6 +40,50 @@ extern void mp_config_ioapic_for_sci(int irq); extern void mp_parse_prt (void); #endif /*CONFIG_ACPI_BOOT*/ + +#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) + +struct physid_mask +{ + unsigned long mask[PHYSID_ARRAY_SIZE]; +}; + +typedef struct physid_mask physid_mask_t; + +#define physid_set(physid, map) set_bit(physid, (map).mask) +#define physid_clear(physid, map) clear_bit(physid, (map).mask) +#define physid_isset(physid, map) test_bit(physid, (map).mask) +#define physid_test_and_set(physid, map) test_and_set_bit(physid, (map).mask) + +#define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) +#define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) +#define physids_clear(map) bitmap_clear((map).mask, MAX_APICS) +#define physids_complement(map) bitmap_complement((map).mask, MAX_APICS) +#define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) +#define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) +#define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) +#define physids_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS) +#define physids_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) +#define physids_coerce(map) ((map).mask[0]) + +#define physids_promote(physids) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + __physid_mask.mask[0] = physids; \ + __physid_mask; \ + }) + +#define physid_mask_of_physid(physid) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + physid_set(physid, __physid_mask); \ + __physid_mask; \ + }) + +#define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } +#define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } + +extern physid_mask_t phys_cpu_present_map; #endif diff -Nru a/include/asm-i386/numaq.h b/include/asm-i386/numaq.h --- a/include/asm-i386/numaq.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-i386/numaq.h Mon Aug 18 22:21:03 2003 @@ -28,7 +28,7 @@ #ifdef CONFIG_X86_NUMAQ -#define MAX_NUMNODES 8 +#define MAX_NUMNODES 16 extern void get_memcfg_numaq(void); #define get_memcfg_numa() get_memcfg_numaq() @@ -159,7 +159,7 @@ static inline unsigned long *get_zholes_size(int nid) { - return 0; + return NULL; } #endif /* CONFIG_X86_NUMAQ */ #endif /* NUMAQ_H */ diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h --- a/include/asm-i386/smp.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/smp.h Mon Aug 18 22:21:04 2003 @@ -8,6 +8,7 @@ #include #include #include +#include #endif #ifdef CONFIG_X86_LOCAL_APIC @@ -31,9 +32,7 @@ */ extern void smp_alloc_memory(void); -extern unsigned long phys_cpu_present_map; -extern unsigned long cpu_online_map; -extern volatile unsigned long smp_invalidate_needed; +extern physid_mask_t phys_cpu_present_map; extern int pic_mode; extern int smp_num_siblings; extern int cpu_sibling_map[]; @@ -54,37 +53,19 @@ */ #define smp_processor_id() (current_thread_info()->cpu) -extern volatile unsigned long cpu_callout_map; +extern cpumask_t cpu_callout_map; -#define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu))) -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) - -#define for_each_cpu(cpu, mask) \ - for(mask = cpu_online_map; \ - cpu = __ffs(mask), mask != 0; \ - mask &= ~(1< +#include + /* Mappings between logical cpu number and node number */ -extern volatile unsigned long node_2_cpu_mask[]; -extern volatile int cpu_2_node[]; +extern cpumask_t node_2_cpu_mask[]; +extern int cpu_2_node[]; /* Returns the number of the node containing CPU 'cpu' */ static inline int cpu_to_node(int cpu) @@ -49,7 +51,7 @@ #define parent_node(node) (node) /* Returns a bitmask of CPUs on Node 'node'. */ -static inline unsigned long node_to_cpumask(int node) +static inline cpumask_t node_to_cpumask(int node) { return node_2_cpu_mask[node]; } @@ -57,14 +59,15 @@ /* Returns the number of the first CPU on Node 'node'. */ static inline int node_to_first_cpu(int node) { - return __ffs(node_to_cpumask(node)); + cpumask_t mask = node_to_cpumask(node); + return first_cpu(mask); } /* Returns the number of the first MemBlk on Node 'node' */ #define node_to_memblk(node) (node) /* Returns the number of the node containing PCI bus 'bus' */ -static inline unsigned long pcibus_to_cpumask(int bus) +static inline cpumask_t pcibus_to_cpumask(int bus) { return node_to_cpumask(mp_bus_id_to_node[bus]); } diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h --- a/include/asm-i386/unistd.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-i386/unistd.h Mon Aug 18 22:21:04 2003 @@ -277,8 +277,9 @@ #define __NR_fstatfs64 269 #define __NR_tgkill 270 #define __NR_utimes 271 +#define __NR_fadvise64_64 272 -#define NR_syscalls 272 +#define NR_syscalls 273 /* user-visible error numbers are in the range -1 - -124: see */ diff -Nru a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h --- a/include/asm-ia64/bitops.h Mon Aug 18 22:21:05 2003 +++ b/include/asm-ia64/bitops.h Mon Aug 18 22:21:05 2003 @@ -409,7 +409,7 @@ * Find next bit in a bitmap reasonably efficiently.. */ static inline int -find_next_bit (void *addr, unsigned long size, unsigned long offset) +find_next_bit(const void *addr, unsigned long size, unsigned long offset) { unsigned long *p = ((unsigned long *) addr) + (offset >> 6); unsigned long result = offset & ~63UL; diff -Nru a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h --- a/include/asm-ia64/smp.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-ia64/smp.h Mon Aug 18 22:21:03 2003 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -37,8 +38,8 @@ extern char no_int_routing __initdata; -extern unsigned long phys_cpu_present_map; -extern volatile unsigned long cpu_online_map; +extern cpumask_t phys_cpu_present_map; +extern cpumask_t cpu_online_map; extern unsigned long ipi_base_addr; extern unsigned char smp_int_redirect; @@ -47,22 +48,7 @@ extern unsigned long ap_wakeup_vector; -#define cpu_possible(cpu) (phys_cpu_present_map & (1UL << (cpu))) -#define cpu_online(cpu) (cpu_online_map & (1UL << (cpu))) - -static inline unsigned int -num_online_cpus (void) -{ - return hweight64(cpu_online_map); -} - -static inline unsigned int -any_online_cpu (unsigned int mask) -{ - if (mask & cpu_online_map) - return __ffs(mask & cpu_online_map); - return NR_CPUS; -} +#define cpu_possible(cpu) cpu_isset(cpu, phys_cpu_present_map) /* * Function to map hard smp processor id to logical id. Slow, so don't use this in diff -Nru a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h --- a/include/asm-ia64/sn/nodepda.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-ia64/sn/nodepda.h Mon Aug 18 22:21:01 2003 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,7 @@ * Check if given a compact node id the corresponding node has all the * cpus disabled. */ -#define is_headless_node(cnode) (!test_bit(cnode, &node_has_active_cpus)) +#define is_headless_node(cnode) (!node_to_cpumask(cnode)) /* * Check if given a node vertex handle the corresponding node has all the diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h --- a/include/asm-ia64/unistd.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-ia64/unistd.h Mon Aug 18 22:21:01 2003 @@ -257,96 +257,138 @@ extern long __ia64_syscall (long a0, long a1, long a2, long a3, long a4, long nr); -#define _syscall0(type,name) \ -type \ -name (void) \ -{ \ - register long dummy1 __asm__ ("out0"); \ - register long dummy2 __asm__ ("out1"); \ - register long dummy3 __asm__ ("out2"); \ - register long dummy4 __asm__ ("out3"); \ - register long dummy5 __asm__ ("out4"); \ - \ - return __ia64_syscall(dummy1, dummy2, dummy3, dummy4, dummy5, \ - __NR_##name); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type \ -name (type1 arg1) \ -{ \ - register long dummy2 __asm__ ("out1"); \ - register long dummy3 __asm__ ("out2"); \ - register long dummy4 __asm__ ("out3"); \ - register long dummy5 __asm__ ("out4"); \ - \ - return __ia64_syscall((long) arg1, dummy2, dummy3, dummy4, \ - dummy5, __NR_##name); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type \ -name (type1 arg1, type2 arg2) \ -{ \ - register long dummy3 __asm__ ("out2"); \ - register long dummy4 __asm__ ("out3"); \ - register long dummy5 __asm__ ("out4"); \ - \ - return __ia64_syscall((long) arg1, (long) arg2, dummy3, dummy4, \ - dummy5, __NR_##name); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3) \ -{ \ - register long dummy4 __asm__ ("out3"); \ - register long dummy5 __asm__ ("out4"); \ - \ - return __ia64_syscall((long) arg1, (long) arg2, (long) arg3, \ - dummy4, dummy5, __NR_##name); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - register long dummy5 __asm__ ("out4"); \ - \ - return __ia64_syscall((long) arg1, (long) arg2, (long) arg3, \ - (long) arg4, dummy5, __NR_##name); \ -} - -#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) \ -{ \ - return __ia64_syscall((long) arg1, (long) arg2, (long) arg3, \ - (long) arg4, (long) arg5, __NR_##name); \ +#ifdef __KERNEL_SYSCALLS__ + +#include +#include +#include +#include + +static inline long +open (const char * name, int mode, int flags) +{ + extern long sys_open (const char *, int, int); + return sys_open(name, mode, flags); } -#ifdef __KERNEL_SYSCALLS__ +static inline long +dup (int fd) +{ + extern long sys_dup (int); + return sys_dup(fd); +} + +static inline long +close (int fd) +{ + extern long sys_close(unsigned int); + return sys_close(fd); +} + +static inline off_t +lseek (int fd, off_t off, int whence) +{ + extern off_t sys_lseek (int, off_t, int); + return sys_lseek(fd, off, whence); +} + +static inline long +_exit (int value) +{ + extern long sys_exit (int); + return sys_exit(value); +} + +#define exit(x) _exit(x) + +static inline long +write (int fd, const char * buf, size_t nr) +{ + extern long sys_write (int, const char *, size_t); + return sys_write(fd, buf, nr); +} + +static inline long +read (int fd, char * buf, size_t nr) +{ + extern long sys_read (int, char *, size_t); + return sys_read(fd, buf, nr); +} + + +static inline long +setsid (void) +{ + extern long sys_setsid (void); + return sys_setsid(); +} struct rusage; -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 _syscall4(pid_t,wait4,pid_t,pid,int *,wait_stat,int,options,struct rusage*, rusage) -static inline _syscall2(pid_t,clone,unsigned long,flags,void*,sp); +static inline pid_t +waitpid (int pid, int * wait_stat, int flags) +{ + extern asmlinkage long sys_wait4 (pid_t, unsigned int *, int, struct rusage *); + + return sys_wait4(pid, wait_stat, flags, NULL); +} -#define __NR__exit __NR_exit -static inline _syscall1(int,_exit,int,exitcode) + +static inline int +execve (const char *filename, char *const av[], char *const ep[]) +{ + register long r8 asm("r8"); + register long r10 asm("r10"); + register long r15 asm("r15") = __NR_execve; + register long out0 asm("out0") = (long)filename; + register long out1 asm("out1") = (long)av; + register long out2 asm("out2") = (long)ep; + + asm volatile ("break " __stringify(__BREAK_SYSCALL) ";;\n\t" + : "=r" (r8), "=r" (r10), "=r" (r15), "=r" (out0), "=r" (out1), "=r" (out2) + : "2" (r15), "3" (out0), "4" (out1), "5" (out2) + : "memory", "out3", "out4", "out5", "out6", "out7", + /* Non-stacked integer registers, minus r8, r10, r15, r13 */ + "r2", "r3", "r9", "r11", "r12", "r14", "r16", "r17", "r18", + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", + "r28", "r29", "r30", "r31", + /* Predicate registers. */ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", + /* Non-rotating fp registers. */ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + /* Branch registers. */ + "b6", "b7" ); + return r8; +} static inline pid_t -waitpid (int pid, int *wait_stat, int flags) +clone (unsigned long flags, void *sp) { - return wait4(pid, wait_stat, flags, NULL); + register long r8 asm("r8"); + register long r10 asm("r10"); + register long r15 asm("r15") = __NR_clone; + register long out0 asm("out0") = (long)flags; + register long out1 asm("out1") = (long)sp; + long retval; + + /* clone clobbers current, hence the "r13" in the clobbers list */ + asm volatile ( "break " __stringify(__BREAK_SYSCALL) ";;\n\t" + : "=r" (r8), "=r" (r10), "=r" (r15), "=r" (out0), "=r" (out1) + : "2" (r15), "3" (out0), "4" (out1) + : "memory", "out2", "out3", "out4", "out5", "out6", "out7", "r13", + /* Non-stacked integer registers, minus r8, r10, r15, r13 */ + "r2", "r3", "r9", "r11", "r12", "r14", "r16", "r17", "r18", + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", + "r28", "r29", "r30", "r31", + /* Predicate registers. */ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", + /* Non-rotating fp registers. */ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + /* Branch registers. */ + "b6", "b7" ); + retval = r8; + return retval;; + } #endif /* __KERNEL_SYSCALLS__ */ diff -Nru a/include/asm-mips/smp.h b/include/asm-mips/smp.h --- a/include/asm-mips/smp.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-mips/smp.h Mon Aug 18 22:21:01 2003 @@ -17,6 +17,7 @@ #include #include +#include #include #define smp_processor_id() (current_thread_info()->cpu) @@ -45,56 +46,22 @@ #define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ #define SMP_CALL_FUNCTION 0x2 -#if (NR_CPUS <= _MIPS_SZLONG) - -typedef unsigned long cpumask_t; - -#define CPUMASK_CLRALL(p) (p) = 0 -#define CPUMASK_SETB(p, bit) (p) |= 1UL << (bit) -#define CPUMASK_CLRB(p, bit) (p) &= ~(1UL << (bit)) -#define CPUMASK_TSTB(p, bit) ((p) & (1UL << (bit))) - -#elif (NR_CPUS <= 128) - -/* - * The foll should work till 128 cpus. - */ -#define CPUMASK_SIZE (NR_CPUS/_MIPS_SZLONG) -#define CPUMASK_INDEX(bit) ((bit) >> 6) -#define CPUMASK_SHFT(bit) ((bit) & 0x3f) - -typedef struct { - unsigned long _bits[CPUMASK_SIZE]; -} cpumask_t; - -#define CPUMASK_CLRALL(p) (p)._bits[0] = 0, (p)._bits[1] = 0 -#define CPUMASK_SETB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] |= \ - (1UL << CPUMASK_SHFT(bit)) -#define CPUMASK_CLRB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] &= \ - ~(1UL << CPUMASK_SHFT(bit)) -#define CPUMASK_TSTB(p, bit) ((p)._bits[CPUMASK_INDEX(bit)] & \ - (1UL << CPUMASK_SHFT(bit))) - -#else -#error cpumask macros only defined for 128p kernels -#endif - extern cpumask_t phys_cpu_present_map; extern cpumask_t cpu_online_map; -#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu))) -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) +#define cpu_possible(cpu) cpu_isset(cpu, phys_cpu_present_map) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) static inline unsigned int num_online_cpus(void) { - return hweight32(cpu_online_map); + return cpus_weight(cpu_online_map); } -extern volatile unsigned long cpu_callout_map; +extern cpumask_t cpu_callout_map; /* We don't mark CPUs online until __cpu_up(), so we need another measure */ static inline int num_booting_cpus(void) { - return hweight32(cpu_callout_map); + return cpus_weight(cpu_callout_map); } #endif /* CONFIG_SMP */ diff -Nru a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h --- a/include/asm-parisc/smp.h Mon Aug 18 22:21:05 2003 +++ b/include/asm-parisc/smp.h Mon Aug 18 22:21:05 2003 @@ -14,9 +14,10 @@ #ifndef ASSEMBLY #include #include /* for NR_CPUS */ +#include typedef unsigned long address_t; -extern volatile unsigned long cpu_online_map; +extern cpumask_t cpu_online_map; /* @@ -51,22 +52,10 @@ extern unsigned long cpu_present_mask; #define smp_processor_id() (current_thread_info()->cpu) -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -#define cpu_possible(cpu) (cpu_present_mask & (1<<(cpu))) +#define cpu_possible(cpu) cpu_isset(cpu, cpu_present_mask) -extern inline unsigned int num_online_cpus(void) -{ - return hweight32(cpu_online_map); -} - -extern inline unsigned int any_online_cpu(unsigned int mask) -{ - if (mask & cpu_online_map) - return __ffs(mask & cpu_online_map); - - return NR_CPUS; -} #endif /* CONFIG_SMP */ #define NO_PROC_ID 0xFF /* No processor magic marker */ diff -Nru a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-ppc/macio.h Mon Aug 18 22:21:01 2003 @@ -0,0 +1,68 @@ +#ifndef __MACIO_ASIC_H__ +#define __MACIO_ASIC_H__ + +#include + +extern struct bus_type macio_bus_type; + +/* MacIO device driver is defined later */ +struct macio_driver; +struct macio_chip; + +#define MACIO_DEV_COUNT_RESOURCE 8 +#define MACIO_DEV_COUNT_IRQS 8 + +/* + * the macio_bus structure is used to describe a "virtual" bus + * within a MacIO ASIC. It's typically provided by a macio_pci_asic + * PCI device, but could be provided differently as well (nubus + * machines using a fake OF tree). + * + * The pdev field can be NULL on non-PCI machines + */ +struct macio_bus +{ + struct macio_chip *chip; /* macio_chip (private use) */ + int index; /* macio chip index in system */ +#ifdef CONFIG_PCI + struct pci_dev *pdev; /* PCI device hosting this bus */ +#endif +}; + +/* + * the macio_dev structure is used to describe a device + * within an Apple MacIO ASIC. + */ +struct macio_dev +{ + struct macio_bus *bus; /* macio bus this device is on */ + struct macio_dev *media_bay; /* Device is part of a media bay */ + struct of_device ofdev; +}; +#define to_macio_device(d) container_of(d, struct macio_dev, ofdev.dev) +#define of_to_macio_device(d) container_of(d, struct macio_dev, ofdev) + +/* + * A driver for a mac-io chip based device + */ +struct macio_driver +{ + char *name; + struct of_match *match_table; + struct module *owner; + + int (*probe)(struct macio_dev* dev, const struct of_match *match); + int (*remove)(struct macio_dev* dev); + + int (*suspend)(struct macio_dev* dev, u32 state, u32 level); + int (*resume)(struct macio_dev* dev, u32 level); + int (*shutdown)(struct macio_dev* dev); + + struct device_driver driver; +}; +#define to_macio_driver(drv) container_of(drv,struct macio_driver, driver) + +extern int macio_register_driver(struct macio_driver *); +extern void macio_unregister_driver(struct macio_driver *); + +#endif /* __MACIO_ASIC_H__ */ diff -Nru a/include/asm-ppc/macio_asic.h b/include/asm-ppc/macio_asic.h --- a/include/asm-ppc/macio_asic.h Mon Aug 18 22:21:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,80 +0,0 @@ -#ifndef __MACIO_ASIC_H__ -#define __MACIO_ASIC_H__ - -#include - -extern struct bus_type macio_bus_type; - -/* MacIO device driver is defined later */ -struct macio_driver; -struct macio_chip; - -#define MACIO_DEV_COUNT_RESOURCE 8 -#define MACIO_DEV_COUNT_IRQS 8 - -/* - * the macio_bus structure is used to describe a "virtual" bus - * within a MacIO ASIC. It's typically provided by a macio_pci_asic - * PCI device, but could be provided differently as well (nubus - * machines using a fake OF tree). - */ -struct macio_bus -{ - struct macio_chip *chip; /* macio_chip (private use) */ - struct pci_dev *pdev; /* PCI device hosting this bus */ - struct list_head devices; /* list of devices on this bus */ -}; - -/* - * the macio_dev structure is used to describe a device - * within an Apple MacIO ASIC. - */ -struct macio_dev -{ - struct macio_bus *bus; /* virtual bus this device is on */ - - struct device_node *node; /* OF node */ - struct macio_driver *driver; /* which driver allocated this device */ - void *driver_data; /* placeholder for driver specific stuffs */ - struct resource resources[MACIO_DEV_COUNT_RESOURCE]; /* I/O */ - int irqs[MACIO_DEV_COUNT_IRQS]; - - struct device dev; /* Generic device interface */ -}; -#define to_macio_device(d) container_of(d, struct macio_dev, dev) - -/* - * Struct used for matching a device - */ -struct macio_match -{ - char *name; - char *type; - char *compatible; -}; -#define MACIO_ANY_MATCH ((char *)-1L) - -/* - * A driver for a mac-io chip based device - */ -struct macio_driver -{ - struct list_head node; - char *name; - struct macio_match *match_table; - - int (*probe)(struct macio_dev* dev, const struct macio_match *match); - int (*remove)(struct macio_dev* dev); - - int (*suspend)(struct macio_dev* dev, u32 state, u32 level); - int (*resume)(struct macio_dev* dev, u32 level); - int (*shutdown)(struct macio_dev* dev); - - struct device_driver driver; -}; -#define to_macio_driver(drv) container_of(drv,struct macio_driver, driver) - -extern int macio_register_driver(struct macio_driver *); -extern void macio_unregister_driver(struct macio_driver *); - -#endif /* __MACIO_ASIC_H__ */ diff -Nru a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-ppc/of_device.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,70 @@ +#ifndef __OF_DEVICE_H__ +#define __OF_DEVICE_H__ + +#include +#include + +/* + * The of_platform_bus_type is a bus type used by drivers that do not + * attach to a macio or similar bus but still use OF probing + * mecanism + */ +extern struct bus_type of_platform_bus_type; + +/* + * The of_device is a kind of "base class" that is a superset of + * struct device for use by devices attached to an OF node and + * probed using OF properties + */ +struct of_device +{ + struct device_node *node; /* OF device node */ + u64 dma_mask; /* DMA mask */ + struct device dev; /* Generic device interface */ +}; +#define to_of_device(d) container_of(d, struct of_device, dev) + +/* + * Struct used for matching a device + */ +struct of_match +{ + char *name; + char *type; + char *compatible; + void *data; +}; +#define OF_ANY_MATCH ((char *)-1L) + +extern const struct of_match *of_match_device( + const struct of_match *matches, const struct of_device *dev); + +/* + * An of_platform_driver driver is attached to a basic of_device on + * the "platform bus" (of_platform_bus_type) + */ +struct of_platform_driver +{ + char *name; + struct of_match *match_table; + struct module *owner; + + int (*probe)(struct of_device* dev, const struct of_match *match); + int (*remove)(struct of_device* dev); + + int (*suspend)(struct of_device* dev, u32 state, u32 level); + int (*resume)(struct of_device* dev, u32 level); + int (*shutdown)(struct of_device* dev); + + struct device_driver driver; +}; +#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver) + +extern int of_register_driver(struct of_platform_driver *drv); +extern void of_unregister_driver(struct of_platform_driver *drv); +extern int of_device_register(struct of_device *ofdev); +extern void of_device_unregister(struct of_device *ofdev); +extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id); + +#endif /* __OF_DEVICE_H__ */ + diff -Nru a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h --- a/include/asm-ppc/pmac_feature.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-ppc/pmac_feature.h Mon Aug 18 22:21:00 2003 @@ -31,7 +31,7 @@ #ifndef __PPC_ASM_PMAC_FEATURE_H #define __PPC_ASM_PMAC_FEATURE_H -#include +#include /* * Known Mac motherboard models diff -Nru a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h --- a/include/asm-ppc/smp.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-ppc/smp.h Mon Aug 18 22:21:01 2003 @@ -14,6 +14,8 @@ #include #include #include +#include +#include #ifdef CONFIG_SMP @@ -28,8 +30,8 @@ }; extern struct cpuinfo_PPC cpu_data[]; -extern unsigned long cpu_online_map; -extern unsigned long cpu_possible_map; +extern cpumask_t cpu_online_map; +extern cpumask_t cpu_possible_map; extern unsigned long smp_proc_in_lock[]; extern volatile unsigned long cpu_callin_map[]; extern int smp_tb_synchronized; @@ -45,21 +47,8 @@ #define smp_processor_id() (current_thread_info()->cpu) -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) -#define cpu_possible(cpu) (cpu_possible_map & (1<<(cpu))) - -extern inline unsigned int num_online_cpus(void) -{ - return hweight32(cpu_online_map); -} - -extern inline unsigned int any_online_cpu(unsigned int mask) -{ - if (mask & cpu_online_map) - return __ffs(mask & cpu_online_map); - - return NR_CPUS; -} +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) +#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) extern int __cpu_up(unsigned int cpu); diff -Nru a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h --- a/include/asm-ppc64/mmu_context.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-ppc64/mmu_context.h Mon Aug 18 22:21:02 2003 @@ -143,7 +143,7 @@ struct task_struct *tsk) { flush_stab(tsk, next); - set_bit(smp_processor_id(), &next->cpu_vm_mask); + cpu_set(smp_processor_id(), next->cpu_vm_mask); } #define deactivate_mm(tsk,mm) do { } while (0) diff -Nru a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h --- a/include/asm-ppc64/smp.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-ppc64/smp.h Mon Aug 18 22:21:00 2003 @@ -19,6 +19,7 @@ #include #include +#include #include #ifdef CONFIG_SMP @@ -27,30 +28,13 @@ #include -extern unsigned long cpu_online_map; - extern void smp_message_pass(int target, int msg, unsigned long data, int wait); extern void smp_send_tlb_invalidate(int); extern void smp_send_xmon_break(int cpu); struct pt_regs; extern void smp_message_recv(int, struct pt_regs *); -#define cpu_online(cpu) test_bit((cpu), &cpu_online_map) - #define cpu_possible(cpu) paca[cpu].active - -static inline unsigned int num_online_cpus(void) -{ - return hweight64(cpu_online_map); -} - -static inline unsigned int any_online_cpu(unsigned long mask) -{ - if (mask & cpu_online_map) - return __ffs(mask & cpu_online_map); - - return NR_CPUS; -} #define smp_processor_id() (get_paca()->xPacaIndex) diff -Nru a/include/asm-ppc64/tlb.h b/include/asm-ppc64/tlb.h --- a/include/asm-ppc64/tlb.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-ppc64/tlb.h Mon Aug 18 22:21:02 2003 @@ -49,6 +49,7 @@ struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[cpu]; unsigned long i = batch->index; pte_t pte; + cpumask_t local_cpumask = cpumask_of_cpu(cpu); if (pte_val(*ptep) & _PAGE_HASHPTE) { pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0)); @@ -61,7 +62,7 @@ if (i == PPC64_TLB_BATCH_NR) { int local = 0; - if (tlb->mm->cpu_vm_mask == (1UL << cpu)) + if (cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) local = 1; flush_hash_range(tlb->mm->context, i, local); @@ -78,8 +79,9 @@ int cpu = smp_processor_id(); struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[cpu]; int local = 0; + cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); - if (tlb->mm->cpu_vm_mask == (1UL << smp_processor_id())) + if (cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) local = 1; flush_hash_range(tlb->mm->context, batch->index, local); diff -Nru a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h --- a/include/asm-s390/bitops.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-s390/bitops.h Mon Aug 18 22:21:00 2003 @@ -505,7 +505,7 @@ unsigned char ch; addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - ch = *(unsigned char *) addr; + ch = *(volatile unsigned char *) addr; return (ch >> (nr & 7)) & 1; } diff -Nru a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h --- a/include/asm-s390/mmu_context.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-s390/mmu_context.h Mon Aug 18 22:21:03 2003 @@ -42,7 +42,7 @@ : : "m" (pgd) ); #endif /* __s390x__ */ } - set_bit(smp_processor_id(), &next->cpu_vm_mask); + cpu_set(smp_processor_id(), next->cpu_vm_mask); } #define deactivate_mm(tsk,mm) do { } while (0) diff -Nru a/include/asm-s390/smp.h b/include/asm-s390/smp.h --- a/include/asm-s390/smp.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-s390/smp.h Mon Aug 18 22:21:03 2003 @@ -11,6 +11,7 @@ #include #include +#include #include #if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__) @@ -28,8 +29,8 @@ __u16 cpu; } sigp_info; -extern volatile unsigned long cpu_online_map; -extern volatile unsigned long cpu_possible_map; +extern cpumask_t cpu_online_map; +extern cpumask_t cpu_possible_map; #define NO_PROC_ID 0xFF /* No processor magic marker */ @@ -47,25 +48,8 @@ #define smp_processor_id() (current_thread_info()->cpu) -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) -#define cpu_possible(cpu) (cpu_possible_map & (1<<(cpu))) - -extern inline unsigned int num_online_cpus(void) -{ -#ifndef __s390x__ - return hweight32(cpu_online_map); -#else /* __s390x__ */ - return hweight64(cpu_online_map); -#endif /* __s390x__ */ -} - -extern inline unsigned int any_online_cpu(unsigned int mask) -{ - if (mask & cpu_online_map) - return __ffs(mask & cpu_online_map); - - return NR_CPUS; -} +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) +#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) extern __inline__ __u16 hard_smp_processor_id(void) { diff -Nru a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h --- a/include/asm-s390/tlbflush.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-s390/tlbflush.h Mon Aug 18 22:21:06 2003 @@ -98,13 +98,15 @@ static inline void __flush_tlb_mm(struct mm_struct * mm) { + cpumask_t local_cpumask; preempt_disable(); - if (mm->cpu_vm_mask != (1UL << smp_processor_id())) { + local_cpumask = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(mm->cpu_vm_mask, local_cpumask)) { /* mm was active on more than one cpu. */ if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) /* this cpu is the only one using the mm. */ - mm->cpu_vm_mask = 1UL << smp_processor_id(); + mm->cpu_vm_mask = local_cpumask; global_flush_tlb(); } else local_flush_tlb(); diff -Nru a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h --- a/include/asm-sparc/smp.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-sparc/smp.h Mon Aug 18 22:21:02 2003 @@ -8,6 +8,7 @@ #include #include +#include #include #include diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h --- a/include/asm-sparc/unistd.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-sparc/unistd.h Mon Aug 18 22:21:01 2003 @@ -225,9 +225,9 @@ #define __NR_socketcall 206 /* Linux Specific */ #define __NR_syslog 207 /* Linux Specific */ #define __NR_lookup_dcookie 208 /* Linux Specific */ -/* #define __NR_iopl 209 Linux Specific - i386 specific, unused */ -/* #define __NR_idle 210 Linux Specific - was sys_idle, now unused */ -/* #define __NR_vm86 211 Linux Specific - i386 specific, unused */ +#define __NR_fadvise64 209 /* Linux Specific */ +#define __NR_fadvise64_64 210 /* Linux Specific */ +#define __NR_tgkill 211 /* Linux Specific */ #define __NR_waitpid 212 /* Linux Specific */ #define __NR_swapoff 213 /* Linux Specific */ #define __NR_sysinfo 214 /* Linux Specific */ @@ -272,10 +272,20 @@ #define __NR_fdatasync 253 #define __NR_nfsservctl 254 #define __NR_aplib 255 -/* WARNING: You MAY NOT add syscall numbers larger than 255, since +#define __NR_clock_settime 256 +#define __NR_clock_gettime 257 +#define __NR_clock_getres 258 +#define __NR_clock_nanosleep 259 +#define __NR_sched_getaffinity 260 +#define __NR_sched_setaffinity 261 +#define __NR_timer_settime 262 +#define __NR_timer_gettime 263 +#define __NR_timer_getoverrun 264 +#define __NR_timer_delete 265 +/* WARNING: You MAY NOT add syscall numbers larger than 265, since * all of the syscall tables in the Sparc kernel are - * sized to have 256 entries (starting at zero). Therefore - * find a free slot in the 0-255 range. + * sized to have 266 entries (starting at zero). Therefore + * find a free slot in the 0-265 range. */ #define _syscall0(type,name) \ diff -Nru a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h --- a/include/asm-sparc64/bitops.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-sparc64/bitops.h Mon Aug 18 22:21:01 2003 @@ -156,6 +156,14 @@ #ifdef ULTRA_HAS_POPULATION_COUNT +static __inline__ unsigned int hweight64(unsigned long w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); + return res; +} + static __inline__ unsigned int hweight32(unsigned int w) { unsigned int res; @@ -182,6 +190,7 @@ #else +#define hweight64(x) generic_hweight64(x) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) diff -Nru a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h --- a/include/asm-sparc64/mmu_context.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-sparc64/mmu_context.h Mon Aug 18 22:21:06 2003 @@ -125,7 +125,7 @@ } { - unsigned long vm_mask = (1UL << smp_processor_id()); + int cpu = smp_processor_id(); /* Even if (mm == old_mm) we _must_ check * the cpu_vm_mask. If we do not we could @@ -133,8 +133,8 @@ * smp_flush_tlb_{page,range,mm} on sparc64 * and lazy tlb switches work. -DaveM */ - if (!ctx_valid || !(mm->cpu_vm_mask & vm_mask)) { - mm->cpu_vm_mask |= vm_mask; + if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) { + cpu_set(cpu, mm->cpu_vm_mask); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); } } @@ -148,14 +148,14 @@ /* Activate a new MM instance for the current task. */ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm) { - unsigned long vm_mask; + int cpu; spin_lock(&mm->page_table_lock); if (!CTX_VALID(mm->context)) get_new_mmu_context(mm); - vm_mask = (1UL << smp_processor_id()); - if (!(mm->cpu_vm_mask & vm_mask)) - mm->cpu_vm_mask |= vm_mask; + cpu = smp_processor_id(); + if (!cpu_isset(cpu, mm->cpu_vm_mask)) + cpu_set(cpu, mm->cpu_vm_mask); spin_unlock(&mm->page_table_lock); load_secondary_context(mm); diff -Nru a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h --- a/include/asm-sparc64/smp.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-sparc64/smp.h Mon Aug 18 22:21:02 2003 @@ -14,6 +14,7 @@ #ifndef __ASSEMBLY__ +#include #include /* PROM provided per-processor information we need @@ -68,24 +69,13 @@ extern unsigned char boot_cpu_id; -extern unsigned long phys_cpu_present_map; -#define cpu_possible(cpu) (phys_cpu_present_map & (1UL << (cpu))) +extern cpumask_t phys_cpu_present_map; +#define cpu_possible(cpu) cpu_isset(cpu, phys_cpu_present_map) -extern unsigned long cpu_online_map; -#define cpu_online(cpu) (cpu_online_map & (1UL << (cpu))) - -extern atomic_t sparc64_num_cpus_online; -#define num_online_cpus() (atomic_read(&sparc64_num_cpus_online)) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) extern atomic_t sparc64_num_cpus_possible; #define num_possible_cpus() (atomic_read(&sparc64_num_cpus_possible)) - -static inline unsigned int any_online_cpu(unsigned long mask) -{ - if ((mask &= cpu_online_map) != 0UL) - return __ffs(mask); - return NR_CPUS; -} /* * General functions that each host system must provide. diff -Nru a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h --- a/include/asm-sparc64/ttable.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-sparc64/ttable.h Mon Aug 18 22:21:01 2003 @@ -95,9 +95,10 @@ sethi %hi(109f), %g7; \ ba,pt %xcc, scetrap; \ 109: or %g7, %lo(109b), %g7; \ + sethi %hi(systbl), %l7; \ ba,pt %xcc, routine; \ - sethi %hi(systbl), %l7; \ - nop; nop; nop; + or %l7, %lo(systbl), %l7; \ + nop; nop; #define INDIRECT_SOLARIS_SYSCALL(num) \ sethi %hi(109f), %g7; \ diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h --- a/include/asm-sparc64/unistd.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-sparc64/unistd.h Mon Aug 18 22:21:01 2003 @@ -225,9 +225,9 @@ #define __NR_socketcall 206 /* Linux Specific */ #define __NR_syslog 207 /* Linux Specific */ #define __NR_lookup_dcookie 208 /* Linux Specific */ -/* #define __NR_iopl 209 Linux Specific - i386 specific, unused */ -/* #define __NR_idle 210 Linux Specific - was sys_idle, now unused */ -/* #define __NR_vm86 211 Linux Specific - i386 specific, unused */ +#define __NR_fadvise64 209 /* Linux Specific */ +#define __NR_fadvise64_64 210 /* Linux Specific */ +#define __NR_tgkill 211 /* Linux Specific */ #define __NR_waitpid 212 /* Linux Specific */ #define __NR_swapoff 213 /* Linux Specific */ #define __NR_sysinfo 214 /* Linux Specific */ @@ -274,10 +274,20 @@ #define __NR_fdatasync 253 #define __NR_nfsservctl 254 #define __NR_aplib 255 -/* WARNING: You MAY NOT add syscall numbers larger than 255, since - * all of the syscall tables in the Sparc64 kernel are - * sized to have 256 entries (starting at zero). Therefore - * find a free slot in the 0-255 range. +#define __NR_clock_settime 256 +#define __NR_clock_gettime 257 +#define __NR_clock_getres 258 +#define __NR_clock_nanosleep 259 +#define __NR_sched_getaffinity 260 +#define __NR_sched_setaffinity 261 +#define __NR_timer_settime 262 +#define __NR_timer_gettime 263 +#define __NR_timer_getoverrun 264 +#define __NR_timer_delete 265 +/* WARNING: You MAY NOT add syscall numbers larger than 265, since + * all of the syscall tables in the Sparc kernel are + * sized to have 266 entries (starting at zero). Therefore + * find a free slot in the 0-265 range. */ #define _syscall0(type,name) \ diff -Nru a/include/asm-um/smp.h b/include/asm-um/smp.h --- a/include/asm-um/smp.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-um/smp.h Mon Aug 18 22:21:00 2003 @@ -1,13 +1,14 @@ #ifndef __UM_SMP_H #define __UM_SMP_H -extern unsigned long cpu_online_map; - #ifdef CONFIG_SMP #include "linux/config.h" #include "linux/bitops.h" #include "asm/current.h" +#include "linux/cpumask.h" + +extern cpumask_t cpu_online_map; #define smp_processor_id() (current->thread_info->cpu) #define cpu_logical_map(n) (n) @@ -16,15 +17,10 @@ extern int hard_smp_processor_id(void); #define NO_PROC_ID -1 -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) extern int ncpus; #define cpu_possible(cpu) (cpu < ncpus) - -extern inline unsigned int num_online_cpus(void) -{ - return(hweight32(cpu_online_map)); -} extern inline void smp_cpus_done(unsigned int maxcpus) { diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h --- a/include/asm-x86_64/bitops.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-x86_64/bitops.h Mon Aug 18 22:21:03 2003 @@ -402,12 +402,12 @@ } } -static inline void clear_bit_string(unsigned long *bitmap, unsigned long i, +static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i, int len) { unsigned long end = i + len; while (i < end) { - clear_bit(i, bitmap); + __clear_bit(i, bitmap); i++; } } @@ -477,6 +477,7 @@ * The Hamming Weight of a number is the total number of bits set in it. */ +#define hweight64(x) generic_hweight64(x) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) diff -Nru a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h --- a/include/asm-x86_64/ia32_unistd.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-x86_64/ia32_unistd.h Mon Aug 18 22:21:04 2003 @@ -264,7 +264,20 @@ #define __NR_ia32_sys_epoll_wait 256 #define __NR_ia32_remap_file_pages 257 #define __NR_ia32_set_tid_address 258 +#define __NR_ia32_timer_create 259 +#define __NR_ia32_timer_settime (__NR_ia32_timer_create+1) +#define __NR_ia32_timer_gettime (__NR_ia32_timer_create+2) +#define __NR_ia32_timer_getoverrun (__NR_ia32_timer_create+3) +#define __NR_ia32_timer_delete (__NR_ia32_timer_create+4) +#define __NR_ia32_clock_settime (__NR_ia32_timer_create+5) +#define __NR_ia32_clock_gettime (__NR_ia32_timer_create+6) +#define __NR_ia32_clock_getres (__NR_ia32_timer_create+7) +#define __NR_ia32_clock_nanosleep (__NR_ia32_timer_create+8) +#define __NR_ia32_statfs64 268 +#define __NR_ia32_fstatfs64 269 +#define __NR_ia32_tgkill 270 +#define __NR_ia32_utimes 271 -#define IA32_NR_syscalls 265 /* must be > than biggest syscall! */ +#define IA32_NR_syscalls 275 /* must be > than biggest syscall! */ #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ diff -Nru a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h --- a/include/asm-x86_64/io.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-x86_64/io.h Mon Aug 18 22:21:03 2003 @@ -301,6 +301,12 @@ #define flush_write_buffers() +/* Disable vmerge for now. Need to fix the block layer code + to check for non iommu addresses first. + When the IOMMU is force it is safe to enable. */ +extern int force_iommu; +#define BIO_VERMGE_BOUNDARY (force_iommu ? 4096 : 0) + #endif /* __KERNEL__ */ #endif diff -Nru a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h --- a/include/asm-x86_64/mpspec.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-x86_64/mpspec.h Mon Aug 18 22:21:03 2003 @@ -166,10 +166,10 @@ }; extern unsigned char mp_bus_id_to_type [MAX_MP_BUSSES]; extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; -extern unsigned long mp_bus_to_cpumask [MAX_MP_BUSSES]; +extern cpumask_t mp_bus_to_cpumask [MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; -extern unsigned long phys_cpu_present_map; +extern cpumask_t phys_cpu_present_map; extern int smp_found_config; extern void find_smp_config (void); extern void get_smp_config (void); diff -Nru a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h --- a/include/asm-x86_64/nmi.h Mon Aug 18 22:21:01 2003 +++ b/include/asm-x86_64/nmi.h Mon Aug 18 22:21:01 2003 @@ -48,6 +48,4 @@ extern void default_do_nmi(struct pt_regs *); -extern void default_do_nmi(struct pt_regs *); - #endif /* ASM_NMI_H */ diff -Nru a/include/asm-x86_64/pci-direct.h b/include/asm-x86_64/pci-direct.h --- a/include/asm-x86_64/pci-direct.h Mon Aug 18 22:21:02 2003 +++ b/include/asm-x86_64/pci-direct.h Mon Aug 18 22:21:02 2003 @@ -14,7 +14,26 @@ u32 v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); v = inl(0xcfc); - PDprintk("%x reading from %x: %x\n", slot, offset, v); + if (v != 0xffffffff) + PDprintk("%x reading 4 from %x: %x\n", slot, offset, v); + return v; +} + +static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) +{ + u8 v; + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + v = inb(0xcfc + (offset&3)); + PDprintk("%x reading 1 from %x: %x\n", slot, offset, v); + return v; +} + +static inline u8 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) +{ + u16 v; + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + v = inw(0xcfc + (offset&2)); + PDprintk("%x reading 2 from %x: %x\n", slot, offset, v); return v; } diff -Nru a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h --- a/include/asm-x86_64/pci.h Mon Aug 18 22:21:03 2003 +++ b/include/asm-x86_64/pci.h Mon Aug 18 22:21:03 2003 @@ -8,9 +8,6 @@ #include /* for struct page */ - -extern dma_addr_t bad_dma_address; - /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ @@ -21,6 +18,8 @@ #define pcibios_assign_all_busses() 0 #endif +extern int no_iommu, force_iommu; + extern unsigned long pci_mem_start; #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM (pci_mem_start) @@ -46,6 +45,9 @@ extern int iommu_setup(char *opt); +extern dma_addr_t bad_dma_address; +#define pci_dma_error(x) ((x) == bad_dma_address) + /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices, * NULL for PCI-like buses (ISA, EISA). @@ -119,10 +121,16 @@ /* The PCI address space does equal the physical memory * address space. The networking and block device layers use - * this boolean for bounce buffer decisions. + * this boolean for bounce buffer decisions + * + * On AMD64 it mostly equals, but we set it to zero to tell some subsystems + * that an IOMMU is available. */ -#define PCI_DMA_BUS_IS_PHYS (0) +#define PCI_DMA_BUS_IS_PHYS (no_iommu ? 1 : 0) +/* We lie slightly when the IOMMU is forced to get the device to + use SAC instead of DAC. */ +#define pci_dac_dma_supported(pci_dev, mask) (force_iommu ? 0 : 1) #else static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, @@ -206,6 +214,7 @@ #define PCI_DMA_BUS_IS_PHYS 1 +#define pci_dac_dma_supported(pci_dev, mask) 1 #endif extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, @@ -220,21 +229,7 @@ * only drive the low 24-bits during PCI bus mastering, then * you would pass 0x00ffffff as the mask to this function. */ -static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) -{ - /* - * we fall back to GFP_DMA when the mask isn't all 1s, - * so we can't guarantee allocations that must be - * within a tighter range than GFP_DMA.. - */ - if(mask < 0x00ffffff) - return 0; - - return 1; -} - -/* This is always fine. */ -#define pci_dac_dma_supported(pci_dev, mask) (1) +extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); static __inline__ dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction) diff -Nru a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h --- a/include/asm-x86_64/percpu.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-x86_64/percpu.h Mon Aug 18 22:21:04 2003 @@ -1,53 +1,51 @@ #ifndef _ASM_X8664_PERCPU_H_ #define _ASM_X8664_PERCPU_H_ +#include -#include +/* Same as asm-generic/percpu.h, except that we store the per cpu offset + in the PDA. Longer term the PDA and every per cpu variable + should be just put into a single section and referenced directly + from %gs */ #ifdef CONFIG_SMP -/* Same as the generic code except that we cache the per cpu offset - in the pda. This gives an 3 instruction reference for per cpu data */ - -#include #include -#define __my_cpu_offset() read_pda(data_offset) + #define __per_cpu_offset(cpu) (cpu_pda[cpu].data_offset) +#define __my_cpu_offset() read_pda(data_offset) /* Separate out the type, so (int[3], foo) works. */ #define DEFINE_PER_CPU(type, name) \ - __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu + __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name /* var is in discarded region: offset to particular copy we want */ -#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset(cpu))) -#define __get_cpu_var(var) \ - (*RELOC_HIDE(&var##__per_cpu, __my_cpu_offset())) - -static inline void percpu_modcopy(void *pcpudst, const void *src, - unsigned long size) -{ - unsigned int i; - for (i = 0; i < NR_CPUS; i++) - if (cpu_possible(i)) - memcpy(pcpudst + __per_cpu_offset(i), src, size); -} - -extern void setup_per_cpu_areas(void); +#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) +#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset())) +/* A macro to avoid #include hell... */ +#define percpu_modcopy(pcpudst, src, size) \ +do { \ + unsigned int __i; \ + for (__i = 0; __i < NR_CPUS; __i++) \ + if (cpu_possible(__i)) \ + memcpy((pcpudst)+__per_cpu_offset(__i), \ + (src), (size)); \ +} while (0) #else /* ! SMP */ #define DEFINE_PER_CPU(type, name) \ - __typeof__(type) name##__per_cpu + __typeof__(type) per_cpu__##name -#define per_cpu(var, cpu) ((void)cpu, var##__per_cpu) -#define __get_cpu_var(var) var##__per_cpu +#define per_cpu(var, cpu) ((void)cpu, per_cpu__##var) +#define __get_cpu_var(var) per_cpu__##var #endif /* SMP */ -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu +#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name -#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu) -#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu) +#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) +#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) -DECLARE_PER_CPU(struct x8664_pda, per_cpu_pda); +extern void setup_per_cpu_areas(void); -#endif +#endif /* _ASM_X8664_PERCPU_H_ */ diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h --- a/include/asm-x86_64/proto.h Mon Aug 18 22:21:05 2003 +++ b/include/asm-x86_64/proto.h Mon Aug 18 22:21:05 2003 @@ -77,7 +77,7 @@ extern unsigned long table_start, table_end; extern int exception_trace; -extern int no_iommu, force_mmu; +extern int force_iommu, no_iommu; extern int using_apic_timer; extern int disable_apic; extern unsigned cpu_khz; diff -Nru a/include/asm-x86_64/siginfo.h b/include/asm-x86_64/siginfo.h --- a/include/asm-x86_64/siginfo.h Mon Aug 18 22:21:06 2003 +++ b/include/asm-x86_64/siginfo.h Mon Aug 18 22:21:06 2003 @@ -1,6 +1,8 @@ #ifndef _X8664_SIGINFO_H #define _X8664_SIGINFO_H +#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) + #include #endif diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h --- a/include/asm-x86_64/smp.h Mon Aug 18 22:21:00 2003 +++ b/include/asm-x86_64/smp.h Mon Aug 18 22:21:00 2003 @@ -7,6 +7,7 @@ #ifndef __ASSEMBLY__ #include #include +#include #include extern int disable_apic; #endif @@ -35,8 +36,8 @@ */ extern void smp_alloc_memory(void); -extern unsigned long phys_cpu_present_map; -extern unsigned long cpu_online_map; +extern cpumask_t phys_cpu_present_map; +extern cpumask_t cpu_online_map; extern volatile unsigned long smp_invalidate_needed; extern int pic_mode; extern void smp_flush_tlb(void); @@ -56,36 +57,16 @@ * compresses data structures. */ -extern volatile unsigned long cpu_callout_map; +extern cpumask_t cpu_callout_map; -#define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu))) -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) - -#define for_each_cpu(cpu, mask) \ - for(mask = cpu_online_map; \ - cpu = __ffs(mask), mask != 0; \ - mask &= ~(1UL< diff -Nru a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h --- a/include/asm-x86_64/topology.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-x86_64/topology.h Mon Aug 18 22:21:04 2003 @@ -10,18 +10,21 @@ /* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */ extern int fake_node; -extern unsigned long cpu_online_map; +extern cpumask_t cpu_online_map; #define cpu_to_node(cpu) (fake_node ? 0 : (cpu)) #define memblk_to_node(memblk) (fake_node ? 0 : (memblk)) #define parent_node(node) (node) #define node_to_first_cpu(node) (fake_node ? 0 : (node)) -#define node_to_cpu_mask(node) (fake_node ? cpu_online_map : (1UL << (node))) +#define node_to_cpu_mask(node) (fake_node ? cpu_online_map : cpumask_of_cpu(node)) #define node_to_memblk(node) (node) -static inline unsigned long pcibus_to_cpumask(int bus) +static inline cpumask_t pcibus_to_cpumask(int bus) { - return mp_bus_to_cpumask[bus] & cpu_online_map; + cpumask_t ret; + + cpus_and(ret, mp_bus_to_cpumask[bus], cpu_online_map); + return ret; } #define NODE_BALANCE_RATE 30 /* CHECKME */ diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h --- a/include/asm-x86_64/unistd.h Mon Aug 18 22:21:04 2003 +++ b/include/asm-x86_64/unistd.h Mon Aug 18 22:21:04 2003 @@ -461,7 +461,7 @@ #define __NR_tkill 200 __SYSCALL(__NR_tkill, sys_tkill) #define __NR_time 201 -__SYSCALL(__NR_time, sys_time) +__SYSCALL(__NR_time, sys_time64) #define __NR_futex 202 __SYSCALL(__NR_futex, sys_futex) #define __NR_sched_setaffinity 203 diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h --- a/include/linux/acpi.h Mon Aug 18 22:21:00 2003 +++ b/include/linux/acpi.h Mon Aug 18 22:21:00 2003 @@ -37,7 +37,7 @@ #include -#ifdef CONFIG_ACPI +#ifdef CONFIG_ACPI_BOOT enum acpi_irq_model_id { ACPI_IRQ_MODEL_PIC = 0, @@ -369,11 +369,11 @@ extern int acpi_mp_config; -#else +#else /*!CONFIG_ACPI_BOOT*/ #define acpi_mp_config 0 -#endif +#endif /*!CONFIG_ACPI_BOOT*/ #ifdef CONFIG_ACPI_PCI diff -Nru a/include/linux/bitmap.h b/include/linux/bitmap.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/bitmap.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,159 @@ +#ifndef __LINUX_BITMAP_H +#define __LINUX_BITMAP_H + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include +#include +#include + +static inline int bitmap_empty(const unsigned long *bitmap, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap[k]) + return 0; + + if (bits % BITS_PER_LONG) + if (bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + + return 1; +} + +static inline int bitmap_full(const unsigned long *bitmap, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (~bitmap[k]) + return 0; + + if (bits % BITS_PER_LONG) + if (~bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + + return 1; +} + +static inline int bitmap_equal(const unsigned long *bitmap1, + unsigned long *bitmap2, int bits) +{ + int k, lim = bits/BITS_PER_LONG;; + for (k = 0; k < lim; ++k) + if (bitmap1[k] != bitmap2[k]) + return 0; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] ^ bitmap2[k]) & + ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + + return 1; +} + +static inline void bitmap_complement(unsigned long *bitmap, int bits) +{ + int k; + + for (k = 0; k < BITS_TO_LONGS(bits); ++k) + bitmap[k] = ~bitmap[k]; +} + +static inline void bitmap_clear(unsigned long *bitmap, int bits) +{ + CLEAR_BITMAP((unsigned long *)bitmap, bits); +} + +static inline void bitmap_fill(unsigned long *bitmap, int bits) +{ + memset(bitmap, 0xff, BITS_TO_LONGS(bits)*sizeof(unsigned long)); +} + +static inline void bitmap_copy(unsigned long *dst, + const unsigned long *src, int bits) +{ + memcpy(dst, src, BITS_TO_LONGS(bits)*sizeof(unsigned long)); +} + +static inline void bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int shift, int bits) +{ + int k; + DECLARE_BITMAP(__shr_tmp, bits); + + bitmap_clear(__shr_tmp, bits); + for (k = 0; k < bits - shift; ++k) + if (test_bit(k + shift, src)) + set_bit(k, __shr_tmp); + bitmap_copy(dst, __shr_tmp, bits); +} + +static inline void bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int shift, int bits) +{ + int k; + DECLARE_BITMAP(__shl_tmp, bits); + + bitmap_clear(__shl_tmp, bits); + for (k = bits; k >= shift; --k) + if (test_bit(k - shift, src)) + set_bit(k, __shl_tmp); + bitmap_copy(dst, __shl_tmp, bits); +} + +static inline void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] & bitmap2[k]; +} + +static inline void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] | bitmap2[k]; +} + +#if BITS_PER_LONG == 32 +static inline int bitmap_weight(const unsigned long *bitmap, int bits) +{ + int k, w = 0, lim = bits/BITS_PER_LONG; + + for (k = 0; k < lim; k++) + w += hweight32(bitmap[k]); + + if (bits % BITS_PER_LONG) + w += hweight32(bitmap[k] & + ((1UL << (bits % BITS_PER_LONG)) - 1)); + + return w; +} +#else +static inline int bitmap_weight(const unsigned long *bitmap, int bits) +{ + int k, w = 0, lim = bits/BITS_PER_LONG; + + for (k = 0; k < lim; k++) + w += hweight64(bitmap[k]); + + if (bits % BITS_PER_LONG) + w += hweight64(bitmap[k] & + ((1UL << (bits % BITS_PER_LONG)) - 1)); + + return w; +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __LINUX_BITMAP_H */ diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/blkdev.h Mon Aug 18 22:21:02 2003 @@ -547,6 +547,7 @@ extern void blk_queue_max_hw_segments(request_queue_t *, unsigned short); extern void blk_queue_max_segment_size(request_queue_t *, unsigned int); extern void blk_queue_hardsect_size(request_queue_t *, unsigned short); +extern void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b); extern void blk_queue_segment_boundary(request_queue_t *, unsigned long); extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn); extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *); diff -Nru a/include/linux/compat.h b/include/linux/compat.h --- a/include/linux/compat.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/compat.h Mon Aug 18 22:21:03 2003 @@ -15,6 +15,11 @@ #define compat_jiffies_to_clock_t(x) \ (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) +struct compat_itimerspec { + struct compat_timespec it_interval; + struct compat_timespec it_value; +}; + struct compat_utimbuf { compat_time_t actime; compat_time_t modtime; @@ -69,6 +74,20 @@ compat_long_t ru_nsignals; compat_long_t ru_nvcsw; compat_long_t ru_nivcsw; +}; + +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; }; #endif /* CONFIG_COMPAT */ diff -Nru a/include/linux/compiler.h b/include/linux/compiler.h --- a/include/linux/compiler.h Mon Aug 18 22:21:04 2003 +++ b/include/linux/compiler.h Mon Aug 18 22:21:04 2003 @@ -24,8 +24,8 @@ #define __builtin_expect(x, expected_value) (x) #endif -#define likely(x) __builtin_expect((x),1) -#define unlikely(x) __builtin_expect((x),0) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) /* * Allow us to mark functions as 'deprecated' and have gcc emit a nice diff -Nru a/include/linux/cpumask.h b/include/linux/cpumask.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/cpumask.h Mon Aug 18 22:21:06 2003 @@ -0,0 +1,71 @@ +#ifndef __LINUX_CPUMASK_H +#define __LINUX_CPUMASK_H + +#include +#include +#include +#include +#include + +#if NR_CPUS > BITS_PER_LONG && NR_CPUS != 1 +#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS) + +struct cpumask +{ + unsigned long mask[CPU_ARRAY_SIZE]; +}; + +typedef struct cpumask cpumask_t; + +#else +typedef unsigned long cpumask_t; +#endif + +#ifdef CONFIG_SMP +#if NR_CPUS > BITS_PER_LONG +#include +#else +#include +#endif +#else +#include +#endif + +#if NR_CPUS <= 4*BITS_PER_LONG +#include +#else +#include +#endif + + +#ifdef CONFIG_SMP + +extern cpumask_t cpu_online_map; + +#define num_online_cpus() cpus_weight(cpu_online_map) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) +#else +#define cpu_online_map cpumask_of_cpu(0) +#define num_online_cpus() 1 +#define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) +#endif + +static inline int next_online_cpu(int cpu, cpumask_t map) +{ + do + cpu = next_cpu_const(cpu, map); + while (cpu < NR_CPUS && !cpu_online(cpu)); + return cpu; +} + +#define for_each_cpu(cpu, map) \ + for (cpu = first_cpu_const(map); \ + cpu < NR_CPUS; \ + cpu = next_cpu_const(cpu,map)) + +#define for_each_online_cpu(cpu, map) \ + for (cpu = first_cpu_const(map); \ + cpu < NR_CPUS; \ + cpu = next_online_cpu(cpu,map)) + +#endif /* __LINUX_CPUMASK_H */ diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h --- a/include/linux/crypto.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/crypto.h Mon Aug 18 22:21:02 2003 @@ -65,7 +65,6 @@ struct cipher_alg { unsigned int cia_min_keysize; unsigned int cia_max_keysize; - unsigned int cia_ivsize; int (*cia_setkey)(void *ctx, const u8 *key, unsigned int keylen, u32 *flags); void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); @@ -128,6 +127,7 @@ struct cipher_tfm { void *cit_iv; + unsigned int cit_ivsize; u32 cit_mode; int (*cit_setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen); @@ -237,7 +237,7 @@ static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->__crt_alg->cra_cipher.cia_ivsize; + return tfm->crt_cipher.cit_ivsize; } static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) diff -Nru a/include/linux/device.h b/include/linux/device.h --- a/include/linux/device.h Mon Aug 18 22:21:05 2003 +++ b/include/linux/device.h Mon Aug 18 22:21:05 2003 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -41,13 +42,6 @@ RESUME_ENABLE, }; -enum device_state { - DEVICE_UNINITIALIZED = 0, - DEVICE_INITIALIZED = 1, - DEVICE_REGISTERED = 2, - DEVICE_GONE = 3, -}; - struct device; struct device_driver; struct class; @@ -64,8 +58,8 @@ struct device * (*add) (struct device * parent, char * bus_id); int (*hotplug) (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); -}; +}; extern int bus_register(struct bus_type * bus); extern void bus_unregister(struct bus_type * bus); @@ -182,8 +176,8 @@ .store = _store, \ }; -extern int class_create_file(struct class *, struct class_attribute *); -extern void class_remove_file(struct class *, struct class_attribute *); +extern int class_create_file(struct class *, const struct class_attribute *); +extern void class_remove_file(struct class *, const struct class_attribute *); struct class_device { @@ -234,8 +228,10 @@ .store = _store, \ }; -extern int class_device_create_file(struct class_device *, struct class_device_attribute *); -extern void class_device_remove_file(struct class_device *, struct class_device_attribute *); +extern int class_device_create_file(struct class_device *, + const struct class_device_attribute *); +extern void class_device_remove_file(struct class_device *, + const struct class_device_attribute *); struct class_interface { @@ -258,7 +254,6 @@ struct device * parent; struct kobject kobj; - char name[DEVICE_NAME_SIZE]; /* descriptive ascii string */ char bus_id[BUS_ID_SIZE]; /* position on parent bus */ struct bus_type * bus; /* type of bus device is on */ @@ -267,13 +262,16 @@ void *driver_data; /* data private to the driver */ void *platform_data; /* Platform specific data (e.g. ACPI, BIOS data relevant to device) */ - + struct dev_pm_info power; u32 power_state; /* Current operating state. In ACPI-speak, this is D0-D3, D0 being fully functional, and D3 being off. */ unsigned char *saved_state; /* saved device state */ + u32 detach_state; /* State to enter when device is + detached from its driver. */ + u64 *dma_mask; /* dma mask (if dma'able device) */ void (*release)(struct device * dev); diff -Nru a/include/linux/eisa.h b/include/linux/eisa.h --- a/include/linux/eisa.h Mon Aug 18 22:21:05 2003 +++ b/include/linux/eisa.h Mon Aug 18 22:21:05 2003 @@ -42,6 +42,9 @@ struct resource res[EISA_MAX_RESOURCES]; u64 dma_mask; struct device dev; /* generic device */ +#ifdef CONFIG_EISA_NAMES + char pretty_name[DEVICE_NAME_SIZE]; +#endif }; #define to_eisa_device(n) container_of(n, struct eisa_device, dev) diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h --- a/include/linux/ethtool.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/ethtool.h Mon Aug 18 22:21:02 2003 @@ -97,7 +97,7 @@ u32 rx_max_coalesced_frames; /* Same as above two parameters, except that these values - * apply while an IRQ is being services by the host. Not + * apply while an IRQ is being serviced by the host. Not * all cards support this feature and the values are ignored * in that case. */ @@ -119,7 +119,7 @@ u32 tx_max_coalesced_frames; /* Same as above two parameters, except that these values - * apply while an IRQ is being services by the host. Not + * apply while an IRQ is being serviced by the host. Not * all cards support this feature and the values are ignored * in that case. */ @@ -248,6 +248,101 @@ u32 cmd; /* ETHTOOL_GSTATS */ u32 n_stats; /* number of u64's being returned */ u64 data[0]; +}; + +struct net_device; + +/* Some generic methods drivers may use in their ethtool_ops */ +u32 ethtool_op_get_link(struct net_device *dev); +u32 ethtool_op_get_tx_csum(struct net_device *dev); +u32 ethtool_op_get_sg(struct net_device *dev); +int ethtool_op_set_sg(struct net_device *dev, u32 data); + +/** + * ðtool_ops - Alter and report network device settings + * get_settings: Get device-specific settings + * set_settings: Set device-specific settings + * get_drvinfo: Report driver information + * get_regs: Get device registers + * get_wol: Report whether Wake-on-Lan is enabled + * set_wol: Turn Wake-on-Lan on or off + * get_msglevel: Report driver message level + * set_msglevel: Set driver message level + * nway_reset: Restart autonegotiation + * get_link: Get link status + * get_eeprom: Read data from the device EEPROM + * set_eeprom: Write data to the device EEPROM + * get_coalesce: Get interrupt coalescing parameters + * set_coalesce: Set interrupt coalescing parameters + * get_ringparam: Report ring sizes + * set_ringparam: Set ring sizes + * get_pauseparam: Report pause parameters + * set_pauseparam: Set pause paramters + * get_rx_csum: Report whether receive checksums are turned on or off + * set_rx_csum: Turn receive checksum on or off + * get_tx_csum: Report whether transmit checksums are turned on or off + * set_tx_csum: Turn transmit checksums on or off + * get_sg: Report whether scatter-gather is enabled + * set_sg: Turn scatter-gather on or off + * self_test: Run specified self-tests + * get_strings: Return a set of strings that describe the requested objects + * phys_id: Identify the device + * get_stats: Return statistics about the device + * + * Description: + * + * get_settings: + * @get_settings is passed an ðtool_cmd to fill in. It returns + * an negative errno or zero. + * + * set_settings: + * @set_settings is passed an ðtool_cmd and should attempt to set + * all the settings this device supports. It may return an error value + * if something goes wrong (otherwise 0). + * + * get_eeprom: + * Should fill in the magic field. Don't need to check len for zero + * or wraparound but must check offset + len < size. Fill in the data + * argument with the eeprom values from offset to offset + len. Update + * len to the amount read. Returns an error or zero. + * + * set_eeprom: + * Should validate the magic field. Don't need to check len for zero + * or wraparound but must check offset + len < size. Update len to + * the amount written. Returns an error or zero. + */ +struct ethtool_ops { + int (*get_settings)(struct net_device *, struct ethtool_cmd *); + int (*set_settings)(struct net_device *, struct ethtool_cmd *); + void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); + int (*get_regs_len)(struct net_device *); + void (*get_regs)(struct net_device *, struct ethtool_regs *, void *); + void (*get_wol)(struct net_device *, struct ethtool_wolinfo *); + int (*set_wol)(struct net_device *, struct ethtool_wolinfo *); + u32 (*get_msglevel)(struct net_device *); + void (*set_msglevel)(struct net_device *, u32); + int (*nway_reset)(struct net_device *); + u32 (*get_link)(struct net_device *); + int (*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *); + int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *); + void (*get_ringparam)(struct net_device *, struct ethtool_ringparam *); + int (*set_ringparam)(struct net_device *, struct ethtool_ringparam *); + void (*get_pauseparam)(struct net_device *, struct ethtool_pauseparam*); + int (*set_pauseparam)(struct net_device *, struct ethtool_pauseparam*); + u32 (*get_rx_csum)(struct net_device *); + int (*set_rx_csum)(struct net_device *, u32); + u32 (*get_tx_csum)(struct net_device *); + int (*set_tx_csum)(struct net_device *, u32); + u32 (*get_sg)(struct net_device *); + int (*set_sg)(struct net_device *, u32); + int (*self_test_count)(struct net_device *); + void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); + void (*get_strings)(struct net_device *, u32 stringset, u8 *); + int (*phys_id)(struct net_device *, u32); + int (*get_stats_count)(struct net_device *); + void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); }; /* CMDs currently supported */ diff -Nru a/include/linux/hdreg.h b/include/linux/hdreg.h --- a/include/linux/hdreg.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/hdreg.h Mon Aug 18 22:21:03 2003 @@ -395,14 +395,6 @@ unsigned long start; }; -/* BIG GEOMETRY - dying, used only by HDIO_GETGEO_BIG_RAW */ -struct hd_big_geometry { - unsigned char heads; - unsigned char sectors; - unsigned int cylinders; - unsigned long start; -}; - /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */ #define HDIO_GETGEO 0x0301 /* get device geometry */ #define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ @@ -456,7 +448,7 @@ /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */ /* 0x330 is reserved - used to be HDIO_GETGEO_BIG */ -#define HDIO_GETGEO_BIG_RAW 0x0331 /* */ +/* 0x331 is reserved - used to be HDIO_GETGEO_BIG_RAW */ #define HDIO_SET_IDE_SCSI 0x0338 #define HDIO_SET_SCSI_IDE 0x0339 diff -Nru a/include/linux/ide.h b/include/linux/ide.h --- a/include/linux/ide.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/ide.h Mon Aug 18 22:21:02 2003 @@ -766,8 +766,7 @@ unsigned int failures; /* current failure count */ unsigned int max_failures; /* maximum allowed failure count */ - u32 capacity; /* total number of sectors */ - u64 capacity48; /* total number of sectors */ + u64 capacity64; /* total number of sectors */ int last_lun; /* last logical unit */ int forced_lun; /* if hdxlun was given at boot */ @@ -1008,7 +1007,6 @@ int mmio; /* hosts iomio (0), mmio (1) or custom (2) select */ int rqsize; /* max sectors per request */ - int addressing; /* hosts addressing */ int irq; /* our irq number */ int initializing; /* set while initializing self */ @@ -1037,6 +1035,7 @@ unsigned reset : 1; /* reset after probe */ unsigned autodma : 1; /* auto-attempt using DMA at boot */ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ + unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */ unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */ unsigned auto_poll : 1; /* supports nop auto-poll */ diff -Nru a/include/linux/if_tun.h b/include/linux/if_tun.h --- a/include/linux/if_tun.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/if_tun.h Mon Aug 18 22:21:02 2003 @@ -32,7 +32,7 @@ #endif struct tun_struct { - char *name; + struct list_head list; unsigned long flags; int attached; uid_t owner; diff -Nru a/include/linux/init_task.h b/include/linux/init_task.h --- a/include/linux/init_task.h Mon Aug 18 22:21:01 2003 +++ b/include/linux/init_task.h Mon Aug 18 22:21:01 2003 @@ -70,7 +70,7 @@ .prio = MAX_PRIO-20, \ .static_prio = MAX_PRIO-20, \ .policy = SCHED_NORMAL, \ - .cpus_allowed = ~0UL, \ + .cpus_allowed = CPU_MASK_ALL, \ .mm = NULL, \ .active_mm = &init_mm, \ .run_list = LIST_HEAD_INIT(tsk.run_list), \ diff -Nru a/include/linux/ipv6.h b/include/linux/ipv6.h --- a/include/linux/ipv6.h Mon Aug 18 22:21:04 2003 +++ b/include/linux/ipv6.h Mon Aug 18 22:21:04 2003 @@ -71,7 +71,7 @@ __u32 bitmap; /* strict/loose bit map */ struct in6_addr addr[0]; -#define rt0_type rt_hdr.type; +#define rt0_type rt_hdr.type }; struct ipv6_auth_hdr { diff -Nru a/include/linux/irq.h b/include/linux/irq.h --- a/include/linux/irq.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/irq.h Mon Aug 18 22:21:03 2003 @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -44,7 +45,7 @@ void (*disable)(unsigned int irq); void (*ack)(unsigned int irq); void (*end)(unsigned int irq); - void (*set_affinity)(unsigned int irq, unsigned long mask); + void (*set_affinity)(unsigned int irq, cpumask_t dest); }; typedef struct hw_interrupt_type hw_irq_controller; diff -Nru a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h --- a/include/linux/kernel_stat.h Mon Aug 18 22:21:06 2003 +++ b/include/linux/kernel_stat.h Mon Aug 18 22:21:06 2003 @@ -17,6 +17,8 @@ unsigned int user; unsigned int nice; unsigned int system; + unsigned int softirq; + unsigned int irq; unsigned int idle; unsigned int iowait; }; diff -Nru a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h --- a/include/linux/lockd/lockd.h Mon Aug 18 22:21:01 2003 +++ b/include/linux/lockd/lockd.h Mon Aug 18 22:21:01 2003 @@ -26,7 +26,7 @@ /* * Version string */ -#define LOCKD_VERSION "0.4" +#define LOCKD_VERSION "0.5" /* * Default timeout for RPC calls (seconds) diff -Nru a/include/linux/mca.h b/include/linux/mca.h --- a/include/linux/mca.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/mca.h Mon Aug 18 22:21:02 2003 @@ -73,6 +73,7 @@ void *proc_dev; #endif struct device dev; + char name[32]; }; #define to_mca_device(mdev) container_of(mdev, struct mca_device, dev) @@ -92,6 +93,7 @@ int number; struct mca_bus_accessor_functions f; struct device dev; + char name[32]; }; #define to_mca_bus(mdev) container_of(mdev, struct mca_bus, dev) @@ -118,6 +120,12 @@ void *mem); extern int mca_device_claimed(struct mca_device *mca_dev); extern void mca_device_set_claim(struct mca_device *mca_dev, int val); +extern void mca_device_set_name(struct mca_device *mca_dev, const char *name); +static inline char *mca_device_get_name(struct mca_device *mca_dev) +{ + return mca_dev ? mca_dev->name : NULL; +} + extern enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev); extern struct bus_type mca_bus_type; diff -Nru a/include/linux/mm.h b/include/linux/mm.h --- a/include/linux/mm.h Mon Aug 18 22:21:01 2003 +++ b/include/linux/mm.h Mon Aug 18 22:21:01 2003 @@ -400,6 +400,8 @@ #define VM_FAULT_MINOR 1 #define VM_FAULT_MAJOR 2 +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) + extern void show_free_areas(void); struct page *shmem_nopage(struct vm_area_struct * vma, @@ -433,6 +435,7 @@ extern int make_pages_present(unsigned long addr, unsigned long end); extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); extern long sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long nonblock); +extern long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); void put_dirty_page(struct task_struct *tsk, struct page *page, unsigned long address, pgprot_t prot); diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h Mon Aug 18 22:21:06 2003 +++ b/include/linux/netdevice.h Mon Aug 18 22:21:06 2003 @@ -43,6 +43,11 @@ struct divert_blk; struct vlan_group; +struct ethtool_ops; + + /* source back-compat hook */ +#define SET_ETHTOOL_OPS(netdev,ops) \ + ( (netdev)->ethtool_ops = (ops) ) #define HAVE_ALLOC_NETDEV /* feature macro: alloc_xxxdev functions are available. */ @@ -300,6 +305,8 @@ * See for details. Jean II */ struct iw_handler_def * wireless_handlers; + struct ethtool_ops *ethtool_ops; + /* * This marks the end of the "visible" part of the structure. All * fields hereafter are internal to the system, and may change at @@ -463,9 +470,6 @@ /* class/net/name entry */ struct class_device class_dev; - - /* statistics sub-directory */ - struct kobject stats_kobj; }; #define SET_MODULE_OWNER(dev) do { } while (0) @@ -485,7 +489,6 @@ struct list_head list; }; - #include #include @@ -633,6 +636,7 @@ #define HAVE_NETIF_RECEIVE_SKB 1 extern int netif_receive_skb(struct sk_buff *skb); extern int dev_ioctl(unsigned int cmd, void *); +extern int dev_ethtool(struct ifreq *); extern unsigned dev_get_flags(const struct net_device *); extern int dev_change_flags(struct net_device *, unsigned); extern int dev_set_mtu(struct net_device *, int); diff -Nru a/include/linux/node.h b/include/linux/node.h --- a/include/linux/node.h Mon Aug 18 22:21:06 2003 +++ b/include/linux/node.h Mon Aug 18 22:21:06 2003 @@ -20,9 +20,10 @@ #define _LINUX_NODE_H_ #include +#include struct node { - unsigned long cpumap; /* Bitmap of CPUs on the Node */ + cpumask_t cpumap; /* Bitmap of CPUs on the Node */ struct sys_device sysdev; }; diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/pci_ids.h Mon Aug 18 22:21:03 2003 @@ -213,6 +213,25 @@ #define PCI_DEVICE_ID_ATI_264VT 0x5654 #define PCI_DEVICE_ID_ATI_264VU 0x5655 #define PCI_DEVICE_ID_ATI_264VV 0x5656 +/* Rage128 GL */ +#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245 +#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246 +#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x534b +#define PCI_DEVICE_ID_ATI_RAGE128_RH 0x534c +#define PCI_DEVICE_ID_ATI_RAGE128_RI 0x534d +/* Rage128 VR */ +#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b +#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c +#define PCI_DEVICE_ID_ATI_RAGE128_RM 0x5345 +#define PCI_DEVICE_ID_ATI_RAGE128_RN 0x5346 +#define PCI_DEVICE_ID_ATI_RAGE128_RO 0x5347 +/* Rage128 M3 */ +#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45 +#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46 +/* Rage128 Pro Ultra */ +#define PCI_DEVICE_ID_ATI_RAGE128_U1 0x5446 +#define PCI_DEVICE_ID_ATI_RAGE128_U2 0x544C +#define PCI_DEVICE_ID_ATI_RAGE128_U3 0x5452 /* Rage128 Pro GL */ #define PCI_DEVICE_ID_ATI_Rage128_PA 0x5041 #define PCI_DEVICE_ID_ATI_Rage128_PB 0x5042 @@ -240,31 +259,9 @@ #define PCI_DEVICE_ID_ATI_RAGE128_PV 0x5056 #define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057 #define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058 -/* Rage128 GL */ -#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245 -#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246 -#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x534b -#define PCI_DEVICE_ID_ATI_RAGE128_RH 0x534c -#define PCI_DEVICE_ID_ATI_RAGE128_RI 0x534d -/* Rage128 VR */ -#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b -#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c -#define PCI_DEVICE_ID_ATI_RAGE128_RM 0x5345 -#define PCI_DEVICE_ID_ATI_RAGE128_RN 0x5346 -#define PCI_DEVICE_ID_ATI_RAGE128_RO 0x5347 -/* Rage128 M3 */ -#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45 -#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46 -/* Rage128 Pro Ultra */ -#define PCI_DEVICE_ID_ATI_RAGE128_U1 0x5446 -#define PCI_DEVICE_ID_ATI_RAGE128_U2 0x544C -#define PCI_DEVICE_ID_ATI_RAGE128_U3 0x5452 -/* Radeon M4 */ +/* Rage128 M4 */ #define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45 #define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46 -/* Radeon NV-100 */ -#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159 -#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a /* Radeon R100 */ #define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144 #define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145 @@ -279,37 +276,60 @@ #define PCI_DEVICE_ID_ATI_RADEON_QO 0x514f #define PCI_DEVICE_ID_ATI_RADEON_Ql 0x516c #define PCI_DEVICE_ID_ATI_RADEON_BB 0x4242 +/* Radeon R200 (9100) */ +#define PCI_DEVICE_ID_ATI_RADEON_QM 0x514d /* Radeon RV200 (7500) */ #define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157 #define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158 +/* Radeon NV-100 */ +#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159 +#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a /* Radeon RV250 (9000) */ #define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964 #define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965 #define PCI_DEVICE_ID_ATI_RADEON_If 0x4966 #define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 -#define PCI_DEVICE_ID_ATI_RADEON_QM 0x514d +/* Radeon RV280 (9200) */ +#define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960 +/* Radeon R300 (9500) */ +#define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144 /* Radeon R300 (9700) */ #define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44 #define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45 #define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46 #define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47 +#define PCI_DEVICE_ID_ATI_RADEON_AE 0x4145 +#define PCI_DEVICE_ID_ATI_RADEON_AF 0x4146 +/* Radeon R350 (9800) */ +#define PCI_DEVICE_ID_ATI_RADEON_NH 0x4e48 +#define PCI_DEVICE_ID_ATI_RADEON_NI 0x4e49 +/* Radeon RV350 (9600) */ +#define PCI_DEVICE_ID_ATI_RADEON_AP 0x4150 +#define PCI_DEVICE_ID_ATI_RADEON_AR 0x4152 /* Radeon M6 */ #define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59 #define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a /* Radeon M7 */ #define PCI_DEVICE_ID_ATI_RADEON_LW 0x4c57 #define PCI_DEVICE_ID_ATI_RADEON_LX 0x4c58 -#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4964 -#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4965 -#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4966 -#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4967 +/* Radeon M9 */ +#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4c64 +#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4c65 +#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66 +#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67 /* Radeon */ #define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144 #define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145 #define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146 #define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147 /* RadeonIGP */ -#define PCI_DEVICE_ID_ATI_RADEON_IGP 0xCAB0 +#define PCI_DEVICE_ID_ATI_RS100 0xcab0 +#define PCI_DEVICE_ID_ATI_RS200 0xcab2 +#define PCI_DEVICE_ID_ATI_RS250 0xcab3 +#define PCI_DEVICE_ID_ATI_RS300_100 0x5830 +#define PCI_DEVICE_ID_ATI_RS300_133 0x5831 +#define PCI_DEVICE_ID_ATI_RS300_166 0x5832 +#define PCI_DEVICE_ID_ATI_RS300_200 0x5833 #define PCI_VENDOR_ID_VLSI 0x1004 #define PCI_DEVICE_ID_VLSI_82C592 0x0005 diff -Nru a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h --- a/include/linux/pfkeyv2.h Mon Aug 18 22:21:05 2003 +++ b/include/linux/pfkeyv2.h Mon Aug 18 22:21:05 2003 @@ -284,7 +284,10 @@ #define SADB_X_EALG_BLOWFISHCBC 7 #define SADB_EALG_NULL 11 #define SADB_X_EALG_AESCBC 12 -#define SADB_EALG_MAX 12 +#define SADB_EALG_MAX 253 /* last EALG */ +/* private allocations should use 249-255 (RFC2407) */ +#define SADB_X_EALG_SERPENTCBC 252 /* draft-ietf-ipsec-ciph-aes-cbc-00 */ +#define SADB_X_EALG_TWOFISHCBC 253 /* draft-ietf-ipsec-ciph-aes-cbc-00 */ /* Compression algorithms */ #define SADB_X_CALG_NONE 0 diff -Nru a/include/linux/pm.h b/include/linux/pm.h --- a/include/linux/pm.h Mon Aug 18 22:21:04 2003 +++ b/include/linux/pm.h Mon Aug 18 22:21:04 2003 @@ -25,6 +25,7 @@ #include #include +#include /* * Power management requests @@ -187,6 +188,26 @@ extern void (*pm_idle)(void); extern void (*pm_power_off)(void); + +struct device; + +struct dev_pm_info { +#ifdef CONFIG_PM + u32 power_state; + u8 * saved_state; + atomic_t pm_users; + struct device * pm_parent; + struct list_head entry; +#endif +}; + +extern void device_pm_set_parent(struct device * dev, struct device * parent); + +extern int device_pm_suspend(u32 state); +extern int device_pm_power_down(u32 state); +extern void device_pm_power_up(void); +extern void device_pm_resume(void); + #endif /* __KERNEL__ */ diff -Nru a/include/linux/pnp.h b/include/linux/pnp.h --- a/include/linux/pnp.h Mon Aug 18 22:21:06 2003 +++ b/include/linux/pnp.h Mon Aug 18 22:21:06 2003 @@ -19,6 +19,7 @@ #define PNP_MAX_DMA 2 #define PNP_MAX_DEVICES 8 #define PNP_ID_LEN 8 +#define PNP_NAME_LEN 50 struct pnp_protocol; struct pnp_dev; @@ -133,6 +134,7 @@ struct pnp_protocol * protocol; struct pnp_id * id; /* contains supported EISA IDs*/ + char name[PNP_NAME_LEN]; /* contains a human-readable name */ unsigned char pnpver; /* Plug & Play version */ unsigned char productver; /* product version */ unsigned int serial; /* serial number */ @@ -187,6 +189,7 @@ struct pnp_option * dependent; struct pnp_resource_table res; + char name[PNP_NAME_LEN]; /* contains a human-readable name */ unsigned short regs; /* ISAPnP: supported registers */ int flags; /* used by protocols */ struct proc_dir_entry *procent; /* device entry in /proc/bus/isapnp */ @@ -204,7 +207,7 @@ for((dev) = card_to_pnp_dev((card)->devices.next); \ (dev) != card_to_pnp_dev(&(card)->devices); \ (dev) = card_to_pnp_dev((dev)->card_list.next)) -#define pnp_dev_name(dev) (dev)->dev.name +#define pnp_dev_name(dev) (dev)->name static inline void *pnp_get_drvdata (struct pnp_dev *pdev) { diff -Nru a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h --- a/include/linux/ppp-comp.h Mon Aug 18 22:21:00 2003 +++ b/include/linux/ppp-comp.h Mon Aug 18 22:21:00 2003 @@ -185,10 +185,9 @@ #define DEFLATE_MIN_SIZE 9 #define DEFLATE_MAX_SIZE 15 #define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) +#define DEFLATE_SIZE(x) (((x) >> 4) + 8) #define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ - + DEFLATE_METHOD_VAL) +#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL) #define DEFLATE_CHK_SEQUENCE 0 /* diff -Nru a/include/linux/prctl.h b/include/linux/prctl.h --- a/include/linux/prctl.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/prctl.h Mon Aug 18 22:21:03 2003 @@ -34,4 +34,14 @@ # define PR_FP_EXC_ASYNC 2 /* async recoverable exception mode */ # define PR_FP_EXC_PRECISE 3 /* precise exception mode */ +/* Get/set whether we use statistical process timing or accurate timestamp + * based process timing */ +#define PR_GET_TIMING 13 +#define PR_SET_TIMING 14 +# define PR_TIMING_STATISTICAL 0 /* Normal, traditional, + statistical process timing */ +# define PR_TIMING_TIMESTAMP 1 /* Accurate timestamp based + process timing */ + + #endif /* _LINUX_PRCTL_H */ diff -Nru a/include/linux/rcupdate.h b/include/linux/rcupdate.h --- a/include/linux/rcupdate.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/rcupdate.h Mon Aug 18 22:21:02 2003 @@ -40,6 +40,7 @@ #include #include #include +#include /** * struct rcu_head - callback structure for use with RCU @@ -67,7 +68,7 @@ spinlock_t mutex; /* Guard this struct */ long curbatch; /* Current batch number. */ long maxbatch; /* Max requested batch number. */ - unsigned long rcu_cpu_mask; /* CPUs that need to switch in order */ + cpumask_t rcu_cpu_mask; /* CPUs that need to switch in order */ /* for current batch to proceed. */ }; @@ -114,7 +115,7 @@ rcu_batch_before(RCU_batch(cpu), rcu_ctrlblk.curbatch)) || (list_empty(&RCU_curlist(cpu)) && !list_empty(&RCU_nxtlist(cpu))) || - test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask)) + cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) return 1; else return 0; diff -Nru a/include/linux/reboot.h b/include/linux/reboot.h --- a/include/linux/reboot.h Mon Aug 18 22:21:06 2003 +++ b/include/linux/reboot.h Mon Aug 18 22:21:06 2003 @@ -21,7 +21,7 @@ * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task. * POWER_OFF Stop OS and remove all power from system, if possible. * RESTART2 Restart system using given command string. - * SW_SUSPEND Suspend system using Software Suspend if compiled in + * SW_SUSPEND Suspend system using software suspend if compiled in. */ #define LINUX_REBOOT_CMD_RESTART 0x01234567 diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h --- a/include/linux/reiserfs_fs.h Mon Aug 18 22:21:05 2003 +++ b/include/linux/reiserfs_fs.h Mon Aug 18 22:21:05 2003 @@ -879,19 +879,14 @@ /* we want common flags to have the same values as in ext2, so chattr(1) will work without problems */ #define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE_FL +#define REISERFS_APPEND_FL EXT2_APPEND_FL #define REISERFS_SYNC_FL EXT2_SYNC_FL #define REISERFS_NOATIME_FL EXT2_NOATIME_FL #define REISERFS_NODUMP_FL EXT2_NODUMP_FL #define REISERFS_SECRM_FL EXT2_SECRM_FL #define REISERFS_UNRM_FL EXT2_UNRM_FL #define REISERFS_COMPR_FL EXT2_COMPR_FL -/* persistent flag to disable tails on per-file basic. - Note, that is inheritable: mark directory with this and - all new files inside will not have tails. - - Teodore Tso allocated EXT2_NODUMP_FL (0x00008000) for this. Change - numeric constant to ext2 macro when available. */ -#define REISERFS_NOTAIL_FL (0x00008000) /* EXT2_NOTAIL_FL */ +#define REISERFS_NOTAIL_FL EXT2_NOTAIL_FL /* persistent flags that file inherits from the parent directory */ #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \ diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Mon Aug 18 22:21:01 2003 +++ b/include/linux/sched.h Mon Aug 18 22:21:01 2003 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -49,7 +50,7 @@ #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ -#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */ +#define CLONE_DETACHED 0x00400000 /* Not used - CLONE_THREAD implies detached uniquely */ #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ @@ -203,7 +204,7 @@ unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags; - unsigned long cpu_vm_mask; + cpumask_t cpu_vm_mask; unsigned long swap_address; unsigned dumpable:1; @@ -342,7 +343,7 @@ unsigned long last_run; unsigned long policy; - unsigned long cpus_allowed; + cpumask_t cpus_allowed; unsigned int time_slice, first_time_slice; struct list_head tasks; @@ -489,9 +490,9 @@ #define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ #ifdef CONFIG_SMP -extern int set_cpus_allowed(task_t *p, unsigned long new_mask); +extern int set_cpus_allowed(task_t *p, cpumask_t new_mask); #else -static inline int set_cpus_allowed(task_t *p, unsigned long new_mask) +static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask) { return 0; } diff -Nru a/include/linux/smp.h b/include/linux/smp.h --- a/include/linux/smp.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/smp.h Mon Aug 18 22:21:03 2003 @@ -102,9 +102,6 @@ #define smp_call_function(func,info,retry,wait) ({ 0; }) #define on_each_cpu(func,info,retry,wait) ({ func(info); 0; }) static inline void smp_send_reschedule(int cpu) { } -#define cpu_online_map 1 -#define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) -#define num_online_cpus() 1 #define num_booting_cpus() 1 #define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define smp_prepare_boot_cpu() do {} while (0) diff -Nru a/include/linux/suspend.h b/include/linux/suspend.h --- a/include/linux/suspend.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/suspend.h Mon Aug 18 22:21:02 2003 @@ -11,9 +11,6 @@ extern unsigned char software_suspend_enabled; -#define NORESUME 1 -#define RESUME_SPECIFIED 2 - #ifdef CONFIG_SOFTWARE_SUSPEND /* page backup entry */ typedef struct pbe { @@ -50,8 +47,7 @@ extern void drain_local_pages(void); /* kernel/suspend.c */ -extern void software_suspend(void); -extern void software_resume(void); +extern int software_suspend(void); extern int register_suspend_notifier(struct notifier_block *); extern int unregister_suspend_notifier(struct notifier_block *); @@ -72,10 +68,10 @@ extern void do_suspend_lowlevel_s4bios(int resume); #else /* CONFIG_SOFTWARE_SUSPEND */ -static inline void software_suspend(void) +static inline int software_suspend(void) { + return -EPERM; } -#define software_resume() do { } while(0) #define register_suspend_notifier(a) do { } while(0) #define unregister_suspend_notifier(a) do { } while(0) #endif /* CONFIG_SOFTWARE_SUSPEND */ diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h --- a/include/linux/sysfs.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/sysfs.h Mon Aug 18 22:21:02 2003 @@ -40,21 +40,30 @@ sysfs_remove_dir(struct kobject *); extern void -sysfs_rename_dir(struct kobject *, char *new_name); +sysfs_rename_dir(struct kobject *, const char *new_name); extern int -sysfs_create_file(struct kobject *, struct attribute *); +sysfs_create_file(struct kobject *, const struct attribute *); extern int -sysfs_update_file(struct kobject *, struct attribute *); +sysfs_update_file(struct kobject *, const struct attribute *); extern void -sysfs_remove_file(struct kobject *, struct attribute *); +sysfs_remove_file(struct kobject *, const struct attribute *); extern int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name); extern void sysfs_remove_link(struct kobject *, char * name); + + +struct attribute_group { + char * name; + struct attribute ** attrs; +}; + +int sysfs_create_group(struct kobject *, const struct attribute_group *); +void sysfs_remove_group(struct kobject *, const struct attribute_group *); #endif /* _SYSFS_H_ */ diff -Nru a/include/linux/timer.h b/include/linux/timer.h --- a/include/linux/timer.h Mon Aug 18 22:21:04 2003 +++ b/include/linux/timer.h Mon Aug 18 22:21:04 2003 @@ -60,11 +60,30 @@ return timer->base != NULL; } -extern void add_timer(struct timer_list * timer); extern void add_timer_on(struct timer_list *timer, int cpu); extern int del_timer(struct timer_list * timer); +extern int __mod_timer(struct timer_list *timer, unsigned long expires); extern int mod_timer(struct timer_list *timer, unsigned long expires); - + +/*** + * add_timer - start a timer + * @timer: the timer to be added + * + * The kernel will do a ->function(->data) callback from the + * timer interrupt at the ->expired point in the future. The + * current time is 'jiffies'. + * + * The timer's ->expired, ->function (and if the handler uses it, ->data) + * fields must be set prior calling this function. + * + * Timers with an ->expired field in the past will be executed in the next + * timer tick. + */ +static inline void add_timer(struct timer_list * timer) +{ + __mod_timer(timer, timer->expires); +} + #ifdef CONFIG_SMP extern int del_timer_sync(struct timer_list * timer); #else diff -Nru a/include/linux/topology.h b/include/linux/topology.h --- a/include/linux/topology.h Mon Aug 18 22:21:04 2003 +++ b/include/linux/topology.h Mon Aug 18 22:21:04 2003 @@ -27,6 +27,7 @@ #ifndef _LINUX_TOPOLOGY_H #define _LINUX_TOPOLOGY_H +#include #include #include #include @@ -34,7 +35,12 @@ #include #ifndef nr_cpus_node -#define nr_cpus_node(node) (hweight_long(node_to_cpumask(node))) +#define nr_cpus_node(node) \ + ({ \ + cpumask_t __tmp__; \ + __tmp__ = node_to_cpumask(node); \ + cpus_weight(__tmp__); \ + }) #endif static inline int __next_node_with_cpus(int node) diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Mon Aug 18 22:21:03 2003 +++ b/include/linux/usb.h Mon Aug 18 22:21:03 2003 @@ -123,10 +123,9 @@ struct usb_driver *driver; /* driver */ int minor; /* minor number this interface is bound to */ struct device dev; /* interface specific device info */ - struct class_device class_dev; + struct class_device *class_dev; }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) -#define class_dev_to_usb_interface(d) container_of(d, struct usb_interface, class_dev) #define interface_to_usbdev(intf) \ container_of(intf->dev.parent, struct usb_device, dev) @@ -290,7 +289,7 @@ extern int usb_get_current_frame_number (struct usb_device *usb_dev); /* used these for multi-interface device registration */ -extern void usb_driver_claim_interface(struct usb_driver *driver, +extern int usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv); extern int usb_interface_claimed(struct usb_interface *iface); extern void usb_driver_release_interface(struct usb_driver *driver, @@ -869,6 +868,7 @@ /* wrappers that also update important state inside usbcore */ extern int usb_clear_halt(struct usb_device *dev, int pipe); +extern int usb_reset_configuration(struct usb_device *dev); extern int usb_set_configuration(struct usb_device *dev, int configuration); extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); diff -Nru a/include/linux/xfrm.h b/include/linux/xfrm.h --- a/include/linux/xfrm.h Mon Aug 18 22:21:02 2003 +++ b/include/linux/xfrm.h Mon Aug 18 22:21:02 2003 @@ -37,6 +37,7 @@ __u16 dport_mask; __u16 sport; __u16 sport_mask; + __u16 family; __u8 prefixlen_d; __u8 prefixlen_s; __u8 proto; @@ -125,6 +126,7 @@ struct xfrm_user_tmpl { struct xfrm_id id; + __u16 family; xfrm_address_t saddr; __u32 reqid; __u8 mode; @@ -189,7 +191,6 @@ struct xfrm_lifetime_cur curlft; __u32 priority; __u32 index; - __u16 family; __u8 dir; __u8 action; #define XFRM_POLICY_ALLOW 0 diff -Nru a/include/net/dst.h b/include/net/dst.h --- a/include/net/dst.h Mon Aug 18 22:21:05 2003 +++ b/include/net/dst.h Mon Aug 18 22:21:05 2003 @@ -247,8 +247,16 @@ extern void dst_init(void); struct flowi; +#ifndef CONFIG_XFRM +static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, + struct sock *sk, int flags) +{ + return 0; +} +#else extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, struct sock *sk, int flags); +#endif #endif #endif /* _NET_DST_H */ diff -Nru a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h --- a/include/net/irda/irda_device.h Mon Aug 18 22:21:06 2003 +++ b/include/net/irda/irda_device.h Mon Aug 18 22:21:06 2003 @@ -209,7 +209,7 @@ * We declare them here to avoid the driver pulling a whole bunch stack * headers they don't really need - Jean II */ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, - char * hw_name); + const char *hw_name); void irlap_close(struct irlap_cb *self); /* Interface to be uses by IrLAP */ @@ -222,7 +222,7 @@ int irda_device_set_raw_mode(struct net_device* self, int status); int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts); int irda_device_change_speed(struct net_device *dev, __u32 speed); -int irda_device_setup(struct net_device *dev); +void irda_device_setup(struct net_device *dev); /* Dongle interface */ void irda_device_unregister_dongle(struct dongle_reg *dongle); diff -Nru a/include/net/irda/irlap.h b/include/net/irda/irlap.h --- a/include/net/irda/irlap.h Mon Aug 18 22:21:03 2003 +++ b/include/net/irda/irlap.h Mon Aug 18 22:21:03 2003 @@ -208,8 +208,6 @@ int next_bofs; /* Negotiated extra BOFs after next frame */ }; -extern hashbin_t *irlap; - /* * Function prototypes */ @@ -217,7 +215,7 @@ void irlap_cleanup(void); struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, - char * hw_name); + const char *hw_name); void irlap_close(struct irlap_cb *self); void irlap_connect_request(struct irlap_cb *self, __u32 daddr, diff -Nru a/include/net/irda/irtty.h b/include/net/irda/irtty.h --- a/include/net/irda/irtty.h Mon Aug 18 22:21:05 2003 +++ b/include/net/irda/irtty.h Mon Aug 18 22:21:05 2003 @@ -31,7 +31,6 @@ #include #include -#include #include /* Used by ioctl */ @@ -45,7 +44,6 @@ #define IRTTY_IOC_MAXNR 2 struct irtty_cb { - irda_queue_t q; /* Must be first */ magic_t magic; struct net_device *netdev; /* Yes! we are some kind of netdevice */ diff -Nru a/include/net/netrom.h b/include/net/netrom.h --- a/include/net/netrom.h Mon Aug 18 22:21:03 2003 +++ b/include/net/netrom.h Mon Aug 18 22:21:03 2003 @@ -7,6 +7,7 @@ #ifndef _NETROM_H #define _NETROM_H #include +#include #define NR_NETWORK_LEN 15 #define NR_TRANSPORT_LEN 5 @@ -77,16 +78,17 @@ #define nr_sk(__sk) ((nr_cb *)(__sk)->sk_protinfo) struct nr_neigh { - struct nr_neigh *next; - ax25_address callsign; - ax25_digi *digipeat; - ax25_cb *ax25; - struct net_device *dev; - unsigned char quality; - unsigned char locked; - unsigned short count; - unsigned int number; - unsigned char failed; + struct hlist_node neigh_node; + ax25_address callsign; + ax25_digi *digipeat; + ax25_cb *ax25; + struct net_device *dev; + unsigned char quality; + unsigned char locked; + unsigned short count; + unsigned int number; + unsigned char failed; + atomic_t refcount; }; struct nr_route { @@ -96,14 +98,74 @@ }; struct nr_node { - struct nr_node *next; - ax25_address callsign; - char mnemonic[7]; - unsigned char which; - unsigned char count; - struct nr_route routes[3]; + struct hlist_node node_node; + ax25_address callsign; + char mnemonic[7]; + unsigned char which; + unsigned char count; + struct nr_route routes[3]; + atomic_t refcount; + spinlock_t node_lock; }; +/********************************************************************* + * nr_node & nr_neigh lists, refcounting and locking + *********************************************************************/ + +extern struct hlist_head nr_node_list; +extern struct hlist_head nr_neigh_list; + +#define nr_node_hold(__nr_node) \ + atomic_inc(&((__nr_node)->refcount)) + +static __inline__ void nr_node_put(struct nr_node *nr_node) +{ + if (atomic_dec_and_test(&nr_node->refcount)) { + kfree(nr_node); + } +} + +#define nr_neigh_hold(__nr_neigh) \ + atomic_inc(&((__nr_neigh)->refcount)) + +static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh) +{ + if (atomic_dec_and_test(&nr_neigh->refcount)) { + if (nr_neigh->digipeat != NULL) + kfree(nr_neigh->digipeat); + kfree(nr_neigh); + } +} + +/* nr_node_lock and nr_node_unlock also hold/put the node's refcounter. + */ +static __inline__ void nr_node_lock(struct nr_node *nr_node) +{ + nr_node_hold(nr_node); + spin_lock_bh(&nr_node->node_lock); +} + +static __inline__ void nr_node_unlock(struct nr_node *nr_node) +{ + spin_unlock_bh(&nr_node->node_lock); + nr_node_put(nr_node); +} + +#define nr_neigh_for_each(__nr_neigh, node, list) \ + hlist_for_each_entry(__nr_neigh, node, list, neigh_node) + +#define nr_neigh_for_each_safe(__nr_neigh, node, node2, list) \ + hlist_for_each_entry_safe(__nr_neigh, node, node2, list, neigh_node) + +#define nr_node_for_each(__nr_node, node, list) \ + hlist_for_each_entry(__nr_node, node, list, node_node) + +#define nr_node_for_each_safe(__nr_node, node, node2, list) \ + hlist_for_each_entry_safe(__nr_node, node, node2, list, node_node) + + +/*********************************************************************/ + /* af_netrom.c */ extern int sysctl_netrom_default_path_quality; extern int sysctl_netrom_obsolescence_count_initialiser; @@ -121,7 +183,7 @@ /* nr_dev.c */ extern int nr_rx_ip(struct sk_buff *, struct net_device *); -extern int nr_init(struct net_device *); +extern void nr_setup(struct net_device *); /* nr_in.c */ extern int nr_process_rx_frame(struct sock *, struct sk_buff *); @@ -147,8 +209,8 @@ extern int nr_rt_ioctl(unsigned int, void *); extern void nr_link_failed(ax25_cb *, int); extern int nr_route_frame(struct sk_buff *, ax25_cb *); -extern int nr_nodes_get_info(char *, char **, off_t, int); -extern int nr_neigh_get_info(char *, char **, off_t, int); +extern struct file_operations nr_nodes_fops; +extern struct file_operations nr_neigh_fops; extern void nr_rt_free(void); /* nr_subr.c */ diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h --- a/include/net/xfrm.h Mon Aug 18 22:21:05 2003 +++ b/include/net/xfrm.h Mon Aug 18 22:21:05 2003 @@ -588,6 +588,8 @@ return !0; } +#ifdef CONFIG_XFRM + extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family); static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) @@ -653,6 +655,26 @@ } } +#else + +static inline void xfrm_sk_free_policy(struct sock *sk) {} +static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } +static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } +static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } +static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) +{ + return 1; +} +static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) +{ + return 1; +} +static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) +{ + return 1; +} +#endif + static __inline__ xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family) { @@ -783,12 +805,32 @@ extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl); extern int xfrm_check_output(struct xfrm_state *x, struct sk_buff *skb, unsigned short family); extern int xfrm4_rcv(struct sk_buff *skb); -extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_check_size(struct sk_buff *skb); extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); + +#ifdef CONFIG_XFRM +extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type); extern int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen); +extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family); +#else +static inline int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen) +{ + return -ENOPROTOOPT; +} + +static inline int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) +{ + /* should not happen */ + kfree_skb(skb); + return 0; +} +static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family) +{ + return -EINVAL; +} +#endif void xfrm_policy_init(void); void xfrm4_policy_init(void); @@ -810,7 +852,6 @@ extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); extern struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl); extern int xfrm_flush_bundles(struct xfrm_state *x); -extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family); extern wait_queue_head_t km_waitq; extern void km_state_expired(struct xfrm_state *x, int hard); diff -Nru a/include/pcmcia/ds.h b/include/pcmcia/ds.h --- a/include/pcmcia/ds.h Mon Aug 18 22:21:00 2003 +++ b/include/pcmcia/ds.h Mon Aug 18 22:21:00 2003 @@ -118,7 +118,6 @@ dev_node_t *dev; u_int state, open; wait_queue_head_t pending; - struct timer_list release; client_handle_t handle; io_req_t io; irq_req_t irq; diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h --- a/include/scsi/scsi.h Mon Aug 18 22:21:06 2003 +++ b/include/scsi/scsi.h Mon Aug 18 22:21:06 2003 @@ -6,6 +6,8 @@ * the scsi code for linux. */ +#include + /* $Header: /usr/src/linux/include/linux/RCS/scsi.h,v 1.3 1993/09/24 12:20:33 drew Exp $ @@ -14,6 +16,8 @@ */ +#include + /* * SCSI command lengths */ @@ -208,18 +212,18 @@ struct ccs_modesel_head { - u_char _r1; /* reserved */ - u_char medium; /* device-specific medium type */ - u_char _r2; /* reserved */ - u_char block_desc_length; /* block descriptor length */ - u_char density; /* device-specific density code */ - u_char number_blocks_hi; /* number of blocks in this block desc */ - u_char number_blocks_med; - u_char number_blocks_lo; - u_char _r3; - u_char block_length_hi; /* block length for blocks in this desc */ - u_char block_length_med; - u_char block_length_lo; + u8 _r1; /* reserved */ + u8 medium; /* device-specific medium type */ + u8 _r2; /* reserved */ + u8 block_desc_length; /* block descriptor length */ + u8 density; /* device-specific density code */ + u8 number_blocks_hi; /* number of blocks in this block desc */ + u8 number_blocks_med; + u8 number_blocks_lo; + u8 _r3; + u8 block_length_hi; /* block length for blocks in this desc */ + u8 block_length_med; + u8 block_length_lo; }; /* diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h --- a/include/scsi/scsi_device.h Mon Aug 18 22:21:01 2003 +++ b/include/scsi/scsi_device.h Mon Aug 18 22:21:01 2003 @@ -10,6 +10,16 @@ struct scsi_mode_data; +/* + * sdev state + */ +enum { + SDEV_ADD, + SDEV_DEL, + SDEV_CANCEL, + SDEV_RECOVERY, +}; + struct scsi_device { struct list_head siblings; /* list of all devices on this host */ struct list_head same_target_siblings; /* just the devices sharing same target id */ @@ -86,14 +96,19 @@ struct device sdev_gendev; struct class_device sdev_classdev; + + unsigned long sdev_state; }; #define to_scsi_device(d) \ container_of(d, struct scsi_device, sdev_gendev) +#define class_to_sdev(d) \ + container_of(d, struct scsi_device, sdev_classdev) extern struct scsi_device *scsi_add_device(struct Scsi_Host *, uint, uint, uint); -extern int scsi_remove_device(struct scsi_device *); -extern void scsi_set_device_offline(struct scsi_device *); +extern void scsi_remove_device(struct scsi_device *); +extern int scsi_device_cancel_cb(struct device *, void *); +extern int scsi_device_cancel(struct scsi_device *, int); extern int scsi_device_get(struct scsi_device *); extern void scsi_device_put(struct scsi_device *); @@ -106,5 +121,4 @@ extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, unsigned char *buffer, int len, int timeout, int retries, struct scsi_mode_data *data); - #endif /* _SCSI_SCSI_DEVICE_H */ diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h --- a/include/scsi/scsi_host.h Mon Aug 18 22:21:01 2003 +++ b/include/scsi/scsi_host.h Mon Aug 18 22:21:01 2003 @@ -262,6 +262,12 @@ unsigned short max_sectors; /* + * dma scatter gather segment boundary limit. a segment crossing this + * boundary will be split in two. + */ + unsigned long dma_boundary; + + /* * This specifies "machine infinity" for host templates which don't * limit the transfer size. Note this limit represents an absolute * maximum, and may be over the transfer limits allowed for @@ -306,8 +312,6 @@ */ unsigned emulated:1; - unsigned highmem_io:1; - /* * True if the driver wishes to use the generic block layer * tag queueing functions @@ -348,6 +352,16 @@ struct list_head legacy_hosts; }; +/* + * shost states + */ +enum { + SHOST_ADD, + SHOST_DEL, + SHOST_CANCEL, + SHOST_RECOVERY, +}; + struct Scsi_Host { struct list_head my_devices; struct scsi_host_cmd_pool *cmd_pool; @@ -412,8 +426,8 @@ short cmd_per_lun; short unsigned int sg_tablesize; short unsigned int max_sectors; + unsigned long dma_boundary; - unsigned in_recovery:1; unsigned unchecked_isa_dma:1; unsigned use_clustering:1; unsigned highmem_io:1; @@ -448,6 +462,9 @@ unsigned char n_io_port; unsigned char dma_channel; unsigned int irq; + + + unsigned long shost_state; /* ldm bits */ struct device shost_gendev; @@ -478,8 +495,8 @@ extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); extern int scsi_add_host(struct Scsi_Host *, struct device *); extern void scsi_scan_host(struct Scsi_Host *); -extern int scsi_remove_host(struct Scsi_Host *); -extern void scsi_host_get(struct Scsi_Host *); +extern void scsi_remove_host(struct Scsi_Host *); +extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); extern void scsi_host_put(struct Scsi_Host *t); extern struct Scsi_Host *scsi_host_lookup(unsigned short); diff -Nru a/init/Kconfig b/init/Kconfig --- a/init/Kconfig Mon Aug 18 22:21:05 2003 +++ b/init/Kconfig Mon Aug 18 22:21:05 2003 @@ -32,6 +32,17 @@ you say Y here, you will be offered the choice of using features or drivers that are currently considered to be in the alpha-test phase. +config BROKEN + bool "Prompt for old and known-broken drivers" + depends on EXPERIMENTAL + default n + help + This option allows you to choose whether you want to try to + compile (and fix) old drivers that haven't been updated to + new infrastructure. + + If unsure, say N. + endmenu diff -Nru a/init/do_mounts.c b/init/do_mounts.c --- a/init/do_mounts.c Mon Aug 18 22:21:02 2003 +++ b/init/do_mounts.c Mon Aug 18 22:21:02 2003 @@ -71,13 +71,19 @@ if (len <= 0 || len == 32 || buf[len - 1] != '\n') goto fail; buf[len - 1] = '\0'; - /* - * The format of dev is now %u:%u -- see print_dev_t() - */ - if (sscanf(buf, "%u:%u", &maj, &min) == 2) + if (sscanf(buf, "%u:%u", &maj, &min) == 2) { + /* + * Try the %u:%u format -- see print_dev_t() + */ res = MKDEV(maj, min); - else - goto fail; + } else { + /* + * Nope. Try old-style "0321" + */ + res = (dev_t)simple_strtoul(buf, &s, 16); + if (*s) + goto fail; + } /* if it's there and we are not looking for a partition - that's it */ if (!part) @@ -135,9 +141,15 @@ goto out; if (strncmp(name, "/dev/", 5) != 0) { - res = (dev_t) simple_strtoul(name, &p, 16); - if (*p) - goto fail; + unsigned maj, min; + + if (sscanf(name, "%u:%u", &maj, &min) == 2) { + res = MKDEV(maj, min); + } else { + res = (dev_t)simple_strtoul(name, &p, 16); + if (*p) + goto fail; + } goto done; } name += 5; @@ -273,6 +285,9 @@ printk("VFS: Cannot open root device \"%s\" or %s\n", root_device_name, b); printk("Please append a correct \"root=\" boot option\n"); + + mount_root_failed_msg(); /* architecture dependent */ + panic("VFS: Unable to mount root fs on %s", b); } panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b)); @@ -369,10 +384,6 @@ } is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; - - /* This has to be before mounting root, because even readonly mount of reiserfs would replay - log corrupting stuff */ - software_resume(); if (initrd_load()) goto out; diff -Nru a/init/do_mounts.h b/init/do_mounts.h --- a/init/do_mounts.h Mon Aug 18 22:21:04 2003 +++ b/init/do_mounts.h Mon Aug 18 22:21:04 2003 @@ -79,3 +79,14 @@ static inline void md_run_setup(void) {} #endif + +#ifdef CONFIG_MOUNT_ROOT_FAILED_MSG + +void mount_root_failed_msg(void); + +#else + +static inline void mount_root_failed_msg(void) {} + +#endif + diff -Nru a/ipc/sem.c b/ipc/sem.c --- a/ipc/sem.c Mon Aug 18 22:21:02 2003 +++ b/ipc/sem.c Mon Aug 18 22:21:02 2003 @@ -425,7 +425,7 @@ ipc_rcu_free(sma, size); } -static unsigned long copy_semid_to_user(void *buf, struct semid64_ds *in, int version) +static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version) { switch(version) { case IPC_64: @@ -686,7 +686,7 @@ mode_t mode; }; -static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void *buf, int version) +static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void __user *buf, int version) { switch(version) { case IPC_64: @@ -960,13 +960,13 @@ return un; } -asmlinkage long sys_semop (int semid, struct sembuf *tsops, unsigned nsops) +asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsops) { return sys_semtimedop(semid, tsops, nsops, NULL); } -asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops, - unsigned nsops, const struct timespec *timeout) +asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, + unsigned nsops, const struct timespec __user *timeout) { int error = -EINVAL; struct sem_array *sma; diff -Nru a/kernel/Makefile b/kernel/Makefile --- a/kernel/Makefile Mon Aug 18 22:21:01 2003 +++ b/kernel/Makefile Mon Aug 18 22:21:01 2003 @@ -14,7 +14,7 @@ obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += ksyms.o module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o -obj-$(CONFIG_PM) += pm.o power/ +obj-$(CONFIG_PM) += power/ obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_COMPAT) += compat.o diff -Nru a/kernel/compat.c b/kernel/compat.c --- a/kernel/compat.c Mon Aug 18 22:21:03 2003 +++ b/kernel/compat.c Mon Aug 18 22:21:03 2003 @@ -430,3 +430,130 @@ return ret; } +static int get_compat_itimerspec(struct itimerspec *dst, + struct compat_itimerspec *src) +{ + if (get_compat_timespec(&dst->it_interval, &src->it_interval) || + get_compat_timespec(&dst->it_value, &src->it_value)) + return -EFAULT; + return 0; +} + +static int put_compat_itimerspec(struct compat_itimerspec *dst, + struct itimerspec *src) +{ + if (put_compat_timespec(&src->it_interval, &dst->it_interval) || + put_compat_timespec(&src->it_value, &dst->it_value)) + return -EFAULT; + return 0; +} + +extern asmlinkage long sys_timer_settime(timer_t timer_id, int flags, + struct itimerspec __user *new_setting, + struct itimerspec __user *old_setting); +extern asmlinkage long sys_timer_gettime(timer_t timer_id, + struct itimerspec __user *setting); + +long compat_timer_settime(timer_t timer_id, int flags, + struct compat_itimerspec *new, + struct compat_itimerspec *old) +{ + long err; + mm_segment_t oldfs; + struct itimerspec newts, oldts; + if (get_compat_itimerspec(&newts, new)) + return -EFAULT; + oldfs = get_fs(); + err = sys_timer_settime(timer_id, flags, &newts, &oldts); + set_fs(oldfs); + if (!err && old && put_compat_itimerspec(old, &oldts)) + return -EFAULT; + return err; +} + +long compat_timer_gettime(timer_t timer_id, struct compat_itimerspec *setting) +{ + long err; + mm_segment_t oldfs; + struct itimerspec ts; + oldfs = get_fs(); + err = sys_timer_gettime(timer_id, &ts); + set_fs(oldfs); + if (!err && put_compat_itimerspec(setting, &ts)) + return -EFAULT; + return err; +} + +extern asmlinkage long +sys_clock_settime(clockid_t which_clock, struct timespec __user *tp); + +long compat_clock_settime(clockid_t which_clock, struct compat_timespec *tp) +{ + long err; + mm_segment_t oldfs; + struct timespec ts; + if (get_compat_timespec(&ts, tp)) + return -EFAULT; + oldfs = get_fs(); + err = sys_clock_settime(which_clock, &ts); + set_fs(oldfs); + return err; +} + +extern asmlinkage long +sys_clock_gettime(clockid_t which_clock, struct timespec __user *tp); + +long compat_clock_gettime(clockid_t which_clock, struct compat_timespec *tp) +{ + long err; + mm_segment_t oldfs; + struct timespec ts; + oldfs = get_fs(); + err = sys_clock_gettime(which_clock, &ts); + set_fs(oldfs); + if (!err && put_compat_timespec(&ts, tp)) + return -EFAULT; + return err; +} + +extern asmlinkage long +sys_clock_getres(clockid_t which_clock, struct timespec __user *tp); + +long compat_clock_getres(clockid_t which_clock, struct compat_timespec *tp) +{ + long err; + mm_segment_t oldfs; + struct timespec ts; + oldfs = get_fs(); + err = sys_clock_getres(which_clock, &ts); + set_fs(oldfs); + if (!err && put_compat_timespec(&ts, tp)) + return -EFAULT; + return err; +} + +extern asmlinkage long +sys_clock_nanosleep(clockid_t which_clock, int flags, + struct timespec __user *rqtp, + struct timespec __user *rmtp); + +long compat_clock_nanosleep(clockid_t which_clock, int flags, + struct compat_timespec __user *rqtp, + struct compat_timespec __user *rmtp) +{ + long err; + mm_segment_t oldfs; + struct timespec in, out; + if (get_compat_timespec(&in, rqtp)) + return -EFAULT; + oldfs = get_fs(); + err = sys_clock_nanosleep(which_clock, flags, &in, &out); + set_fs(oldfs); + if ((err == -ERESTART_RESTARTBLOCK) && rmtp && + put_compat_timespec(&out, rmtp)) + return -EFAULT; + return err; +} + +/* timer_create is architecture specific because it needs sigevent conversion */ + diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Mon Aug 18 22:21:01 2003 +++ b/kernel/fork.c Mon Aug 18 22:21:01 2003 @@ -233,7 +233,7 @@ mm->free_area_cache = TASK_UNMAPPED_BASE; mm->map_count = 0; mm->rss = 0; - mm->cpu_vm_mask = 0; + cpus_clear(mm->cpu_vm_mask); pprev = &mm->mmap; /* @@ -746,8 +746,22 @@ */ if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND)) return ERR_PTR(-EINVAL); - if ((clone_flags & CLONE_DETACHED) && !(clone_flags & CLONE_THREAD)) + + /* + * CLONE_DETACHED must match CLONE_THREAD: it's a historical + * thing. + */ + if (!(clone_flags & CLONE_DETACHED) != !(clone_flags & CLONE_THREAD)) { + /* Warn about the old no longer supported case so that we see it */ + if (clone_flags & CLONE_THREAD) { + static int count; + if (count < 5) { + count++; + printk(KERN_WARNING "%s trying to use CLONE_THREAD without CLONE_DETACH\n", current->comm); + } + } return ERR_PTR(-EINVAL); + } retval = security_task_create(clone_flags); if (retval) @@ -877,10 +891,7 @@ p->parent_exec_id = p->self_exec_id; /* ok, now we should be set up.. */ - if (clone_flags & CLONE_DETACHED) - p->exit_signal = -1; - else - p->exit_signal = clone_flags & CSIGNAL; + p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); p->pdeath_signal = 0; /* diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c --- a/kernel/ksyms.c Mon Aug 18 22:21:00 2003 +++ b/kernel/ksyms.c Mon Aug 18 22:21:00 2003 @@ -405,8 +405,6 @@ EXPORT_SYMBOL(proc_doulongvec_minmax); /* interrupt handling */ -EXPORT_SYMBOL(add_timer); -EXPORT_SYMBOL(del_timer); EXPORT_SYMBOL(request_irq); EXPORT_SYMBOL(free_irq); @@ -433,7 +431,10 @@ #ifdef CONFIG_SMP EXPORT_SYMBOL(del_timer_sync); #endif +EXPORT_SYMBOL(add_timer); +EXPORT_SYMBOL(del_timer); EXPORT_SYMBOL(mod_timer); +EXPORT_SYMBOL(__mod_timer); #ifdef HAVE_DISABLE_HLT EXPORT_SYMBOL(disable_hlt); diff -Nru a/kernel/module.c b/kernel/module.c --- a/kernel/module.c Mon Aug 18 22:21:04 2003 +++ b/kernel/module.c Mon Aug 18 22:21:04 2003 @@ -482,7 +482,7 @@ struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; setscheduler(current->pid, SCHED_FIFO, ¶m); #endif - set_cpus_allowed(current, 1UL << (unsigned long)cpu); + set_cpus_allowed(current, cpumask_of_cpu((int)(long)cpu)); /* Ack: we are alive */ atomic_inc(&stopref_thread_ack); @@ -535,7 +535,7 @@ static int stop_refcounts(void) { unsigned int i, cpu; - unsigned long old_allowed; + cpumask_t old_allowed; int ret = 0; /* One thread per cpu. We'll do our own. */ @@ -543,7 +543,7 @@ /* FIXME: racy with set_cpus_allowed. */ old_allowed = current->cpus_allowed; - set_cpus_allowed(current, 1UL << (unsigned long)cpu); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); atomic_set(&stopref_thread_ack, 0); stopref_num_threads = 0; diff -Nru a/kernel/params.c b/kernel/params.c --- a/kernel/params.c Mon Aug 18 22:21:05 2003 +++ b/kernel/params.c Mon Aug 18 22:21:05 2003 @@ -165,9 +165,9 @@ } STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol); -STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", long, simple_strtol); +STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul); STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol); -STANDARD_PARAM_DEF(uint, unsigned int, "%u", long, simple_strtol); +STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul); STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol); STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul); diff -Nru a/kernel/pm.c b/kernel/pm.c --- a/kernel/pm.c Mon Aug 18 22:21:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,333 +0,0 @@ -/* - * pm.c - Power management interface - * - * Copyright (C) 2000 Andrew Henroid - * - * 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 - -int pm_active; - -/* - * Locking notes: - * pm_devs_lock can be a semaphore providing pm ops are not called - * from an interrupt handler (already a bad idea so no change here). Each - * change must be protected so that an unlink of an entry doesn't clash - * with a pm send - which is permitted to sleep in the current architecture - * - * Module unloads clashing with pm events now work out safely, the module - * unload path will block until the event has been sent. It may well block - * until a resume but that will be fine. - */ - -static DECLARE_MUTEX(pm_devs_lock); -static LIST_HEAD(pm_devs); - -/** - * pm_register - register a device with power management - * @type: device type - * @id: device ID - * @callback: callback function - * - * Add a device to the list of devices that wish to be notified about - * power management events. A &pm_dev structure is returned on success, - * on failure the return is %NULL. - * - * The callback function will be called in process context and - * it may sleep. - */ - -struct pm_dev *pm_register(pm_dev_t type, - unsigned long id, - pm_callback callback) -{ - struct pm_dev *dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL); - if (dev) { - memset(dev, 0, sizeof(*dev)); - dev->type = type; - dev->id = id; - dev->callback = callback; - - down(&pm_devs_lock); - list_add(&dev->entry, &pm_devs); - up(&pm_devs_lock); - } - return dev; -} - -/** - * pm_unregister - unregister a device with power management - * @dev: device to unregister - * - * Remove a device from the power management notification lists. The - * dev passed must be a handle previously returned by pm_register. - */ - -void pm_unregister(struct pm_dev *dev) -{ - if (dev) { - down(&pm_devs_lock); - list_del(&dev->entry); - up(&pm_devs_lock); - - kfree(dev); - } -} - -static void __pm_unregister(struct pm_dev *dev) -{ - if (dev) { - list_del(&dev->entry); - kfree(dev); - } -} - -/** - * pm_unregister_all - unregister all devices with matching callback - * @callback: callback function pointer - * - * Unregister every device that would call the callback passed. This - * is primarily meant as a helper function for loadable modules. It - * enables a module to give up all its managed devices without keeping - * its own private list. - */ - -void pm_unregister_all(pm_callback callback) -{ - struct list_head *entry; - - if (!callback) - return; - - down(&pm_devs_lock); - entry = pm_devs.next; - while (entry != &pm_devs) { - struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); - entry = entry->next; - if (dev->callback == callback) - __pm_unregister(dev); - } - up(&pm_devs_lock); -} - -/** - * pm_send - send request to a single device - * @dev: device to send to - * @rqst: power management request - * @data: data for the callback - * - * Issue a power management request to a given device. The - * %PM_SUSPEND and %PM_RESUME events are handled specially. The - * data field must hold the intended next state. No call is made - * if the state matches. - * - * BUGS: what stops two power management requests occurring in parallel - * and conflicting. - * - * WARNING: Calling pm_send directly is not generally recommended, in - * particular there is no locking against the pm_dev going away. The - * caller must maintain all needed locking or have 'inside knowledge' - * on the safety. Also remember that this function is not locked against - * pm_unregister. This means that you must handle SMP races on callback - * execution and unload yourself. - */ - -int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data) -{ - int status = 0; - unsigned long prev_state, next_state; - - if (in_interrupt()) - BUG(); - - switch (rqst) { - case PM_SUSPEND: - case PM_RESUME: - prev_state = dev->state; - next_state = (unsigned long) data; - if (prev_state != next_state) { - if (dev->callback) - status = (*dev->callback)(dev, rqst, data); - if (!status) { - dev->state = next_state; - dev->prev_state = prev_state; - } - } - else { - dev->prev_state = prev_state; - } - break; - default: - if (dev->callback) - status = (*dev->callback)(dev, rqst, data); - break; - } - return status; -} - -/* - * Undo incomplete request - */ -static void pm_undo_all(struct pm_dev *last) -{ - struct list_head *entry = last->entry.prev; - while (entry != &pm_devs) { - struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); - if (dev->state != dev->prev_state) { - /* previous state was zero (running) resume or - * previous state was non-zero (suspended) suspend - */ - pm_request_t undo = (dev->prev_state - ? PM_SUSPEND:PM_RESUME); - pm_send(dev, undo, (void*) dev->prev_state); - } - entry = entry->prev; - } -} - -/** - * pm_send_all - send request to all managed devices - * @rqst: power management request - * @data: data for the callback - * - * Issue a power management request to a all devices. The - * %PM_SUSPEND events are handled specially. Any device is - * permitted to fail a suspend by returning a non zero (error) - * value from its callback function. If any device vetoes a - * suspend request then all other devices that have suspended - * during the processing of this request are restored to their - * previous state. - * - * WARNING: This function takes the pm_devs_lock. The lock is not dropped until - * the callbacks have completed. This prevents races against pm locking - * functions, races against module unload pm_unregister code. It does - * mean however that you must not issue pm_ functions within the callback - * or you will deadlock and users will hate you. - * - * Zero is returned on success. If a suspend fails then the status - * from the device that vetoes the suspend is returned. - * - * BUGS: what stops two power management requests occurring in parallel - * and conflicting. - */ - -int pm_send_all(pm_request_t rqst, void *data) -{ - struct list_head *entry; - - down(&pm_devs_lock); - entry = pm_devs.next; - while (entry != &pm_devs) { - struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); - if (dev->callback) { - int status = pm_send(dev, rqst, data); - if (status) { - /* return devices to previous state on - * failed suspend request - */ - if (rqst == PM_SUSPEND) - pm_undo_all(dev); - up(&pm_devs_lock); - return status; - } - } - entry = entry->next; - } - up(&pm_devs_lock); - return 0; -} - -/** - * pm_find - find a device - * @type: type of device - * @from: where to start looking - * - * Scan the power management list for devices of a specific type. The - * return value for a matching device may be passed to further calls - * to this function to find further matches. A %NULL indicates the end - * of the list. - * - * To search from the beginning pass %NULL as the @from value. - * - * The caller MUST hold the pm_devs_lock lock when calling this - * function. The instant that the lock is dropped all pointers returned - * may become invalid. - */ - -struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from) -{ - struct list_head *entry = from ? from->entry.next:pm_devs.next; - while (entry != &pm_devs) { - struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); - if (type == PM_UNKNOWN_DEV || dev->type == type) - return dev; - entry = entry->next; - } - return 0; -} - -EXPORT_SYMBOL(pm_register); -EXPORT_SYMBOL(pm_unregister); -EXPORT_SYMBOL(pm_unregister_all); -EXPORT_SYMBOL(pm_send); -EXPORT_SYMBOL(pm_send_all); -EXPORT_SYMBOL(pm_find); -EXPORT_SYMBOL(pm_active); - - -#ifdef CONFIG_MAGIC_SYSRQ - -/** - * handle_poweroff - sysrq callback for power down - * @key: key pressed (unused) - * @pt_regs: register state (unused) - * @kbd: keyboard state (unused) - * @tty: tty involved (unused) - * - * When the user hits Sys-Rq o to power down the machine this is the - * callback we use. - */ - -static void handle_poweroff (int key, struct pt_regs *pt_regs, - struct tty_struct *tty) -{ - if (pm_power_off) - pm_power_off(); -} - -static struct sysrq_key_op sysrq_poweroff_op = { - .handler = handle_poweroff, - .help_msg = "powerOff", - .action_msg = "Power Off\n" -}; - -#endif /* CONFIG_MAGIC_SYSRQ */ - - -static int pm_init(void) -{ - register_sysrq_key('o', &sysrq_poweroff_op); - return 0; -} - -subsys_initcall(pm_init); diff -Nru a/kernel/power/Makefile b/kernel/power/Makefile --- a/kernel/power/Makefile Mon Aug 18 22:21:05 2003 +++ b/kernel/power/Makefile Mon Aug 18 22:21:05 2003 @@ -1,2 +1,4 @@ -obj-y := process.o console.o +obj-y := main.o process.o console.o pm.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o + +obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff -Nru a/kernel/power/console.c b/kernel/power/console.c --- a/kernel/power/console.c Mon Aug 18 22:21:00 2003 +++ b/kernel/power/console.c Mon Aug 18 22:21:00 2003 @@ -1,3 +1,9 @@ +/* + * drivers/power/process.c - Functions for saving/restoring console. + * + * Originally from swsusp. + */ + #include #include #include "power.h" @@ -14,13 +20,13 @@ #ifdef SUSPEND_CONSOLE orig_fgconsole = fg_console; - if(vc_allocate(SUSPEND_CONSOLE)) + if (vc_allocate(SUSPEND_CONSOLE)) /* we can't have a free VC for now. Too bad, * we don't want to mess the screen for now. */ return 1; - set_console (SUSPEND_CONSOLE); - if(vt_waitactive(SUSPEND_CONSOLE)) { + set_console(SUSPEND_CONSOLE); + if (vt_waitactive(SUSPEND_CONSOLE)) { pr_debug("Suspend: Can't switch VCs."); return 1; } @@ -34,7 +40,7 @@ { console_loglevel = orig_loglevel; #ifdef SUSPEND_CONSOLE - set_console (orig_fgconsole); + set_console(orig_fgconsole); #endif return; } diff -Nru a/kernel/power/main.c b/kernel/power/main.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/kernel/power/main.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,129 @@ +/* + * kernel/power/main.c - PM subsystem core functionality. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * + * This file is release under the GPLv2 + * + */ + +#include +#include +#include +#include +#include + + + +static int standby(void) +{ + return 0; +} + +static int suspend(void) +{ + return 0; +} + +static int hibernate(void) +{ + return 0; +} + +#define decl_state(_name) \ + { .name = __stringify(_name), .fn = _name } + +struct pm_state { + char * name; + int (*fn)(void); +} pm_states[] = { + decl_state(standby), + decl_state(suspend), + decl_state(hibernate), + { NULL }, +}; + + +static int enter_state(struct pm_state * state) +{ + return state->fn(); +} + + + +decl_subsys(power,NULL,NULL); + + +#define power_attr(_name) \ +static struct subsys_attribute _name##_attr = { \ + .attr = { \ + .name = __stringify(_name), \ + .mode = 0644, \ + }, \ + .show = _name##_show, \ + .store = _name##_store, \ +} + +/** + * state - control system power state. + * + * show() returns what states are supported, which is hard-coded to + * 'standby' (Power-On Suspend), 'suspend' (Suspend-to-RAM), and + * 'hibernate' (Suspend-to-Disk). + * + * store() accepts one of those strings, translates it into the + * proper enumerated value, and initiates a suspend transition. + */ + +static ssize_t state_show(struct subsystem * subsys, char * buf) +{ + struct pm_state * state; + char * s = buf; + + for (state = &pm_states[0]; state->name; state++) + s += sprintf(s,"%s ",state->name); + s += sprintf(s,"\n"); + return (s - buf); +} + +static ssize_t state_store(struct subsystem * s, const char * buf, size_t n) +{ + struct pm_state * state; + int error; + char * end = strchr(buf,'\n'); + + if (end) + *end = '\0'; + + for (state = &pm_states[0]; state; state++) { + if (!strcmp(buf,state->name)) + break; + } + if (!state) + return -EINVAL; + error = enter_state(state); + return error ? error : n; +} + +power_attr(state); + +static struct attribute * g[] = { + &state_attr.attr, + NULL, +}; + +static struct attribute_group attr_group = { + .attrs = g, +}; + + +static int pm_init(void) +{ + int error = subsystem_register(&power_subsys); + if (!error) + error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group); + return error; +} + +core_initcall(pm_init); diff -Nru a/kernel/power/pm.c b/kernel/power/pm.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/kernel/power/pm.c Mon Aug 18 22:21:01 2003 @@ -0,0 +1,296 @@ +/* + * pm.c - Power management interface + * + * Copyright (C) 2000 Andrew Henroid + * + * 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 + +int pm_active; + +/* + * Locking notes: + * pm_devs_lock can be a semaphore providing pm ops are not called + * from an interrupt handler (already a bad idea so no change here). Each + * change must be protected so that an unlink of an entry doesn't clash + * with a pm send - which is permitted to sleep in the current architecture + * + * Module unloads clashing with pm events now work out safely, the module + * unload path will block until the event has been sent. It may well block + * until a resume but that will be fine. + */ + +static DECLARE_MUTEX(pm_devs_lock); +static LIST_HEAD(pm_devs); + +/** + * pm_register - register a device with power management + * @type: device type + * @id: device ID + * @callback: callback function + * + * Add a device to the list of devices that wish to be notified about + * power management events. A &pm_dev structure is returned on success, + * on failure the return is %NULL. + * + * The callback function will be called in process context and + * it may sleep. + */ + +struct pm_dev *pm_register(pm_dev_t type, + unsigned long id, + pm_callback callback) +{ + struct pm_dev *dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL); + if (dev) { + memset(dev, 0, sizeof(*dev)); + dev->type = type; + dev->id = id; + dev->callback = callback; + + down(&pm_devs_lock); + list_add(&dev->entry, &pm_devs); + up(&pm_devs_lock); + } + return dev; +} + +/** + * pm_unregister - unregister a device with power management + * @dev: device to unregister + * + * Remove a device from the power management notification lists. The + * dev passed must be a handle previously returned by pm_register. + */ + +void pm_unregister(struct pm_dev *dev) +{ + if (dev) { + down(&pm_devs_lock); + list_del(&dev->entry); + up(&pm_devs_lock); + + kfree(dev); + } +} + +static void __pm_unregister(struct pm_dev *dev) +{ + if (dev) { + list_del(&dev->entry); + kfree(dev); + } +} + +/** + * pm_unregister_all - unregister all devices with matching callback + * @callback: callback function pointer + * + * Unregister every device that would call the callback passed. This + * is primarily meant as a helper function for loadable modules. It + * enables a module to give up all its managed devices without keeping + * its own private list. + */ + +void pm_unregister_all(pm_callback callback) +{ + struct list_head *entry; + + if (!callback) + return; + + down(&pm_devs_lock); + entry = pm_devs.next; + while (entry != &pm_devs) { + struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); + entry = entry->next; + if (dev->callback == callback) + __pm_unregister(dev); + } + up(&pm_devs_lock); +} + +/** + * pm_send - send request to a single device + * @dev: device to send to + * @rqst: power management request + * @data: data for the callback + * + * Issue a power management request to a given device. The + * %PM_SUSPEND and %PM_RESUME events are handled specially. The + * data field must hold the intended next state. No call is made + * if the state matches. + * + * BUGS: what stops two power management requests occurring in parallel + * and conflicting. + * + * WARNING: Calling pm_send directly is not generally recommended, in + * particular there is no locking against the pm_dev going away. The + * caller must maintain all needed locking or have 'inside knowledge' + * on the safety. Also remember that this function is not locked against + * pm_unregister. This means that you must handle SMP races on callback + * execution and unload yourself. + */ + +int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + int status = 0; + unsigned long prev_state, next_state; + + if (in_interrupt()) + BUG(); + + switch (rqst) { + case PM_SUSPEND: + case PM_RESUME: + prev_state = dev->state; + next_state = (unsigned long) data; + if (prev_state != next_state) { + if (dev->callback) + status = (*dev->callback)(dev, rqst, data); + if (!status) { + dev->state = next_state; + dev->prev_state = prev_state; + } + } + else { + dev->prev_state = prev_state; + } + break; + default: + if (dev->callback) + status = (*dev->callback)(dev, rqst, data); + break; + } + return status; +} + +/* + * Undo incomplete request + */ +static void pm_undo_all(struct pm_dev *last) +{ + struct list_head *entry = last->entry.prev; + while (entry != &pm_devs) { + struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); + if (dev->state != dev->prev_state) { + /* previous state was zero (running) resume or + * previous state was non-zero (suspended) suspend + */ + pm_request_t undo = (dev->prev_state + ? PM_SUSPEND:PM_RESUME); + pm_send(dev, undo, (void*) dev->prev_state); + } + entry = entry->prev; + } +} + +/** + * pm_send_all - send request to all managed devices + * @rqst: power management request + * @data: data for the callback + * + * Issue a power management request to a all devices. The + * %PM_SUSPEND events are handled specially. Any device is + * permitted to fail a suspend by returning a non zero (error) + * value from its callback function. If any device vetoes a + * suspend request then all other devices that have suspended + * during the processing of this request are restored to their + * previous state. + * + * WARNING: This function takes the pm_devs_lock. The lock is not dropped until + * the callbacks have completed. This prevents races against pm locking + * functions, races against module unload pm_unregister code. It does + * mean however that you must not issue pm_ functions within the callback + * or you will deadlock and users will hate you. + * + * Zero is returned on success. If a suspend fails then the status + * from the device that vetoes the suspend is returned. + * + * BUGS: what stops two power management requests occurring in parallel + * and conflicting. + */ + +int pm_send_all(pm_request_t rqst, void *data) +{ + struct list_head *entry; + + down(&pm_devs_lock); + entry = pm_devs.next; + while (entry != &pm_devs) { + struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); + if (dev->callback) { + int status = pm_send(dev, rqst, data); + if (status) { + /* return devices to previous state on + * failed suspend request + */ + if (rqst == PM_SUSPEND) + pm_undo_all(dev); + up(&pm_devs_lock); + return status; + } + } + entry = entry->next; + } + up(&pm_devs_lock); + return 0; +} + +/** + * pm_find - find a device + * @type: type of device + * @from: where to start looking + * + * Scan the power management list for devices of a specific type. The + * return value for a matching device may be passed to further calls + * to this function to find further matches. A %NULL indicates the end + * of the list. + * + * To search from the beginning pass %NULL as the @from value. + * + * The caller MUST hold the pm_devs_lock lock when calling this + * function. The instant that the lock is dropped all pointers returned + * may become invalid. + */ + +struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from) +{ + struct list_head *entry = from ? from->entry.next:pm_devs.next; + while (entry != &pm_devs) { + struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); + if (type == PM_UNKNOWN_DEV || dev->type == type) + return dev; + entry = entry->next; + } + return 0; +} + +EXPORT_SYMBOL(pm_register); +EXPORT_SYMBOL(pm_unregister); +EXPORT_SYMBOL(pm_unregister_all); +EXPORT_SYMBOL(pm_send); +EXPORT_SYMBOL(pm_send_all); +EXPORT_SYMBOL(pm_find); +EXPORT_SYMBOL(pm_active); + + diff -Nru a/kernel/power/poweroff.c b/kernel/power/poweroff.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/kernel/power/poweroff.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,44 @@ +/* + * poweroff.c - sysrq handler to gracefully power down machine. + * + * This file is released under the GPL v2 + */ + +#include +#include +#include +#include + + +/** + * handle_poweroff - sysrq callback for power down + * @key: key pressed (unused) + * @pt_regs: register state (unused) + * @kbd: keyboard state (unused) + * @tty: tty involved (unused) + * + * When the user hits Sys-Rq o to power down the machine this is the + * callback we use. + */ + +static void handle_poweroff (int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + if (pm_power_off) + pm_power_off(); +} + +static struct sysrq_key_op sysrq_poweroff_op = { + .handler = handle_poweroff, + .help_msg = "powerOff", + .action_msg = "Power Off\n" +}; + + +static int pm_sysrq_init(void) +{ + register_sysrq_key('o', &sysrq_poweroff_op); + return 0; +} + +subsys_initcall(pm_sysrq_init); diff -Nru a/kernel/power/process.c b/kernel/power/process.c --- a/kernel/power/process.c Mon Aug 18 22:21:00 2003 +++ b/kernel/power/process.c Mon Aug 18 22:21:00 2003 @@ -8,6 +8,7 @@ #undef DEBUG +#include #include #include #include diff -Nru a/kernel/power/swsusp.c b/kernel/power/swsusp.c --- a/kernel/power/swsusp.c Mon Aug 18 22:21:02 2003 +++ b/kernel/power/swsusp.c Mon Aug 18 22:21:02 2003 @@ -67,7 +67,7 @@ extern long sys_sync(void); -unsigned char software_suspend_enabled = 0; +unsigned char software_suspend_enabled = 1; #define __ADDRESS(x) ((unsigned long) phys_to_virt(x)) #define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT) @@ -85,8 +85,7 @@ static int pagedir_order_check; static int nr_copy_pages_check; -static int resume_status; -static char resume_file[256] = ""; /* For resume= kernel option */ +static char resume_file[256]; /* For resume= kernel option */ static dev_t resume_device; /* Local variables that should not be affected by save */ unsigned int nr_copy_pages __nosavedata = 0; @@ -352,15 +351,10 @@ int pfn; struct page *page; -#ifdef CONFIG_DISCONTIGMEM - panic("Discontingmem not supported"); -#else BUG_ON (max_pfn != num_physpages); -#endif + for (pfn = 0; pfn < max_pfn; pfn++) { page = pfn_to_page(pfn); - if (PageHighMem(page)) - panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to and try again ;-)."); if (!PageReserved(page)) { if (PageNosave(page)) @@ -479,19 +473,23 @@ /* Called from process context */ static int drivers_suspend(void) { - device_suspend(4, SUSPEND_NOTIFY); - device_suspend(4, SUSPEND_SAVE_STATE); - device_suspend(4, SUSPEND_DISABLE); - if(!pm_suspend_state) { + if (device_suspend(4, SUSPEND_NOTIFY)) + return -EIO; + if (device_suspend(4, SUSPEND_SAVE_STATE)) { + device_resume(RESUME_RESTORE_STATE); + return -EIO; + } + if (!pm_suspend_state) { if(pm_send_all(PM_SUSPEND,(void *)3)) { printk(KERN_WARNING "Problem while sending suspend event\n"); - return(1); + return -EIO; } pm_suspend_state=1; } else printk(KERN_WARNING "PM suspend state already raised\n"); + device_suspend(4, SUSPEND_DISABLE); - return(0); + return 0; } #define RESUME_PHASE1 1 /* Called from interrupts disabled */ @@ -504,7 +502,7 @@ device_resume(RESUME_ENABLE); } if (flags & RESUME_PHASE2) { - if(pm_suspend_state) { + if (pm_suspend_state) { if(pm_send_all(PM_RESUME,(void *)0)) printk(KERN_WARNING "Problem while sending resume event\n"); pm_suspend_state=0; @@ -696,7 +694,7 @@ mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME); } -static void do_software_suspend(void) +static int do_software_suspend(void) { arch_prepare_suspend(); if (pm_prepare_console()) @@ -715,7 +713,7 @@ blk_run_queues(); /* Save state of all device drivers, and stop them. */ - if(drivers_suspend()==0) + if (drivers_suspend()==0) /* If stopping device drivers worked, we proceed basically into * suspend_save_image. * @@ -731,20 +729,35 @@ software_suspend_enabled = 1; MDELAY(1000); pm_restore_console(); + return 0; } -/* - * This is main interface to the outside world. It needs to be - * called from process context. + +/** + * software_suspend - initiate suspend-to-swap transition. + * + * This is main interface to the outside world. It needs to be + * called from process context. */ -void software_suspend(void) + +int software_suspend(void) { if(!software_suspend_enabled) - return; + return -EINVAL; + + if (num_online_cpus() > 1) { + printk(KERN_WARNING "swsusp does not support SMP.\n"); + return -EPERM; + } + +#if defined (CONFIG_HIGHMEM) || defined (COFNIG_DISCONTIGMEM) + printk("swsusp is not supported with high- or discontig-mem.\n"); + return -EPERM; +#endif software_suspend_enabled = 0; might_sleep(); - do_software_suspend(); + return do_software_suspend(); } /* More restore stuff */ @@ -890,31 +903,9 @@ return 0; } -static int bdev_write_page(struct block_device *bdev, long pos, void *buf) -{ -#if 0 - struct buffer_head *bh; - BUG_ON (pos%PAGE_SIZE); - bh = __bread(bdev, pos/PAGE_SIZE, PAGE_SIZE); - if (!bh || (!bh->b_data)) { - return -1; - } - memcpy(bh->b_data, buf, PAGE_SIZE); /* FIXME: may need kmap() */ - BUG_ON(!buffer_uptodate(bh)); - generic_make_request(WRITE, bh); - if (!buffer_uptodate(bh)) - printk(KERN_CRIT "%sWarning %s: Fixing swap signatures unsuccessful...\n", name_resume, resume_file); - wait_on_buffer(bh); - brelse(bh); - return 0; -#endif - printk(KERN_CRIT "%sWarning %s: Fixing swap signatures unimplemented...\n", name_resume, resume_file); - return 0; -} - extern dev_t __init name_to_dev_t(const char *line); -static int __read_suspend_image(struct block_device *bdev, union diskpage *cur, int noresume) +static int __read_suspend_image(struct block_device *bdev, union diskpage *cur) { swp_entry_t next; int i, nr_pgdir_pages; @@ -939,18 +930,9 @@ 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", + printk("swsusp: %s: Unable to find suspended-data signature (%.10s - misspelled?\n", name_resume, cur->swh.magic.magic); - } - 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 - we must write the device directly */ - printk("%s: Fixing swap signatures %s...\n", name_resume, resume_file); - bdev_write_page(bdev, 0, cur); + return -EFAULT; } printk( "%sSignature found, resuming\n", name_resume ); @@ -1000,7 +982,7 @@ return 0; } -static int read_suspend_image(const char * specialfile, int noresume) +static int read_suspend_image(const char * specialfile) { union diskpage *cur; unsigned long scratch_page = 0; @@ -1019,7 +1001,7 @@ error = PTR_ERR(bdev); } else { set_blocksize(bdev, PAGE_SIZE); - error = __read_suspend_image(bdev, cur, noresume); + error = __read_suspend_image(bdev, cur); blkdev_put(bdev, BDEV_RAW); } } else error = -ENOMEM; @@ -1048,64 +1030,47 @@ return error; } -/* - * Called from init kernel_thread. - * We check if we have an image and if so we try to resume +/** + * software_resume - Check and load saved image from swap. + * + * Defined as a late_initcall, so it gets called after all devices + * have been probed and initialized, but before we've mounted anything. */ -void software_resume(void) +static int software_resume(void) { - if (num_online_cpus() > 1) { - printk(KERN_WARNING "Software Suspend has malfunctioning SMP support. Disabled :(\n"); - return; - } - /* We enable the possibility of machine suspend */ - software_suspend_enabled = 1; - if (!resume_status) - return; - - printk( "%s", name_resume ); - if (resume_status == NORESUME) { - if(resume_file[0]) - read_suspend_image(resume_file, 1); - printk( "disabled\n" ); - return; - } - MDELAY(1000); + if (!strlen(resume_file)) + return 0; if (pm_prepare_console()) printk("swsusp: Can't allocate a console... proceeding\n"); - if (!resume_file[0] && resume_status == RESUME_SPECIFIED) { - printk( "suspension device unspecified\n" ); - return; - } + printk("swsusp: %s\n", name_resume ); + + MDELAY(1000); - printk( "resuming from %s\n", resume_file); - if (read_suspend_image(resume_file, 0)) + printk("swsusp: resuming from %s\n", resume_file); + if (read_suspend_image(resume_file)) goto read_failure; do_magic(1); - panic("This never returns"); + printk("swsusp: Resume failed. Continuing.\n"); read_failure: pm_restore_console(); - return; + return -EFAULT; } +late_initcall(software_resume); + static int __init resume_setup(char *str) { - if (resume_status == NORESUME) - return 1; - strncpy( resume_file, str, 255 ); - resume_status = RESUME_SPECIFIED; - return 1; } static int __init noresume_setup(char *str) { - resume_status = NORESUME; + resume_file[0] = '\0'; return 1; } diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c --- a/kernel/ptrace.c Mon Aug 18 22:21:06 2003 +++ b/kernel/ptrace.c Mon Aug 18 22:21:06 2003 @@ -189,6 +189,7 @@ if (write) { memcpy(maddr + offset, buf, bytes); flush_icache_user_range(vma, page, addr, bytes); + set_page_dirty_lock(page); } else { memcpy(buf, maddr + offset, bytes); } diff -Nru a/kernel/rcupdate.c b/kernel/rcupdate.c --- a/kernel/rcupdate.c Mon Aug 18 22:21:00 2003 +++ b/kernel/rcupdate.c Mon Aug 18 22:21:00 2003 @@ -48,7 +48,7 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = { .mutex = SPIN_LOCK_UNLOCKED, .curbatch = 1, - .maxbatch = 1, .rcu_cpu_mask = 0 }; + .maxbatch = 1, .rcu_cpu_mask = CPU_MASK_NONE }; DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; /* Fake initialization required by compiler */ @@ -107,7 +107,7 @@ rcu_ctrlblk.maxbatch = newbatch; } if (rcu_batch_before(rcu_ctrlblk.maxbatch, rcu_ctrlblk.curbatch) || - (rcu_ctrlblk.rcu_cpu_mask != 0)) { + !cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) { return; } rcu_ctrlblk.rcu_cpu_mask = cpu_online_map; @@ -122,7 +122,7 @@ { int cpu = smp_processor_id(); - if (!test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask)) + if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) return; /* @@ -138,12 +138,12 @@ return; spin_lock(&rcu_ctrlblk.mutex); - if (!test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask)) + if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) goto out_unlock; - clear_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask); + cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask); RCU_last_qsctr(cpu) = RCU_QSCTR_INVALID; - if (rcu_ctrlblk.rcu_cpu_mask != 0) + if (!cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) goto out_unlock; rcu_ctrlblk.curbatch++; diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Mon Aug 18 22:21:05 2003 +++ b/kernel/sched.c Mon Aug 18 22:21:05 2003 @@ -489,7 +489,7 @@ */ if (unlikely(sync && !task_running(rq, p) && (task_cpu(p) != smp_processor_id()) && - (p->cpus_allowed & (1UL << smp_processor_id())))) { + cpu_isset(smp_processor_id(), p->cpus_allowed))) { set_task_cpu(p, smp_processor_id()); task_rq_unlock(rq, &flags); @@ -613,12 +613,29 @@ { runqueue_t *rq = this_rq(); struct mm_struct *mm = rq->prev_mm; + int drop_task_ref; rq->prev_mm = NULL; + + /* + * A task struct has one reference for the use as "current". + * If a task dies, then it sets TASK_ZOMBIE in tsk->state and calls + * schedule one last time. The schedule call will never return, + * and the scheduled task must drop that reference. + * The test for TASK_ZOMBIE must occur while the runqueue locks are + * still held, otherwise prev could be scheduled on another cpu, die + * there before we look at prev->state, and then the reference would + * be dropped twice. + * Manfred Spraul + */ + drop_task_ref = 0; + if (unlikely(prev->state & (TASK_DEAD | TASK_ZOMBIE))) + drop_task_ref = 1; + finish_arch_switch(rq, prev); if (mm) mmdrop(mm); - if (prev->state & (TASK_DEAD | TASK_ZOMBIE)) + if (drop_task_ref) put_task_struct(prev); } @@ -758,13 +775,13 @@ */ static void sched_migrate_task(task_t *p, int dest_cpu) { - unsigned long old_mask; + cpumask_t old_mask; old_mask = p->cpus_allowed; - if (!(old_mask & (1UL << dest_cpu))) + if (!cpu_isset(dest_cpu, old_mask)) return; /* force the process onto the specified CPU */ - set_cpus_allowed(p, 1UL << dest_cpu); + set_cpus_allowed(p, cpumask_of_cpu(dest_cpu)); /* restore the cpus allowed mask */ set_cpus_allowed(p, old_mask); @@ -777,7 +794,7 @@ static int sched_best_cpu(struct task_struct *p) { int i, minload, load, best_cpu, node = 0; - unsigned long cpumask; + cpumask_t cpumask; best_cpu = task_cpu(p); if (cpu_rq(best_cpu)->nr_running <= 2) @@ -801,7 +818,7 @@ minload = 10000000; cpumask = node_to_cpumask(node); for (i = 0; i < NR_CPUS; ++i) { - if (!(cpumask & (1UL << i))) + if (!cpu_isset(i, cpumask)) continue; if (cpu_rq(i)->nr_running < minload) { best_cpu = i; @@ -888,7 +905,7 @@ /* * find_busiest_queue - find the busiest runqueue among the cpus in cpumask. */ -static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance, unsigned long cpumask) +static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance, cpumask_t cpumask) { int nr_running, load, max_load, i; runqueue_t *busiest, *rq_src; @@ -923,7 +940,7 @@ busiest = NULL; max_load = 1; for (i = 0; i < NR_CPUS; i++) { - if (!((1UL << i) & cpumask)) + if (!cpu_isset(i, cpumask)) continue; rq_src = cpu_rq(i); @@ -995,7 +1012,7 @@ * We call this with the current runqueue locked, * irqs disabled. */ -static void load_balance(runqueue_t *this_rq, int idle, unsigned long cpumask) +static void load_balance(runqueue_t *this_rq, int idle, cpumask_t cpumask) { int imbalance, idx, this_cpu = smp_processor_id(); runqueue_t *busiest; @@ -1049,7 +1066,7 @@ #define CAN_MIGRATE_TASK(p,rq,this_cpu) \ ((!idle || (jiffies - (p)->last_run > cache_decay_ticks)) && \ !task_running(rq, p) && \ - ((p)->cpus_allowed & (1UL << (this_cpu)))) + cpu_isset(this_cpu, (p)->cpus_allowed)) curr = curr->prev; @@ -1092,10 +1109,10 @@ static void balance_node(runqueue_t *this_rq, int idle, int this_cpu) { int node = find_busiest_node(cpu_to_node(this_cpu)); - unsigned long cpumask, this_cpumask = 1UL << this_cpu; if (node >= 0) { - cpumask = node_to_cpumask(node) | this_cpumask; + cpumask_t cpumask = node_to_cpumask(node); + cpu_set(this_cpu, cpumask); spin_lock(&this_rq->lock); load_balance(this_rq, idle, cpumask); spin_unlock(&this_rq->lock); @@ -1184,11 +1201,17 @@ if (rcu_pending(cpu)) rcu_check_callbacks(cpu, user_ticks); + /* note: this timer irq context must be accounted for as well */ + if (hardirq_count() - HARDIRQ_OFFSET) { + cpustat->irq += sys_ticks; + sys_ticks = 0; + } else if (softirq_count()) { + cpustat->softirq += sys_ticks; + sys_ticks = 0; + } + if (p == rq->idle) { - /* note: this timer irq context must be accounted for as well */ - if (irq_count() - HARDIRQ_OFFSET >= SOFTIRQ_OFFSET) - cpustat->system += sys_ticks; - else if (atomic_read(&rq->nr_iowait) > 0) + if (atomic_read(&rq->nr_iowait) > 0) cpustat->iowait += sys_ticks; else cpustat->idle += sys_ticks; @@ -1900,7 +1923,7 @@ asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long __user *user_mask_ptr) { - unsigned long new_mask; + cpumask_t new_mask; int retval; task_t *p; @@ -1948,7 +1971,7 @@ unsigned long __user *user_mask_ptr) { unsigned int real_len; - unsigned long mask; + cpumask_t mask; int retval; task_t *p; @@ -1964,7 +1987,7 @@ goto out_unlock; retval = 0; - mask = p->cpus_allowed & cpu_online_map; + cpus_and(mask, p->cpus_allowed, cpu_online_map); out_unlock: read_unlock(&tasklist_lock); @@ -2294,7 +2317,7 @@ * task must not exit() & deallocate itself prematurely. The * call is not atomic; no spinlocks may be held. */ -int set_cpus_allowed(task_t *p, unsigned long new_mask) +int set_cpus_allowed(task_t *p, cpumask_t new_mask) { unsigned long flags; migration_req_t req; @@ -2309,7 +2332,7 @@ * Can the task run on the task's current CPU? If not then * migrate the thread off to a proper CPU. */ - if (new_mask & (1UL << task_cpu(p))) { + if (cpu_isset(task_cpu(p), new_mask)) { task_rq_unlock(rq, &flags); return 0; } @@ -2379,7 +2402,7 @@ * migration thread on this CPU, guaranteed (we're started * serially). */ - set_cpus_allowed(current, 1UL << cpu); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); ret = setscheduler(0, SCHED_FIFO, ¶m); diff -Nru a/kernel/signal.c b/kernel/signal.c --- a/kernel/signal.c Mon Aug 18 22:21:02 2003 +++ b/kernel/signal.c Mon Aug 18 22:21:02 2003 @@ -1011,9 +1011,11 @@ * killed as part of a thread group due to another * thread doing an execve() or similar. So set the * exit signal to -1 to allow immediate reaping of - * the process. + * the process. But don't detach the thread group + * leader. */ - t->exit_signal = -1; + if (t != p->group_leader) + t->exit_signal = -1; sigaddset(&t->pending.signal, SIGKILL); rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); diff -Nru a/kernel/softirq.c b/kernel/softirq.c --- a/kernel/softirq.c Mon Aug 18 22:21:02 2003 +++ b/kernel/softirq.c Mon Aug 18 22:21:02 2003 @@ -322,9 +322,8 @@ current->flags |= PF_IOTHREAD; /* Migrate to the right CPU */ - set_cpus_allowed(current, 1UL << cpu); - if (smp_processor_id() != cpu) - BUG(); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(smp_processor_id() != cpu); __set_current_state(TASK_INTERRUPTIBLE); mb(); diff -Nru a/kernel/sys.c b/kernel/sys.c --- a/kernel/sys.c Mon Aug 18 22:21:01 2003 +++ b/kernel/sys.c Mon Aug 18 22:21:01 2003 @@ -1399,7 +1399,15 @@ case PR_GET_FPEXC: error = GET_FPEXC_CTL(current, arg2); break; - + case PR_GET_TIMING: + error = PR_TIMING_STATISTICAL; + break; + case PR_SET_TIMING: + if (arg2 == PR_TIMING_STATISTICAL) + error = 0; + else + error = -EINVAL; + break; case PR_GET_KEEPCAPS: if (current->keep_capabilities) diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Mon Aug 18 22:21:05 2003 +++ b/kernel/timer.c Mon Aug 18 22:21:05 2003 @@ -144,34 +144,67 @@ list_add_tail(&timer->entry, vec); } -/*** - * add_timer - start a timer - * @timer: the timer to be added - * - * The kernel will do a ->function(->data) callback from the - * timer interrupt at the ->expired point in the future. The - * current time is 'jiffies'. - * - * The timer's ->expired, ->function (and if the handler uses it, ->data) - * fields must be set prior calling this function. - * - * Timers with an ->expired field in the past will be executed in the next - * timer tick. It's illegal to add an already pending timer. - */ -void add_timer(struct timer_list *timer) +int __mod_timer(struct timer_list *timer, unsigned long expires) { - tvec_base_t *base = &get_cpu_var(tvec_bases); - unsigned long flags; - - BUG_ON(timer_pending(timer) || !timer->function); + tvec_base_t *old_base, *new_base; + unsigned long flags; + int ret = 0; + + BUG_ON(!timer->function); check_timer(timer); - spin_lock_irqsave(&base->lock, flags); - internal_add_timer(base, timer); - timer->base = base; - spin_unlock_irqrestore(&base->lock, flags); - put_cpu_var(tvec_bases); + spin_lock_irqsave(&timer->lock, flags); + new_base = &__get_cpu_var(tvec_bases); +repeat: + old_base = timer->base; + + /* + * Prevent deadlocks via ordering by old_base < new_base. + */ + if (old_base && (new_base != old_base)) { + if (old_base < new_base) { + spin_lock(&new_base->lock); + spin_lock(&old_base->lock); + } else { + spin_lock(&old_base->lock); + spin_lock(&new_base->lock); + } + /* + * The timer base might have been cancelled while we were + * trying to take the lock(s): + */ + if (timer->base != old_base) { + spin_unlock(&new_base->lock); + spin_unlock(&old_base->lock); + goto repeat; + } + } else { + spin_lock(&new_base->lock); + if (timer->base != old_base) { + spin_unlock(&new_base->lock); + goto repeat; + } + } + + /* + * Delete the previous timeout (if there was any), and install + * the new one: + */ + if (old_base) { + list_del(&timer->entry); + ret = 1; + } + timer->expires = expires; + internal_add_timer(new_base, timer); + timer->base = new_base; + + if (old_base && (new_base != old_base)) + spin_unlock(&old_base->lock); + spin_unlock(&new_base->lock); + spin_unlock_irqrestore(&timer->lock, flags); + + return ret; } /*** @@ -179,7 +212,7 @@ * @timer: the timer to be added * @cpu: the CPU to start it on * - * This is not very scalable on SMP. + * This is not very scalable on SMP. Double adds are not possible. */ void add_timer_on(struct timer_list *timer, int cpu) { @@ -217,10 +250,6 @@ */ int mod_timer(struct timer_list *timer, unsigned long expires) { - tvec_base_t *old_base, *new_base; - unsigned long flags; - int ret = 0; - BUG_ON(!timer->function); check_timer(timer); @@ -233,52 +262,7 @@ if (timer->expires == expires && timer_pending(timer)) return 1; - spin_lock_irqsave(&timer->lock, flags); - new_base = &__get_cpu_var(tvec_bases); -repeat: - old_base = timer->base; - - /* - * Prevent deadlocks via ordering by old_base < new_base. - */ - if (old_base && (new_base != old_base)) { - if (old_base < new_base) { - spin_lock(&new_base->lock); - spin_lock(&old_base->lock); - } else { - spin_lock(&old_base->lock); - spin_lock(&new_base->lock); - } - /* - * The timer base might have been cancelled while we were - * trying to take the lock(s): - */ - if (timer->base != old_base) { - spin_unlock(&new_base->lock); - spin_unlock(&old_base->lock); - goto repeat; - } - } else - spin_lock(&new_base->lock); - - /* - * Delete the previous timeout (if there was any), and install - * the new one: - */ - if (old_base) { - list_del(&timer->entry); - ret = 1; - } - timer->expires = expires; - internal_add_timer(new_base, timer); - timer->base = new_base; - - if (old_base && (new_base != old_base)) - spin_unlock(&old_base->lock); - spin_unlock(&new_base->lock); - spin_unlock_irqrestore(&timer->lock, flags); - - return ret; + return __mod_timer(timer, expires); } /*** @@ -605,6 +589,15 @@ time_adj -= (-time_adj >> 2) + (-time_adj >> 5); else time_adj += (time_adj >> 2) + (time_adj >> 5); +#endif +#if HZ == 1000 + /* Compensate for (HZ==1000) != (1 << SHIFT_HZ). + * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14) + */ + if (time_adj < 0) + time_adj -= (-time_adj >> 6) + (-time_adj >> 7); + else + time_adj += (time_adj >> 6) + (time_adj >> 7); #endif } diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c --- a/kernel/workqueue.c Mon Aug 18 22:21:06 2003 +++ b/kernel/workqueue.c Mon Aug 18 22:21:06 2003 @@ -176,7 +176,7 @@ cwq->thread = current; set_user_nice(current, -10); - set_cpus_allowed(current, 1UL << cpu); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); complete(&startup->done); diff -Nru a/lib/string.c b/lib/string.c --- a/lib/string.c Mon Aug 18 22:21:05 2003 +++ b/lib/string.c Mon Aug 18 22:21:05 2003 @@ -87,13 +87,12 @@ { char *tmp = dest; - while (count && (*dest++ = *src++) != '\0') - count--; while (count) { - *dest++ = 0; + if ((*tmp = *src) != 0) src++; + tmp++; count--; } - return tmp; + return dest; } #endif diff -Nru a/mm/fadvise.c b/mm/fadvise.c --- a/mm/fadvise.c Mon Aug 18 22:21:02 2003 +++ b/mm/fadvise.c Mon Aug 18 22:21:02 2003 @@ -20,12 +20,14 @@ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. */ -long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) { struct file *file = fget(fd); struct inode *inode; struct address_space *mapping; struct backing_dev_info *bdi; + pgoff_t start_index; + pgoff_t end_index; int ret = 0; if (!file) @@ -65,8 +67,10 @@ case POSIX_FADV_DONTNEED: if (!bdi_write_congested(mapping->backing_dev_info)) filemap_flush(mapping); - invalidate_mapping_pages(mapping, offset >> PAGE_CACHE_SHIFT, - (len >> PAGE_CACHE_SHIFT) + 1); + start_index = offset >> PAGE_CACHE_SHIFT; + end_index = (offset + len + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT; + invalidate_mapping_pages(mapping, start_index, end_index); break; default: ret = -EINVAL; @@ -75,3 +79,9 @@ fput(file); return ret; } + +long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +{ + return sys_fadvise64_64(fd, offset, len, advice); +} + diff -Nru a/mm/filemap.c b/mm/filemap.c --- a/mm/filemap.c Mon Aug 18 22:21:02 2003 +++ b/mm/filemap.c Mon Aug 18 22:21:02 2003 @@ -60,16 +60,22 @@ * ->swap_list_lock * ->swap_device_lock (exclusive_swap_page, others) * ->mapping->page_lock + * * ->mmap_sem * ->i_shared_sem (various places) * + * ->mmap_sem + * ->lock_page (access_process_vm) + * * ->inode_lock * ->sb_lock (fs/fs-writeback.c) * ->mapping->page_lock (__sync_single_inode) + * * ->page_table_lock * ->swap_device_lock (try_to_unmap_one) * ->private_lock (try_to_unmap_one) * ->page_lock (try_to_unmap_one) + * ->zone.lru_lock (follow_page->mark_page_accessed) */ /* diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Mon Aug 18 22:21:03 2003 +++ b/mm/memory.c Mon Aug 18 22:21:03 2003 @@ -646,8 +646,12 @@ if (pte_present(pte)) { if (!write || (pte_write(pte) && pte_dirty(pte))) { pfn = pte_pfn(pte); - if (pfn_valid(pfn)) - return pfn_to_page(pfn); + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + + mark_page_accessed(page); + return page; + } } } diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c --- a/mm/page-writeback.c Mon Aug 18 22:21:04 2003 +++ b/mm/page-writeback.c Mon Aug 18 22:21:04 2003 @@ -345,7 +345,7 @@ * sysctl handler for /proc/sys/vm/dirty_writeback_centisecs */ int dirty_writeback_centisecs_handler(ctl_table *table, int write, - struct file *file, void *buffer, size_t *length) + struct file *file, void __user *buffer, size_t *length) { proc_dointvec(table, write, file, buffer, length); if (dirty_writeback_centisecs) { diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c --- a/mm/page_alloc.c Mon Aug 18 22:21:01 2003 +++ b/mm/page_alloc.c Mon Aug 18 22:21:01 2003 @@ -1610,7 +1610,7 @@ * changes. */ int min_free_kbytes_sysctl_handler(ctl_table *table, int write, - struct file *file, void *buffer, size_t *length) + struct file *file, void __user *buffer, size_t *length) { proc_dointvec(table, write, file, buffer, length); setup_per_zone_pages_min(); diff -Nru a/mm/vmalloc.c b/mm/vmalloc.c --- a/mm/vmalloc.c Mon Aug 18 22:21:04 2003 +++ b/mm/vmalloc.c Mon Aug 18 22:21:04 2003 @@ -178,21 +178,11 @@ return err; } - -/** - * get_vm_area - reserve a contingous kernel virtual area - * - * @size: size of the area - * @flags: %VM_IOREMAP for I/O mappings or VM_ALLOC - * - * Search an area of @size in the kernel virtual mapping area, - * and reserved it for out purposes. Returns the area descriptor - * on success or %NULL on failure. - */ -struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) +struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, + unsigned long start, unsigned long end) { struct vm_struct **p, *tmp, *area; - unsigned long addr = VMALLOC_START; + unsigned long addr = start; area = kmalloc(sizeof(*area), GFP_KERNEL); if (unlikely(!area)) @@ -209,12 +199,14 @@ write_lock(&vmlist_lock); for (p = &vmlist; (tmp = *p) ;p = &tmp->next) { + if ((unsigned long)tmp->addr < addr) + continue; if ((size + addr) < addr) goto out; if (size + addr <= (unsigned long)tmp->addr) goto found; addr = tmp->size + (unsigned long)tmp->addr; - if (addr > VMALLOC_END-size) + if (addr > end - size) goto out; } @@ -236,6 +228,21 @@ write_unlock(&vmlist_lock); kfree(area); return NULL; +} + +/** + * get_vm_area - reserve a contingous kernel virtual area + * + * @size: size of the area + * @flags: %VM_IOREMAP for I/O mappings or VM_ALLOC + * + * Search an area of @size in the kernel virtual mapping area, + * and reserved it for out purposes. Returns the area descriptor + * on success or %NULL on failure. + */ +struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) +{ + return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END); } /** diff -Nru a/mm/vmscan.c b/mm/vmscan.c --- a/mm/vmscan.c Mon Aug 18 22:21:01 2003 +++ b/mm/vmscan.c Mon Aug 18 22:21:01 2003 @@ -991,11 +991,11 @@ struct reclaim_state reclaim_state = { .reclaimed_slab = 0, }; - unsigned long cpumask; + cpumask_t cpumask; daemonize("kswapd%d", pgdat->node_id); cpumask = node_to_cpumask(pgdat->node_id); - if (cpumask) + if (!cpus_empty(cpumask)) set_cpus_allowed(tsk, cpumask); current->reclaim_state = &reclaim_state; diff -Nru a/net/Kconfig b/net/Kconfig --- a/net/Kconfig Mon Aug 18 22:21:01 2003 +++ b/net/Kconfig Mon Aug 18 22:21:01 2003 @@ -83,6 +83,7 @@ config NET_KEY tristate "PF_KEY sockets" + select XFRM ---help--- PF_KEYv2 socket family, compatible to KAME ones. They are required if you are going to use IPsec tools ported diff -Nru a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c --- a/net/bridge/br_stp_bpdu.c Mon Aug 18 22:21:05 2003 +++ b/net/bridge/br_stp_bpdu.c Mon Aug 18 22:21:05 2003 @@ -201,6 +201,6 @@ out: spin_unlock_bh(&br->lock); err: - kfree(skb); + kfree_skb(skb); return 0; } diff -Nru a/net/core/Makefile b/net/core/Makefile --- a/net/core/Makefile Mon Aug 18 22:21:06 2003 +++ b/net/core/Makefile Mon Aug 18 22:21:06 2003 @@ -6,8 +6,8 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o -obj-y += flow.o dev.o net-sysfs.o dev_mcast.o dst.o neighbour.o \ - rtnetlink.o utils.o link_watch.o filter.o +obj-y += flow.o dev.o ethtool.o net-sysfs.o dev_mcast.o dst.o \ + neighbour.o rtnetlink.o utils.o link_watch.o filter.o obj-$(CONFIG_NETFILTER) += netfilter.o obj-$(CONFIG_NET_DIVERT) += dv.o diff -Nru a/net/core/dev.c b/net/core/dev.c --- a/net/core/dev.c Mon Aug 18 22:21:03 2003 +++ b/net/core/dev.c Mon Aug 18 22:21:03 2003 @@ -187,7 +187,6 @@ extern int netdev_sysfs_init(void); extern int netdev_register_sysfs(struct net_device *); -extern void netdev_unregister_sysfs(struct net_device *); /******************************************************************************* @@ -2343,14 +2342,18 @@ case SIOCSIFNAME: if (dev->flags & IFF_UP) return -EBUSY; + ifr->ifr_newname[IFNAMSIZ-1] = '\0'; if (__dev_get_by_name(ifr->ifr_newname)) return -EEXIST; - memcpy(dev->name, ifr->ifr_newname, IFNAMSIZ); - dev->name[IFNAMSIZ - 1] = 0; - strlcpy(dev->class_dev.class_id, dev->name, BUS_ID_SIZE); - notifier_call_chain(&netdev_chain, - NETDEV_CHANGENAME, dev); - return 0; + err = class_device_rename(&dev->class_dev, + ifr->ifr_newname); + if (!err) { + strlcpy(dev->name, ifr->ifr_newname, IFNAMSIZ); + + notifier_call_chain(&netdev_chain, + NETDEV_CHANGENAME, dev); + } + return err; /* * Unknown or private ioctl @@ -2365,7 +2368,6 @@ cmd == SIOCBONDSLAVEINFOQUERY || cmd == SIOCBONDINFOQUERY || cmd == SIOCBONDCHANGEACTIVE || - cmd == SIOCETHTOOL || cmd == SIOCGMIIPHY || cmd == SIOCGMIIREG || cmd == SIOCSMIIREG || @@ -2462,13 +2464,26 @@ } return ret; + case SIOCETHTOOL: + dev_load(ifr.ifr_name); + rtnl_lock(); + ret = dev_ethtool(&ifr); + rtnl_unlock(); + if (!ret) { + if (colon) + *colon = ':'; + if (copy_to_user(arg, &ifr, + sizeof(struct ifreq))) + ret = -EFAULT; + } + return ret; + /* * These ioctl calls: * - require superuser power. * - require strict serialization. * - return a value */ - case SIOCETHTOOL: case SIOCGMIIPHY: case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) @@ -2706,38 +2721,17 @@ goto out; } -/** - * netdev_finish_unregister - complete unregistration - * @dev: device +/* + * netdev_wait_allrefs - wait until all references are gone. + * + * This is called when unregistering network devices. * - * Destroy and free a dead device. A value of zero is returned on - * success. + * Any protocol or device that holds a reference should register + * for netdevice notification, and cleanup and put back the + * reference if they receive an UNREGISTER event. + * We can get stuck here if buggy protocols don't correctly + * call dev_put. */ -static int netdev_finish_unregister(struct net_device *dev) -{ - BUG_TRAP(!dev->ip_ptr); - BUG_TRAP(!dev->ip6_ptr); - BUG_TRAP(!dev->dn_ptr); - - if (dev->reg_state != NETREG_UNREGISTERED) { - printk(KERN_ERR "Freeing alive device %p, %s\n", - dev, dev->name); - return 0; - } -#ifdef NET_REFCNT_DEBUG - printk(KERN_DEBUG "netdev_finish_unregister: %s%s.\n", dev->name, - (dev->destructor != NULL)?"":", old style"); -#endif - - /* It must be the very last action, after this 'dev' may point - * to freed up memory. - */ - if (dev->destructor) - dev->destructor(dev); - - return 0; -} - static void netdev_wait_allrefs(struct net_device *dev) { unsigned long rebroadcast_time, warning_time; @@ -2833,13 +2827,23 @@ break; case NETREG_UNREGISTERING: - netdev_unregister_sysfs(dev); + class_device_unregister(&dev->class_dev); dev->reg_state = NETREG_UNREGISTERED; netdev_wait_allrefs(dev); + + /* paranoia */ BUG_ON(atomic_read(&dev->refcnt)); - - netdev_finish_unregister(dev); + BUG_TRAP(!dev->ip_ptr); + BUG_TRAP(!dev->ip6_ptr); + BUG_TRAP(!dev->dn_ptr); + + + /* It must be the very last action, + * after this 'dev' may point to freed up memory. + */ + if (dev->destructor) + dev->destructor(dev); break; default: diff -Nru a/net/core/ethtool.c b/net/core/ethtool.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/core/ethtool.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,672 @@ +/* + * net/core/ethtool.c - Ethtool ioctl handler + * Copyright (c) 2003 Matthew Wilcox + * + * This file is where we call all the ethtool_ops commands to get + * the information ethtool needs. We fall back to calling do_ioctl() + * for drivers which haven't been converted to ethtool_ops yet. + * + * It's GPL, stupid. + */ + +#include +#include +#include +#include + +/* + * Some useful ethtool_ops methods that're device independent. + * If we find that all drivers want to do the same thing here, + * we can turn these into dev_() function calls. + */ + +u32 ethtool_op_get_link(struct net_device *dev) +{ + return netif_carrier_ok(dev) ? 1 : 0; +} + +u32 ethtool_op_get_tx_csum(struct net_device *dev) +{ + return (dev->features & NETIF_F_IP_CSUM) != 0; +} + +u32 ethtool_op_get_sg(struct net_device *dev) +{ + return (dev->features & NETIF_F_SG) != 0; +} + +int ethtool_op_set_sg(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= NETIF_F_SG; + else + dev->features &= ~NETIF_F_SG; + + return 0; +} + +/* Handlers for each ethtool command */ + +static int ethtool_get_settings(struct net_device *dev, void *useraddr) +{ + struct ethtool_cmd cmd = { ETHTOOL_GSET }; + int err; + + if (!dev->ethtool_ops->get_settings) + return -EOPNOTSUPP; + + err = dev->ethtool_ops->get_settings(dev, &cmd); + if (err < 0) + return err; + + if (copy_to_user(useraddr, &cmd, sizeof(cmd))) + return -EFAULT; + return 0; +} + +static int ethtool_set_settings(struct net_device *dev, void *useraddr) +{ + struct ethtool_cmd cmd; + + if (!dev->ethtool_ops->set_settings) + return -EOPNOTSUPP; + + if (copy_from_user(&cmd, useraddr, sizeof(cmd))) + return -EFAULT; + + return dev->ethtool_ops->set_settings(dev, &cmd); +} + +static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr) +{ + struct ethtool_drvinfo info; + struct ethtool_ops *ops = dev->ethtool_ops; + + if (!ops->get_drvinfo) + return -EOPNOTSUPP; + + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + ops->get_drvinfo(dev, &info); + + if (ops->self_test_count) + info.testinfo_len = ops->self_test_count(dev); + if (ops->get_stats_count) + info.n_stats = ops->get_stats_count(dev); + if (ops->get_regs_len) + info.regdump_len = ops->get_regs_len(dev); + /* XXX: eeprom? */ + + if (copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static int ethtool_get_regs(struct net_device *dev, char *useraddr) +{ + struct ethtool_regs regs; + struct ethtool_ops *ops = dev->ethtool_ops; + void *regbuf; + int reglen, ret; + + if (!ops->get_regs || !ops->get_regs_len) + return -EOPNOTSUPP; + + if (copy_from_user(®s, useraddr, sizeof(regs))) + return -EFAULT; + + reglen = ops->get_regs_len(dev); + if (regs.len > reglen) + regs.len = reglen; + + regbuf = kmalloc(reglen, GFP_USER); + if (!regbuf) + return -ENOMEM; + + ops->get_regs(dev, ®s, regbuf); + + ret = -EFAULT; + if (copy_to_user(useraddr, ®s, sizeof(regs))) + goto out; + useraddr += offsetof(struct ethtool_regs, data); + if (copy_to_user(useraddr, regbuf, reglen)) + goto out; + ret = 0; + + out: + kfree(regbuf); + return ret; +} + +static int ethtool_get_wol(struct net_device *dev, char *useraddr) +{ + struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; + + if (!dev->ethtool_ops->get_wol) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_wol(dev, &wol); + + if (copy_to_user(useraddr, &wol, sizeof(wol))) + return -EFAULT; + return 0; +} + +static int ethtool_set_wol(struct net_device *dev, char *useraddr) +{ + struct ethtool_wolinfo wol; + + if (!dev->ethtool_ops->set_wol) + return -EOPNOTSUPP; + + if (copy_from_user(&wol, useraddr, sizeof(wol))) + return -EFAULT; + + return dev->ethtool_ops->set_wol(dev, &wol); +} + +static int ethtool_get_msglevel(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + + if (!dev->ethtool_ops->get_msglevel) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_msglevel(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_msglevel(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_msglevel) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + dev->ethtool_ops->set_msglevel(dev, edata.data); + return 0; +} + +static int ethtool_nway_reset(struct net_device *dev) +{ + if (!dev->ethtool_ops->nway_reset) + return -EOPNOTSUPP; + + return dev->ethtool_ops->nway_reset(dev); +} + +static int ethtool_get_link(struct net_device *dev, void *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + + if (!dev->ethtool_ops->get_link) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_link(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_get_eeprom(struct net_device *dev, void *useraddr) +{ + struct ethtool_eeprom eeprom; + u8 *data; + int len, ret; + + if (!dev->ethtool_ops->get_eeprom) + return -EOPNOTSUPP; + + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) + return -EFAULT; + + len = eeprom.len; + /* Check for wrap and zero */ + if (eeprom.offset + len <= eeprom.offset) + return -EINVAL; + + data = kmalloc(len, GFP_USER); + if (!data) + return -ENOMEM; + + if (copy_from_user(data, useraddr + sizeof(eeprom), len)) + return -EFAULT; + + ret = dev->ethtool_ops->get_eeprom(dev, &eeprom, data); + if (!ret) + goto out; + + ret = -EFAULT; + if (copy_to_user(useraddr, &eeprom, sizeof(eeprom))) + goto out; + if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) + goto out; + ret = 0; + + out: + kfree(data); + return ret; +} + +static int ethtool_set_eeprom(struct net_device *dev, void *useraddr) +{ + struct ethtool_eeprom eeprom; + u8 *data; + int len, ret; + + if (!dev->ethtool_ops->set_eeprom) + return -EOPNOTSUPP; + + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) + return -EFAULT; + + len = eeprom.len; + /* Check for wrap and zero */ + if (eeprom.offset + len <= eeprom.offset) + return -EINVAL; + + data = kmalloc(len, GFP_USER); + if (!data) + return -ENOMEM; + + if (copy_from_user(data, useraddr + sizeof(eeprom), len)) + return -EFAULT; + + ret = dev->ethtool_ops->set_eeprom(dev, &eeprom, data); + if (ret) + goto out; + + if (copy_to_user(useraddr + sizeof(eeprom), data, len)) + ret = -EFAULT; + + out: + kfree(data); + return ret; +} + +static int ethtool_get_coalesce(struct net_device *dev, void *useraddr) +{ + struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; + + if (!dev->ethtool_ops->get_coalesce) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_coalesce(dev, &coalesce); + + if (copy_to_user(useraddr, &coalesce, sizeof(coalesce))) + return -EFAULT; + return 0; +} + +static int ethtool_set_coalesce(struct net_device *dev, void *useraddr) +{ + struct ethtool_coalesce coalesce; + + if (!dev->ethtool_ops->get_coalesce) + return -EOPNOTSUPP; + + if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) + return -EFAULT; + + return dev->ethtool_ops->set_coalesce(dev, &coalesce); +} + +static int ethtool_get_ringparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; + + if (!dev->ethtool_ops->get_ringparam) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_ringparam(dev, &ringparam); + + if (copy_to_user(useraddr, &ringparam, sizeof(ringparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_ringparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_ringparam ringparam; + + if (!dev->ethtool_ops->get_ringparam) + return -EOPNOTSUPP; + + if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) + return -EFAULT; + + return dev->ethtool_ops->set_ringparam(dev, &ringparam); +} + +static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; + + if (!dev->ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_pauseparam(dev, &pauseparam); + + if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_pauseparam pauseparam; + + if (!dev->ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) + return -EFAULT; + + return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); +} + +static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GRXCSUM }; + + if (!dev->ethtool_ops->get_rx_csum) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_rx_csum(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_rx_csum) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + dev->ethtool_ops->set_rx_csum(dev, edata.data); + return 0; +} + +static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTXCSUM }; + + if (!dev->ethtool_ops->get_tx_csum) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_tx_csum(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_tx_csum) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_tx_csum(dev, edata.data); +} + +static int ethtool_get_sg(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GSG }; + + if (!dev->ethtool_ops->get_sg) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_sg(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_sg(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_sg) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_sg(dev, edata.data); +} + +static int ethtool_self_test(struct net_device *dev, char *useraddr) +{ + struct ethtool_test test; + struct ethtool_ops *ops = dev->ethtool_ops; + u64 *data; + int ret; + + if (!ops->self_test || !ops->self_test_count) + return -EOPNOTSUPP; + + if (copy_from_user(&test, useraddr, sizeof(test))) + return -EFAULT; + + test.len = ops->self_test_count(dev); + data = kmalloc(test.len * sizeof(u64), GFP_USER); + if (!data) + return -ENOMEM; + + ops->self_test(dev, &test, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &test, sizeof(test))) + goto out; + useraddr += sizeof(test); + if (copy_to_user(useraddr, data, test.len * sizeof(u64))) + goto out; + ret = 0; + + out: + kfree(data); + return ret; +} + +static int ethtool_get_strings(struct net_device *dev, void *useraddr) +{ + struct ethtool_gstrings gstrings; + struct ethtool_ops *ops = dev->ethtool_ops; + u8 *data; + int ret; + + if (!ops->get_strings) + return -EOPNOTSUPP; + + if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) + return -EFAULT; + + switch (gstrings.string_set) { + case ETH_SS_TEST: + if (ops->self_test_count) + gstrings.len = ops->self_test_count(dev); + else + return -EOPNOTSUPP; + case ETH_SS_STATS: + if (ops->get_stats_count) + gstrings.len = ops->get_stats_count(dev); + else + return -EOPNOTSUPP; + default: + return -EINVAL; + } + + data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); + if (!data) + return -ENOMEM; + + ops->get_strings(dev, gstrings.string_set, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) + goto out; + useraddr += sizeof(gstrings); + if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) + goto out; + ret = 0; + + out: + kfree(data); + return ret; +} + +static int ethtool_phys_id(struct net_device *dev, void *useraddr) +{ + struct ethtool_value id; + + if (!dev->ethtool_ops->phys_id) + return -EOPNOTSUPP; + + if (copy_from_user(&id, useraddr, sizeof(id))) + return -EFAULT; + + return dev->ethtool_ops->phys_id(dev, id.data); +} + +static int ethtool_get_stats(struct net_device *dev, void *useraddr) +{ + struct ethtool_stats stats; + struct ethtool_ops *ops = dev->ethtool_ops; + u64 *data; + int ret; + + if (!ops->get_ethtool_stats || !ops->get_stats_count) + return -EOPNOTSUPP; + + if (copy_from_user(&stats, useraddr, sizeof(stats))) + return -EFAULT; + + stats.n_stats = ops->get_stats_count(dev); + data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER); + if (!data) + return -ENOMEM; + + ops->get_ethtool_stats(dev, &stats, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &stats, sizeof(stats))) + goto out; + useraddr += sizeof(stats); + if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) + goto out; + ret = 0; + + out: + kfree(data); + return ret; +} + +/* The main entry point in this file. Called from net/core/dev.c */ + +int dev_ethtool(struct ifreq *ifr) +{ + struct net_device *dev = __dev_get_by_name(ifr->ifr_name); + void *useraddr = (void *) ifr->ifr_data; + u32 ethcmd; + + /* + * XXX: This can be pushed down into the ethtool_* handlers that + * need it. Keep existing behaviour for the moment. + */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!dev || !netif_device_present(dev)) + return -ENODEV; + + if (!dev->ethtool_ops) + goto ioctl; + + if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GSET: + return ethtool_get_settings(dev, useraddr); + case ETHTOOL_SSET: + return ethtool_set_settings(dev, useraddr); + case ETHTOOL_GDRVINFO: + return ethtool_get_drvinfo(dev, useraddr); + case ETHTOOL_GREGS: + return ethtool_get_regs(dev, useraddr); + case ETHTOOL_GWOL: + return ethtool_get_wol(dev, useraddr); + case ETHTOOL_SWOL: + return ethtool_set_wol(dev, useraddr); + case ETHTOOL_GMSGLVL: + return ethtool_get_msglevel(dev, useraddr); + case ETHTOOL_SMSGLVL: + return ethtool_set_msglevel(dev, useraddr); + case ETHTOOL_NWAY_RST: + return ethtool_nway_reset(dev); + case ETHTOOL_GLINK: + return ethtool_get_link(dev, useraddr); + case ETHTOOL_GEEPROM: + return ethtool_get_eeprom(dev, useraddr); + case ETHTOOL_SEEPROM: + return ethtool_set_eeprom(dev, useraddr); + case ETHTOOL_GCOALESCE: + return ethtool_get_coalesce(dev, useraddr); + case ETHTOOL_SCOALESCE: + return ethtool_set_coalesce(dev, useraddr); + case ETHTOOL_GRINGPARAM: + return ethtool_get_ringparam(dev, useraddr); + case ETHTOOL_SRINGPARAM: + return ethtool_set_ringparam(dev, useraddr); + case ETHTOOL_GPAUSEPARAM: + return ethtool_get_pauseparam(dev, useraddr); + case ETHTOOL_SPAUSEPARAM: + return ethtool_set_pauseparam(dev, useraddr); + case ETHTOOL_GRXCSUM: + return ethtool_get_rx_csum(dev, useraddr); + case ETHTOOL_SRXCSUM: + return ethtool_set_rx_csum(dev, useraddr); + case ETHTOOL_GTXCSUM: + return ethtool_get_tx_csum(dev, useraddr); + case ETHTOOL_STXCSUM: + return ethtool_set_tx_csum(dev, useraddr); + case ETHTOOL_GSG: + return ethtool_get_sg(dev, useraddr); + case ETHTOOL_SSG: + return ethtool_set_sg(dev, useraddr); + case ETHTOOL_TEST: + return ethtool_self_test(dev, useraddr); + case ETHTOOL_GSTRINGS: + return ethtool_get_strings(dev, useraddr); + case ETHTOOL_PHYS_ID: + return ethtool_phys_id(dev, useraddr); + case ETHTOOL_GSTATS: + return ethtool_get_stats(dev, useraddr); + default: + return -EOPNOTSUPP; + } + + ioctl: + if (dev->do_ioctl) + return dev->do_ioctl(dev, ifr, SIOCETHTOOL); + return -EOPNOTSUPP; +} diff -Nru a/net/core/net-sysfs.c b/net/core/net-sysfs.c --- a/net/core/net-sysfs.c Mon Aug 18 22:21:05 2003 +++ b/net/core/net-sysfs.c Mon Aug 18 22:21:05 2003 @@ -3,6 +3,10 @@ * * Copyright (c) 2003 Stephen Hemminger * + * 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 @@ -11,10 +15,15 @@ #include #include #include +#include #define to_class_dev(obj) container_of(obj,struct class_device,kobj) #define to_net_dev(class) container_of(class, struct net_device, class_dev) +static const char *fmt_hex = "%#x\n"; +static const char *fmt_dec = "%d\n"; +static const char *fmt_ulong = "%lu\n"; + static inline int dev_isalive(const struct net_device *dev) { return dev->reg_state == NETREG_REGISTERED; @@ -79,11 +88,11 @@ NETDEVICE_SHOW(field, format_string) \ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \ -NETDEVICE_ATTR(addr_len, "%d\n"); -NETDEVICE_ATTR(iflink, "%d\n"); -NETDEVICE_ATTR(ifindex, "%d\n"); -NETDEVICE_ATTR(features, "%#x\n"); -NETDEVICE_ATTR(type, "%d\n"); +NETDEVICE_ATTR(addr_len, fmt_dec); +NETDEVICE_ATTR(iflink, fmt_dec); +NETDEVICE_ATTR(ifindex, fmt_dec); +NETDEVICE_ATTR(features, fmt_hex); +NETDEVICE_ATTR(type, fmt_dec); /* use same locking rules as GIFHWADDR ioctl's */ static ssize_t format_addr(char *buf, const unsigned char *addr, int len) @@ -91,20 +100,22 @@ int i; char *cp = buf; - read_lock(&dev_base_lock); for (i = 0; i < len; i++) cp += sprintf(cp, "%02x%c", addr[i], i == (len - 1) ? '\n' : ':'); - read_unlock(&dev_base_lock); return cp - buf; } static ssize_t show_address(struct class_device *dev, char *buf) { struct net_device *net = to_net_dev(dev); + ssize_t ret = -EINVAL; + + read_lock(&dev_base_lock); if (dev_isalive(net)) - return format_addr(buf, net->dev_addr, net->addr_len); - return -EINVAL; + ret = format_addr(buf, net->dev_addr, net->addr_len); + read_unlock(&dev_base_lock); + return ret; } static ssize_t show_broadcast(struct class_device *dev, char *buf) @@ -119,7 +130,7 @@ static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL); /* read-write attributes */ -NETDEVICE_SHOW(mtu, "%d\n"); +NETDEVICE_SHOW(mtu, fmt_dec); static int change_mtu(struct net_device *net, unsigned long new_mtu) { @@ -133,7 +144,7 @@ static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu); -NETDEVICE_SHOW(flags, "%#x\n"); +NETDEVICE_SHOW(flags, fmt_hex); static int change_flags(struct net_device *net, unsigned long new_flags) { @@ -147,7 +158,7 @@ static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags); -NETDEVICE_SHOW(tx_queue_len, "%lu\n"); +NETDEVICE_SHOW(tx_queue_len, fmt_ulong); static int change_tx_queue_len(struct net_device *net, unsigned long new_len) { @@ -178,107 +189,155 @@ NULL }; -struct netstat_fs_entry { - struct attribute attr; - ssize_t (*show)(const struct net_device_stats *, char *); - ssize_t (*store)(struct net_device_stats *, const char *, size_t); -}; - -static ssize_t net_device_stat_show(unsigned long var, char *buf) +/* Show a given an attribute in the statistics group */ +static ssize_t netstat_show(const struct class_device *cd, char *buf, + unsigned long offset) { - return sprintf(buf, "%lu\n", var); + struct net_device *dev = to_net_dev(cd); + struct net_device_stats *stats; + ssize_t ret = -EINVAL; + + if (offset > sizeof(struct net_device_stats) || + offset % sizeof(unsigned long) != 0) + WARN_ON(1); + + read_lock(&dev_base_lock); + if (dev_isalive(dev) && dev->get_stats && + (stats = (*dev->get_stats)(dev))) + ret = sprintf(buf, fmt_ulong, + *(unsigned long *)(((u8 *) stats) + offset)); + + read_unlock(&dev_base_lock); + return ret; } /* generate a read-only statistics attribute */ -#define NETDEVICE_STAT(_NAME) \ -static ssize_t show_stat_##_NAME(const struct net_device_stats *stats, \ - char *buf) \ +#define NETSTAT_ENTRY(name) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return net_device_stat_show(stats->_NAME, buf); \ + return netstat_show(cd, buf, \ + offsetof(struct net_device_stats, name)); \ } \ -static struct netstat_fs_entry net_stat_##_NAME = { \ - .attr = {.name = __stringify(_NAME), .mode = S_IRUGO }, \ - .show = show_stat_##_NAME, \ -} - -NETDEVICE_STAT(rx_packets); -NETDEVICE_STAT(tx_packets); -NETDEVICE_STAT(rx_bytes); -NETDEVICE_STAT(tx_bytes); -NETDEVICE_STAT(rx_errors); -NETDEVICE_STAT(tx_errors); -NETDEVICE_STAT(rx_dropped); -NETDEVICE_STAT(tx_dropped); -NETDEVICE_STAT(multicast); -NETDEVICE_STAT(collisions); -NETDEVICE_STAT(rx_length_errors); -NETDEVICE_STAT(rx_over_errors); -NETDEVICE_STAT(rx_crc_errors); -NETDEVICE_STAT(rx_frame_errors); -NETDEVICE_STAT(rx_fifo_errors); -NETDEVICE_STAT(rx_missed_errors); -NETDEVICE_STAT(tx_aborted_errors); -NETDEVICE_STAT(tx_carrier_errors); -NETDEVICE_STAT(tx_fifo_errors); -NETDEVICE_STAT(tx_heartbeat_errors); -NETDEVICE_STAT(tx_window_errors); -NETDEVICE_STAT(rx_compressed); -NETDEVICE_STAT(tx_compressed); - -static struct attribute *default_attrs[] = { - &net_stat_rx_packets.attr, - &net_stat_tx_packets.attr, - &net_stat_rx_bytes.attr, - &net_stat_tx_bytes.attr, - &net_stat_rx_errors.attr, - &net_stat_tx_errors.attr, - &net_stat_rx_dropped.attr, - &net_stat_tx_dropped.attr, - &net_stat_multicast.attr, - &net_stat_collisions.attr, - &net_stat_rx_length_errors.attr, - &net_stat_rx_over_errors.attr, - &net_stat_rx_crc_errors.attr, - &net_stat_rx_frame_errors.attr, - &net_stat_rx_fifo_errors.attr, - &net_stat_rx_missed_errors.attr, - &net_stat_tx_aborted_errors.attr, - &net_stat_tx_carrier_errors.attr, - &net_stat_tx_fifo_errors.attr, - &net_stat_tx_heartbeat_errors.attr, - &net_stat_tx_window_errors.attr, - &net_stat_rx_compressed.attr, - &net_stat_tx_compressed.attr, +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) + +NETSTAT_ENTRY(rx_packets); +NETSTAT_ENTRY(tx_packets); +NETSTAT_ENTRY(rx_bytes); +NETSTAT_ENTRY(tx_bytes); +NETSTAT_ENTRY(rx_errors); +NETSTAT_ENTRY(tx_errors); +NETSTAT_ENTRY(rx_dropped); +NETSTAT_ENTRY(tx_dropped); +NETSTAT_ENTRY(multicast); +NETSTAT_ENTRY(collisions); +NETSTAT_ENTRY(rx_length_errors); +NETSTAT_ENTRY(rx_over_errors); +NETSTAT_ENTRY(rx_crc_errors); +NETSTAT_ENTRY(rx_frame_errors); +NETSTAT_ENTRY(rx_fifo_errors); +NETSTAT_ENTRY(rx_missed_errors); +NETSTAT_ENTRY(tx_aborted_errors); +NETSTAT_ENTRY(tx_carrier_errors); +NETSTAT_ENTRY(tx_fifo_errors); +NETSTAT_ENTRY(tx_heartbeat_errors); +NETSTAT_ENTRY(tx_window_errors); +NETSTAT_ENTRY(rx_compressed); +NETSTAT_ENTRY(tx_compressed); + +static struct attribute *netstat_attrs[] = { + &class_device_attr_rx_packets.attr, + &class_device_attr_tx_packets.attr, + &class_device_attr_rx_bytes.attr, + &class_device_attr_tx_bytes.attr, + &class_device_attr_rx_errors.attr, + &class_device_attr_tx_errors.attr, + &class_device_attr_rx_dropped.attr, + &class_device_attr_tx_dropped.attr, + &class_device_attr_multicast.attr, + &class_device_attr_collisions.attr, + &class_device_attr_rx_length_errors.attr, + &class_device_attr_rx_over_errors.attr, + &class_device_attr_rx_crc_errors.attr, + &class_device_attr_rx_frame_errors.attr, + &class_device_attr_rx_fifo_errors.attr, + &class_device_attr_rx_missed_errors.attr, + &class_device_attr_tx_aborted_errors.attr, + &class_device_attr_tx_carrier_errors.attr, + &class_device_attr_tx_fifo_errors.attr, + &class_device_attr_tx_heartbeat_errors.attr, + &class_device_attr_tx_window_errors.attr, + &class_device_attr_rx_compressed.attr, + &class_device_attr_tx_compressed.attr, NULL }; -static ssize_t -netstat_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +static struct attribute_group netstat_group = { + .name = "statistics", + .attrs = netstat_attrs, +}; + +#ifdef WIRELESS_EXT +/* helper function that does all the locking etc for wireless stats */ +static ssize_t wireless_show(struct class_device *cd, char *buf, + ssize_t (*format)(const struct iw_statistics *, + char *)) { - struct netstat_fs_entry *entry - = container_of(attr, struct netstat_fs_entry, attr); - struct net_device *dev - = to_net_dev(to_class_dev(kobj->parent)); - struct net_device_stats *stats; + struct net_device *dev = to_net_dev(cd); + const struct iw_statistics *iw; ssize_t ret = -EINVAL; read_lock(&dev_base_lock); - if (dev_isalive(dev) && entry->show && dev->get_stats && - (stats = (*dev->get_stats)(dev))) - ret = entry->show(stats, buf); + if (dev_isalive(dev) && dev->get_wireless_stats + && (iw = dev->get_wireless_stats(dev)) != NULL) + ret = (*format)(iw, buf); read_unlock(&dev_base_lock); + return ret; } -static struct sysfs_ops netstat_sysfs_ops = { - .show = netstat_attr_show, +/* show function template for wireless fields */ +#define WIRELESS_SHOW(name, field, format_string) \ +static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \ +{ \ + return sprintf(buf, format_string, iw->field); \ +} \ +static ssize_t show_iw_##name(struct class_device *cd, char *buf) \ +{ \ + return wireless_show(cd, buf, format_iw_##name); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL) + +WIRELESS_SHOW(status, status, fmt_hex); +WIRELESS_SHOW(link, qual.qual, fmt_dec); +WIRELESS_SHOW(level, qual.level, fmt_dec); +WIRELESS_SHOW(noise, qual.noise, fmt_dec); +WIRELESS_SHOW(nwid, discard.nwid, fmt_dec); +WIRELESS_SHOW(crypt, discard.code, fmt_dec); +WIRELESS_SHOW(fragment, discard.fragment, fmt_dec); +WIRELESS_SHOW(misc, discard.misc, fmt_dec); +WIRELESS_SHOW(retries, discard.retries, fmt_dec); +WIRELESS_SHOW(beacon, miss.beacon, fmt_dec); + +static struct attribute *wireless_attrs[] = { + &class_device_attr_status.attr, + &class_device_attr_link.attr, + &class_device_attr_level.attr, + &class_device_attr_noise.attr, + &class_device_attr_nwid.attr, + &class_device_attr_crypt.attr, + &class_device_attr_fragment.attr, + &class_device_attr_retries.attr, + &class_device_attr_misc.attr, + &class_device_attr_beacon.attr, + NULL }; -static struct kobj_type netstat_ktype = { - .sysfs_ops = &netstat_sysfs_ops, - .default_attrs = default_attrs, +static struct attribute_group wireless_group = { + .name = "wireless", + .attrs = wireless_attrs, }; +#endif #ifdef CONFIG_HOTPLUG static int netdev_hotplug(struct class_device *cd, char **envp, @@ -329,33 +388,24 @@ goto out_unreg; } - net->stats_kobj.parent = NULL; - if (net->get_stats) { - struct kobject *k = &net->stats_kobj; - - k->parent = &class_dev->kobj; - strlcpy(k->name, "statistics", KOBJ_NAME_LEN); - k->ktype = &netstat_ktype; - if((ret = kobject_register(k))) - goto out_unreg; - } + if (net->get_stats && + (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) + goto out_unreg; + +#ifdef WIRELESS_EXT + if (net->get_wireless_stats && + (ret = sysfs_create_group(&class_dev->kobj, &wireless_group))) + goto out_unreg; +#endif + return 0; -out: - return ret; out_unreg: printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n", net->name, ret); class_device_unregister(class_dev); - goto out; -} - -void netdev_unregister_sysfs(struct net_device *net) -{ - if (net->stats_kobj.parent) - kobject_unregister(&net->stats_kobj); - - class_device_unregister(&net->class_dev); +out: + return ret; } int netdev_sysfs_init(void) diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c --- a/net/core/skbuff.c Mon Aug 18 22:21:04 2003 +++ b/net/core/skbuff.c Mon Aug 18 22:21:04 2003 @@ -225,7 +225,7 @@ } dst_release(skb->dst); -#ifdef CONFIG_INET +#ifdef CONFIG_XFRM secpath_put(skb->sp); #endif if(skb->destructor) { diff -Nru a/net/ipv4/Kconfig b/net/ipv4/Kconfig --- a/net/ipv4/Kconfig Mon Aug 18 22:21:05 2003 +++ b/net/ipv4/Kconfig Mon Aug 18 22:21:05 2003 @@ -187,6 +187,7 @@ config NET_IPIP tristate "IP: tunneling" depends on INET + select XFRM ---help--- Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the @@ -205,6 +206,7 @@ config NET_IPGRE tristate "IP: GRE tunnels over IP" depends on INET + select XFRM help Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the @@ -343,6 +345,7 @@ config INET_AH tristate "IP: AH transformation" + select XFRM select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -354,6 +357,7 @@ config INET_ESP tristate "IP: ESP transformation" + select XFRM select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -366,6 +370,7 @@ config INET_IPCOMP tristate "IP: IPComp transformation" + select XFRM select CRYPTO select CRYPTO_DEFLATE ---help--- diff -Nru a/net/ipv4/Makefile b/net/ipv4/Makefile --- a/net/ipv4/Makefile Mon Aug 18 22:21:02 2003 +++ b/net/ipv4/Makefile Mon Aug 18 22:21:02 2003 @@ -23,4 +23,4 @@ obj-$(CONFIG_NETFILTER) += netfilter/ obj-$(CONFIG_IP_VS) += ipvs/ -obj-y += xfrm4_policy.o xfrm4_state.o xfrm4_input.o xfrm4_tunnel.o +obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o xfrm4_tunnel.o diff -Nru a/net/ipv4/ah4.c b/net/ipv4/ah4.c --- a/net/ipv4/ah4.c Mon Aug 18 22:21:05 2003 +++ b/net/ipv4/ah4.c Mon Aug 18 22:21:05 2003 @@ -308,6 +308,9 @@ { struct ah_data *ahp = x->data; + if (!ahp) + return; + if (ahp->work_icv) { kfree(ahp->work_icv); ahp->work_icv = NULL; diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c --- a/net/ipv4/devinet.c Mon Aug 18 22:21:02 2003 +++ b/net/ipv4/devinet.c Mon Aug 18 22:21:02 2003 @@ -922,6 +922,7 @@ unsigned char *b = skb->tail; nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); + if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; ifm = NLMSG_DATA(nlh); ifm->ifa_family = AF_INET; ifm->ifa_prefixlen = ifa->ifa_prefixlen; diff -Nru a/net/ipv4/esp4.c b/net/ipv4/esp4.c --- a/net/ipv4/esp4.c Mon Aug 18 22:21:04 2003 +++ b/net/ipv4/esp4.c Mon Aug 18 22:21:04 2003 @@ -437,6 +437,9 @@ { struct esp_data *esp = x->data; + if (!esp) + return; + if (esp->conf.tfm) { crypto_free_tfm(esp->conf.tfm); esp->conf.tfm = NULL; @@ -505,7 +508,10 @@ } esp->conf.key = x->ealg->alg_key; esp->conf.key_len = (x->ealg->alg_key_len+7)/8; - esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC); + if (x->props.ealgo == SADB_EALG_NULL) + esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); + else + esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC); if (esp->conf.tfm == NULL) goto error; esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); diff -Nru a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c --- a/net/ipv4/ipcomp.c Mon Aug 18 22:21:05 2003 +++ b/net/ipv4/ipcomp.c Mon Aug 18 22:21:05 2003 @@ -279,6 +279,7 @@ t->props.family = AF_INET; t->props.mode = 1; t->props.saddr.a4 = x->props.saddr.a4; + t->props.flags = x->props.flags; t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); if (t->type == NULL) @@ -335,6 +336,8 @@ static void ipcomp_destroy(struct xfrm_state *x) { struct ipcomp_data *ipcd = x->data; + if (!ipcd) + return; ipcomp_free_data(ipcd); kfree(ipcd); } @@ -353,7 +356,6 @@ x->props.header_len = sizeof(struct ip_comp_hdr); if (x->props.mode) x->props.header_len += sizeof(struct iphdr); - x->data = ipcd; ipcd->scratch = kmalloc(IPCOMP_SCRATCH_SIZE, GFP_KERNEL); if (!ipcd->scratch) @@ -372,6 +374,7 @@ calg_desc = xfrm_calg_get_byname(x->calg->alg_name); BUG_ON(!calg_desc); ipcd->threshold = calg_desc->uinfo.comp.threshold; + x->data = ipcd; err = 0; out: return err; diff -Nru a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c --- a/net/ipv4/ipconfig.c Mon Aug 18 22:21:01 2003 +++ b/net/ipv4/ipconfig.c Mon Aug 18 22:21:01 2003 @@ -125,14 +125,14 @@ int ic_host_name_set __initdata = 0; /* Host name set by us? */ -u32 ic_myaddr __initdata = INADDR_NONE; /* My IP address */ -u32 ic_netmask __initdata = INADDR_NONE; /* Netmask for local subnet */ -u32 ic_gateway __initdata = INADDR_NONE; /* Gateway IP address */ +u32 ic_myaddr = INADDR_NONE; /* My IP address */ +u32 ic_netmask = INADDR_NONE; /* Netmask for local subnet */ +u32 ic_gateway = INADDR_NONE; /* Gateway IP address */ -u32 ic_servaddr __initdata = INADDR_NONE; /* Boot server IP address */ +u32 ic_servaddr = INADDR_NONE; /* Boot server IP address */ -u32 root_server_addr __initdata = INADDR_NONE; /* Address of NFS server */ -u8 root_server_path[256] __initdata = { 0, }; /* Path to mount as root */ +u32 root_server_addr = INADDR_NONE; /* Address of NFS server */ +u8 root_server_path[256] = { 0, }; /* Path to mount as root */ /* Persistent data: */ diff -Nru a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig --- a/net/ipv4/ipvs/Kconfig Mon Aug 18 22:21:02 2003 +++ b/net/ipv4/ipvs/Kconfig Mon Aug 18 22:21:02 2003 @@ -241,7 +241,7 @@ config IP_VS_FTP tristate "FTP protocol helper" - depends on IP_VS + depends on IP_VS && IP_VS_PROTO_TCP ---help--- FTP is a protocol that transfers IP address and/or port number in the payload. In the virtual server via Network Address Translation, diff -Nru a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c --- a/net/ipv4/ipvs/ip_vs_core.c Mon Aug 18 22:21:00 2003 +++ b/net/ipv4/ipvs/ip_vs_core.c Mon Aug 18 22:21:00 2003 @@ -53,7 +53,9 @@ EXPORT_SYMBOL(ip_vs_conn_new); EXPORT_SYMBOL(ip_vs_conn_in_get); EXPORT_SYMBOL(ip_vs_conn_out_get); +#ifdef CONFIG_IP_VS_PROTO_TCP EXPORT_SYMBOL(ip_vs_tcp_conn_listen); +#endif EXPORT_SYMBOL(ip_vs_conn_put); #ifdef CONFIG_IP_VS_DEBUG EXPORT_SYMBOL(ip_vs_get_debug_level); diff -Nru a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c --- a/net/ipv4/ipvs/ip_vs_sched.c Mon Aug 18 22:21:00 2003 +++ b/net/ipv4/ipvs/ip_vs_sched.c Mon Aug 18 22:21:00 2003 @@ -157,9 +157,7 @@ * If scheduler not found, load the module and search again */ if (sched == NULL) { - char module_name[IP_VS_SCHEDNAME_MAXLEN+8]; - sprintf(module_name,"ip_vs_%s", sched_name); - request_module(module_name); + request_module("ip_vs_%s", sched_name); sched = ip_vs_sched_getbyname(sched_name); } diff -Nru a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c --- a/net/ipv4/netfilter/ipt_MASQUERADE.c Mon Aug 18 22:21:04 2003 +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c Mon Aug 18 22:21:04 2003 @@ -91,11 +91,18 @@ #ifdef CONFIG_IP_ROUTE_FWMARK .fwmark = (*pskb)->nfmark #endif - } }, - .oif = out->ifindex }; + } } }; if (ip_route_output_key(&rt, &fl) != 0) { - /* Shouldn't happen */ - printk("MASQUERADE: No route: Rusty's brain broke!\n"); + /* Funky routing can do this. */ + if (net_ratelimit()) + printk("MASQUERADE:" + " No route: Rusty's brain broke!\n"); + return NF_DROP; + } + if (rt->u.dst.dev != out) { + if (net_ratelimit()) + printk("MASQUERADE:" + " Route sent us somewhere else.\n"); return NF_DROP; } } diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c --- a/net/ipv4/route.c Mon Aug 18 22:21:06 2003 +++ b/net/ipv4/route.c Mon Aug 18 22:21:06 2003 @@ -463,7 +463,9 @@ */ static inline u32 rt_score(struct rtable *rt) { - u32 score = rt->u.dst.__use; + u32 score = jiffies - rt->u.dst.lastuse; + + score = ~score & ~(3<<30); if (rt_valuable(rt)) score |= (1<<31); @@ -805,8 +807,7 @@ * The second limit is less certain. At the moment it allows * only 2 entries per bucket. We will see. */ - if (chain_length > ip_rt_gc_elasticity || - (chain_length > 1 && !(min_score & (1<<31)))) { + if (chain_length > ip_rt_gc_elasticity) { *candp = cand->u.rt_next; rt_free(cand); } @@ -2785,8 +2786,10 @@ create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL); #endif #endif +#ifdef CONFIG_XFRM xfrm_init(); xfrm4_init(); +#endif out: return rc; out_enomem: diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c --- a/net/ipv4/sysctl_net_ipv4.c Mon Aug 18 22:21:04 2003 +++ b/net/ipv4/sysctl_net_ipv4.c Mon Aug 18 22:21:04 2003 @@ -109,6 +109,7 @@ } } + *valp = new; inet_forward_change(); return 1; } diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c --- a/net/ipv4/tcp_ipv4.c Mon Aug 18 22:21:02 2003 +++ b/net/ipv4/tcp_ipv4.c Mon Aug 18 22:21:02 2003 @@ -1884,6 +1884,7 @@ __sk_dst_set(sk, &rt->u.dst); tcp_v4_setup_caps(sk, &rt->u.dst); + tcp_sk(sk)->ext2_header_len = rt->u.dst.header_len; new_saddr = rt->rt_src; @@ -1943,6 +1944,7 @@ if (!err) { __sk_dst_set(sk, &rt->u.dst); tcp_v4_setup_caps(sk, &rt->u.dst); + tcp_sk(sk)->ext2_header_len = rt->u.dst.header_len; return 0; } diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c --- a/net/ipv4/udp.c Mon Aug 18 22:21:01 2003 +++ b/net/ipv4/udp.c Mon Aug 18 22:21:01 2003 @@ -938,6 +938,9 @@ */ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) { +#ifndef CONFIG_XFRM + return 1; +#else struct udp_opt *up = udp_sk(sk); struct udphdr *uh = skb->h.uh; struct iphdr *iph; @@ -997,10 +1000,12 @@ return -1; default: - printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n", - encap_type); + if (net_ratelimit()) + printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n", + encap_type); return 1; } +#endif } /* returns: diff -Nru a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c --- a/net/ipv4/xfrm4_input.c Mon Aug 18 22:21:01 2003 +++ b/net/ipv4/xfrm4_input.c Mon Aug 18 22:21:01 2003 @@ -27,6 +27,20 @@ IP_ECN_set_ce(inner_iph); } +static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) +{ + switch (nexthdr) { + case IPPROTO_IPIP: + if (!pskb_may_pull(skb, sizeof(struct iphdr))) + return -EINVAL; + *spi = skb->nh.iph->saddr; + *seq = 0; + return 0; + } + + return xfrm_parse_spi(skb, nexthdr, spi, seq); +} + int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) { int err; @@ -36,7 +50,7 @@ int xfrm_nr = 0; int decaps = 0; - if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0) + if ((err = xfrm4_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0) goto drop; do { diff -Nru a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c --- a/net/ipv4/xfrm4_tunnel.c Mon Aug 18 22:21:01 2003 +++ b/net/ipv4/xfrm4_tunnel.c Mon Aug 18 22:21:01 2003 @@ -83,31 +83,8 @@ return err; } -static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb) -{ - struct iphdr *inner_iph = skb->nh.iph; - - if (INET_ECN_is_ce(outer_iph->tos) && - INET_ECN_is_not_ce(inner_iph->tos)) - IP_ECN_set_ce(inner_iph); -} - static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { - struct iphdr *outer_iph = skb->nh.iph; - - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - return -EINVAL; - skb->mac.raw = skb->nh.raw; - skb->nh.raw = skb->data; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); - dst_release(skb->dst); - skb->dst = NULL; - skb->protocol = htons(ETH_P_IP); - skb->pkt_type = PACKET_HOST; - ipip_ecn_decapsulate(outer_iph, skb); - netif_rx(skb); - return 0; } @@ -149,46 +126,12 @@ static int ipip_rcv(struct sk_buff *skb) { struct xfrm_tunnel *handler = ipip_handler; - struct xfrm_state *x = NULL; - int err; /* Tunnel devices take precedence. */ - if (handler) { - err = handler->handler(skb); - if (!err) - goto out; - } - - x = xfrm_state_lookup((xfrm_address_t *)&skb->nh.iph->daddr, - skb->nh.iph->saddr, - IPPROTO_IPIP, AF_INET); - - if (!x) - goto drop; - - spin_lock(&x->lock); - - if (unlikely(x->km.state != XFRM_STATE_VALID)) - goto drop_unlock; - - err = ipip_xfrm_rcv(x, NULL, skb); - if (err) - goto drop_unlock; - - x->curlft.bytes += skb->len; - x->curlft.packets++; - spin_unlock(&x->lock); - xfrm_state_put(x); -out: - return err; - -drop_unlock: - spin_unlock(&x->lock); - xfrm_state_put(x); -drop: - err = NET_RX_DROP; - kfree_skb(skb); - goto out; + if (handler && handler->handler(skb) == 0) + return 0; + + return xfrm4_rcv_encap(skb, 0); } static void ipip_err(struct sk_buff *skb, u32 info) diff -Nru a/net/ipv6/Kconfig b/net/ipv6/Kconfig --- a/net/ipv6/Kconfig Mon Aug 18 22:21:03 2003 +++ b/net/ipv6/Kconfig Mon Aug 18 22:21:03 2003 @@ -22,6 +22,7 @@ config INET6_AH tristate "IPv6: AH transformation" depends on IPV6 + select XFRM select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -34,6 +35,7 @@ config INET6_ESP tristate "IPv6: ESP transformation" depends on IPV6 + select XFRM select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -47,6 +49,7 @@ config INET6_IPCOMP tristate "IPv6: IPComp transformation" depends on IPV6 + select XFRM select CRYPTO select CRYPTO_DEFLATE ---help--- diff -Nru a/net/ipv6/Makefile b/net/ipv6/Makefile --- a/net/ipv6/Makefile Mon Aug 18 22:21:05 2003 +++ b/net/ipv6/Makefile Mon Aug 18 22:21:05 2003 @@ -8,8 +8,10 @@ route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ - ip6_flowlabel.o ipv6_syms.o \ - xfrm6_policy.o xfrm6_state.o xfrm6_input.o + ip6_flowlabel.o ipv6_syms.o + +ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o +ipv6-objs += $(ipv6-y) obj-$(CONFIG_INET6_AH) += ah6.o obj-$(CONFIG_INET6_ESP) += esp6.o diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c Mon Aug 18 22:21:06 2003 +++ b/net/ipv6/addrconf.c Mon Aug 18 22:21:06 2003 @@ -1110,10 +1110,10 @@ struct scatterlist sg[2]; sg[0].page = virt_to_page(idev->entropy); - sg[0].offset = ((long) idev->entropy & ~PAGE_MASK); + sg[0].offset = offset_in_page(idev->entropy); sg[0].length = 8; sg[1].page = virt_to_page(eui64); - sg[1].offset = ((long) eui64 & ~PAGE_MASK); + sg[1].offset = offset_in_page(eui64); sg[1].length = 8; dev = idev->dev; @@ -2443,6 +2443,7 @@ unsigned char *b = skb->tail; nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); + if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; ifm = NLMSG_DATA(nlh); ifm->ifa_family = AF_INET6; ifm->ifa_prefixlen = ifa->prefix_len; @@ -2593,6 +2594,53 @@ return ret; } +static int addrconf_sysctl_forward_strategy(ctl_table *table, + int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context) +{ + int *valp = table->data; + int new; + + if (!newval || !newlen) + return 0; + if (newlen != sizeof(int)) + return -EINVAL; + if (get_user(new, (int *)newval)) + return -EFAULT; + if (new == *valp) + return 0; + if (oldval && oldlenp) { + size_t len; + if (get_user(len, oldlenp)) + return -EFAULT; + if (len) { + if (len > table->maxlen) + len = table->maxlen; + if (copy_to_user(oldval, valp, len)) + return -EFAULT; + if (put_user(len, oldlenp)) + return -EFAULT; + } + } + + if (valp != &ipv6_devconf_dflt.forwarding) { + struct inet6_dev *idev; + if (valp != &ipv6_devconf.forwarding) { + idev = (struct inet6_dev *)table->extra1; + if (unlikely(idev == NULL)) + return -ENODEV; + } else + idev = NULL; + *valp = new; + addrconf_forward_change(idev); + } else + *valp = new; + + return 1; +} + static struct addrconf_sysctl_table { struct ctl_table_header *sysctl_header; @@ -2611,6 +2659,7 @@ .maxlen = sizeof(int), .mode = 0644, .proc_handler = &addrconf_sysctl_forward, + .strategy = &addrconf_sysctl_forward_strategy, }, { .ctl_name = NET_IPV6_HOP_LIMIT, diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c --- a/net/ipv6/ah6.c Mon Aug 18 22:21:04 2003 +++ b/net/ipv6/ah6.c Mon Aug 18 22:21:04 2003 @@ -265,13 +265,12 @@ * There is offset of AH before IPv6 header after the process. */ - struct ipv6hdr *iph = skb->nh.ipv6h; struct ipv6_auth_hdr *ah; struct ah_data *ahp; unsigned char *tmp_hdr = NULL; - u16 hdr_len = skb->data - skb->nh.raw; + u16 hdr_len; u16 ah_hlen; - u16 cleared_hlen = hdr_len; + u16 cleared_hlen; u16 nh_offset = 0; u8 nexthdr = 0; u8 *prevhdr; @@ -279,6 +278,14 @@ if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) goto out; + /* We are going to _remove_ AH header to keep sockets happy, + * so... Later this can change. */ + if (skb_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto out; + + hdr_len = skb->data - skb->nh.raw; + cleared_hlen = hdr_len; ah = (struct ipv6_auth_hdr*)skb->data; ahp = x->data; nexthdr = ah->nexthdr; @@ -297,27 +304,22 @@ if (!pskb_may_pull(skb, ah_hlen)) goto out; - /* We are going to _remove_ AH header to keep sockets happy, - * so... Later this can change. */ - if (skb_cloned(skb) && - pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) - goto out; - tmp_hdr = kmalloc(cleared_hlen, GFP_ATOMIC); if (!tmp_hdr) goto out; memcpy(tmp_hdr, skb->nh.raw, cleared_hlen); ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN); - iph->priority = 0; - iph->flow_lbl[0] = 0; - iph->flow_lbl[1] = 0; - iph->flow_lbl[2] = 0; - iph->hop_limit = 0; + skb->nh.ipv6h->priority = 0; + skb->nh.ipv6h->flow_lbl[0] = 0; + skb->nh.ipv6h->flow_lbl[1] = 0; + skb->nh.ipv6h->flow_lbl[2] = 0; + skb->nh.ipv6h->hop_limit = 0; { u8 auth_data[ahp->icv_trunc_len]; memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); + memset(ah->auth_data, 0, ahp->icv_trunc_len); skb_push(skb, skb->data - skb->nh.raw); ahp->icv(ahp, skb, ah->auth_data); if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { @@ -441,6 +443,9 @@ static void ah6_destroy(struct xfrm_state *x) { struct ah_data *ahp = x->data; + + if (!ahp) + return; if (ahp->work_icv) { kfree(ahp->work_icv); diff -Nru a/net/ipv6/esp6.c b/net/ipv6/esp6.c --- a/net/ipv6/esp6.c Mon Aug 18 22:21:04 2003 +++ b/net/ipv6/esp6.c Mon Aug 18 22:21:04 2003 @@ -342,6 +342,9 @@ { struct esp_data *esp = x->data; + if (!esp) + return; + if (esp->conf.tfm) { crypto_free_tfm(esp->conf.tfm); esp->conf.tfm = NULL; @@ -409,7 +412,10 @@ } esp->conf.key = x->ealg->alg_key; esp->conf.key_len = (x->ealg->alg_key_len+7)/8; - esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC); + if (x->props.ealgo == SADB_EALG_NULL) + esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); + else + esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC); if (esp->conf.tfm == NULL) goto error; esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c --- a/net/ipv6/icmp.c Mon Aug 18 22:21:02 2003 +++ b/net/ipv6/icmp.c Mon Aug 18 22:21:02 2003 @@ -356,7 +356,8 @@ fl.oif = np->mcast_oif; err = ip6_dst_lookup(sk, &dst, &fl); - if (err) goto out; + if (err) + goto out; if (hlimit < 0) { if (ipv6_addr_is_multicast(&fl.fl6_dst)) @@ -375,7 +376,7 @@ if (net_ratelimit()) printk(KERN_DEBUG "icmp: len problem\n"); __skb_push(skb, plen); - goto out; + goto out_dst_release; } idev = in6_dev_get(skb->dev); @@ -396,6 +397,8 @@ out_put: if (likely(idev != NULL)) in6_dev_put(idev); +out_dst_release: + dst_release(dst); out: icmpv6_xmit_unlock(); } @@ -435,8 +438,8 @@ fl.oif = np->mcast_oif; err = ip6_dst_lookup(sk, &dst, &fl); - - if (err) goto out; + if (err) + goto out; if (hlimit < 0) { if (ipv6_addr_is_multicast(&fl.fl6_dst)) @@ -465,6 +468,7 @@ out_put: if (likely(idev != NULL)) in6_dev_put(idev); + dst_release(dst); out: icmpv6_xmit_unlock(); } diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c --- a/net/ipv6/ip6_output.c Mon Aug 18 22:21:01 2003 +++ b/net/ipv6/ip6_output.c Mon Aug 18 22:21:01 2003 @@ -209,11 +209,6 @@ int seg_len = skb->len; int hlimit; u32 mtu; - int err = 0; - - if ((err = xfrm_lookup(&skb->dst, fl, sk, 0)) < 0) { - return err; - } if (opt) { int head_room; @@ -1143,70 +1138,72 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) { - struct ipv6_pinfo *np = inet6_sk(sk); int err = 0; - *dst = __sk_dst_check(sk, np->dst_cookie); - if (*dst) { - struct rt6_info *rt = (struct rt6_info*)*dst; - - /* Yes, checking route validity in not connected - case is not very simple. Take into account, - that we do not support routing by source, TOS, - and MSG_DONTROUTE --ANK (980726) - - 1. If route was host route, check that - cached destination is current. - If it is network route, we still may - check its validity using saved pointer - to the last used address: daddr_cache. - We do not want to save whole address now, - (because main consumer of this service - is tcp, which has not this problem), - so that the last trick works only on connected - sockets. - 2. oif also should be the same. - */ - - if (((rt->rt6i_dst.plen != 128 || - ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr)) - && (np->daddr_cache == NULL || - ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache))) - || (fl->oif && fl->oif != (*dst)->dev->ifindex)) { - *dst = NULL; - } else - dst_hold(*dst); + if (sk) { + struct ipv6_pinfo *np = inet6_sk(sk); + + *dst = __sk_dst_check(sk, np->dst_cookie); + if (*dst) { + struct rt6_info *rt = (struct rt6_info*)*dst; + + /* Yes, checking route validity in not connected + case is not very simple. Take into account, + that we do not support routing by source, TOS, + and MSG_DONTROUTE --ANK (980726) + + 1. If route was host route, check that + cached destination is current. + If it is network route, we still may + check its validity using saved pointer + to the last used address: daddr_cache. + We do not want to save whole address now, + (because main consumer of this service + is tcp, which has not this problem), + so that the last trick works only on connected + sockets. + 2. oif also should be the same. + */ + + if (((rt->rt6i_dst.plen != 128 || + ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr)) + && (np->daddr_cache == NULL || + ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache))) + || (fl->oif && fl->oif != (*dst)->dev->ifindex)) { + *dst = NULL; + } else + dst_hold(*dst); + } } if (*dst == NULL) *dst = ip6_route_output(sk, fl); - if ((*dst)->error) { - IP6_INC_STATS(Ip6OutNoRoutes); - dst_release(*dst); - return -ENETUNREACH; - } + if ((err = (*dst)->error)) + goto out_err_release; if (ipv6_addr_any(&fl->fl6_src)) { err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); if (err) { #if IP6_DEBUG >= 2 - printk(KERN_DEBUG "ip6_build_xmit: " + printk(KERN_DEBUG "ip6_dst_lookup: " "no available source address\n"); #endif - return err; + goto out_err_release; } } - - if (*dst) { - if ((err = xfrm_lookup(dst, fl, sk, 0)) < 0) { - dst_release(*dst); - return -ENETUNREACH; - } + if ((err = xfrm_lookup(dst, fl, sk, 0)) < 0) { + err = -ENETUNREACH; + goto out_err_release; } return 0; + +out_err_release: + dst_release(*dst); + *dst = NULL; + return err; } int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), @@ -1487,6 +1484,7 @@ np->cork.opt = NULL; } if (np->cork.rt) { + dst_release(&np->cork.rt->u.dst); np->cork.rt = NULL; } if (np->cork.fl) { @@ -1513,6 +1511,7 @@ np->cork.opt = NULL; } if (np->cork.rt) { + dst_release(&np->cork.rt->u.dst); np->cork.rt = NULL; } if (np->cork.fl) { diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c --- a/net/ipv6/ip6_tunnel.c Mon Aug 18 22:21:01 2003 +++ b/net/ipv6/ip6_tunnel.c Mon Aug 18 22:21:01 2003 @@ -423,7 +423,7 @@ if (teli && teli == info - 2) { tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; - if (tel->encap_limit <= 1) { + if (tel->encap_limit == 0) { if (net_ratelimit()) printk(KERN_WARNING "%s: Too small encapsulation " @@ -621,6 +621,14 @@ return opt; } +static int +ip6ip6_getfrag(void *from, char *to, int offset, int len, int odd, + struct sk_buff *skb) +{ + memcpy(to, (char *) from + offset, len); + return 0; +} + /** * ip6ip6_tnl_addr_conflict - compare packet addresses to tunnel's own * @t: the outgoing tunnel device @@ -661,7 +669,7 @@ struct ipv6hdr *ipv6h = skb->nh.ipv6h; struct ipv6_txoptions *orig_opt = NULL; struct ipv6_txoptions *opt = NULL; - __u8 encap_limit = 0; + int encap_limit = -1; __u16 offset; struct flowi fl; struct ip6_flowlabel *fl_lbl = NULL; @@ -684,7 +692,7 @@ if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) { struct ipv6_tlv_tnl_enc_lim *tel; tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset]; - if (tel->encap_limit <= 1) { + if (tel->encap_limit == 0) { icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD, offset + 2, skb->dev); goto tx_err; @@ -707,7 +715,7 @@ if (fl_lbl) orig_opt = fl_lbl->opt; } - if (encap_limit > 0) { + if (encap_limit >= 0) { if (!(opt = merge_options(sk, encap_limit, orig_opt))) { goto tx_err_free_fl_lbl; } @@ -755,9 +763,9 @@ } if (skb->len > mtu) { icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); - goto tx_err_opt_release; + goto tx_err_dst_release; } - err = ip6_append_data(sk, ip_generic_getfrag, skb->nh.raw, skb->len, 0, + err = ip6_append_data(sk, ip6ip6_getfrag, skb->nh.raw, skb->len, 0, t->parms.hop_limit, opt, &fl, (struct rt6_info *)dst, MSG_DONTWAIT); @@ -785,7 +793,6 @@ return 0; tx_err_dst_release: dst_release(dst); -tx_err_opt_release: if (opt && opt != orig_opt) sock_kfree_s(sk, opt, opt->tot_len); tx_err_free_fl_lbl: diff -Nru a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c --- a/net/ipv6/ipcomp6.c Mon Aug 18 22:21:03 2003 +++ b/net/ipv6/ipcomp6.c Mon Aug 18 22:21:03 2003 @@ -268,6 +268,8 @@ static void ipcomp6_destroy(struct xfrm_state *x) { struct ipcomp_data *ipcd = x->data; + if (!ipcd) + return; ipcomp6_free_data(ipcd); kfree(ipcd); } @@ -286,7 +288,6 @@ x->props.header_len = sizeof(struct ipv6_comp_hdr); if (x->props.mode) x->props.header_len += sizeof(struct ipv6hdr); - x->data = ipcd; ipcd->scratch = kmalloc(IPCOMP_SCRATCH_SIZE, GFP_KERNEL); if (!ipcd->scratch) @@ -299,6 +300,7 @@ calg_desc = xfrm_calg_get_byname(x->calg->alg_name); BUG_ON(!calg_desc); ipcd->threshold = calg_desc->uinfo.comp.threshold; + x->data = ipcd; err = 0; out: return err; diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c --- a/net/ipv6/ipv6_syms.c Mon Aug 18 22:21:04 2003 +++ b/net/ipv6/ipv6_syms.c Mon Aug 18 22:21:04 2003 @@ -36,7 +36,9 @@ EXPORT_SYMBOL(in6addr_loopback); EXPORT_SYMBOL(in6_dev_finish_destroy); EXPORT_SYMBOL(ip6_find_1stfragopt); +#ifdef CONFIG_XFRM EXPORT_SYMBOL(xfrm6_rcv); +#endif EXPORT_SYMBOL(rt6_lookup); EXPORT_SYMBOL(fl6_sock_lookup); EXPORT_SYMBOL(ipv6_ext_hdr); diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c --- a/net/ipv6/raw.c Mon Aug 18 22:21:02 2003 +++ b/net/ipv6/raw.c Mon Aug 18 22:21:02 2003 @@ -833,6 +833,7 @@ val = -1; else val = opt->offset; + break; default: return -ENOPROTOOPT; diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c --- a/net/ipv6/route.c Mon Aug 18 22:21:05 2003 +++ b/net/ipv6/route.c Mon Aug 18 22:21:05 2003 @@ -432,6 +432,7 @@ /* Race condition! In the gap, when rt6_lock was released someone could insert this route. Relookup. */ + dst_release(&rt->u.dst); goto relookup; } dst_hold(&rt->u.dst); @@ -486,6 +487,7 @@ /* Race condition! In the gap, when rt6_lock was released someone could insert this route. Relookup. */ + dst_release(&rt->u.dst); goto relookup; } dst_hold(&rt->u.dst); @@ -1094,8 +1096,8 @@ */ dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires); nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; - dst_release(&nrt->u.dst); } + dst_release(&nrt->u.dst); } else { nrt = ip6_rt_copy(rt); if (nrt == NULL) @@ -1983,12 +1985,15 @@ NULL, NULL); fib6_init(); #ifdef CONFIG_PROC_FS - proc_net_create("ipv6_route", 0, rt6_proc_info); - p = create_proc_entry("rt6_stats", S_IRUGO, proc_net); + p = proc_net_create("ipv6_route", 0, rt6_proc_info); if (p) - p->proc_fops = &rt6_stats_seq_fops; + p->owner = THIS_MODULE; + + proc_net_fops_create("rt6_stats", S_IRUGO, &rt6_stats_seq_fops); #endif +#ifdef CONFIG_XFRM xfrm6_init(); +#endif } #ifdef MODULE @@ -1998,7 +2003,9 @@ proc_net_remove("ipv6_route"); proc_net_remove("rt6_stats"); #endif +#ifdef CONFIG_XFRM xfrm6_fini(); +#endif rt6_ifdown(NULL); fib6_gc_cleanup(); kmem_cache_destroy(ip6_dst_ops.kmem_cachep); diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c --- a/net/ipv6/tcp_ipv6.c Mon Aug 18 22:21:03 2003 +++ b/net/ipv6/tcp_ipv6.c Mon Aug 18 22:21:04 2003 @@ -663,19 +663,12 @@ ipv6_addr_copy(&fl.fl6_dst, rt0->addr); } - dst = ip6_route_output(sk, &fl); + err = ip6_dst_lookup(sk, &dst, &fl); - if ((err = dst->error) != 0) { - dst_release(dst); + if (err) goto failure; - } if (saddr == NULL) { - err = ipv6_get_saddr(dst, &np->daddr, &fl.fl6_src); - if (err) { - dst_release(dst); - goto failure; - } saddr = &fl.fl6_src; ipv6_addr_copy(&np->rcv_saddr, saddr); } @@ -686,11 +679,13 @@ ip6_dst_store(sk, dst, NULL); sk->sk_route_caps = dst->dev->features & - ~(NETIF_F_IP_CSUM | NETIF_F_TSO); + ~(NETIF_F_IP_CSUM | NETIF_F_TSO); tp->ext_header_len = 0; if (np->opt) tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen; + tp->ext2_header_len = dst->header_len; + tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); inet->dport = usin->sin6_port; @@ -788,13 +783,14 @@ fl.fl_ip_dport = inet->dport; fl.fl_ip_sport = inet->sport; - dst = ip6_route_output(sk, &fl); + if ((err = ip6_dst_lookup(sk, &dst, &fl))) { + sk->sk_err_soft = -err; + goto out; + } } else dst_hold(dst); - if (dst->error) { - sk->sk_err_soft = -dst->error; - } else if (tp->pmtu_cookie > dst_pmtu(dst)) { + if (tp->pmtu_cookie > dst_pmtu(dst)) { tcp_sync_mss(sk, dst_pmtu(dst)); tcp_simple_retransmit(sk); } /* else let the usual retransmit timer handle it */ @@ -889,8 +885,8 @@ ipv6_addr_copy(&fl.fl6_dst, rt0->addr); } - dst = ip6_route_output(sk, &fl); - if (dst->error) + err = ip6_dst_lookup(sk, &dst, &fl); + if (err) goto done; } @@ -1018,9 +1014,7 @@ fl.fl_ip_sport = t1->source; /* sk = NULL, but it is safe for now. RST socket required. */ - buff->dst = ip6_route_output(NULL, &fl); - - if (buff->dst->error == 0) { + if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { ip6_xmit(NULL, buff, &fl, NULL, 0); TCP_INC_STATS_BH(TcpOutSegs); TCP_INC_STATS_BH(TcpOutRsts); @@ -1081,9 +1075,7 @@ fl.fl_ip_dport = t1->dest; fl.fl_ip_sport = t1->source; - buff->dst = ip6_route_output(NULL, &fl); - - if (buff->dst->error == 0) { + if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { ip6_xmit(NULL, buff, &fl, NULL, 0); TCP_INC_STATS_BH(TcpOutSegs); return; @@ -1329,11 +1321,9 @@ fl.fl_ip_dport = req->rmt_port; fl.fl_ip_sport = inet_sk(sk)->sport; - dst = ip6_route_output(sk, &fl); - } - - if (dst->error) - goto out; + if (ip6_dst_lookup(sk, &dst, &fl)) + goto out; + } newsk = tcp_create_openreq_child(sk, req, skb); if (newsk == NULL) @@ -1345,8 +1335,8 @@ #endif ip6_dst_store(newsk, dst, NULL); - sk->sk_route_caps = dst->dev->features & - ~(NETIF_F_IP_CSUM | NETIF_F_TSO); + newsk->sk_route_caps = dst->dev->features & + ~(NETIF_F_IP_CSUM | NETIF_F_TSO); newtcp6sk = (struct tcp6_sock *)newsk; newtcp6sk->pinet6 = &newtcp6sk->inet6; @@ -1401,6 +1391,7 @@ if (newnp->opt) newtp->ext_header_len = newnp->opt->opt_nflen + newnp->opt->opt_flen; + newtp->ext2_header_len = dst->header_len; tcp_sync_mss(newsk, dst_pmtu(dst)); newtp->advmss = dst_metric(dst, RTAX_ADVMSS); @@ -1727,18 +1718,17 @@ ipv6_addr_copy(&fl.fl6_dst, rt0->addr); } - dst = ip6_route_output(sk, &fl); + err = ip6_dst_lookup(sk, &dst, &fl); - if (dst->error) { - err = dst->error; - dst_release(dst); + if (err) { sk->sk_route_caps = 0; return err; } ip6_dst_store(sk, dst, NULL); sk->sk_route_caps = dst->dev->features & - ~(NETIF_F_IP_CSUM | NETIF_F_TSO); + ~(NETIF_F_IP_CSUM | NETIF_F_TSO); + tcp_sk(sk)->ext2_header_len = dst->header_len; } return 0; @@ -1770,15 +1760,17 @@ dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { - dst = ip6_route_output(sk, &fl); + int err = ip6_dst_lookup(sk, &dst, &fl); - if (dst->error) { - sk->sk_err_soft = -dst->error; - dst_release(dst); - return -sk->sk_err_soft; + if (err) { + sk->sk_err_soft = -err; + return err; } ip6_dst_store(sk, dst, NULL); + sk->sk_route_caps = dst->dev->features & + ~(NETIF_F_IP_CSUM | NETIF_F_TSO); + tcp_sk(sk)->ext2_header_len = dst->header_len; } skb->dst = dst_clone(dst); diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c --- a/net/ipv6/udp.c Mon Aug 18 22:21:05 2003 +++ b/net/ipv6/udp.c Mon Aug 18 22:21:05 2003 @@ -330,21 +330,11 @@ ipv6_addr_copy(&fl.fl6_dst, rt0->addr); } - dst = ip6_route_output(sk, &fl); - - if ((err = dst->error) != 0) { - dst_release(dst); + err = ip6_dst_lookup(sk, &dst, &fl); + if (err) goto out; - } - - /* get the source address used in the appropriate device */ - - err = ipv6_get_saddr(dst, daddr, &fl.fl6_src); - if (err) { - dst_release(dst); - goto out; - } + /* source address lookup done in ip6_dst_lookup */ if (ipv6_addr_any(&np->saddr)) ipv6_addr_copy(&np->saddr, &fl.fl6_src); @@ -811,8 +801,10 @@ * The socket lock must be held while it's corked. */ lock_sock(sk); - if (likely(up->pending)) + if (likely(up->pending)) { + dst = NULL; goto do_append_data; + } release_sock(sk); } ulen += sizeof(struct udphdr); @@ -968,9 +960,10 @@ else if (!corkreq) err = udp_v6_push_pending_frames(sk, up); - ip6_dst_store(sk, dst, - !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ? - &np->daddr : NULL); + if (dst) + ip6_dst_store(sk, dst, + !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ? + &np->daddr : NULL); if (err > 0) err = np->recverr ? net_xmit_errno(err) : 0; release_sock(sk); diff -Nru a/net/irda/irda_device.c b/net/irda/irda_device.c --- a/net/irda/irda_device.c Mon Aug 18 22:21:03 2003 +++ b/net/irda/irda_device.c Mon Aug 18 22:21:03 2003 @@ -383,10 +383,8 @@ * This function should be used by low level device drivers in a similar way * as ether_setup() is used by normal network device drivers */ -int irda_device_setup(struct net_device *dev) +void irda_device_setup(struct net_device *dev) { - ASSERT(dev != NULL, return -1;); - dev->hard_header_len = 0; dev->addr_len = 0; @@ -399,7 +397,6 @@ dev->mtu = 2048; dev->flags = IFF_NOARP; - return 0; } /* diff -Nru a/net/irda/irlap.c b/net/irda/irlap.c --- a/net/irda/irlap.c Mon Aug 18 22:21:06 2003 +++ b/net/irda/irlap.c Mon Aug 18 22:21:06 2003 @@ -48,7 +48,7 @@ #include #include -hashbin_t *irlap = NULL; +static hashbin_t *irlap = NULL; int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ; /* This is the delay of missed pf period before generating an event @@ -110,7 +110,7 @@ * */ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, - char * hw_name) + const char *hw_name) { struct irlap_cb *self; diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c --- a/net/netrom/af_netrom.c Mon Aug 18 22:21:03 2003 +++ b/net/netrom/af_netrom.c Mon Aug 18 22:21:03 2003 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -57,8 +58,8 @@ static unsigned short circuit = 0x101; -HLIST_HEAD(nr_list); -static spinlock_t nr_list_lock; +static HLIST_HEAD(nr_list); +static spinlock_t nr_list_lock = SPIN_LOCK_UNLOCKED; static struct proto_ops nr_proto_ops; @@ -147,8 +148,10 @@ spin_lock_bh(&nr_list_lock); sk_for_each(s, node, &nr_list) if (!ax25cmp(&nr_sk(s)->source_addr, addr) && - s->sk_state == TCP_LISTEN) + s->sk_state == TCP_LISTEN) { + bh_lock_sock(s); goto found; + } s = NULL; found: spin_unlock_bh(&nr_list_lock); @@ -167,8 +170,10 @@ sk_for_each(s, node, &nr_list) { nr_cb *nr = nr_sk(s); - if (nr->my_index == index && nr->my_id == id) + if (nr->my_index == index && nr->my_id == id) { + bh_lock_sock(s); goto found; + } } s = NULL; found: @@ -190,8 +195,10 @@ nr_cb *nr = nr_sk(s); if (nr->your_index == index && nr->your_id == id && - !ax25cmp(&nr->dest_addr, dest)) + !ax25cmp(&nr->dest_addr, dest)) { + bh_lock_sock(s); goto found; + } } s = NULL; found: @@ -206,14 +213,17 @@ { unsigned short id = circuit; unsigned char i, j; + struct sock *sk; for (;;) { i = id / 256; j = id % 256; - if (i != 0 && j != 0) - if (nr_find_socket(i, j) == NULL) + if (i != 0 && j != 0) { + if ((sk=nr_find_socket(i, j)) == NULL) break; + bh_unlock_sock(sk); + } id++; } @@ -231,7 +241,12 @@ */ static void nr_destroy_timer(unsigned long data) { - nr_destroy_socket((struct sock *)data); + struct sock *sk=(struct sock *)data; + bh_lock_sock(sk); + sock_hold(sk); + nr_destroy_socket(sk); + bh_unlock_sock(sk); + sock_put(sk); } /* @@ -264,17 +279,20 @@ kfree_skb(skb); } + while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) { + kfree_skb(skb); + } if (atomic_read(&sk->sk_wmem_alloc) || atomic_read(&sk->sk_rmem_alloc)) { /* Defer: outstanding buffers */ init_timer(&sk->sk_timer); - sk->sk_timer.expires = jiffies + 10 * HZ; + sk->sk_timer.expires = jiffies + 2 * HZ; sk->sk_timer.function = nr_destroy_timer; sk->sk_timer.data = (unsigned long)sk; add_timer(&sk->sk_timer); } else - sk_free(sk); + sock_put(sk); } /* @@ -388,12 +406,15 @@ { struct sock *sk = sock->sk; + lock_sock(sk); if (sk->sk_state != TCP_LISTEN) { memset(&nr_sk(sk)->user_addr, 0, AX25_ADDR_LEN); sk->sk_max_ack_backlog = backlog; sk->sk_state = TCP_LISTEN; + release_sock(sk); return 0; } + release_sock(sk); return -EOPNOTSUPP; } @@ -495,6 +516,8 @@ if (sk == NULL) return 0; + sock_hold(sk); + lock_sock(sk); nr = nr_sk(sk); switch (nr->state) { @@ -528,6 +551,8 @@ } sock->sk = NULL; + release_sock(sk); + sock_put(sk); return 0; } @@ -540,21 +565,26 @@ struct net_device *dev; ax25_address *user, *source; - if (!sk->sk_zapped) + lock_sock(sk); + if (!sk->sk_zapped) { + release_sock(sk); return -EINVAL; - - if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct -full_sockaddr_ax25)) + } + if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct full_sockaddr_ax25)) { + release_sock(sk); return -EINVAL; - - if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25))) + } + if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25))) { + release_sock(sk); return -EINVAL; - - if (addr->fsa_ax25.sax25_family != AF_NETROM) + } + if (addr->fsa_ax25.sax25_family != AF_NETROM) { + release_sock(sk); return -EINVAL; - + } if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) { SOCK_DEBUG(sk, "NET/ROM: bind failed: invalid node callsign\n"); + release_sock(sk); return -EADDRNOTAVAIL; } @@ -562,16 +592,22 @@ * Only the super user can set an arbitrary user callsign. */ if (addr->fsa_ax25.sax25_ndigis == 1) { - if (!capable(CAP_NET_BIND_SERVICE)) + if (!capable(CAP_NET_BIND_SERVICE)) { + dev_put(dev); + release_sock(sk); return -EACCES; + } nr->user_addr = addr->fsa_digipeater[0]; nr->source_addr = addr->fsa_ax25.sax25_call; } else { source = &addr->fsa_ax25.sax25_call; if ((user = ax25_findbyuid(current->euid)) == NULL) { - if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) + if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { + release_sock(sk); + dev_put(dev); return -EPERM; + } user = source; } @@ -583,6 +619,8 @@ nr_insert_socket(sk); sk->sk_zapped = 0; + dev_put(dev); + release_sock(sk); SOCK_DEBUG(sk, "NET/ROM: socket is bound\n"); return 0; } @@ -596,39 +634,50 @@ ax25_address *user, *source = NULL; struct net_device *dev; + lock_sock(sk); if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { sock->state = SS_CONNECTED; + release_sock(sk); return 0; /* Connect completed during a ERESTARTSYS event */ } if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { sock->state = SS_UNCONNECTED; + release_sock(sk); return -ECONNREFUSED; } - if (sk->sk_state == TCP_ESTABLISHED) + if (sk->sk_state == TCP_ESTABLISHED) { + release_sock(sk); return -EISCONN; /* No reconnect on a seqpacket socket */ + } sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; - if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25)) + if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25)) { + release_sock(sk); return -EINVAL; - - if (addr->sax25_family != AF_NETROM) + } + if (addr->sax25_family != AF_NETROM) { + release_sock(sk); return -EINVAL; - + } if (sk->sk_zapped) { /* Must bind first - autobinding in this may or may not work */ sk->sk_zapped = 0; - if ((dev = nr_dev_first()) == NULL) + if ((dev = nr_dev_first()) == NULL) { + release_sock(sk); return -ENETUNREACH; - + } source = (ax25_address *)dev->dev_addr; if ((user = ax25_findbyuid(current->euid)) == NULL) { - if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) + if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) { + dev_put(dev); + release_sock(sk); return -EPERM; + } user = source; } @@ -636,12 +685,15 @@ nr->source_addr = *source; nr->device = dev; + dev_put(dev); nr_insert_socket(sk); /* Finish the bind */ } nr->dest_addr = addr->sax25_call; + release_sock(sk); circuit = nr_find_next_circuit(); + lock_sock(sk); nr->my_index = circuit / 256; nr->my_id = circuit % 256; @@ -659,8 +711,10 @@ nr_start_heartbeat(sk); /* Now the loop */ - if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) + if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) { + release_sock(sk); return -EINPROGRESS; + } /* * A Connect Ack with Choke or timeout or failed routing will go to @@ -675,8 +729,10 @@ set_current_state(TASK_INTERRUPTIBLE); if (sk->sk_state != TCP_SYN_SENT) break; + release_sock(sk); if (!signal_pending(tsk)) { schedule(); + lock_sock(sk); continue; } return -ERESTARTSYS; @@ -687,10 +743,12 @@ if (sk->sk_state != TCP_ESTABLISHED) { sock->state = SS_UNCONNECTED; + release_sock(sk); return sock_error(sk); /* Always set at this point */ } sock->state = SS_CONNECTED; + release_sock(sk); return 0; } @@ -753,6 +811,7 @@ newsock->sk = newsk; out: + release_sock(sk); return err; } @@ -763,9 +822,12 @@ struct sock *sk = sock->sk; nr_cb *nr = nr_sk(sk); + lock_sock(sk); if (peer != 0) { - if (sk->sk_state != TCP_ESTABLISHED) + if (sk->sk_state != TCP_ESTABLISHED) { + release_sock(sk); return -ENOTCONN; + } sax->fsa_ax25.sax25_family = AF_NETROM; sax->fsa_ax25.sax25_ndigis = 1; sax->fsa_ax25.sax25_call = nr->user_addr; @@ -777,6 +839,7 @@ sax->fsa_ax25.sax25_call = nr->source_addr; *uaddr_len = sizeof(struct sockaddr_ax25); } + release_sock(sk); return 0; } @@ -790,6 +853,7 @@ unsigned short circuit_index, circuit_id; unsigned short peer_circuit_index, peer_circuit_id; unsigned short frametype, flags, window, timeout; + int ret; skb->sk = NULL; /* Initially we don't know who it's for */ @@ -847,7 +911,9 @@ else nr_sk(sk)->bpqext = 0; - return nr_process_rx_frame(sk, skb); + ret = nr_process_rx_frame(sk, skb); + bh_unlock_sock(sk); + return ret; } /* @@ -877,6 +943,8 @@ if (!sk || sk->sk_ack_backlog == sk->sk_max_ack_backlog || (make = nr_make_new(sk)) == NULL) { nr_transmit_refusal(skb, 0); + if (sk) + bh_unlock_sock(sk); return 0; } @@ -894,7 +962,9 @@ nr_make->your_index = circuit_index; nr_make->your_id = circuit_id; + bh_unlock_sock(sk); circuit = nr_find_next_circuit(); + bh_lock_sock(sk); nr_make->my_index = circuit / 256; nr_make->my_id = circuit % 256; @@ -936,6 +1006,7 @@ if (!sock_flag(sk, SOCK_DEAD)) sk->sk_data_ready(sk, skb->len); + bh_unlock_sock(sk); return 1; } @@ -954,28 +1025,42 @@ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR)) return -EINVAL; - if (sk->sk_zapped) - return -EADDRNOTAVAIL; + lock_sock(sk); + if (sk->sk_zapped) { + err = -EADDRNOTAVAIL; + goto out; + } if (sk->sk_shutdown & SEND_SHUTDOWN) { send_sig(SIGPIPE, current, 0); - return -EPIPE; + err = -EPIPE; + goto out; } - if (nr->device == NULL) - return -ENETUNREACH; + if (nr->device == NULL) { + err = -ENETUNREACH; + goto out; + } if (usax) { - if (msg->msg_namelen < sizeof(sax)) - return -EINVAL; + if (msg->msg_namelen < sizeof(sax)) { + err = -EINVAL; + goto out; + } sax = *usax; - if (ax25cmp(&nr->dest_addr, &sax.sax25_call) != 0) - return -EISCONN; - if (sax.sax25_family != AF_NETROM) - return -EINVAL; + if (ax25cmp(&nr->dest_addr, &sax.sax25_call) != 0) { + err = -EISCONN; + goto out; + } + if (sax.sax25_family != AF_NETROM) { + err = -EINVAL; + goto out; + } } else { - if (sk->sk_state != TCP_ESTABLISHED) - return -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) { + err = -ENOTCONN; + goto out; + } sax.sax25_family = AF_NETROM; sax.sax25_call = nr->dest_addr; } @@ -984,10 +1069,10 @@ /* Build a packet */ SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n"); - size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN; + size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN; if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL) - return err; + goto out; skb_reserve(skb, size - len); @@ -1022,12 +1107,16 @@ if (sk->sk_state != TCP_ESTABLISHED) { kfree_skb(skb); - return -ENOTCONN; + err = -ENOTCONN; + goto out; } nr_output(sk, skb); /* Shove it onto the queue */ - return len; + err = len; +out: + release_sock(sk); + return err; } static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, @@ -1044,12 +1133,17 @@ * us! We do one quick check first though */ - if (sk->sk_state != TCP_ESTABLISHED) + lock_sock(sk); + if (sk->sk_state != TCP_ESTABLISHED) { + release_sock(sk); return -ENOTCONN; + } /* Now we can treat all alike */ - if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL) + if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL) { + release_sock(sk); return er; + } skb->h.raw = skb->data; copied = skb->len; @@ -1070,6 +1164,7 @@ skb_free_datagram(sk, skb); + release_sock(sk); return copied; } @@ -1077,13 +1172,16 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; + int ret; + lock_sock(sk); switch (cmd) { case TIOCOUTQ: { long amount; amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); if (amount < 0) amount = 0; + release_sock(sk); return put_user(amount, (int *)arg); } @@ -1093,15 +1191,21 @@ /* These two are safe on a single CPU system as only user tasks fiddle here */ if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; + release_sock(sk); return put_user(amount, (int *)arg); } case SIOCGSTAMP: if (sk != NULL) { - if (!sk->sk_stamp.tv_sec) + if (!sk->sk_stamp.tv_sec) { + release_sock(sk); return -ENOENT; - return copy_to_user((void *)arg, &sk->sk_stamp, sizeof(struct timeval)) ? -EFAULT : 0; + } + ret = copy_to_user((void *)arg, &sk->sk_stamp, sizeof(struct timeval)) ? -EFAULT : 0; + release_sock(sk); + return ret; } + release_sock(sk); return -EINVAL; case SIOCGIFADDR: @@ -1114,48 +1218,85 @@ case SIOCSIFNETMASK: case SIOCGIFMETRIC: case SIOCSIFMETRIC: + release_sock(sk); return -EINVAL; case SIOCADDRT: case SIOCDELRT: case SIOCNRDECOBS: + release_sock(sk); if (!capable(CAP_NET_ADMIN)) return -EPERM; return nr_rt_ioctl(cmd, (void *)arg); default: + release_sock(sk); return dev_ioctl(cmd, (void *)arg); } + release_sock(sk); return 0; } -static int nr_get_info(char *buffer, char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS + +/* Marker for header entry */ +#define NETROM_PROC_START ((void *)1) +static void *nr_info_start(struct seq_file *seq, loff_t *pos) { struct sock *s; struct hlist_node *node; + int i = 1; + + spin_lock_bh(&nr_list_lock); + if (*pos == 0) + return NETROM_PROC_START; + + sk_for_each(s, node, &nr_list) { + if (i == *pos) + return s; + ++i; + } + return NULL; +} + +static void *nr_info_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + + return (v == NETROM_PROC_START) ? sk_head(&nr_list) + : sk_next((struct sock *)v); +} + +static void nr_info_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&nr_list_lock); +} + +static int nr_info_show(struct seq_file *seq, void *v) +{ + struct sock *s = v; struct net_device *dev; + nr_cb *nr; const char *devname; - int len = 0; - off_t pos = 0; - off_t begin = 0; - spin_lock_bh(&nr_list_lock); + if (v == NETROM_PROC_START) + seq_puts(seq, +"user_addr dest_node src_node dev my your st vs vr va t1 t2 t4 idle n2 wnd Snd-Q Rcv-Q inode\n"); - len += sprintf(buffer, "user_addr dest_node src_node dev my your st vs vr va t1 t2 t4 idle n2 wnd Snd-Q Rcv-Q inode\n"); + else { - sk_for_each(s, node, &nr_list) { - nr_cb *nr = nr_sk(s); + bh_lock_sock(s); + nr = nr_sk(s); if ((dev = nr->device) == NULL) devname = "???"; else devname = dev->name; - len += sprintf(buffer + len, "%-9s ", - ax2asc(&nr->user_addr)); - len += sprintf(buffer + len, "%-9s ", - ax2asc(&nr->dest_addr)); - len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %ld\n", + seq_printf(seq, "%-9s ", ax2asc(&nr->user_addr)); + seq_printf(seq, "%-9s ", ax2asc(&nr->dest_addr)); + seq_printf(seq, +"%-9s %-3s %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %ld\n", ax2asc(&nr->source_addr), devname, nr->my_index, @@ -1181,27 +1322,31 @@ atomic_read(&s->sk_rmem_alloc), s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - - if (pos > offset + length) - break; + bh_unlock_sock(s); } + return 0; +} - spin_unlock_bh(&nr_list_lock); - - *start = buffer + (offset - begin); - len -= (offset - begin); - - if (len > length) - len = length; - - return len; +static struct seq_operations nr_info_seqops = { + .start = nr_info_start, + .next = nr_info_next, + .stop = nr_info_stop, + .show = nr_info_show, +}; + +static int nr_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &nr_info_seqops); } + +static struct file_operations nr_info_fops = { + .owner = THIS_MODULE, + .open = nr_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#endif /* CONFIG_PROC_FS */ static struct net_proto_family nr_family_ops = { .family = PF_NETROM, @@ -1234,7 +1379,7 @@ .notifier_call = nr_device_event, }; -static struct net_device *dev_nr; +static struct net_device **dev_nr; static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n"; @@ -1247,20 +1392,39 @@ return -1; } - if ((dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) { - printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); + dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL); + if (dev_nr == NULL) { + printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n"); return -1; } - memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device)); + memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device *)); for (i = 0; i < nr_ndevs; i++) { - sprintf(dev_nr[i].name, "nr%d", i); - dev_nr[i].init = nr_init; - register_netdev(&dev_nr[i]); + char name[IFNAMSIZ]; + struct net_device *dev; + + sprintf(name, "nr%d", i); + dev = alloc_netdev(sizeof(struct net_device_stats), name, + nr_setup); + if (!dev) { + printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); + goto fail; + } + + dev->base_addr = i; + if (register_netdev(dev)) { + printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register network device\n"); + goto fail; + } + dev_nr[i] = dev; } - sock_register(&nr_family_ops); + if (sock_register(&nr_family_ops)) { + printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register socket family\n"); + goto fail; + } + register_netdevice_notifier(&nr_dev_notifier); printk(banner); @@ -1273,10 +1437,16 @@ nr_loopback_init(); - proc_net_create("nr", 0, nr_get_info); - proc_net_create("nr_neigh", 0, nr_neigh_get_info); - proc_net_create("nr_nodes", 0, nr_nodes_get_info); + proc_net_fops_create("nr", S_IRUGO, &nr_info_fops); + proc_net_fops_create("nr_neigh", S_IRUGO, &nr_neigh_fops); + proc_net_fops_create("nr_nodes", S_IRUGO, &nr_nodes_fops); return 0; + + fail: + while (--i >= 0) + unregister_netdev(dev_nr[i]); + kfree(dev_nr); + return -1; } module_init(nr_proto_init); @@ -1300,23 +1470,21 @@ nr_rt_free(); - ax25_protocol_release(AX25_P_NETROM); +#ifdef CONFIG_SYSCTL + nr_unregister_sysctl(); +#endif + ax25_linkfail_release(nr_link_failed); + ax25_protocol_release(AX25_P_NETROM); unregister_netdevice_notifier(&nr_dev_notifier); -#ifdef CONFIG_SYSCTL - nr_unregister_sysctl(); -#endif sock_unregister(PF_NETROM); for (i = 0; i < nr_ndevs; i++) { - if (dev_nr[i].priv != NULL) { - kfree(dev_nr[i].priv); - dev_nr[i].priv = NULL; - unregister_netdev(&dev_nr[i]); - } - kfree(dev_nr[i].name); + struct net_device *dev = dev_nr[i]; + if (dev) + unregister_netdev(dev); } kfree(dev_nr); diff -Nru a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c --- a/net/netrom/nr_dev.c Mon Aug 18 22:21:05 2003 +++ b/net/netrom/nr_dev.c Mon Aug 18 22:21:05 2003 @@ -159,11 +159,13 @@ { struct sockaddr *sa = addr; - ax25_listen_release((ax25_address *)dev->dev_addr, NULL); + if (dev->flags & IFF_UP) + ax25_listen_release((ax25_address *)dev->dev_addr, NULL); memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); - ax25_listen_register((ax25_address *)dev->dev_addr, NULL); + if (dev->flags & IFF_UP) + ax25_listen_register((ax25_address *)dev->dev_addr, NULL); return 0; } @@ -177,8 +179,8 @@ static int nr_close(struct net_device *dev) { - netif_stop_queue(dev); ax25_listen_release((ax25_address *)dev->dev_addr, NULL); + netif_stop_queue(dev); return 0; } @@ -195,30 +197,25 @@ return (struct net_device_stats *)dev->priv; } -int nr_init(struct net_device *dev) +void nr_setup(struct net_device *dev) { SET_MODULE_OWNER(dev); dev->mtu = NR_MAX_PACKET_SIZE; dev->hard_start_xmit = nr_xmit; dev->open = nr_open; dev->stop = nr_close; + dev->destructor = (void (*)(struct net_device *))kfree; dev->hard_header = nr_header; - dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN; + dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; dev->addr_len = AX25_ADDR_LEN; dev->type = ARPHRD_NETROM; + dev->tx_queue_len = 40; dev->rebuild_header = nr_rebuild_header; dev->set_mac_address = nr_set_mac_address; /* New-style flags. */ dev->flags = 0; - if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL) - return -ENOMEM; - - memset(dev->priv, 0, sizeof(struct net_device_stats)); - - dev->get_stats = nr_get_stats; - - return 0; -}; + dev->get_stats = nr_get_stats; +} diff -Nru a/net/netrom/nr_in.c b/net/netrom/nr_in.c --- a/net/netrom/nr_in.c Mon Aug 18 22:21:02 2003 +++ b/net/netrom/nr_in.c Mon Aug 18 22:21:02 2003 @@ -74,6 +74,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) { + bh_lock_sock(sk); switch (frametype) { case NR_CONNACK: { nr_cb *nr = nr_sk(sk); @@ -102,6 +103,7 @@ default: break; } + bh_unlock_sock(sk); return 0; } @@ -114,6 +116,7 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype) { + bh_lock_sock(sk); switch (frametype) { case NR_CONNACK | NR_CHOKE_FLAG: nr_disconnect(sk, ECONNRESET); @@ -129,6 +132,7 @@ default: break; } + bh_unlock_sock(sk); return 0; } @@ -150,6 +154,7 @@ nr = skb->data[18]; ns = skb->data[17]; + bh_lock_sock(sk); switch (frametype) { case NR_CONNREQ: nr_write_internal(sk, NR_CONNACK); @@ -260,6 +265,7 @@ default: break; } + bh_unlock_sock(sk); return queued; } diff -Nru a/net/netrom/nr_route.c b/net/netrom/nr_route.c --- a/net/netrom/nr_route.c Mon Aug 18 22:21:06 2003 +++ b/net/netrom/nr_route.c Mon Aug 18 22:21:06 2003 @@ -36,13 +36,49 @@ #include #include #include +#include static unsigned int nr_neigh_no = 1; -static struct nr_node *nr_node_list; -static spinlock_t nr_node_lock; -static struct nr_neigh *nr_neigh_list; -static spinlock_t nr_neigh_lock; +static HLIST_HEAD(nr_node_list); +static spinlock_t nr_node_list_lock = SPIN_LOCK_UNLOCKED; +static HLIST_HEAD(nr_neigh_list); +static spinlock_t nr_neigh_list_lock = SPIN_LOCK_UNLOCKED; + +struct nr_node *nr_node_get(ax25_address *callsign) +{ + struct nr_node *found = NULL; + struct nr_node *nr_node; + struct hlist_node *node; + + spin_lock_bh(&nr_node_list_lock); + nr_node_for_each(nr_node, node, &nr_node_list) + if (ax25cmp(callsign, &nr_node->callsign) == 0) { + nr_node_hold(nr_node); + found = nr_node; + break; + } + spin_unlock_bh(&nr_node_list_lock); + return found; +} + +struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign, struct net_device *dev) +{ + struct nr_neigh *found = NULL; + struct nr_neigh *nr_neigh; + struct hlist_node *node; + + spin_lock_bh(&nr_neigh_list_lock); + nr_neigh_for_each(nr_neigh, node, &nr_neigh_list) + if (ax25cmp(callsign, &nr_neigh->callsign) == 0 && + nr_neigh->dev == dev) { + nr_neigh_hold(nr_neigh); + found = nr_neigh; + break; + } + spin_unlock_bh(&nr_neigh_list_lock); + return found; +} static void nr_remove_neigh(struct nr_neigh *); @@ -57,17 +93,16 @@ struct nr_neigh *nr_neigh; struct nr_route nr_route; int i, found; + struct net_device *odev; - if (nr_dev_get(nr) != NULL) /* Can't add routes to ourself */ + if ((odev=nr_dev_get(nr)) != NULL) { /* Can't add routes to ourself */ + dev_put(odev); return -EINVAL; + } - for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) - if (ax25cmp(nr, &nr_node->callsign) == 0) - break; + nr_node = nr_node_get(nr); - for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) - if (ax25cmp(ax25, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev) - break; + nr_neigh = nr_neigh_get_dev(ax25, dev); /* * The L2 link to a neighbour has failed in the past @@ -76,24 +111,36 @@ * routes now (and not wait for a node broadcast). */ if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) { - struct nr_node *node; + struct nr_node *nr_nodet; + struct hlist_node *node; - for (node = nr_node_list; node != NULL; node = node->next) - for (i = 0; i < node->count; i++) - if (node->routes[i].neighbour == nr_neigh) - if (i < node->which) - node->which = i; + spin_lock_bh(&nr_node_list_lock); + nr_node_for_each(nr_nodet, node, &nr_node_list) { + nr_node_lock(nr_nodet); + for (i = 0; i < nr_nodet->count; i++) + if (nr_nodet->routes[i].neighbour == nr_neigh) + if (i < nr_nodet->which) + nr_nodet->which = i; + nr_node_unlock(nr_nodet); + } + spin_unlock_bh(&nr_node_list_lock); } if (nr_neigh != NULL) nr_neigh->failed = 0; - if (quality == 0 && nr_neigh != NULL && nr_node != NULL) + if (quality == 0 && nr_neigh != NULL && nr_node != NULL) { + nr_neigh_put(nr_neigh); + nr_node_put(nr_node); return 0; + } if (nr_neigh == NULL) { - if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) + if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) { + if (nr_node) + nr_node_put(nr_node); return -ENOMEM; + } nr_neigh->callsign = *ax25; nr_neigh->digipeat = NULL; @@ -104,48 +151,58 @@ nr_neigh->count = 0; nr_neigh->number = nr_neigh_no++; nr_neigh->failed = 0; + atomic_set(&nr_neigh->refcount, 1); if (ax25_digi != NULL && ax25_digi->ndigi > 0) { if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) { kfree(nr_neigh); + if (nr_node) + nr_node_put(nr_node); return -ENOMEM; } memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi)); } - spin_lock_bh(&nr_neigh_lock); - nr_neigh->next = nr_neigh_list; - nr_neigh_list = nr_neigh; - spin_unlock_bh(&nr_neigh_lock); + spin_lock_bh(&nr_neigh_list_lock); + hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list); + nr_neigh_hold(nr_neigh); + spin_unlock_bh(&nr_neigh_list_lock); } if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked) nr_neigh->quality = quality; if (nr_node == NULL) { - if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) + if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) { + if (nr_neigh) + nr_neigh_put(nr_neigh); return -ENOMEM; + } nr_node->callsign = *nr; strcpy(nr_node->mnemonic, mnemonic); nr_node->which = 0; nr_node->count = 1; + atomic_set(&nr_node->refcount, 1); + nr_node->node_lock = SPIN_LOCK_UNLOCKED; nr_node->routes[0].quality = quality; nr_node->routes[0].obs_count = obs_count; nr_node->routes[0].neighbour = nr_neigh; - spin_lock_bh(&nr_node_lock); - nr_node->next = nr_node_list; - nr_node_list = nr_node; - spin_unlock_bh(&nr_node_lock); - + nr_neigh_hold(nr_neigh); nr_neigh->count++; + spin_lock_bh(&nr_node_list_lock); + hlist_add_head(&nr_node->node_node, &nr_node_list); + /* refcount initialized at 1 */ + spin_unlock_bh(&nr_node_list_lock); + return 0; } + nr_node_lock(nr_node); if (quality != 0) strcpy(nr_node->mnemonic, mnemonic); @@ -171,11 +228,13 @@ nr_node->which++; nr_node->count++; + nr_neigh_hold(nr_neigh); nr_neigh->count++; } else { /* It must be better than the worst */ if (quality > nr_node->routes[2].quality) { nr_node->routes[2].neighbour->count--; + nr_neigh_put(nr_node->routes[2].neighbour); if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked) nr_remove_neigh(nr_node->routes[2].neighbour); @@ -184,6 +243,7 @@ nr_node->routes[2].obs_count = obs_count; nr_node->routes[2].neighbour = nr_neigh; + nr_neigh_hold(nr_neigh); nr_neigh->count++; } } @@ -244,62 +304,42 @@ } } + nr_neigh_put(nr_neigh); + nr_node_unlock(nr_node); + nr_node_put(nr_node); return 0; } -static void nr_remove_node(struct nr_node *nr_node) +static inline void __nr_remove_node(struct nr_node *nr_node) { - struct nr_node *s; - - spin_lock_bh(&nr_node_lock); - if ((s = nr_node_list) == nr_node) { - nr_node_list = nr_node->next; - spin_unlock_bh(&nr_node_lock); - kfree(nr_node); - return; - } - - while (s != NULL && s->next != NULL) { - if (s->next == nr_node) { - s->next = nr_node->next; - spin_unlock_bh(&nr_node_lock); - kfree(nr_node); - return; - } + hlist_del_init(&nr_node->node_node); + nr_node_put(nr_node); +} - s = s->next; - } +#define nr_remove_node_locked(__node) \ + __nr_remove_node(__node) - spin_unlock_bh(&nr_node_lock); +static void nr_remove_node(struct nr_node *nr_node) +{ + spin_lock_bh(&nr_node_list_lock); + __nr_remove_node(nr_node); + spin_unlock_bh(&nr_node_list_lock); } -static void nr_remove_neigh(struct nr_neigh *nr_neigh) +static inline void __nr_remove_neigh(struct nr_neigh *nr_neigh) { - struct nr_neigh *s; - - spin_lock_bh(&nr_neigh_lock); - if ((s = nr_neigh_list) == nr_neigh) { - nr_neigh_list = nr_neigh->next; - spin_unlock_bh(&nr_neigh_lock); - if (nr_neigh->digipeat != NULL) - kfree(nr_neigh->digipeat); - kfree(nr_neigh); - return; - } + hlist_del_init(&nr_neigh->neigh_node); + nr_neigh_put(nr_neigh); +} - while (s != NULL && s->next != NULL) { - if (s->next == nr_neigh) { - s->next = nr_neigh->next; - spin_unlock_bh(&nr_neigh_lock); - if (nr_neigh->digipeat != NULL) - kfree(nr_neigh->digipeat); - kfree(nr_neigh); - return; - } +#define nr_remove_neigh_locked(__neigh) \ + __nr_remove_neigh(__neigh) - s = s->next; - } - spin_unlock_bh(&nr_neigh_lock); +static void nr_remove_neigh(struct nr_neigh *nr_neigh) +{ + spin_lock_bh(&nr_neigh_list_lock); + __nr_remove_neigh(nr_neigh); + spin_unlock_bh(&nr_neigh_list_lock); } /* @@ -312,26 +352,27 @@ struct nr_neigh *nr_neigh; int i; - for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) - if (ax25cmp(callsign, &nr_node->callsign) == 0) - break; + nr_node = nr_node_get(callsign); if (nr_node == NULL) return -EINVAL; - for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) - if (ax25cmp(neighbour, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev) - break; + nr_neigh = nr_neigh_get_dev(neighbour, dev); - if (nr_neigh == NULL) + if (nr_neigh == NULL) { + nr_node_put(nr_node); return -EINVAL; + } + nr_node_lock(nr_node); for (i = 0; i < nr_node->count; i++) { if (nr_node->routes[i].neighbour == nr_neigh) { nr_neigh->count--; + nr_neigh_put(nr_neigh); if (nr_neigh->count == 0 && !nr_neigh->locked) nr_remove_neigh(nr_neigh); + nr_neigh_put(nr_neigh); nr_node->count--; @@ -346,11 +387,16 @@ case 2: break; } + nr_node_put(nr_node); } + nr_node_unlock(nr_node); return 0; } } + nr_neigh_put(nr_neigh); + nr_node_unlock(nr_node); + nr_node_put(nr_node); return -EINVAL; } @@ -362,12 +408,12 @@ { struct nr_neigh *nr_neigh; - for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) { - if (ax25cmp(callsign, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev) { - nr_neigh->quality = quality; - nr_neigh->locked = 1; - return 0; - } + nr_neigh = nr_neigh_get_dev(callsign, dev); + if (nr_neigh) { + nr_neigh->quality = quality; + nr_neigh->locked = 1; + nr_neigh_put(nr_neigh); + return 0; } if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) @@ -382,6 +428,7 @@ nr_neigh->count = 0; nr_neigh->number = nr_neigh_no++; nr_neigh->failed = 0; + atomic_set(&nr_neigh->refcount, 1); if (ax25_digi != NULL && ax25_digi->ndigi > 0) { if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) { @@ -391,10 +438,10 @@ memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi)); } - spin_lock_bh(&nr_neigh_lock); - nr_neigh->next = nr_neigh_list; - nr_neigh_list = nr_neigh; - spin_unlock_bh(&nr_neigh_lock); + spin_lock_bh(&nr_neigh_list_lock); + hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list); + /* refcount is initialized at 1 */ + spin_unlock_bh(&nr_neigh_list_lock); return 0; } @@ -407,9 +454,7 @@ { struct nr_neigh *nr_neigh; - for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) - if (ax25cmp(callsign, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev) - break; + nr_neigh = nr_neigh_get_dev(callsign, dev); if (nr_neigh == NULL) return -EINVAL; @@ -418,6 +463,7 @@ if (nr_neigh->count == 0) nr_remove_neigh(nr_neigh); + nr_neigh_put(nr_neigh); return 0; } @@ -430,15 +476,13 @@ static int nr_dec_obs(void) { struct nr_neigh *nr_neigh; - struct nr_node *s, *nr_node; + struct nr_node *s; + struct hlist_node *node, *nodet; int i; - nr_node = nr_node_list; - - while (nr_node != NULL) { - s = nr_node; - nr_node = nr_node->next; - + spin_lock_bh(&nr_node_list_lock); + nr_node_for_each_safe(s, node, nodet, &nr_node_list) { + nr_node_lock(s); for (i = 0; i < s->count; i++) { switch (s->routes[i].obs_count) { case 0: /* A locked entry */ @@ -448,6 +492,7 @@ nr_neigh = s->routes[i].neighbour; nr_neigh->count--; + nr_neigh_put(nr_neigh); if (nr_neigh->count == 0 && !nr_neigh->locked) nr_remove_neigh(nr_neigh); @@ -472,8 +517,10 @@ } if (s->count <= 0) - nr_remove_node(s); + nr_remove_node_locked(s); + nr_node_unlock(s); } + spin_unlock_bh(&nr_node_list_lock); return 0; } @@ -483,21 +530,17 @@ */ void nr_rt_device_down(struct net_device *dev) { - struct nr_neigh *s, *nr_neigh = nr_neigh_list; - struct nr_node *t, *nr_node; + struct nr_neigh *s; + struct hlist_node *node, *nodet, *node2, *node2t; + struct nr_node *t; int i; - while (nr_neigh != NULL) { - s = nr_neigh; - nr_neigh = nr_neigh->next; - + spin_lock_bh(&nr_neigh_list_lock); + nr_neigh_for_each_safe(s, node, nodet, &nr_neigh_list) { if (s->dev == dev) { - nr_node = nr_node_list; - - while (nr_node != NULL) { - t = nr_node; - nr_node = nr_node->next; - + spin_lock_bh(&nr_node_list_lock); + nr_node_for_each_safe(t, node2, node2t, &nr_node_list) { + nr_node_lock(t); for (i = 0; i < t->count; i++) { if (t->routes[i].neighbour == s) { t->count--; @@ -514,12 +557,15 @@ } if (t->count <= 0) - nr_remove_node(t); + nr_remove_node_locked(t); + nr_node_unlock(t); } + spin_unlock_bh(&nr_node_list_lock); - nr_remove_neigh(s); + nr_remove_neigh_locked(s); } } + spin_unlock_bh(&nr_neigh_list_lock); } /* @@ -553,6 +599,8 @@ if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; } + if (first) + dev_hold(first); read_unlock(&dev_base_lock); return first; @@ -603,6 +651,7 @@ { struct nr_route_struct nr_route; struct net_device *dev; + int ret; switch (cmd) { case SIOCADDRT: @@ -610,23 +659,29 @@ return -EFAULT; if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL) return -EINVAL; - if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) + if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) { + dev_put(dev); return -EINVAL; + } switch (nr_route.type) { case NETROM_NODE: - return nr_add_node(&nr_route.callsign, + ret = nr_add_node(&nr_route.callsign, nr_route.mnemonic, &nr_route.neighbour, nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters), dev, nr_route.quality, nr_route.obs_count); + break; case NETROM_NEIGH: - return nr_add_neigh(&nr_route.callsign, + ret = nr_add_neigh(&nr_route.callsign, nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters), dev, nr_route.quality); + break; default: - return -EINVAL; + ret = -EINVAL; } + dev_put(dev); + return ret; case SIOCDELRT: if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct))) @@ -635,14 +690,18 @@ return -EINVAL; switch (nr_route.type) { case NETROM_NODE: - return nr_del_node(&nr_route.callsign, + ret = nr_del_node(&nr_route.callsign, &nr_route.neighbour, dev); + break; case NETROM_NEIGH: - return nr_del_neigh(&nr_route.callsign, + ret = nr_del_neigh(&nr_route.callsign, dev, nr_route.quality); + break; default: - return -EINVAL; + ret = -EINVAL; } + dev_put(dev); + return ret; case SIOCNRDECOBS: return nr_dec_obs(); @@ -660,22 +719,36 @@ */ void nr_link_failed(ax25_cb *ax25, int reason) { - struct nr_neigh *nr_neigh; - struct nr_node *nr_node; - - for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) - if (nr_neigh->ax25 == ax25) + struct nr_neigh *s, *nr_neigh = NULL; + struct hlist_node *node; + struct nr_node *nr_node = NULL; + + spin_lock_bh(&nr_neigh_list_lock); + nr_neigh_for_each(s, node, &nr_neigh_list) + if (s->ax25 == ax25) { + nr_neigh_hold(s); + nr_neigh = s; break; + } + spin_unlock_bh(&nr_neigh_list_lock); if (nr_neigh == NULL) return; nr_neigh->ax25 = NULL; + // ax25_cb_put(ax25); - if (++nr_neigh->failed < sysctl_netrom_link_fails_count) return; - - for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) + if (++nr_neigh->failed < sysctl_netrom_link_fails_count) { + nr_neigh_put(nr_neigh); + return; + } + spin_lock_bh(&nr_node_list_lock); + nr_node_for_each(nr_node, node, &nr_node_list) + nr_node_lock(nr_node); if (nr_node->which < nr_node->count && nr_node->routes[nr_node->which].neighbour == nr_neigh) nr_node->which++; + nr_node_unlock(nr_node); + spin_unlock_bh(&nr_node_list_lock); + nr_neigh_put(nr_neigh); } /* @@ -689,6 +762,9 @@ struct nr_node *nr_node; struct net_device *dev; unsigned char *dptr; + ax25_cb *ax25s; + int ret; + struct sk_buff *skbn; nr_src = (ax25_address *)(skb->data + 0); @@ -700,98 +776,202 @@ if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */ if (ax25 == NULL) /* Its from me */ - return nr_loopback_queue(skb); + ret = nr_loopback_queue(skb); else - return nr_rx_frame(skb, dev); + ret = nr_rx_frame(skb, dev); + dev_put(dev); + return ret; } if (!sysctl_netrom_routing_control && ax25 != NULL) return 0; /* Its Time-To-Live has expired */ - if (--skb->data[14] == 0) + if (skb->data[14] == 1) { return 0; + } - for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) - if (ax25cmp(nr_dest, &nr_node->callsign) == 0) - break; + nr_node = nr_node_get(nr_dest); + if (nr_node == NULL) + return 0; + nr_node_lock(nr_node); - if (nr_node == NULL || nr_node->which >= nr_node->count) + if (nr_node->which >= nr_node->count) { + nr_node_unlock(nr_node); + nr_node_put(nr_node); return 0; + } nr_neigh = nr_node->routes[nr_node->which].neighbour; - if ((dev = nr_dev_first()) == NULL) + if ((dev = nr_dev_first()) == NULL) { + nr_node_unlock(nr_node); + nr_node_put(nr_node); + return 0; + } + + /* We are going to change the netrom headers so we should get our + own skb, we also did not know until now how much header space + we had to reserve... - RXQ */ + if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) { + nr_node_unlock(nr_node); + nr_node_put(nr_node); + dev_put(dev); return 0; + } + kfree_skb(skb); + skb=skbn; + skb->data[14]--; dptr = skb_push(skb, 1); *dptr = AX25_P_NETROM; - nr_neigh->ax25 = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev); + ax25s = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev); + if (nr_neigh->ax25 && ax25s) { + /* We were already holding this ax25_cb */ + // ax25_cb_put(ax25s); + } + nr_neigh->ax25 = ax25s; - return (nr_neigh->ax25 != NULL); + dev_put(dev); + ret = (nr_neigh->ax25 != NULL); + nr_node_unlock(nr_node); + nr_node_put(nr_node); + return ret; } -int nr_nodes_get_info(char *buffer, char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS +#define NETROM_PROC_START ((void *) 1) + +static void *nr_node_start(struct seq_file *seq, loff_t *pos) { struct nr_node *nr_node; - int len = 0; - off_t pos = 0; - off_t begin = 0; - int i; + struct hlist_node *node; + int i = 1; + + spin_lock_bh(&nr_node_list_lock); + if (*pos == 0) + return NETROM_PROC_START; + + nr_node_for_each(nr_node, node, &nr_node_list) { + if (i == *pos) + return nr_node; + ++i; + } + + return NULL; +} + +static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct hlist_node *node; + ++*pos; + + node = (v == NETROM_PROC_START) + ? nr_node_list.first + : ((struct nr_node *)v)->node_node.next; + + return hlist_entry(node, struct nr_node, node_node); +} + +static void nr_node_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&nr_node_list_lock); +} - spin_lock_bh(&nr_node_lock); - len += sprintf(buffer, "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n"); +static int nr_node_show(struct seq_file *seq, void *v) +{ + int i; - for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) { - len += sprintf(buffer + len, "%-9s %-7s %d %d", + if (v == NETROM_PROC_START) + seq_puts(seq, + "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n"); + else { + struct nr_node *nr_node = v; + nr_node_lock(nr_node); + seq_printf(seq, "%-9s %-7s %d %d", ax2asc(&nr_node->callsign), (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic, nr_node->which + 1, nr_node->count); for (i = 0; i < nr_node->count; i++) { - len += sprintf(buffer + len, " %3d %d %05d", + seq_printf(seq, " %3d %d %05d", nr_node->routes[i].quality, nr_node->routes[i].obs_count, nr_node->routes[i].neighbour->number); } + nr_node_unlock(nr_node); - len += sprintf(buffer + len, "\n"); + seq_puts(seq, "\n"); + } + return 0; +} - pos = begin + len; +static struct seq_operations nr_node_seqops = { + .start = nr_node_start, + .next = nr_node_next, + .stop = nr_node_stop, + .show = nr_node_show, +}; + +static int nr_node_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &nr_node_seqops); +} + +struct file_operations nr_nodes_fops = { + .owner = THIS_MODULE, + .open = nr_node_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - if (pos < offset) { - len = 0; - begin = pos; - } +static void *nr_neigh_start(struct seq_file *seq, loff_t *pos) +{ + struct nr_neigh *nr_neigh; + struct hlist_node *node; + int i = 1; - if (pos > offset + length) - break; + spin_lock_bh(&nr_neigh_list_lock); + if (*pos == 0) + return NETROM_PROC_START; + + nr_neigh_for_each(nr_neigh, node, &nr_neigh_list) { + if (i == *pos) + return nr_neigh; } - spin_unlock_bh(&nr_node_lock); + return NULL; +} - *start = buffer + (offset - begin); - len -= (offset - begin); +static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct hlist_node *node; + ++*pos; + + node = (v == NETROM_PROC_START) + ? nr_neigh_list.first + : ((struct nr_neigh *)v)->neigh_node.next; - if (len > length) len = length; + return hlist_entry(node, struct nr_neigh, neigh_node); +} - return len; +static void nr_neigh_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&nr_neigh_list_lock); } -int nr_neigh_get_info(char *buffer, char **start, off_t offset, int length) +static int nr_neigh_show(struct seq_file *seq, void *v) { - struct nr_neigh *nr_neigh; - int len = 0; - off_t pos = 0; - off_t begin = 0; int i; - spin_lock_bh(&nr_neigh_lock); - len += sprintf(buffer, "addr callsign dev qual lock count failed digipeaters\n"); + if (v == NETROM_PROC_START) + seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n"); + else { + struct nr_neigh *nr_neigh = v; - for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) { - len += sprintf(buffer + len, "%05d %-9s %-4s %3d %d %3d %3d", + seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d", nr_neigh->number, ax2asc(&nr_neigh->callsign), nr_neigh->dev ? nr_neigh->dev->name : "???", @@ -802,51 +982,60 @@ if (nr_neigh->digipeat != NULL) { for (i = 0; i < nr_neigh->digipeat->ndigi; i++) - len += sprintf(buffer + len, " %s", ax2asc(&nr_neigh->digipeat->calls[i])); + seq_printf(seq, " %s", + ax2asc(&nr_neigh->digipeat->calls[i])); } - len += sprintf(buffer + len, "\n"); - - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - - if (pos > offset + length) - break; + seq_puts(seq, "\n"); } + return 0; +} - spin_unlock_bh(&nr_neigh_lock); - - *start = buffer + (offset - begin); - len -= (offset - begin); - - if (len > length) len = length; +static struct seq_operations nr_neigh_seqops = { + .start = nr_neigh_start, + .next = nr_neigh_next, + .stop = nr_neigh_stop, + .show = nr_neigh_show, +}; + +static int nr_neigh_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &nr_neigh_seqops); +} + +struct file_operations nr_neigh_fops = { + .owner = THIS_MODULE, + .open = nr_neigh_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - return len; -} +#endif /* * Free all memory associated with the nodes and routes lists. */ void __exit nr_rt_free(void) { - struct nr_neigh *s, *nr_neigh = nr_neigh_list; - struct nr_node *t, *nr_node = nr_node_list; - - while (nr_node != NULL) { - t = nr_node; - nr_node = nr_node->next; - - nr_remove_node(t); - } - - while (nr_neigh != NULL) { - s = nr_neigh; - nr_neigh = nr_neigh->next; - - nr_remove_neigh(s); + struct nr_neigh *s = NULL; + struct nr_node *t = NULL; + struct hlist_node *node, *nodet; + + spin_lock_bh(&nr_neigh_list_lock); + spin_lock_bh(&nr_node_list_lock); + nr_node_for_each_safe(t, node, nodet, &nr_node_list) { + nr_node_lock(t); + nr_remove_node_locked(t); + nr_node_unlock(t); + } + nr_neigh_for_each_safe(s, node, nodet, &nr_neigh_list) { + while(s->count) { + s->count--; + nr_neigh_put(s); + } + nr_remove_neigh_locked(s); } + spin_unlock_bh(&nr_node_list_lock); + spin_unlock_bh(&nr_neigh_list_lock); } diff -Nru a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c --- a/net/netrom/nr_subr.c Mon Aug 18 22:21:06 2003 +++ b/net/netrom/nr_subr.c Mon Aug 18 22:21:06 2003 @@ -127,7 +127,7 @@ unsigned char *dptr; int len, timeout; - len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN; + len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; switch (frametype & 0x0F) { case NR_CONNREQ: @@ -151,7 +151,7 @@ /* * Space for AX.25 and NET/ROM network header */ - skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN); + skb_reserve(skb, NR_NETWORK_LEN); dptr = skb_put(skb, skb_tailroom(skb)); @@ -219,12 +219,12 @@ unsigned char *dptr; int len; - len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1; + len = NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1; if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL) return; - skb_reserve(skbn, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN); + skb_reserve(skbn, 0); dptr = skb_put(skbn, NR_NETWORK_LEN + NR_TRANSPORT_LEN); diff -Nru a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c --- a/net/netrom/nr_timer.c Mon Aug 18 22:21:04 2003 +++ b/net/netrom/nr_timer.c Mon Aug 18 22:21:04 2003 @@ -143,7 +143,10 @@ is accepted() it isn't 'dead' so doesn't get removed. */ if (sock_flag(sk, SOCK_DESTROY) || (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { + sock_hold(sk); nr_destroy_socket(sk); + bh_unlock_sock(sk); + sock_put(sk); return; } break; @@ -227,6 +230,7 @@ case NR_STATE_1: if (nr->n2count == nr->n2) { nr_disconnect(sk, ETIMEDOUT); + bh_unlock_sock(sk); return; } else { nr->n2count++; @@ -237,6 +241,7 @@ case NR_STATE_2: if (nr->n2count == nr->n2) { nr_disconnect(sk, ETIMEDOUT); + bh_unlock_sock(sk); return; } else { nr->n2count++; @@ -247,6 +252,7 @@ case NR_STATE_3: if (nr->n2count == nr->n2) { nr_disconnect(sk, ETIMEDOUT); + bh_unlock_sock(sk); return; } else { nr->n2count++; diff -Nru a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c --- a/net/netrom/sysctl_net_netrom.c Mon Aug 18 22:21:01 2003 +++ b/net/netrom/sysctl_net_netrom.c Mon Aug 18 22:21:01 2003 @@ -15,9 +15,9 @@ /* * Values taken from NET/ROM documentation. */ -static int min_quality[1], max_quality[] = {255}; -static int min_obs[1], max_obs[] = {255}; -static int min_ttl[1], max_ttl[] = {255}; +static int min_quality[] = {0}, max_quality[] = {255}; +static int min_obs[] = {0}, max_obs[] = {255}; +static int min_ttl[] = {0}, max_ttl[] = {255}; static int min_t1[] = {5 * HZ}; static int max_t1[] = {600 * HZ}; static int min_n2[] = {2}, max_n2[] = {127}; @@ -28,7 +28,7 @@ static int min_window[] = {1}, max_window[] = {127}; static int min_idle[] = {0 * HZ}; static int max_idle[] = {65535 * HZ}; -static int min_route[1], max_route[] = {1}; +static int min_route[] = {0}, max_route[] = {1}; static int min_fails[] = {1}, max_fails[] = {10}; static struct ctl_table_header *nr_table_header; diff -Nru a/net/netsyms.c b/net/netsyms.c --- a/net/netsyms.c Mon Aug 18 22:21:03 2003 +++ b/net/netsyms.c Mon Aug 18 22:21:03 2003 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,6 @@ #include #include #include -#include #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE) #include #endif @@ -276,6 +276,7 @@ EXPORT_SYMBOL(inetdev_by_index); EXPORT_SYMBOL(in_dev_finish_destroy); EXPORT_SYMBOL(ip_defrag); +EXPORT_SYMBOL(inet_peer_idlock); /* Route manipulation */ EXPORT_SYMBOL(ip_rt_ioctl); @@ -293,80 +294,6 @@ /* needed for ip_gre -cw */ EXPORT_SYMBOL(ip_statistics); - -EXPORT_SYMBOL(xfrm_user_policy); -EXPORT_SYMBOL(km_waitq); -EXPORT_SYMBOL(km_new_mapping); -EXPORT_SYMBOL(xfrm_cfg_sem); -EXPORT_SYMBOL(xfrm_policy_alloc); -EXPORT_SYMBOL(__xfrm_policy_destroy); -EXPORT_SYMBOL(xfrm_lookup); -EXPORT_SYMBOL(__xfrm_policy_check); -EXPORT_SYMBOL(__xfrm_route_forward); -EXPORT_SYMBOL(xfrm_state_alloc); -EXPORT_SYMBOL(__xfrm_state_destroy); -EXPORT_SYMBOL(xfrm_state_find); -EXPORT_SYMBOL(xfrm_state_insert); -EXPORT_SYMBOL(xfrm_state_add); -EXPORT_SYMBOL(xfrm_state_update); -EXPORT_SYMBOL(xfrm_state_check_expire); -EXPORT_SYMBOL(xfrm_state_check_space); -EXPORT_SYMBOL(xfrm_state_lookup); -EXPORT_SYMBOL(xfrm_state_register_afinfo); -EXPORT_SYMBOL(xfrm_state_unregister_afinfo); -EXPORT_SYMBOL(xfrm_state_get_afinfo); -EXPORT_SYMBOL(xfrm_state_put_afinfo); -EXPORT_SYMBOL(xfrm_state_delete_tunnel); -EXPORT_SYMBOL(xfrm_replay_check); -EXPORT_SYMBOL(xfrm_replay_advance); -EXPORT_SYMBOL(xfrm_check_selectors); -EXPORT_SYMBOL(xfrm_check_output); -EXPORT_SYMBOL(__secpath_destroy); -EXPORT_SYMBOL(secpath_dup); -EXPORT_SYMBOL(xfrm_get_acqseq); -EXPORT_SYMBOL(xfrm_parse_spi); -EXPORT_SYMBOL(xfrm4_rcv); -EXPORT_SYMBOL(xfrm4_tunnel_register); -EXPORT_SYMBOL(xfrm4_tunnel_deregister); -EXPORT_SYMBOL(xfrm4_tunnel_check_size); -EXPORT_SYMBOL(xfrm_register_type); -EXPORT_SYMBOL(xfrm_unregister_type); -EXPORT_SYMBOL(xfrm_get_type); -EXPORT_SYMBOL(inet_peer_idlock); -EXPORT_SYMBOL(xfrm_register_km); -EXPORT_SYMBOL(xfrm_unregister_km); -EXPORT_SYMBOL(xfrm_state_delete); -EXPORT_SYMBOL(xfrm_state_walk); -EXPORT_SYMBOL(xfrm_find_acq_byseq); -EXPORT_SYMBOL(xfrm_find_acq); -EXPORT_SYMBOL(xfrm_alloc_spi); -EXPORT_SYMBOL(xfrm_state_flush); -EXPORT_SYMBOL(xfrm_policy_kill); -EXPORT_SYMBOL(xfrm_policy_bysel); -EXPORT_SYMBOL(xfrm_policy_insert); -EXPORT_SYMBOL(xfrm_policy_walk); -EXPORT_SYMBOL(xfrm_policy_flush); -EXPORT_SYMBOL(xfrm_policy_byid); -EXPORT_SYMBOL(xfrm_policy_list); -EXPORT_SYMBOL(xfrm_dst_lookup); -EXPORT_SYMBOL(xfrm_policy_register_afinfo); -EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); -EXPORT_SYMBOL(xfrm_policy_get_afinfo); -EXPORT_SYMBOL(xfrm_policy_put_afinfo); - -EXPORT_SYMBOL_GPL(xfrm_probe_algs); -EXPORT_SYMBOL_GPL(xfrm_count_auth_supported); -EXPORT_SYMBOL_GPL(xfrm_count_enc_supported); -EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx); -EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx); -EXPORT_SYMBOL_GPL(xfrm_calg_get_byidx); -EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); -EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); -EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); -EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); -EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); -EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); -EXPORT_SYMBOL_GPL(skb_icv_walk); #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) EXPORT_SYMBOL_GPL(skb_cow_data); EXPORT_SYMBOL_GPL(pskb_put); @@ -482,10 +409,8 @@ EXPORT_SYMBOL(sysctl_max_syn_backlog); #endif -#endif - -#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_IP_SCTP_MODULE) || defined (CONFIG_IPV6_TUNNEL_MODULE) EXPORT_SYMBOL(ip_generic_getfrag); + #endif EXPORT_SYMBOL(tcp_read_sock); @@ -700,5 +625,11 @@ #endif /* CONFIG_NET_RADIO */ EXPORT_SYMBOL(linkwatch_fire_event); + +/* ethtool.c */ +EXPORT_SYMBOL(ethtool_op_get_link); +EXPORT_SYMBOL(ethtool_op_get_tx_csum); +EXPORT_SYMBOL(ethtool_op_get_sg); +EXPORT_SYMBOL(ethtool_op_set_sg); #endif /* CONFIG_NET */ diff -Nru a/net/sctp/Kconfig b/net/sctp/Kconfig --- a/net/sctp/Kconfig Mon Aug 18 22:21:01 2003 +++ b/net/sctp/Kconfig Mon Aug 18 22:21:01 2003 @@ -43,7 +43,7 @@ bool "SCTP: Use old checksum (Adler-32)" depends on IP_SCTP help - RCF2960 currently specifies the Adler-32 checksum algorithm for SCTP. + RFC2960 currently specifies the Adler-32 checksum algorithm for SCTP. This has been deprecated and replaced by an algorithm now referred to as crc32c. 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 Mon Aug 18 22:21:01 2003 +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c Mon Aug 18 22:21:01 2003 @@ -75,7 +75,7 @@ memcpy(out, in, length); sg[0].page = virt_to_page(out); - sg[0].offset = ((long)out & ~PAGE_MASK); + sg[0].offset = offset_in_page(out); sg[0].length = length; ret = crypto_cipher_encrypt(tfm, sg, sg, length); @@ -114,7 +114,7 @@ memcpy(out, in, length); sg[0].page = virt_to_page(out); - sg[0].offset = ((long)out & ~PAGE_MASK); + sg[0].offset = offset_in_page(out); sg[0].length = length; ret = crypto_cipher_decrypt(tfm, sg, sg, length); @@ -151,7 +151,7 @@ goto out_free_tfm; } sg[0].page = virt_to_page(input->data); - sg[0].offset = ((long)input->data & ~PAGE_MASK); + sg[0].offset = offset_in_page(input->data); sg[0].length = input->len; crypto_digest_init(tfm); diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c --- a/net/sunrpc/svcsock.c Mon Aug 18 22:21:01 2003 +++ b/net/sunrpc/svcsock.c Mon Aug 18 22:21:01 2003 @@ -567,14 +567,17 @@ (serv->sv_nrthreads+3) * serv->sv_bufsz, (serv->sv_nrthreads+3) * serv->sv_bufsz); - if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) + if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) { + svc_sock_received(svsk); return svc_deferred_recv(rqstp); + } clear_bit(SK_DATA, &svsk->sk_flags); while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { - svc_sock_received(svsk); - if (err == -EAGAIN) + if (err == -EAGAIN) { + svc_sock_received(svsk); return err; + } /* possibly an icmp error */ dprintk("svc: recvfrom returned error %d\n", -err); } @@ -869,8 +872,10 @@ test_bit(SK_CONN, &svsk->sk_flags), test_bit(SK_CLOSE, &svsk->sk_flags)); - if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) + if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) { + svc_sock_received(svsk); return svc_deferred_recv(rqstp); + } if (test_bit(SK_CLOSE, &svsk->sk_flags)) { svc_delete_socket(svsk); @@ -1545,6 +1550,5 @@ set_bit(SK_DEFERRED, &svsk->sk_flags); } spin_unlock(&serv->sv_lock); - svc_sock_received(svsk); return dr; } diff -Nru a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c --- a/net/sunrpc/sysctl.c Mon Aug 18 22:21:01 2003 +++ b/net/sunrpc/sysctl.c Mon Aug 18 22:21:01 2003 @@ -102,7 +102,7 @@ len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data); if (len > left) len = left; - copy_to_user(buffer, tmpbuf, len); + __copy_to_user(buffer, tmpbuf, len); if ((left -= len) > 0) { put_user('\n', (char *)buffer + len); left--; diff -Nru a/net/xfrm/Kconfig b/net/xfrm/Kconfig --- a/net/xfrm/Kconfig Mon Aug 18 22:21:03 2003 +++ b/net/xfrm/Kconfig Mon Aug 18 22:21:03 2003 @@ -1,9 +1,13 @@ # # XFRM configuration # +config XFRM + bool + depends on NET + config XFRM_USER tristate "IPsec user configuration interface" - depends on INET + depends on INET && XFRM ---help--- Support for IPsec user configuration interface used by native Linux tools. diff -Nru a/net/xfrm/Makefile b/net/xfrm/Makefile --- a/net/xfrm/Makefile Mon Aug 18 22:21:06 2003 +++ b/net/xfrm/Makefile Mon Aug 18 22:21:06 2003 @@ -2,6 +2,7 @@ # Makefile for the XFRM subsystem. # -obj-y := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o +obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o \ + xfrm_export.o obj-$(CONFIG_XFRM_USER) += xfrm_user.o diff -Nru a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c --- a/net/xfrm/xfrm_algo.c Mon Aug 18 22:21:02 2003 +++ b/net/xfrm/xfrm_algo.c Mon Aug 18 22:21:02 2003 @@ -217,6 +217,40 @@ .sadb_alg_maxbits = 256 } }, +{ + .name = "serpent", + + .uinfo = { + .encr = { + .blockbits = 128, + .defkeybits = 128, + } + }, + + .desc = { + .sadb_alg_id = SADB_X_EALG_SERPENTCBC, + .sadb_alg_ivlen = 8, + .sadb_alg_minbits = 128, + .sadb_alg_maxbits = 256, + } +}, +{ + .name = "twofish", + + .uinfo = { + .encr = { + .blockbits = 128, + .defkeybits = 128, + } + }, + + .desc = { + .sadb_alg_id = SADB_X_EALG_TWOFISHCBC, + .sadb_alg_ivlen = 8, + .sadb_alg_minbits = 128, + .sadb_alg_maxbits = 256 + } +}, }; static struct xfrm_algo_desc calg_list[] = { diff -Nru a/net/xfrm/xfrm_export.c b/net/xfrm/xfrm_export.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/xfrm/xfrm_export.c Mon Aug 18 22:21:06 2003 @@ -0,0 +1,75 @@ +#include +#include + +EXPORT_SYMBOL(xfrm_user_policy); +EXPORT_SYMBOL(km_waitq); +EXPORT_SYMBOL(km_new_mapping); +EXPORT_SYMBOL(xfrm_cfg_sem); +EXPORT_SYMBOL(xfrm_policy_alloc); +EXPORT_SYMBOL(__xfrm_policy_destroy); +EXPORT_SYMBOL(xfrm_lookup); +EXPORT_SYMBOL(__xfrm_policy_check); +EXPORT_SYMBOL(__xfrm_route_forward); +EXPORT_SYMBOL(xfrm_state_alloc); +EXPORT_SYMBOL(__xfrm_state_destroy); +EXPORT_SYMBOL(xfrm_state_find); +EXPORT_SYMBOL(xfrm_state_insert); +EXPORT_SYMBOL(xfrm_state_add); +EXPORT_SYMBOL(xfrm_state_update); +EXPORT_SYMBOL(xfrm_state_check_expire); +EXPORT_SYMBOL(xfrm_state_check_space); +EXPORT_SYMBOL(xfrm_state_lookup); +EXPORT_SYMBOL(xfrm_state_register_afinfo); +EXPORT_SYMBOL(xfrm_state_unregister_afinfo); +EXPORT_SYMBOL(xfrm_state_get_afinfo); +EXPORT_SYMBOL(xfrm_state_put_afinfo); +EXPORT_SYMBOL(xfrm_state_delete_tunnel); +EXPORT_SYMBOL(xfrm_replay_check); +EXPORT_SYMBOL(xfrm_replay_advance); +EXPORT_SYMBOL(xfrm_check_selectors); +EXPORT_SYMBOL(xfrm_check_output); +EXPORT_SYMBOL(__secpath_destroy); +EXPORT_SYMBOL(secpath_dup); +EXPORT_SYMBOL(xfrm_get_acqseq); +EXPORT_SYMBOL(xfrm_parse_spi); +EXPORT_SYMBOL(xfrm4_rcv); +EXPORT_SYMBOL(xfrm4_tunnel_register); +EXPORT_SYMBOL(xfrm4_tunnel_deregister); +EXPORT_SYMBOL(xfrm4_tunnel_check_size); +EXPORT_SYMBOL(xfrm_register_type); +EXPORT_SYMBOL(xfrm_unregister_type); +EXPORT_SYMBOL(xfrm_get_type); +EXPORT_SYMBOL(xfrm_register_km); +EXPORT_SYMBOL(xfrm_unregister_km); +EXPORT_SYMBOL(xfrm_state_delete); +EXPORT_SYMBOL(xfrm_state_walk); +EXPORT_SYMBOL(xfrm_find_acq_byseq); +EXPORT_SYMBOL(xfrm_find_acq); +EXPORT_SYMBOL(xfrm_alloc_spi); +EXPORT_SYMBOL(xfrm_state_flush); +EXPORT_SYMBOL(xfrm_policy_kill); +EXPORT_SYMBOL(xfrm_policy_bysel); +EXPORT_SYMBOL(xfrm_policy_insert); +EXPORT_SYMBOL(xfrm_policy_walk); +EXPORT_SYMBOL(xfrm_policy_flush); +EXPORT_SYMBOL(xfrm_policy_byid); +EXPORT_SYMBOL(xfrm_policy_list); +EXPORT_SYMBOL(xfrm_dst_lookup); +EXPORT_SYMBOL(xfrm_policy_register_afinfo); +EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); +EXPORT_SYMBOL(xfrm_policy_get_afinfo); +EXPORT_SYMBOL(xfrm_policy_put_afinfo); + +EXPORT_SYMBOL_GPL(xfrm_probe_algs); +EXPORT_SYMBOL_GPL(xfrm_count_auth_supported); +EXPORT_SYMBOL_GPL(xfrm_count_enc_supported); +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx); +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx); +EXPORT_SYMBOL_GPL(xfrm_calg_get_byidx); +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); +EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); +EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); +EXPORT_SYMBOL_GPL(skb_icv_walk); diff -Nru a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c --- a/net/xfrm/xfrm_user.c Mon Aug 18 22:21:04 2003 +++ b/net/xfrm/xfrm_user.c Mon Aug 18 22:21:04 2003 @@ -527,7 +527,7 @@ return -EINVAL; }; - switch (p->family) { + switch (p->sel.family) { case AF_INET: break; @@ -594,7 +594,7 @@ memcpy(&xp->lft, &p->lft, sizeof(xp->lft)); xp->action = p->action; xp->flags = p->flags; - xp->family = p->family; + xp->family = p->sel.family; /* XXX xp->share = p->share; */ } @@ -605,7 +605,7 @@ memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft)); p->priority = xp->priority; p->index = xp->index; - p->family = xp->family; + p->sel.family = xp->family; p->dir = dir; p->action = xp->action; p->flags = xp->flags; diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build --- a/scripts/Makefile.build Mon Aug 18 22:21:05 2003 +++ b/scripts/Makefile.build Mon Aug 18 22:21:05 2003 @@ -7,9 +7,8 @@ .PHONY: __build __build: -ifdef include_config -include .config -endif +# Read .config if it exist, otherwise ignore +-include .config include $(obj)/Makefile diff -Nru a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile --- a/scripts/genksyms/Makefile Mon Aug 18 22:21:05 2003 +++ b/scripts/genksyms/Makefile Mon Aug 18 22:21:05 2003 @@ -44,4 +44,4 @@ endif -targets += $(obj)/keywords.c $(obj)/lex.c $(obj)/parse.c $(obj)/parse.h +targets += keywords.c lex.c parse.c parse.h diff -Nru a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile --- a/scripts/kconfig/Makefile Mon Aug 18 22:21:06 2003 +++ b/scripts/kconfig/Makefile Mon Aug 18 22:21:06 2003 @@ -1,6 +1,55 @@ -################# -# -# Shared Makefile for the various lkc executables: +# =========================================================================== +# Kernel configuration targets +# These targets are used from top-level makefile + +.PHONY: oldconfig xconfig gconfig menuconfig config + +xconfig: scripts/kconfig/qconf + ./scripts/kconfig/qconf arch/$(ARCH)/Kconfig + +gconfig: scripts/kconfig/gconf + ./scripts/kconfig/gconf arch/$(ARCH)/Kconfig + +menuconfig: scripts/kconfig/mconf + $(Q)$(MAKE) $(build)=scripts/lxdialog + ./scripts/kconfig/mconf arch/$(ARCH)/Kconfig + +config: scripts/kconfig/conf + ./scripts/kconfig/conf arch/$(ARCH)/Kconfig + +oldconfig: scripts/kconfig/conf + ./scripts/kconfig/conf -o arch/$(ARCH)/Kconfig + +.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig + +randconfig: scripts/kconfig/conf + ./scripts/kconfig/conf -r arch/$(ARCH)/Kconfig + +allyesconfig: scripts/kconfig/conf + ./scripts/kconfig/conf -y arch/$(ARCH)/Kconfig + +allnoconfig: scripts/kconfig/conf + ./scripts/kconfig/conf -n arch/$(ARCH)/Kconfig + +allmodconfig: scripts/kconfig/conf + ./scripts/kconfig/conf -m arch/$(ARCH)/Kconfig + +defconfig: scripts/kconfig/conf + ./scripts/kconfig/conf -d arch/$(ARCH)/Kconfig + +# Help text used by make help +help: + @echo ' oldconfig - Update current config utilising a line-oriented program' + @echo ' menuconfig - Update current config utilising a menu based program' + @echo ' xconfig - Update current config utilising a QT based front-end' + @echo ' gconfig - Update current config utilising a GTK based front-end' + @echo ' defconfig - New config with default answer to all options' + @echo ' allmodconfig - New config selecting modules when possible' + @echo ' allyesconfig - New config where all options are accepted with yes' + @echo ' allnoconfig - New minimal config' + +# =========================================================================== +# Shared Makefile for the various kconfig executables: # conf: Used for defconfig, oldconfig and related targets # mconf: Used for the mconfig target. # Utilizes the lxdialog package @@ -8,10 +57,8 @@ # Based on QT which needs to be installed to compile it # gconf: Used for the gconfig target # Based on GTK which needs to be installed to compile it -# -################# +# object files used by all kconfig flavours -# object files used by all lkc flavours libkconfig-objs := zconf.tab.o host-progs := conf mconf qconf gconf diff -Nru a/scripts/makeman b/scripts/makeman --- a/scripts/makeman Mon Aug 18 22:21:03 2003 +++ b/scripts/makeman Mon Aug 18 22:21:03 2003 @@ -12,7 +12,7 @@ ## $3 -- the filename which contained the sgmldoc output ## (I need this so I know which manpages to convert) -my($LISTING); +my($LISTING, $GENERATED, $INPUT, $OUTPUT, $front, $mode, $filename); if($ARGV[0] eq ""){ die "Usage: makeman [convert | install] \n"; @@ -32,8 +32,121 @@ s/typedef //; chomp; - print "Processing $_\n"; - system("cd $ARGV[1]; docbook2man $_.sgml; gzip -f $_.9\n"); + $filename = $_; + print "Processing $filename\n"; + + # Open the input file to extract the front matter, generate the man page, + # and open it, and the rearrange everything until it is happy + open INPUT, "< $ARGV[1]/$filename.sgml"; + $front = ""; + $mode = 0; + while(){ + if(/.*ENDFRONTTAG.*/){ + $mode = 0; + } + + if($mode > 0){ + s///; + s///; + s/<\/bookinfo>//; + s///; + s<\/docinfo>//; + s/^[ \t]*//; + } + + if($mode == 2){ + if(//){ + } + elsif(/<\/para>/){ + $front = "$front.\\\" \n"; + } + elsif(/<\/legalnotice>/){ + $mode = 1; + } + elsif(/^[ \t]*$/){ + } + else{ + $front = "$front.\\\" $_"; + } + } + + if($mode == 1){ + if(/(.*)<\/title>/){ + $front = "$front.\\\" This documentation was generated from the book titled \"$1\", which is part of the Linux kernel source.\n.\\\" \n"; + } + elsif(/<legalnotice>/){ + $front = "$front.\\\" This documentation comes with the following legal notice:\n.\\\" \n"; + $mode = 2; + } + + elsif(/<author>/){ + $front = "$front.\\\" Documentation by: "; + } + elsif(/<firstname>(.*)<\/firstname>/){ + $front = "$front$1 "; + } + elsif(/<surname>(.*)<\/surname>/){ + $front = "$front$1 "; + } + elsif(/<email>(.*)<\/email>/){ + $front = "$front($1)"; + } + elsif(/\/author>/){ + $front = "$front\n"; + } + + elsif(/<copyright>/){ + $front = "$front.\\\" Documentation copyright: "; + } + elsif(/<holder>(.*)<\/holder>/){ + $front = "$front$1 "; + } + elsif(/<year>(.*)<\/year>/){ + $front = "$front$1 "; + } + elsif(/\/copyright>/){ + $front = "$front\n"; + } + + elsif(/^[ \t]*$/ + || /<affiliation>/ + || /<\/affiliation>/ + || /<address>/ + || /<\/address>/ + || /<authorgroup>/ + || /<\/authorgroup>/ + || /<\/legalnotice>/ + || /<date>/ + || /<\/date>/ + || /<edition>/ + || /<\/edition>/){ + } + else{ + print "Unknown tag in manpage conversion: $_"; + } + } + + if(/.*BEGINFRONTTAG.*/){ + $mode = 1; + } + } + close INPUT; + + system("cd $ARGV[1]; docbook2man $filename.sgml; mv $filename.9 /tmp/$$.9\n"); + open GENERATED, "< /tmp/$$.9"; + open OUTPUT, "> $ARGV[1]/$filename.9"; + + print OUTPUT "$front"; + print OUTPUT ".\\\" For comments on the formatting of this manpage, please contact Michael Still <mikal\@stillhq.com>\n\n"; + while(<GENERATED>){ + print OUTPUT "$_"; + } + close OUTPUT; + close GENERATED; + + system("gzip -f $ARGV[1]/$filename.9\n"); + unlink("/tmp/$filename.9"); } } elsif($ARGV[0] eq "install"){ diff -Nru a/scripts/split-man b/scripts/split-man --- a/scripts/split-man Mon Aug 18 22:21:04 2003 +++ b/scripts/split-man Mon Aug 18 22:21:04 2003 @@ -35,7 +35,7 @@ $front = ""; while(<SGML>){ # Starting modes - if(/<legalnotice>/){ + if(/<bookinfo>/ || /<docinfo>/){ $mode = 1; } elsif(/<refentry>/){ @@ -51,14 +51,22 @@ print "Found manpage for $filename\n"; open REF, "> $ARGV[1]/$filename.sgml" or die "Couldn't open output file \"$ARGV[1]/$filename.sgml\": $!\n"; - print REF "<!DOCTYPE refentry PUBLIC \"-//Davenport//DTD DocBook V3.0//EN\">\n\n"; - print REF "$refdata"; + print REF <<EOF; +<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN"> + +<!-- BEGINFRONTTAG: The following is front matter for the parent book --> +$front +<!-- ENDFRONTTAG: End front matter --> + +$refdata +EOF $refdata = ""; } # Extraction if($mode == 1){ - $front = "$front$_"; + chomp $_; + $front = "$front<!-- $_ -->\n"; } elsif($mode == 2){ $refdata = "$refdata$_"; @@ -69,16 +77,8 @@ print REF "<manvolnum>9</manvolnum>\n"; } if(/<\/refentry>/){ - $front =~ s/<legalnotice>//; - $front =~ s/<\/legalnotice>//; print REF <<EOF; <refsect1><title>About this document -$front - -If you have comments on the formatting of this manpage, then please contact -Michael Still (mikal\@stillhq.com). - - This documentation was generated with kernel version $ARGV[2]. @@ -98,7 +98,7 @@ } # Ending modes - if(/<\/legalnotice>/){ + if(/<\/bookinfo>/ || /<\/docinfo>/){ $mode = 0; } elsif(/<\/refentry>/){ diff -Nru a/security/selinux/avc.c b/security/selinux/avc.c --- a/security/selinux/avc.c Mon Aug 18 22:21:04 2003 +++ b/security/selinux/avc.c Mon Aug 18 22:21:04 2003 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff -Nru a/security/selinux/hooks.c b/security/selinux/hooks.c --- a/security/selinux/hooks.c Mon Aug 18 22:21:06 2003 +++ b/security/selinux/hooks.c Mon Aug 18 22:21:06 2003 @@ -84,9 +84,6 @@ /* Lists of inode and superblock security structures initialized before the policy was loaded. */ -static LIST_HEAD(inode_security_head); -static spinlock_t inode_security_lock = SPIN_LOCK_UNLOCKED; - static LIST_HEAD(superblock_security_head); static spinlock_t sb_security_lock = SPIN_LOCK_UNLOCKED; @@ -148,14 +145,15 @@ static void inode_free_security(struct inode *inode) { struct inode_security_struct *isec = inode->i_security; + struct superblock_security_struct *sbsec = inode->i_sb->s_security; if (!isec || isec->magic != SELINUX_MAGIC) return; - spin_lock(&inode_security_lock); + spin_lock(&sbsec->isec_lock); if (!list_empty(&isec->list)) list_del_init(&isec->list); - spin_unlock(&inode_security_lock); + spin_unlock(&sbsec->isec_lock); inode->i_security = NULL; kfree(isec); @@ -207,6 +205,8 @@ memset(sbsec, 0, sizeof(struct superblock_security_struct)); init_MUTEX(&sbsec->sem); INIT_LIST_HEAD(&sbsec->list); + INIT_LIST_HEAD(&sbsec->isec_head); + spin_lock_init(&sbsec->isec_lock); sbsec->magic = SELINUX_MAGIC; sbsec->sb = sb; sbsec->sid = SECINITSID_UNLABELED; @@ -319,6 +319,29 @@ /* Initialize the root inode. */ rc = inode_doinit_with_dentry(sb->s_root->d_inode, sb->s_root); + + /* Initialize any other inodes associated with the superblock, e.g. + inodes created prior to initial policy load or inodes created + during get_sb by a pseudo filesystem that directly + populates itself. */ + spin_lock(&sbsec->isec_lock); +next_inode: + if (!list_empty(&sbsec->isec_head)) { + struct inode_security_struct *isec = + list_entry(sbsec->isec_head.next, + struct inode_security_struct, list); + struct inode *inode = isec->inode; + spin_unlock(&sbsec->isec_lock); + inode = igrab(inode); + if (inode) { + inode_doinit(inode); + iput(inode); + } + spin_lock(&sbsec->isec_lock); + list_del_init(&isec->list); + goto next_inode; + } + spin_unlock(&sbsec->isec_lock); out: up(&sbsec->sem); return rc; @@ -441,14 +464,14 @@ goto out; sbsec = inode->i_sb->s_security; - if (!sbsec || !sbsec->initialized) { + if (!sbsec->initialized) { /* Defer initialization until selinux_complete_init, after the initial policy is loaded and the security server is ready to handle calls. */ - spin_lock(&inode_security_lock); + spin_lock(&sbsec->isec_lock); if (list_empty(&isec->list)) - list_add(&isec->list, &inode_security_head); - spin_unlock(&inode_security_lock); + list_add(&isec->list, &sbsec->isec_head); + spin_unlock(&sbsec->isec_lock); goto out; } @@ -3376,27 +3399,6 @@ goto next_sb; } spin_unlock(&sb_security_lock); - - /* Set up any inodes initialized prior to the policy load. */ - printk(KERN_INFO "SELinux: Setting up existing inodes.\n"); - spin_lock(&inode_security_lock); -next_inode: - if (!list_empty(&inode_security_head)) { - struct inode_security_struct *isec = - list_entry(inode_security_head.next, - struct inode_security_struct, list); - struct inode *inode = isec->inode; - spin_unlock(&inode_security_lock); - inode = igrab(inode); - if (inode) { - inode_doinit(inode); - iput(inode); - } - spin_lock(&inode_security_lock); - list_del_init(&isec->list); - goto next_inode; - } - spin_unlock(&inode_security_lock); } /* SELinux requires early initialization in order to label diff -Nru a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h --- a/security/selinux/include/objsec.h Mon Aug 18 22:21:03 2003 +++ b/security/selinux/include/objsec.h Mon Aug 18 22:21:03 2003 @@ -66,6 +66,8 @@ unsigned char initialized; /* initialization flag */ unsigned char proc; /* proc fs */ struct semaphore sem; + struct list_head isec_head; + spinlock_t isec_lock; }; struct msg_security_struct { diff -Nru a/security/selinux/ss/global.h b/security/selinux/ss/global.h --- a/security/selinux/ss/global.h Mon Aug 18 22:21:05 2003 +++ b/security/selinux/ss/global.h Mon Aug 18 22:21:05 2003 @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "flask.h" #include "avc.h" diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c --- a/sound/core/seq/seq_clientmgr.c Mon Aug 18 22:21:01 2003 +++ b/sound/core/seq/seq_clientmgr.c Mon Aug 18 22:21:01 2003 @@ -58,7 +58,7 @@ */ static char clienttablock[SNDRV_SEQ_MAX_CLIENTS]; static client_t *clienttab[SNDRV_SEQ_MAX_CLIENTS]; -static usage_t client_usage = {0, 0}; +static usage_t client_usage; /* * prototypes diff -Nru a/sound/core/timer.c b/sound/core/timer.c --- a/sound/core/timer.c Mon Aug 18 22:21:04 2003 +++ b/sound/core/timer.c Mon Aug 18 22:21:04 2003 @@ -148,24 +148,19 @@ static void snd_timer_request(snd_timer_id_t *tid) { - char str[32]; - switch (tid->dev_class) { case SNDRV_TIMER_CLASS_GLOBAL: - if (tid->device >= timer_limit) - return; - sprintf(str, "snd-timer-%i", tid->device); + if (tid->device < timer_limit) + request_module("snd-timer-%i", tid->device); break; case SNDRV_TIMER_CLASS_CARD: case SNDRV_TIMER_CLASS_PCM: - if (tid->card >= snd_ecards_limit) - return; - sprintf(str, "snd-card-%i", tid->card); + if (tid->card < snd_ecards_limit) + request_module("snd-card-%i", tid->card); break; default: - return; + break; } - request_module(str); } #endif diff -Nru a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c --- a/sound/drivers/opl3/opl3_lib.c Mon Aug 18 22:21:01 2003 +++ b/sound/drivers/opl3/opl3_lib.c Mon Aug 18 22:21:01 2003 @@ -440,9 +440,9 @@ default: opl3->command = &snd_opl2_command; if ((err = snd_opl3_detect(opl3)) < 0) { - snd_opl3_free(opl3); snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n", opl3->l_port, opl3->r_port); + snd_opl3_free(opl3); return err; } /* detect routine returns correct hardware type */ diff -Nru a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c --- a/sound/oss/ac97_plugin_ad1980.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/ac97_plugin_ad1980.c Mon Aug 18 22:21:00 2003 @@ -83,11 +83,11 @@ static struct ac97_driver ad1980_driver = { - codec_id: 0x41445370, - codec_mask: 0xFFFFFFFF, - name: "AD1980 example", - probe: ad1980_probe, - remove: __devexit_p(ad1980_remove), + .codec_id = 0x41445370, + .codec_mask = 0xFFFFFFFF, + .name = "AD1980 example", + .probe = ad1980_probe, + .remove = __devexit_p(ad1980_remove), }; /** diff -Nru a/sound/oss/ad1816.c b/sound/oss/ad1816.c --- a/sound/oss/ad1816.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/ad1816.c Mon Aug 18 22:21:05 2003 @@ -1213,7 +1213,7 @@ #ifdef __ISAPNP__ /* use isapnp for configuration */ static int isapnp = 1; -static int isapnpjump = 0; +static int isapnpjump; MODULE_PARM(isapnp, "i"); MODULE_PARM(isapnpjump, "i"); #endif diff -Nru a/sound/oss/ad1848.c b/sound/oss/ad1848.c --- a/sound/oss/ad1848.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/ad1848.c Mon Aug 18 22:21:04 2003 @@ -180,12 +180,12 @@ #ifdef CONFIG_PNP static int isapnp = 1; -static int isapnpjump = 0; -static int reverse = 0; +static int isapnpjump; +static int reverse; -static int audio_activated = 0; +static int audio_activated; #else -static int isapnp = 0; +static int isapnp; #endif @@ -2717,7 +2717,7 @@ * Timer stuff (for /dev/music). */ -static unsigned int current_interval = 0; +static unsigned int current_interval; static unsigned int ad1848_tmr_start(int dev, unsigned int usecs) { @@ -2971,8 +2971,10 @@ ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), 0 }, + /* The main driver for this card is opl3sa2 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021), 0 }, + */ { ISAPNP_VENDOR('G','R','V'), ISAPNP_DEVICE(0x0001), ISAPNP_VENDOR('G','R','V'), ISAPNP_FUNCTION(0x0000), 0 }, {0} @@ -3025,7 +3027,7 @@ static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_card *bus, int slot) { - char *busname = bus->dev.name[0] ? bus->dev.name : ad1848_isapnp_list[slot].name; + char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name; /* Initialize this baby. */ diff -Nru a/sound/oss/ad1889.c b/sound/oss/ad1889.c --- a/sound/oss/ad1889.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/ad1889.c Mon Aug 18 22:21:02 2003 @@ -775,14 +775,14 @@ } static struct file_operations ad1889_fops = { - llseek: no_llseek, - read: ad1889_read, - write: ad1889_write, - poll: ad1889_poll, - ioctl: ad1889_ioctl, - mmap: ad1889_mmap, - open: ad1889_open, - release: ad1889_release, + .llseek = no_llseek, + .read = ad1889_read, + .write = ad1889_write, + .poll = ad1889_poll, + .ioctl = ad1889_ioctl, + .mmap = ad1889_mmap, + .open = ad1889_open, + .release = ad1889_release, }; /************************* /dev/mixer interfaces ************************ */ @@ -810,10 +810,10 @@ } static struct file_operations ad1889_mixer_fops = { - llseek: no_llseek, - ioctl: ad1889_mixer_ioctl, - open: ad1889_mixer_open, - release: ad1889_mixer_release, + .llseek = no_llseek, + .ioctl = ad1889_mixer_ioctl, + .open = ad1889_mixer_open, + .release = ad1889_mixer_release, }; /************************* AC97 interfaces ****************************** */ @@ -1064,10 +1064,10 @@ MODULE_LICENSE("GPL"); static struct pci_driver ad1889_driver = { - name: DEVNAME, - id_table: ad1889_id_tbl, - probe: ad1889_probe, - remove: __devexit_p(ad1889_remove), + .name = DEVNAME, + .id_table = ad1889_id_tbl, + .probe = ad1889_probe, + .remove = __devexit_p(ad1889_remove), }; static int __init ad1889_init_module(void) diff -Nru a/sound/oss/ali5455.c b/sound/oss/ali5455.c --- a/sound/oss/ali5455.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/ali5455.c Mon Aug 18 22:21:05 2003 @@ -2933,15 +2933,15 @@ } static /*const */ struct file_operations ali_audio_fops = { - owner:THIS_MODULE, - llseek:no_llseek, - read:ali_read, - write:ali_write, - poll:ali_poll, - ioctl:ali_ioctl, - mmap:ali_mmap, - open:ali_open, - release:ali_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = ali_read, + .write = ali_write, + .poll = ali_poll, + .ioctl = ali_ioctl, + .mmap = ali_mmap, + .open = ali_open, + .release = ali_release, }; /* Read AC97 codec registers */ @@ -3060,10 +3060,10 @@ } static /*const */ struct file_operations ali_mixer_fops = { - owner:THIS_MODULE, - llseek:no_llseek, - ioctl:ali_ioctl_mixdev, - open:ali_open_mixdev, + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = ali_ioctl_mixdev, + .open = ali_open_mixdev, }; /* AC97 codec initialisation. These small functions exist so we don't @@ -3661,10 +3661,13 @@ MODULE_PARM(controller_independent_spdif_locked, "i"); #define ALI5455_MODULE_NAME "ali5455" static struct pci_driver ali_pci_driver = { - name:ALI5455_MODULE_NAME, id_table:ali_pci_tbl, probe:ali_probe, - remove:__devexit_p(ali_remove), + .name = ALI5455_MODULE_NAME, + .id_table = ali_pci_tbl, + .probe = ali_probe, + .remove = __devexit_p(ali_remove), #ifdef CONFIG_PM - suspend:ali_pm_suspend, resume:ali_pm_resume, + .suspend = ali_pm_suspend, + .resume = ali_pm_resume, #endif /* CONFIG_PM */ }; diff -Nru a/sound/oss/au1000.c b/sound/oss/au1000.c --- a/sound/oss/au1000.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/au1000.c Mon Aug 18 22:21:04 2003 @@ -911,11 +911,11 @@ } static /*const */ struct file_operations au1000_mixer_fops = { - owner:THIS_MODULE, - llseek:au1000_llseek, - ioctl:au1000_ioctl_mixdev, - open:au1000_open_mixdev, - release:au1000_release_mixdev, + .owner = THIS_MODULE, + .llseek = au1000_llseek, + .ioctl = au1000_ioctl_mixdev, + .open = au1000_open_mixdev, + .release = au1000_release_mixdev, }; /* --------------------------------------------------------------------- */ @@ -1940,15 +1940,15 @@ } static /*const */ struct file_operations au1000_audio_fops = { - owner: THIS_MODULE, - llseek: au1000_llseek, - read: au1000_read, - write: au1000_write, - poll: au1000_poll, - ioctl: au1000_ioctl, - mmap: au1000_mmap, - open: au1000_open, - release: au1000_release, + .owner = THIS_MODULE, + .llseek = au1000_llseek, + .read = au1000_read, + .write = au1000_write, + .poll = au1000_poll, + .ioctl = au1000_ioctl, + .mmap = au1000_mmap, + .open = au1000_open, + .release = au1000_release, }; diff -Nru a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c --- a/sound/oss/awe_wave.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/awe_wave.c Mon Aug 18 22:21:03 2003 @@ -99,9 +99,9 @@ }; /* sample and information table */ -static int current_sf_id = 0; /* current number of fonts */ -static int locked_sf_id = 0; /* locked position */ -static sf_list *sfhead = NULL, *sftail = NULL; /* linked-lists */ +static int current_sf_id; /* current number of fonts */ +static int locked_sf_id; /* locked position */ +static sf_list *sfhead, *sftail; /* linked-lists */ #define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0) #define awe_free_info() (sftail ? sftail->num_info : 0) @@ -206,7 +206,7 @@ #ifdef __ISAPNP__ static int isapnp = -1; #else -static int isapnp = 0; +static int isapnp; #endif MODULE_AUTHOR("Takashi Iwai "); @@ -226,10 +226,10 @@ /* maximum channels for playing */ static int awe_max_voices = AWE_MAX_VOICES; -static int patch_opened = 0; /* sample already loaded? */ +static int patch_opened; /* sample already loaded? */ static char atten_relative = FALSE; -static short atten_offset = 0; +static short atten_offset; static int awe_present = FALSE; /* awe device present? */ static int awe_busy = FALSE; /* awe device opened? */ @@ -246,7 +246,7 @@ #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT) #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2) -static int current_alloc_time = 0; /* voice allocation index for channel mode */ +static int current_alloc_time; /* voice allocation index for channel mode */ static struct synth_info awe_info = { "AWE32 Synth", /* name */ @@ -5271,10 +5271,10 @@ static int midi_opened = FALSE; static int midi_mode; -static int coarsetune = 0, finetune = 0; +static int coarsetune, finetune; static int xg_mapping = TRUE; -static int xg_bankmode = 0; +static int xg_bankmode; /* effect sensitivity */ diff -Nru a/sound/oss/btaudio.c b/sound/oss/btaudio.c --- a/sound/oss/btaudio.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/btaudio.c Mon Aug 18 22:21:02 2003 @@ -150,9 +150,9 @@ int rate; }; -static struct btaudio *btaudios = NULL; -static unsigned int debug = 0; -static unsigned int irq_debug = 0; +static struct btaudio *btaudios; +static unsigned int debug; +static unsigned int irq_debug; /* -------------------------------------------------------------- */ @@ -876,7 +876,7 @@ static int latency = -1; static int digital = 1; static int analog = 1; -static int rate = 0; +static int rate; #define BTA_OSPREY200 1 diff -Nru a/sound/oss/cs4232.c b/sound/oss/cs4232.c --- a/sound/oss/cs4232.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/cs4232.c Mon Aug 18 22:21:04 2003 @@ -74,9 +74,9 @@ #define CS_OUT3(a, b, c) {CS_OUT(a);CS_OUT(b);CS_OUT(c);} static int __initdata bss = 0; -static int mpu_base = 0, mpu_irq = 0; -static int synth_base = 0, synth_irq = 0; -static int mpu_detected = 0; +static int mpu_base, mpu_irq; +static int synth_base, synth_irq; +static int mpu_detected; int probe_cs4232_mpu(struct address_info *hw_config) { diff -Nru a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c --- a/sound/oss/cs46xx.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/cs46xx.c Mon Aug 18 22:21:00 2003 @@ -180,7 +180,7 @@ static unsigned long cs_debugmask=CS_INIT | CS_ERROR; /* use CS_DBGOUT with various mask values */ MODULE_PARM(cs_debugmask, "i"); #endif -static unsigned long hercules_egpio_disable=0; /* if non-zero set all EGPIO to 0 */ +static unsigned long hercules_egpio_disable; /* if non-zero set all EGPIO to 0 */ MODULE_PARM(hercules_egpio_disable, "i"); static unsigned long initdelay=700; /* PM delay in millisecs */ MODULE_PARM(initdelay, "i"); diff -Nru a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c --- a/sound/oss/dmabuf.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/dmabuf.c Mon Aug 18 22:21:00 2003 @@ -37,7 +37,7 @@ -static int debugmem = 0; /* switched off by default */ +static int debugmem; /* switched off by default */ static int dma_buffsize = DSP_BUFFSIZE; static long dmabuf_timeout(struct dma_buffparms *dmap) diff -Nru a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c --- a/sound/oss/dmasound/dmasound_atari.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/dmasound/dmasound_atari.c Mon Aug 18 22:21:02 2003 @@ -35,7 +35,7 @@ extern void atari_microwire_cmd(int cmd); static int is_falcon; -static int write_sq_ignore_int = 0; /* ++TeSche: used for Falcon */ +static int write_sq_ignore_int; /* ++TeSche: used for Falcon */ static int expand_bal; /* Balance factor for expanding (not volume!) */ static int expand_data; /* Data for expanding */ @@ -1256,7 +1256,7 @@ { #if 0 /* ++TeSche: if you should want to test this... */ - static int cnt = 0; + static int cnt; if (write_sq.active == 2) if (++cnt == 10) { /* simulate losing an interrupt */ diff -Nru a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c --- a/sound/oss/dmasound/dmasound_awacs.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/dmasound/dmasound_awacs.c Mon Aug 18 22:21:02 2003 @@ -137,11 +137,11 @@ */ static void *awacs_tx_cmd_space; static volatile struct dbdma_cmd *awacs_tx_cmds; -static int number_of_tx_cmd_buffers = 0; +static int number_of_tx_cmd_buffers; static void *awacs_rx_cmd_space; static volatile struct dbdma_cmd *awacs_rx_cmds; -static int number_of_rx_cmd_buffers = 0; +static int number_of_rx_cmd_buffers; /* * Cached values of AWACS registers (we can't read them). @@ -154,15 +154,15 @@ /* tracking values for the mixer contents */ -static int spk_vol = 0 ; -static int line_vol = 0 ; -static int passthru_vol = 0 ; +static int spk_vol; +static int line_vol; +static int passthru_vol; -static int ip_gain = 0 ; /* mic preamp settings */ +static int ip_gain; /* mic preamp settings */ static int rec_lev = 0x4545 ; /* default CD gain 69 % */ -static int mic_lev = 0 ; +static int mic_lev; static int cd_lev = 0x6363 ; /* 99 % */ -static int line_lev = 0 ; +static int line_lev; /* * Stuff for outputting a beep. The values range from -327 to +327 @@ -210,8 +210,8 @@ #define BEEP_VOLUME 15 /* 0 - 100 */ static int beep_vol = BEEP_VOLUME; -static int beep_playing = 0; -static int awacs_beep_state = 0; +static int beep_playing; +static int awacs_beep_state; static short *beep_buf; static void *beep_dbdma_cmd_space; static volatile struct dbdma_cmd *beep_dbdma_cmd; @@ -934,7 +934,7 @@ int stat; volatile struct dbdma_cmd *cp; /* != 0 when we are dealing with a DEAD xfer */ - static int emergency_in_use = 0 ; + static int emergency_in_use; spin_lock(&dmasound.lock); while (write_sq.active > 0) { /* we expect to have done something*/ diff -Nru a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c --- a/sound/oss/dmasound/dmasound_core.c Mon Aug 18 22:21:01 2003 +++ b/sound/oss/dmasound/dmasound_core.c Mon Aug 18 22:21:01 2003 @@ -215,12 +215,12 @@ static int sq_unit = -1; static int mixer_unit = -1; static int state_unit = -1; -static int irq_installed = 0; +static int irq_installed; #endif /* MODULE */ /* control over who can modify resources shared between play/record */ -static mode_t shared_resource_owner = 0 ; -static int shared_resources_initialised = 0 ; +static mode_t shared_resource_owner; +static int shared_resources_initialised; /* * Mid level stuff diff -Nru a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c --- a/sound/oss/dmasound/dmasound_q40.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/dmasound/dmasound_q40.c Mon Aug 18 22:21:00 2003 @@ -407,8 +407,8 @@ *DAC_LEFT=*DAC_RIGHT=127; } -static char *q40_pp=NULL; -static unsigned int q40_sc=0; +static char *q40_pp; +static unsigned int q40_sc; static void Q40PlayNextFrame(int index) { diff -Nru a/sound/oss/emu10k1/efxmgr.c b/sound/oss/emu10k1/efxmgr.c --- a/sound/oss/emu10k1/efxmgr.c Mon Aug 18 22:21:01 2003 +++ b/sound/oss/emu10k1/efxmgr.c Mon Aug 18 22:21:01 2003 @@ -123,7 +123,7 @@ { int oss_channel = VOLCTRL_CHANNEL; int left, right; - static int val = 0; + static int val; if (val) { left = val & 0xff; diff -Nru a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c --- a/sound/oss/emu10k1/main.c Mon Aug 18 22:21:06 2003 +++ b/sound/oss/emu10k1/main.c Mon Aug 18 22:21:06 2003 @@ -84,6 +84,8 @@ * Use unsigned long for variables in bit ops. * 0.20a Fixed recording startup * Fixed timer rate setting (it's a 16-bit register) + * 0.21 Converted code to use pci_name() instead of accessing slot_name + * directly (Eugene Teo) *********************************************************************/ /* These are only included once per module */ @@ -345,20 +347,20 @@ goto err_out; } - sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s", pci_name(card->pci_dev)); if (!proc_mkdir (s, 0)) { printk(KERN_ERR "emu10k1: unable to create proc directory %s\n", s); goto err_emu10k1_proc; } - sprintf(s, "driver/emu10k1/%s/info", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s/info", pci_name(card->pci_dev)); if (!create_proc_read_entry (s, 0, 0, emu10k1_info_proc, card)) { printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s); goto err_dev_proc; } if (!card->is_aps) { - sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s/ac97", pci_name(card->pci_dev)); if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) { printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s); goto err_proc_ac97; @@ -368,11 +370,11 @@ return 0; err_proc_ac97: - sprintf(s, "driver/emu10k1/%s/info", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s/info", pci_name(card->pci_dev)); remove_proc_entry(s, NULL); err_dev_proc: - sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s", pci_name(card->pci_dev)); remove_proc_entry(s, NULL); err_emu10k1_proc: @@ -387,14 +389,14 @@ char s[48]; if (!card->is_aps) { - sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s/ac97", pci_name(card->pci_dev)); remove_proc_entry(s, NULL); } - sprintf(s, "driver/emu10k1/%s/info", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s/info", pci_name(card->pci_dev)); remove_proc_entry(s, NULL); - sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name); + sprintf(s, "driver/emu10k1/%s", pci_name(card->pci_dev)); remove_proc_entry(s, NULL); remove_proc_entry("driver/emu10k1", NULL); diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c --- a/sound/oss/es1370.c Mon Aug 18 22:21:06 2003 +++ b/sound/oss/es1370.c Mon Aug 18 22:21:06 2003 @@ -2522,10 +2522,10 @@ /* maximum number of devices; only used for command line params */ #define NR_DEVICE 5 -static int lineout[NR_DEVICE] = { 0, }; -static int micbias[NR_DEVICE] = { 0, }; +static int lineout[NR_DEVICE]; +static int micbias[NR_DEVICE]; -static unsigned int devindex = 0; +static unsigned int devindex; MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i"); MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out"); @@ -2645,6 +2645,10 @@ outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); /* point phantom write channel to "bugbuf" */ s->bugbuf_cpu = pci_alloc_consistent(pcidev,16,&s->bugbuf_dma); + if (!s->bugbuf_cpu) { + ret = -ENOMEM; + goto err_dev5; + } outl((ES1370_REG_PHANTOM_FRAMEADR >> 8) & 15, s->io+ES1370_REG_MEMPAGE); outl(s->bugbuf_dma, s->io+(ES1370_REG_PHANTOM_FRAMEADR & 0xff)); outl(0, s->io+(ES1370_REG_PHANTOM_FRAMECNT & 0xff)); @@ -2676,6 +2680,8 @@ devindex++; return 0; + err_dev5: + unregister_sound_midi(s->dev_midi); err_dev4: unregister_sound_dsp(s->dev_dac); err_dev3: diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c --- a/sound/oss/es1371.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/es1371.c Mon Aug 18 22:21:05 2003 @@ -2738,11 +2738,11 @@ /* maximum number of devices; only used for command line params */ #define NR_DEVICE 5 -static int spdif[NR_DEVICE] = { 0, }; -static int nomix[NR_DEVICE] = { 0, }; -static int amplifier[NR_DEVICE] = { 0, }; +static int spdif[NR_DEVICE]; +static int nomix[NR_DEVICE]; +static int amplifier[NR_DEVICE]; -static unsigned int devindex = 0; +static unsigned int devindex; MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i"); MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode"); diff -Nru a/sound/oss/forte.c b/sound/oss/forte.c --- a/sound/oss/forte.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/forte.c Mon Aug 18 22:21:02 2003 @@ -361,11 +361,11 @@ static struct file_operations forte_mixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - ioctl: forte_mixer_ioctl, - open: forte_mixer_open, - release: forte_mixer_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = forte_mixer_ioctl, + .open = forte_mixer_open, + .release = forte_mixer_release, }; @@ -1632,15 +1632,15 @@ static struct file_operations forte_dsp_fops = { - owner: THIS_MODULE, - llseek: &no_llseek, - read: &forte_dsp_read, - write: &forte_dsp_write, - poll: &forte_dsp_poll, - ioctl: &forte_dsp_ioctl, - open: &forte_dsp_open, - release: &forte_dsp_release, - mmap: &forte_dsp_mmap, + .owner = THIS_MODULE, + .llseek = &no_llseek, + .read = &forte_dsp_read, + .write = &forte_dsp_write, + .poll = &forte_dsp_poll, + .ioctl = &forte_dsp_ioctl, + .open = &forte_dsp_open, + .release = &forte_dsp_release, + .mmap = &forte_dsp_mmap, }; @@ -2099,10 +2099,10 @@ static struct pci_driver forte_pci_driver = { - name: DRIVER_NAME, - id_table: forte_pci_ids, - probe: forte_probe, - remove: forte_remove, + .name = DRIVER_NAME, + .id_table = forte_pci_ids, + .probe = forte_probe, + .remove = forte_remove, }; diff -Nru a/sound/oss/gus_card.c b/sound/oss/gus_card.c --- a/sound/oss/gus_card.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/gus_card.c Mon Aug 18 22:21:00 2003 @@ -34,7 +34,7 @@ extern int have_gus_max; int gus_pnp_flag = 0; #ifdef CONFIG_SOUND_GUS16 -static int db16 = 0; /* Has a Gus16 AD1848 on it */ +static int db16; /* Has a Gus16 AD1848 on it */ #endif static void __init attach_gus(struct address_info *hw_config) @@ -200,10 +200,10 @@ #endif #ifdef CONFIG_SOUND_GUS16 -static int gus16 = 0; +static int gus16; #endif #ifdef CONFIG_SOUND_GUSMAX -static int no_wave_dma = 0;/* Set if no dma is to be used for the +static int no_wave_dma; /* Set if no dma is to be used for the wave table (GF1 chip) */ #endif diff -Nru a/sound/oss/gus_midi.c b/sound/oss/gus_midi.c --- a/sound/oss/gus_midi.c Mon Aug 18 22:21:06 2003 +++ b/sound/oss/gus_midi.c Mon Aug 18 22:21:06 2003 @@ -22,9 +22,9 @@ #include "gus.h" #include "gus_hw.h" -static int midi_busy = 0, input_opened = 0; +static int midi_busy, input_opened; static int my_dev; -static int output_used = 0; +static int output_used; static volatile unsigned char gus_midi_control; static void (*midi_input_intr) (int dev, unsigned char data); diff -Nru a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c --- a/sound/oss/gus_wave.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/gus_wave.c Mon Aug 18 22:21:02 2003 @@ -81,24 +81,24 @@ extern int gus_pnp_flag; extern int gus_no_wave_dma; static int gus_dma2 = -1; -static int dual_dma_mode = 0; -static long gus_mem_size = 0; -static long free_mem_ptr = 0; -static int gus_busy = 0; -static int gus_no_dma = 0; -static int nr_voices = 0; -static int gus_devnum = 0; +static int dual_dma_mode; +static long gus_mem_size; +static long free_mem_ptr; +static int gus_busy; +static int gus_no_dma; +static int nr_voices; +static int gus_devnum; static int volume_base, volume_scale, volume_method; static int gus_recmask = SOUND_MASK_MIC; -static int recording_active = 0; -static int only_read_access = 0; -static int only_8_bits = 0; +static int recording_active; +static int only_read_access; +static int only_8_bits; int iw_mode = 0; int gus_wave_volume = 60; int gus_pcm_volume = 80; int have_gus_max = 0; -static int gus_line_vol = 100, gus_mic_vol = 0; +static int gus_line_vol = 100, gus_mic_vol; static unsigned char mix_image = 0x00; int gus_timer_enabled = 0; @@ -108,7 +108,7 @@ * at the same time. The active_device specifies the active driver */ -static int active_device = 0; +static int active_device; #define GUS_DEV_WAVE 1 /* Wave table synth */ #define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */ @@ -133,7 +133,7 @@ static volatile int pcm_head, pcm_tail, pcm_qlen; static volatile int pcm_active; static volatile int dma_active; -static int pcm_opened = 0; +static int pcm_opened; static int pcm_current_dev; static int pcm_current_block; static unsigned long pcm_current_buf; @@ -168,11 +168,11 @@ 19293 /* 32 */ }; -static struct patch_info *samples = NULL; +static struct patch_info *samples; static long sample_ptrs[MAX_SAMPLE + 1]; static int sample_map[32]; static int free_sample; -static int mixer_type = 0; +static int mixer_type; static int patch_table[MAX_PATCH]; @@ -3034,7 +3034,7 @@ gus_initialize(); - if ((gus_mem_size > 0) & !gus_no_wave_dma) + if ((gus_mem_size > 0) && !gus_no_wave_dma) { hw_config->slots[4] = -1; if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION, @@ -3350,7 +3350,7 @@ */ static volatile int select_addr, data_addr; -static volatile int curr_timer = 0; +static volatile int curr_timer; void gus_timer_command(unsigned int addr, unsigned int val) { diff -Nru a/sound/oss/hal2.c b/sound/oss/hal2.c --- a/sound/oss/hal2.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/hal2.c Mon Aug 18 22:21:05 2003 @@ -1313,22 +1313,22 @@ } static struct file_operations hal2_audio_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: hal2_read, - write: hal2_write, - poll: hal2_poll, - ioctl: hal2_ioctl, - open: hal2_open, - release: hal2_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = hal2_read, + .write = hal2_write, + .poll = hal2_poll, + .ioctl = hal2_ioctl, + .open = hal2_open, + .release = hal2_release, }; static struct file_operations hal2_mixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - ioctl: hal2_ioctl_mixdev, - open: hal2_open_mixdev, - release: hal2_release_mixdev, + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = hal2_ioctl_mixdev, + .open = hal2_open_mixdev, + .release = hal2_release_mixdev, }; static int hal2_request_irq(hal2_card_t *hal2, int irq) diff -Nru a/sound/oss/harmony.c b/sound/oss/harmony.c --- a/sound/oss/harmony.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/harmony.c Mon Aug 18 22:21:05 2003 @@ -822,14 +822,14 @@ */ static struct file_operations harmony_audio_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: harmony_audio_read, - write: harmony_audio_write, - poll: harmony_audio_poll, - ioctl: harmony_audio_ioctl, - open: harmony_audio_open, - release:harmony_audio_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = harmony_audio_read, + .write = harmony_audio_write, + .poll = harmony_audio_poll, + .ioctl = harmony_audio_ioctl, + .open = harmony_audio_open, + .release = harmony_audio_release, }; static int harmony_audio_init(void) @@ -1144,11 +1144,11 @@ } static struct file_operations harmony_mixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - open: harmony_mixer_open, - release: harmony_mixer_release, - ioctl: harmony_mixer_ioctl, + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = harmony_mixer_open, + .release = harmony_mixer_release, + .ioctl = harmony_mixer_ioctl, }; @@ -1274,9 +1274,9 @@ MODULE_DEVICE_TABLE(parisc, harmony_tbl); static struct parisc_driver harmony_driver = { - name: "Lasi Harmony", - id_table: harmony_tbl, - probe: harmony_driver_callback, + .name = "Lasi Harmony", + .id_table = harmony_tbl, + .probe = harmony_driver_callback, }; static int __init init_harmony(void) diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c --- a/sound/oss/i810_audio.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/i810_audio.c Mon Aug 18 22:21:05 2003 @@ -142,10 +142,10 @@ #define PCI_DEVICE_ID_AMD_8111_AC97 0x746d #endif -static int ftsodell=0; -static int strict_clocking=0; -static unsigned int clocking=0; -static int spdif_locked=0; +static int ftsodell; +static int strict_clocking; +static unsigned int clocking; +static int spdif_locked; //#define DEBUG //#define DEBUG2 @@ -3258,6 +3258,8 @@ free_irq(card->irq, devs); release_region(card->iobase, 64); release_region(card->ac97base, 256); + pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH, + card->channel, card->chandma); if (card->use_mmio) { iounmap(card->ac97base_mmio); iounmap(card->iobase_mmio); diff -Nru a/sound/oss/ite8172.c b/sound/oss/ite8172.c --- a/sound/oss/ite8172.c Mon Aug 18 22:21:01 2003 +++ b/sound/oss/ite8172.c Mon Aug 18 22:21:01 2003 @@ -51,6 +51,8 @@ * Revision history * 02.08.2001 Initial release * 06.22.2001 Added I2S support + * 07.30.2003 Removed initialisation to zero for static variables + * (spdif[NR_DEVICE], i2s_fmt[NR_DEVICE], and devindex) */ #include #include @@ -1003,11 +1005,11 @@ } static /*const*/ struct file_operations it8172_mixer_fops = { - owner: THIS_MODULE, - llseek: it8172_llseek, - ioctl: it8172_ioctl_mixdev, - open: it8172_open_mixdev, - release: it8172_release_mixdev, + .owner = THIS_MODULE, + .llseek = it8172_llseek, + .ioctl = it8172_ioctl_mixdev, + .open = it8172_open_mixdev, + .release = it8172_release_mixdev, }; /* --------------------------------------------------------------------- */ @@ -1872,15 +1874,15 @@ } static /*const*/ struct file_operations it8172_audio_fops = { - owner: THIS_MODULE, - llseek: it8172_llseek, - read: it8172_read, - write: it8172_write, - poll: it8172_poll, - ioctl: it8172_ioctl, - mmap: it8172_mmap, - open: it8172_open, - release: it8172_release, + .owner = THIS_MODULE, + .llseek = it8172_llseek, + .read = it8172_read, + .write = it8172_write, + .poll = it8172_poll, + .ioctl = it8172_ioctl, + .mmap = it8172_mmap, + .open = it8172_open, + .release = it8172_release, }; @@ -1952,10 +1954,10 @@ /* maximum number of devices; only used for command line params */ #define NR_DEVICE 5 -static int spdif[NR_DEVICE] = { 0, }; -static int i2s_fmt[NR_DEVICE] = { 0, }; +static int spdif[NR_DEVICE]; +static int i2s_fmt[NR_DEVICE]; -static unsigned int devindex = 0; +static unsigned int devindex; MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i"); MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled"); diff -Nru a/sound/oss/kahlua.c b/sound/oss/kahlua.c --- a/sound/oss/kahlua.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/kahlua.c Mon Aug 18 22:21:05 2003 @@ -203,10 +203,10 @@ MODULE_DEVICE_TABLE(pci, id_tbl); static struct pci_driver kahlua_driver = { - name: "kahlua", - id_table: id_tbl, - probe: probe_one, - remove: __devexit_p(remove_one), + .name = "kahlua", + .id_table = id_tbl, + .probe = probe_one, + .remove = __devexit_p(remove_one), }; diff -Nru a/sound/oss/mad16.c b/sound/oss/mad16.c --- a/sound/oss/mad16.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/mad16.c Mon Aug 18 22:21:05 2003 @@ -54,7 +54,7 @@ static int mad16_cdsel; static struct gameport gameport; static spinlock_t lock=SPIN_LOCK_UNLOCKED; -static int already_initialized = 0; +static int already_initialized; #define C928 1 #define MOZART 2 @@ -93,8 +93,8 @@ static int *mad16_osp; static int c931_detected; /* minor differences from C930 */ -static char c924pnp = 0; /* " " " C924 */ -static int debug = 0; /* debugging output */ +static char c924pnp; /* " " " C924 */ +static int debug; /* debugging output */ #ifdef DDB #undef DDB @@ -686,7 +686,7 @@ static int __init probe_mad16_mpu(struct address_info *hw_config) { - static int mpu_attached = 0; + static int mpu_attached; unsigned char tmp; if (!already_initialized) /* The MSS port must be initialized first */ diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c --- a/sound/oss/maestro.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/maestro.c Mon Aug 18 22:21:05 2003 @@ -242,14 +242,14 @@ #define M_DEBUG 1 #ifdef M_DEBUG -static int debug=0; +static int debug; #define M_printk(args...) {if (debug) printk(args);} #else #define M_printk(x) #endif /* we try to setup 2^(dsps_order) /dev/dsp devices */ -static int dsps_order=0; +static int dsps_order; /* whether or not we mess around with power management */ static int use_pm=2; /* set to 1 for force */ /* clocking for broken hardware - a few laptops seem to use a 50Khz clock diff -Nru a/sound/oss/maui.c b/sound/oss/maui.c --- a/sound/oss/maui.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/maui.c Mon Aug 18 22:21:04 2003 @@ -39,7 +39,7 @@ static int maui_base = 0x330; -static volatile int irq_ok = 0; +static volatile int irq_ok; static int *maui_osp; #define HOST_DATA_PORT (maui_base + 2) @@ -413,7 +413,7 @@ free_irq(irq, NULL); } -static int fw_load = 0; +static int fw_load; static struct address_info cfg; diff -Nru a/sound/oss/midibuf.c b/sound/oss/midibuf.c --- a/sound/oss/midibuf.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/midibuf.c Mon Aug 18 22:21:03 2003 @@ -52,7 +52,7 @@ static struct timer_list poll_timer = TIMER_INITIALIZER(midi_poll, 0, 0); -static volatile int open_devs = 0; +static volatile int open_devs; static spinlock_t lock=SPIN_LOCK_UNLOCKED; #define DATA_AVAIL(q) (q->len) diff -Nru a/sound/oss/mpu401.c b/sound/oss/mpu401.c --- a/sound/oss/mpu401.c Mon Aug 18 22:21:06 2003 +++ b/sound/oss/mpu401.c Mon Aug 18 22:21:06 2003 @@ -109,12 +109,9 @@ #define MPU_RESET 0xFF #define UART_MODE_ON 0x3F -static struct mpu_config dev_conf[MAX_MIDI_DEV] = -{ - {0} -}; +static struct mpu_config dev_conf[MAX_MIDI_DEV]; -static int n_mpu_devs = 0; +static int n_mpu_devs; static int reset_mpu401(struct mpu_config *devc); static void set_uart_mode(int dev, struct mpu_config *devc, int arg); diff -Nru a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c --- a/sound/oss/nec_vrc5477.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/nec_vrc5477.c Mon Aug 18 22:21:04 2003 @@ -104,8 +104,8 @@ #endif /* VRC5477_AC97_DEBUG */ #if defined(VRC5477_AC97_VERBOSE_DEBUG) -static u16 inTicket=0; /* check sync between intr & write */ -static u16 outTicket=0; +static u16 inTicket; /* check sync between intr & write */ +static u16 outTicket; #endif /* --------------------------------------------------------------------- */ @@ -1810,7 +1810,7 @@ /* maximum number of devices; only used for command line params */ #define NR_DEVICE 5 -static unsigned int devindex = 0; +static unsigned int devindex; MODULE_AUTHOR("Monta Vista Software, jsun@mvista.com or jsun@junsun.net"); MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver"); diff -Nru a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c --- a/sound/oss/nm256_audio.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/nm256_audio.c Mon Aug 18 22:21:03 2003 @@ -533,7 +533,7 @@ { struct nm256_info *card = (struct nm256_info *)dev_id; u16 status; - static int badintrcount = 0; + static int badintrcount; int handled = 0; if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) { @@ -636,7 +636,7 @@ { struct nm256_info *card = (struct nm256_info *)dev_id; u32 status; - static int badintrcount = 0; + static int badintrcount; int handled = 0; if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) { diff -Nru a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c --- a/sound/oss/opl3sa.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/opl3sa.c Mon Aug 18 22:21:05 2003 @@ -33,13 +33,13 @@ #ifdef SB_OK #include "sb.h" -static int sb_initialized = 0; +static int sb_initialized; #endif -static int kilroy_was_here = 0; /* Don't detect twice */ -static int mpu_initialized = 0; +static int kilroy_was_here; /* Don't detect twice */ +static int mpu_initialized; static spinlock_t lock=SPIN_LOCK_UNLOCKED; -static int *opl3sa_osp = NULL; +static int *opl3sa_osp; static unsigned char opl3sa_read(int addr) { diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c --- a/sound/oss/opl3sa2.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/opl3sa2.c Mon Aug 18 22:21:00 2003 @@ -125,7 +125,7 @@ #endif /* This should be pretty obvious */ -static int opl3sa2_cards_num; /* = 0 */ +static int opl3sa2_cards_num; typedef struct { /* device resources */ diff -Nru a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c --- a/sound/oss/pas2_card.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/pas2_card.c Mon Aug 18 22:21:04 2003 @@ -37,24 +37,24 @@ */ int pas_translate_code = 0; -static int pas_intr_mask = 0; -static int pas_irq = 0; -static int pas_sb_base = 0; +static int pas_intr_mask; +static int pas_irq; +static int pas_sb_base; spinlock_t pas_lock=SPIN_LOCK_UNLOCKED; #ifndef CONFIG_PAS_JOYSTICK -static int joystick = 0; +static int joystick; #else static int joystick = 1; #endif #ifdef SYMPHONY_PAS static int symphony = 1; #else -static int symphony = 0; +static int symphony; #endif #ifdef BROKEN_BUS_CLOCK static int broken_bus_clock = 1; #else -static int broken_bus_clock = 0; +static int broken_bus_clock; #endif static struct address_info cfg; diff -Nru a/sound/oss/pas2_midi.c b/sound/oss/pas2_midi.c --- a/sound/oss/pas2_midi.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/pas2_midi.c Mon Aug 18 22:21:04 2003 @@ -21,7 +21,7 @@ extern spinlock_t pas_lock; -static int midi_busy = 0, input_opened = 0; +static int midi_busy, input_opened; static int my_dev; int pas2_mididev=-1; diff -Nru a/sound/oss/pas2_mixer.c b/sound/oss/pas2_mixer.c --- a/sound/oss/pas2_mixer.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/pas2_mixer.c Mon Aug 18 22:21:02 2003 @@ -31,7 +31,7 @@ extern int pas_audiodev; static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */ -static int mode_control = 0; +static int mode_control; #define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \ SOUND_MASK_CD | SOUND_MASK_ALTPCM) diff -Nru a/sound/oss/pas2_pcm.c b/sound/oss/pas2_pcm.c --- a/sound/oss/pas2_pcm.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/pas2_pcm.c Mon Aug 18 22:21:02 2003 @@ -34,16 +34,16 @@ #define PCM_DAC 1 #define PCM_ADC 2 -static unsigned long pcm_speed = 0; /* sampling rate */ +static unsigned long pcm_speed; /* sampling rate */ static unsigned char pcm_channels = 1; /* channels (1 or 2) */ static unsigned char pcm_bits = 8; /* bits/sample (8 or 16) */ -static unsigned char pcm_filter = 0; /* filter FLAG */ +static unsigned char pcm_filter; /* filter FLAG */ static unsigned char pcm_mode = PCM_NON; -static unsigned long pcm_count = 0; +static unsigned long pcm_count; static unsigned short pcm_bitsok = 8; /* mask of OK bits */ -static int pcm_busy = 0; +static int pcm_busy; int pas_audiodev = -1; -static int open_mode = 0; +static int open_mode; extern spinlock_t pas_lock; diff -Nru a/sound/oss/pss.c b/sound/oss/pss.c --- a/sound/oss/pss.c Mon Aug 18 22:21:06 2003 +++ b/sound/oss/pss.c Mon Aug 18 22:21:06 2003 @@ -120,7 +120,7 @@ #ifdef CONFIG_PSS_MIXER static unsigned char pss_mixer = 1; #else -static unsigned char pss_mixer = 0; +static unsigned char pss_mixer; #endif @@ -145,10 +145,10 @@ static pss_confdata *devc = &pss_data; static spinlock_t lock=SPIN_LOCK_UNLOCKED; -static int pss_initialized = 0; -static int nonstandard_microcode = 0; +static int pss_initialized; +static int nonstandard_microcode; static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */ -static int pss_enable_joystick = 0;/* Parameter for enabling the joystick */ +static int pss_enable_joystick; /* Parameter for enabling the joystick */ static void pss_write(pss_confdata *devc, int data) { diff -Nru a/sound/oss/sb_card.c b/sound/oss/sb_card.c --- a/sound/oss/sb_card.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/sb_card.c Mon Aug 18 22:21:04 2003 @@ -241,7 +241,7 @@ memset(scc, 0, sizeof(struct sb_card_config)); printk(KERN_INFO "sb: PnP: Found Card Named = \"%s\", Card PnP id = " \ - "%s, Device PnP id = %s\n", dev->dev.name, card_id->id, + "%s, Device PnP id = %s\n", card->card->name, card_id->id, dev->id->id); scc->card_id = card_id->id; diff -Nru a/sound/oss/sequencer.c b/sound/oss/sequencer.c --- a/sound/oss/sequencer.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/sequencer.c Mon Aug 18 22:21:03 2003 @@ -21,21 +21,21 @@ #include "midi_ctrl.h" -static int sequencer_ok = 0; +static int sequencer_ok; static struct sound_timer_operations *tmr; static int tmr_no = -1; /* Currently selected timer */ static int pending_timer = -1; /* For timer change operation */ extern unsigned long seq_time; -static int obsolete_api_used = 0; +static int obsolete_api_used; static spinlock_t lock=SPIN_LOCK_UNLOCKED; /* * Local counts for number of synth and MIDI devices. These are initialized * by the sequencer_open. */ -static int max_mididev = 0; -static int max_synthdev = 0; +static int max_mididev; +static int max_synthdev; /* * The seq_mode gives the operating mode of the sequencer: @@ -50,15 +50,11 @@ static DECLARE_WAIT_QUEUE_HEAD(seq_sleeper); static DECLARE_WAIT_QUEUE_HEAD(midi_sleeper); -static int midi_opened[MAX_MIDI_DEV] = { - 0 -}; - -static int midi_written[MAX_MIDI_DEV] = { - 0 -}; +static int midi_opened[MAX_MIDI_DEV]; -static unsigned long prev_input_time = 0; +static int midi_written[MAX_MIDI_DEV]; + +static unsigned long prev_input_time; static int prev_event_time; #include "tuning.h" @@ -66,13 +62,13 @@ #define EV_SZ 8 #define IEV_SZ 8 -static unsigned char *queue = NULL; -static unsigned char *iqueue = NULL; +static unsigned char *queue; +static unsigned char *iqueue; -static volatile int qhead = 0, qtail = 0, qlen = 0; -static volatile int iqhead = 0, iqtail = 0, iqlen = 0; -static volatile int seq_playing = 0; -static volatile int sequencer_busy = 0; +static volatile int qhead, qtail, qlen; +static volatile int iqhead, iqtail, iqlen; +static volatile int seq_playing; +static volatile int sequencer_busy; static int output_threshold; static long pre_event_timeout; static unsigned synth_open_mask; diff -Nru a/sound/oss/skeleton.c b/sound/oss/skeleton.c --- a/sound/oss/skeleton.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/skeleton.c Mon Aug 18 22:21:02 2003 @@ -53,7 +53,7 @@ */ static struct address_info mss_data[MAX_CARDS]; -static int cards = 0; +static int cards; /* * Install the actual card. This is an example diff -Nru a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c --- a/sound/oss/sonicvibes.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/sonicvibes.c Mon Aug 18 22:21:03 2003 @@ -371,7 +371,7 @@ /* --------------------------------------------------------------------- */ static LIST_HEAD(devs); -static unsigned long wavetable_mem = 0; +static unsigned long wavetable_mem; /* --------------------------------------------------------------------- */ @@ -2448,13 +2448,13 @@ /* maximum number of devices; only used for command line params */ #define NR_DEVICE 5 -static int reverb[NR_DEVICE] = { 0, }; +static int reverb[NR_DEVICE]; #if 0 -static int wavetable[NR_DEVICE] = { 0, }; +static int wavetable[NR_DEVICE]; #endif -static unsigned int devindex = 0; +static unsigned int devindex; MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i"); MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); diff -Nru a/sound/oss/soundcard.c b/sound/oss/soundcard.c --- a/sound/oss/soundcard.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/soundcard.c Mon Aug 18 22:21:03 2003 @@ -65,7 +65,7 @@ int sound_dmap_flag = 0; #endif -static char dma_alloc_map[MAX_DMA_CHANNELS] = {0}; +static char dma_alloc_map[MAX_DMA_CHANNELS]; #define DMA_MAP_UNAVAIL 0 #define DMA_MAP_FREE 1 @@ -78,7 +78,7 @@ * Table for configurable mixer volume handling */ static mixer_vol_table mixer_vols[MAX_MIXER_DEV]; -static int num_mixer_volumes = 0; +static int num_mixer_volumes; int *load_mixer_volumes(char *name, int *levels, int present) { @@ -534,8 +534,8 @@ &num_audiodevs}, }; -static int dmabuf = 0; -static int dmabug = 0; +static int dmabuf; +static int dmabug; MODULE_PARM(dmabuf, "i"); MODULE_PARM(dmabug, "i"); diff -Nru a/sound/oss/sscape.c b/sound/oss/sscape.c --- a/sound/oss/sscape.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/sscape.c Mon Aug 18 22:21:04 2003 @@ -150,7 +150,7 @@ #ifdef REVEAL_SPEA static char old_hardware = 1; #else -static char old_hardware = 0; +static char old_hardware; #endif static void sleep(unsigned howlong) @@ -402,7 +402,7 @@ unsigned long flags; unsigned char temp; volatile int done, timeout_val; - static unsigned char codec_dma_bits = 0; + static unsigned char codec_dma_bits; if (flag & CPF_FIRST) { @@ -595,8 +595,8 @@ &adev_info }; -static int sscape_detected = 0; -static int sscape_is_pnp = 0; +static int sscape_detected; +static int sscape_is_pnp; void __init attach_sscape(struct address_info *hw_config) { diff -Nru a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c --- a/sound/oss/swarm_cs4297a.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/swarm_cs4297a.c Mon Aug 18 22:21:03 2003 @@ -1590,10 +1590,10 @@ // Mixer file operations struct. // ****************************************************************************************** static /*const */ struct file_operations cs4297a_mixer_fops = { - llseek:cs4297a_llseek, - ioctl:cs4297a_ioctl_mixdev, - open:cs4297a_open_mixdev, - release:cs4297a_release_mixdev, + .llseek = cs4297a_llseek, + .ioctl = cs4297a_ioctl_mixdev, + .open = cs4297a_open_mixdev, + .release = cs4297a_release_mixdev, }; // --------------------------------------------------------------------- @@ -2508,14 +2508,14 @@ // Wave (audio) file operations struct. // ****************************************************************************************** static /*const */ struct file_operations cs4297a_audio_fops = { - llseek:cs4297a_llseek, - read:cs4297a_read, - write:cs4297a_write, - poll:cs4297a_poll, - ioctl:cs4297a_ioctl, - mmap:cs4297a_mmap, - open:cs4297a_open, - release:cs4297a_release, + .llseek = cs4297a_llseek, + .read = cs4297a_read, + .write = cs4297a_write, + .poll = cs4297a_poll, + .ioctl = cs4297a_ioctl, + .mmap = cs4297a_mmap, + .open = cs4297a_open, + .release = cs4297a_release, }; static irqreturn_t cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs) diff -Nru a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c --- a/sound/oss/sys_timer.c Mon Aug 18 22:21:03 2003 +++ b/sound/oss/sys_timer.c Mon Aug 18 22:21:03 2003 @@ -18,7 +18,7 @@ #include #include "sound_config.h" -static volatile int opened = 0, tmr_running = 0; +static volatile int opened, tmr_running; static volatile time_t tmr_offs, tmr_ctr; static volatile unsigned long ticks_offs; static volatile int curr_tempo, curr_timebase; diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c --- a/sound/oss/trident.c Mon Aug 18 22:21:05 2003 +++ b/sound/oss/trident.c Mon Aug 18 22:21:05 2003 @@ -3017,6 +3017,8 @@ } data = inl(TRID_REG(card, address)); + + spin_unlock_irqrestore(&card->lock, flags); return ((u16) (data >> 16)); diff -Nru a/sound/oss/trix.c b/sound/oss/trix.c --- a/sound/oss/trix.c Mon Aug 18 22:21:00 2003 +++ b/sound/oss/trix.c Mon Aug 18 22:21:00 2003 @@ -29,15 +29,15 @@ #include "trix_boot.h" -static int kilroy_was_here = 0; /* Don't detect twice */ -static int sb_initialized = 0; -static int mpu_initialized = 0; +static int kilroy_was_here; /* Don't detect twice */ +static int sb_initialized; +static int mpu_initialized; -static int *trix_osp = NULL; +static int *trix_osp; -static int mpu = 0; +static int mpu; -static int joystick=0; +static int joystick; static unsigned char trix_read(int addr) { @@ -426,7 +426,7 @@ static struct address_info cfg2; static struct address_info cfg_mpu; -static int sb = 0; +static int sb; static int fw_load; static int __initdata io = -1; diff -Nru a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c --- a/sound/oss/via82cxxx_audio.c Mon Aug 18 22:21:02 2003 +++ b/sound/oss/via82cxxx_audio.c Mon Aug 18 22:21:02 2003 @@ -335,7 +335,7 @@ /* number of cards, used for assigning unique numbers to cards */ -static unsigned via_num_cards = 0; +static unsigned via_num_cards; @@ -398,10 +398,10 @@ static struct pci_driver via_driver = { - name: VIA_MODULE_NAME, - id_table: via_pci_tbl, - probe: via_init_one, - remove: __devexit_p(via_remove_one), + .name = VIA_MODULE_NAME, + .id_table = via_pci_tbl, + .probe = via_init_one, + .remove = __devexit_p(via_remove_one), }; @@ -2057,15 +2057,15 @@ */ static struct file_operations via_dsp_fops = { - owner: THIS_MODULE, - open: via_dsp_open, - release: via_dsp_release, - read: via_dsp_read, - write: via_dsp_write, - poll: via_dsp_poll, - llseek: no_llseek, - ioctl: via_dsp_ioctl, - mmap: via_dsp_mmap, + .owner = THIS_MODULE, + .open = via_dsp_open, + .release = via_dsp_release, + .read = via_dsp_read, + .write = via_dsp_write, + .poll = via_dsp_poll, + .llseek = no_llseek, + .ioctl = via_dsp_ioctl, + .mmap = via_dsp_mmap, }; @@ -2179,10 +2179,10 @@ struct vm_operations_struct via_mm_ops = { - nopage: via_mm_nopage, + .nopage = via_mm_nopage, #ifndef VM_RESERVED - swapout: via_mm_swapout, + .swapout = via_mm_swapout, #endif }; @@ -3400,7 +3400,7 @@ #endif int rc; struct via_info *card; - static int printed_version = 0; + static int printed_version; DPRINTK ("ENTER\n"); diff -Nru a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c --- a/sound/oss/wf_midi.c Mon Aug 18 22:21:01 2003 +++ b/sound/oss/wf_midi.c Mon Aug 18 22:21:01 2003 @@ -359,7 +359,7 @@ { struct wf_mpu_config *physical_dev = dev_id; - static struct wf_mpu_config *input_dev = 0; + static struct wf_mpu_config *input_dev; struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info; int n; diff -Nru a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c --- a/sound/oss/ymfpci.c Mon Aug 18 22:21:04 2003 +++ b/sound/oss/ymfpci.c Mon Aug 18 22:21:04 2003 @@ -2496,8 +2496,8 @@ #ifdef CONFIG_SOUND_YMFPCI_LEGACY # ifdef MODULE -static int mpu_io = 0; -static int synth_io = 0; +static int mpu_io; +static int synth_io; MODULE_PARM(mpu_io, "i"); MODULE_PARM(synth_io, "i"); # else diff -Nru a/sound/parisc/harmony.c b/sound/parisc/harmony.c --- a/sound/parisc/harmony.c Mon Aug 18 22:21:03 2003 +++ b/sound/parisc/harmony.c Mon Aug 18 22:21:03 2003 @@ -1107,9 +1107,9 @@ */ static struct parisc_driver snd_card_harmony_driver = { - name: "Lasi ALSA Harmony", - id_table: snd_card_harmony_devicetbl, - probe: snd_card_harmony_probe, + .name = "Lasi ALSA Harmony", + .id_table = snd_card_harmony_devicetbl, + .probe = snd_card_harmony_probe, }; static int __init alsa_card_harmony_init(void) diff -Nru a/sound/pci/azt3328.c b/sound/pci/azt3328.c --- a/sound/pci/azt3328.c Mon Aug 18 22:21:04 2003 +++ b/sound/pci/azt3328.c Mon Aug 18 22:21:04 2003 @@ -1021,7 +1021,7 @@ { azf3328_t *chip = snd_magic_cast(azf3328_t, dev_id, return IRQ_NONE); unsigned int status, which; - static unsigned long count = 0; + static unsigned long count; status = inw(chip->codec_port+IDX_IO_IRQSTATUS); diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c --- a/sound/pci/cs46xx/dsp_spos.c Mon Aug 18 22:21:05 2003 +++ b/sound/pci/cs46xx/dsp_spos.c Mon Aug 18 22:21:05 2003 @@ -906,7 +906,7 @@ return 0; } -static int debug_tree = 0; +static int debug_tree; static void _dsp_create_task_tree (cs46xx_t *chip,u32 * task_data, u32 dest, int size) { unsigned long spdst = chip->region.idx[1].remap_addr + @@ -920,7 +920,7 @@ } } -static int debug_scb = 0; +static int debug_scb; static void _dsp_create_scb (cs46xx_t *chip,u32 * scb_data, u32 dest) { unsigned long spdst = chip->region.idx[1].remap_addr + diff -Nru a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c --- a/sound/pci/ice1712/ice1712.c Mon Aug 18 22:21:02 2003 +++ b/sound/pci/ice1712/ice1712.c Mon Aug 18 22:21:02 2003 @@ -113,7 +113,7 @@ static int snd_ice1712_build_pro_mixer(ice1712_t *ice); static int snd_ice1712_build_controls(ice1712_t *ice); -static int PRO_RATE_LOCKED = 0; +static int PRO_RATE_LOCKED; static int PRO_RATE_RESET = 1; static unsigned int PRO_RATE_DEFAULT = 44100; diff -Nru a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c --- a/sound/pci/ice1712/ice1724.c Mon Aug 18 22:21:03 2003 +++ b/sound/pci/ice1712/ice1724.c Mon Aug 18 22:21:03 2003 @@ -85,7 +85,7 @@ MODULE_DEVICE_TABLE(pci, snd_vt1724_ids); -static int PRO_RATE_LOCKED = 0; +static int PRO_RATE_LOCKED; static int PRO_RATE_RESET = 1; static unsigned int PRO_RATE_DEFAULT = 44100; diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c --- a/sound/pci/rme32.c Mon Aug 18 22:21:06 2003 +++ b/sound/pci/rme32.c Mon Aug 18 22:21:06 2003 @@ -1926,7 +1926,7 @@ static int __devinit snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { - static int dev = 0; + static int dev; rme32_t *rme32; snd_card_t *card; int err; diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c --- a/sound/usb/usbaudio.c Mon Aug 18 22:21:04 2003 +++ b/sound/usb/usbaudio.c Mon Aug 18 22:21:04 2003 @@ -2560,8 +2560,8 @@ err = usb_get_device_descriptor(dev); config = dev->actconfig; if (err < 0) snd_printdd("error usb_get_device_descriptor: %d\n", err); - err = usb_set_configuration(dev, get_cfg_desc(config)->bConfigurationValue); - if (err < 0) snd_printdd("error usb_set_configuration: %d\n", err); + err = usb_reset_configuration(dev); + if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err); snd_printdd("extigy_boot: new boot length = %d\n", get_cfg_desc(config)->wTotalLength); return -ENODEV; /* quit this anyway */ } @@ -2761,8 +2761,8 @@ * now look for an empty slot and create a new card instance */ /* first, set the current configuration for this device */ - if (usb_set_configuration(dev, get_cfg_desc(config)->bConfigurationValue) < 0) { - snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", get_cfg_desc(config)->bConfigurationValue); + if (usb_reset_configuration(dev) < 0) { + snd_printk(KERN_ERR "cannot reset configuration (value 0x%x)\n", get_cfg_desc(config)->bConfigurationValue); goto __error; } for (i = 0; i < SNDRV_CARDS; i++)