summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-06-22 22:01:51 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-22 22:01:51 -0700
commit2e7f53ec14475d56559bcdd07acfb737b7bff1e9 (patch)
tree964fee6f7bfc40bae796fe137e293c6831103919
parent5cb7db89366c7c64c5476bec0a2939c7c75af4c9 (diff)
parent8514206eb4e65262f50d6f18293dc3175ab05693 (diff)
Merge home.transmeta.com:/home/torvalds/v2.5/xfs
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--Documentation/firmware_class/README58
-rw-r--r--Documentation/firmware_class/firmware_sample_driver.c126
-rw-r--r--Documentation/firmware_class/firmware_sample_firmware_class.c205
-rw-r--r--Documentation/firmware_class/hotplug-script16
-rw-r--r--Documentation/kobject.txt11
-rw-r--r--Documentation/sched-coding.txt2
-rw-r--r--Documentation/vm/hugetlbpage.txt11
-rw-r--r--MAINTAINERS6
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c2
-rw-r--r--arch/alpha/kernel/entry.S61
-rw-r--r--arch/alpha/kernel/osf_sys.c7
-rw-r--r--arch/alpha/kernel/srmcons.c1
-rw-r--r--arch/alpha/kernel/traps.c4
-rw-r--r--arch/alpha/lib/memmove.S10
-rw-r--r--arch/alpha/oprofile/common.c2
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/kernel/pm.c2
-rw-r--r--arch/arm/lib/lib1funcs.S4
-rw-r--r--arch/arm/mach-sa1100/generic.c25
-rw-r--r--arch/arm/tools/mach-types22
-rw-r--r--arch/arm26/Kconfig2
-rw-r--r--arch/cris/Kconfig2
-rw-r--r--arch/h8300/Kconfig2
-rw-r--r--arch/i386/Kconfig2
-rw-r--r--arch/i386/kernel/acpi/Makefile1
-rw-r--r--arch/i386/kernel/acpi/acpitable.c553
-rw-r--r--arch/i386/kernel/acpi/acpitable.h260
-rw-r--r--arch/i386/kernel/entry.S3
-rw-r--r--arch/i386/kernel/process.c2
-rw-r--r--arch/i386/kernel/setup.c11
-rw-r--r--arch/i386/kernel/time.c10
-rw-r--r--arch/i386/kernel/traps.c16
-rw-r--r--arch/i386/mm/hugetlbpage.c56
-rw-r--r--arch/i386/mm/init.c7
-rw-r--r--arch/i386/pci/common.c23
-rw-r--r--arch/i386/pci/direct.c82
-rw-r--r--arch/i386/pci/fixup.c6
-rw-r--r--arch/i386/pci/irq.c2
-rw-r--r--arch/i386/pci/legacy.c6
-rw-r--r--arch/i386/pci/numa.c26
-rw-r--r--arch/i386/pci/pcbios.c22
-rw-r--r--arch/i386/pci/pci.h2
-rw-r--r--arch/ia64/Kconfig2
-rw-r--r--arch/ia64/ia32/ia32_entry.S22
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/kernel/ivt.S2
-rw-r--r--arch/ia64/pci/pci.c33
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/m68knommu/Kconfig2
-rw-r--r--arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S7
-rw-r--r--arch/m68knommu/platform/5249/config.c6
-rw-r--r--arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S7
-rw-r--r--arch/m68knommu/platform/5272/config.c5
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips64/Kconfig2
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/ppc/Kconfig2
-rw-r--r--arch/ppc64/Kconfig2
-rw-r--r--arch/ppc64/kernel/process.c17
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/kernel/process.c14
-rw-r--r--arch/sparc/kernel/systbls.S4
-rw-r--r--arch/sparc64/Kconfig2
-rw-r--r--arch/sparc64/defconfig78
-rw-r--r--arch/sparc64/kernel/systbls.S11
-rw-r--r--arch/sparc64/kernel/traps.c15
-rw-r--r--arch/sparc64/mm/fault.c6
-rw-r--r--arch/sparc64/solaris/fs.c4
-rw-r--r--arch/um/Kconfig2
-rw-r--r--arch/v850/Kconfig2
-rw-r--r--arch/x86_64/Kconfig2
-rw-r--r--drivers/acpi/Kconfig31
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/asus_acpi.c951
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c25
-rw-r--r--drivers/acpi/events/evgpe.c8
-rw-r--r--drivers/acpi/events/evgpeblk.c29
-rw-r--r--drivers/acpi/executer/exoparg1.c77
-rw-r--r--drivers/acpi/executer/exstore.c4
-rw-r--r--drivers/acpi/executer/exsystem.c4
-rw-r--r--drivers/acpi/executer/exutils.c5
-rw-r--r--drivers/acpi/hardware/hwregs.c47
-rw-r--r--drivers/acpi/hardware/hwsleep.c4
-rw-r--r--drivers/acpi/osl.c41
-rw-r--r--drivers/acpi/pci_root.c2
-rw-r--r--drivers/acpi/tables/tbconvrt.c26
-rw-r--r--drivers/acpi/utilities/utmisc.c2
-rw-r--r--drivers/base/Kconfig10
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/firmware_class.c505
-rw-r--r--drivers/base/sys.c8
-rw-r--r--drivers/block/loop.c207
-rw-r--r--drivers/block/nbd.c91
-rw-r--r--drivers/block/rd.c5
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/raw.c16
-rw-r--r--drivers/char/vt.c3
-rw-r--r--drivers/char/vt_ioctl.c2
-rw-r--r--drivers/ide/pci/sis5513.c464
-rw-r--r--drivers/input/gameport/gameport.c4
-rw-r--r--drivers/input/joystick/gamecon.c18
-rw-r--r--drivers/input/joystick/sidewinder.c11
-rw-r--r--drivers/input/keyboard/atkbd.c8
-rw-r--r--drivers/input/misc/uinput.c5
-rw-r--r--drivers/input/mouse/Kconfig17
-rw-r--r--drivers/input/mouse/Makefile5
-rw-r--r--drivers/input/mouse/logips2pp.c228
-rw-r--r--drivers/input/mouse/logips2pp.h17
-rw-r--r--drivers/input/mouse/psmouse-base.c193
-rw-r--r--drivers/input/mouse/psmouse.h2
-rw-r--r--drivers/input/mouse/synaptics.c7
-rw-r--r--drivers/input/mouse/synaptics.h10
-rw-r--r--drivers/input/serio/serio.c13
-rw-r--r--drivers/isdn/act2000/Makefile2
-rw-r--r--drivers/isdn/capi/Makefile1
-rw-r--r--drivers/isdn/divert/Makefile2
-rw-r--r--drivers/isdn/eicon/Makefile18
-rw-r--r--drivers/isdn/eicon/eicon_isa.c4
-rw-r--r--drivers/isdn/hardware/avm/b1pci.c4
-rw-r--r--drivers/isdn/hardware/avm/b1pcmcia.c2
-rw-r--r--drivers/isdn/hardware/avm/t1pci.c2
-rw-r--r--drivers/isdn/hardware/eicon/Makefile32
-rw-r--r--drivers/isdn/hisax/Makefile80
-rw-r--r--drivers/isdn/hisax/avma1_cs.c6
-rw-r--r--drivers/isdn/hysdn/Makefile13
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c6
-rw-r--r--drivers/isdn/i4l/Makefile31
-rw-r--r--drivers/isdn/i4l/isdn_bsdcomp.c4
-rw-r--r--drivers/isdn/i4l/isdn_ppp_ccp.c100
-rw-r--r--drivers/isdn/i4l/isdn_tty.c15
-rw-r--r--drivers/isdn/i4l/isdn_ttyfax.c2
-rw-r--r--drivers/isdn/isdnloop/Makefile2
-rw-r--r--drivers/isdn/pcbit/Makefile2
-rw-r--r--drivers/isdn/sc/Makefile4
-rw-r--r--drivers/isdn/tpam/Makefile5
-rw-r--r--drivers/isdn/tpam/tpam_queues.c1
-rw-r--r--drivers/mtd/afs.c16
-rw-r--r--drivers/mtd/chips/amd_flash.c3
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c47
-rw-r--r--drivers/mtd/devices/doc2000.c3
-rw-r--r--drivers/mtd/devices/doc2001.c5
-rw-r--r--drivers/mtd/devices/doc2001plus.c3
-rw-r--r--drivers/mtd/ftl.c41
-rw-r--r--drivers/mtd/inftlcore.c31
-rw-r--r--drivers/mtd/inftlmount.c13
-rw-r--r--drivers/mtd/maps/Kconfig4
-rw-r--r--drivers/mtd/maps/arctic-mtd.c47
-rw-r--r--drivers/mtd/maps/ebony.c8
-rw-r--r--drivers/mtd/maps/edb7312.c5
-rw-r--r--drivers/mtd/maps/elan-104nc.c19
-rw-r--r--drivers/mtd/maps/impa7.c69
-rw-r--r--drivers/mtd/maps/iq80310.c6
-rw-r--r--drivers/mtd/maps/lubbock-flash.c6
-rw-r--r--drivers/mtd/maps/pb1xxx-flash.c7
-rw-r--r--drivers/mtd/maps/tqm8xxl.c8
-rw-r--r--drivers/mtd/mtd_blkdevs.c54
-rw-r--r--drivers/mtd/mtdblock.c58
-rw-r--r--drivers/mtd/mtdblock_ro.c3
-rw-r--r--drivers/mtd/mtdpart.c4
-rw-r--r--drivers/mtd/nand/autcpu12.c3
-rw-r--r--drivers/mtd/nand/nand.c18
-rw-r--r--drivers/mtd/nftlcore.c30
-rwxr-xr-xdrivers/net/amd8111e.c12
-rw-r--r--drivers/net/bonding/bond_main.c88
-rw-r--r--drivers/net/hamradio/baycom_epp.c2
-rw-r--r--drivers/net/hamradio/yam.c12
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c1
-rw-r--r--drivers/net/myri_sbus.c11
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c93
-rw-r--r--drivers/net/pcnet32.c2
-rw-r--r--drivers/net/plip.c5
-rw-r--r--drivers/net/ppp_async.c4
-rw-r--r--drivers/net/pppoe.c1
-rw-r--r--drivers/net/sis900.c1
-rw-r--r--drivers/net/sundance.c6
-rw-r--r--drivers/net/tulip/Kconfig2
-rw-r--r--drivers/pci/bus.c6
-rw-r--r--drivers/pci/hotplug.c34
-rw-r--r--drivers/pci/hotplug/acpiphp.h16
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c15
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c50
-rw-r--r--drivers/pci/hotplug/acpiphp_pci.c4
-rw-r--r--drivers/pci/hotplug/acpiphp_res.c4
-rw-r--r--drivers/pci/pci-driver.c20
-rw-r--r--drivers/pci/pci-sysfs.c24
-rw-r--r--drivers/pci/pci.h3
-rw-r--r--drivers/pci/probe.c2
-rw-r--r--drivers/pci/proc.c46
-rw-r--r--drivers/pci/quirks.c4
-rw-r--r--drivers/pci/search.c151
-rw-r--r--drivers/pcmcia/i82365.c7
-rw-r--r--drivers/pnp/base.h20
-rw-r--r--drivers/pnp/core.c6
-rw-r--r--drivers/pnp/interface.c206
-rw-r--r--drivers/pnp/isapnp/core.c203
-rw-r--r--drivers/pnp/manager.c848
-rw-r--r--drivers/pnp/pnpbios/core.c4
-rw-r--r--drivers/pnp/quirks.c18
-rw-r--r--drivers/pnp/resource.c510
-rw-r--r--drivers/pnp/support.c141
-rw-r--r--drivers/scsi/aacraid/aachba.c10
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c4
-rw-r--r--drivers/scsi/arm/powertec.c5
-rw-r--r--drivers/scsi/scsi_scan.c11
-rw-r--r--drivers/scsi/st.c4
-rw-r--r--drivers/serial/8250_pnp.c62
-rw-r--r--drivers/telephony/ixj.c4
-rw-r--r--drivers/telephony/ixj.h6
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/input/hid-core.c7
-rw-r--r--fs/adfs/super.c4
-rw-r--r--fs/affs/super.c4
-rw-r--r--fs/befs/linuxvfs.c4
-rw-r--r--fs/bfs/inode.c2
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/cifs/CHANGES14
-rw-r--r--fs/cifs/asn1.c2
-rw-r--r--fs/cifs/cifs_fs_sb.h4
-rw-r--r--fs/cifs/cifsfs.c24
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/cifssmb.c7
-rw-r--r--fs/cifs/connect.c19
-rw-r--r--fs/cifs/file.c34
-rw-r--r--fs/cifs/inode.c26
-rw-r--r--fs/cifs/misc.c8
-rw-r--r--fs/cifs/netmisc.c6
-rw-r--r--fs/cifs/transport.c2
-rw-r--r--fs/coda/inode.c4
-rw-r--r--fs/coda/upcall.c2
-rw-r--r--fs/compat.c16
-rw-r--r--fs/cramfs/inode.c2
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/ext2/super.c4
-rw-r--r--fs/ext3/acl.c2
-rw-r--r--fs/ext3/balloc.c36
-rw-r--r--fs/ext3/bitmap.c2
-rw-r--r--fs/ext3/dir.c15
-rw-r--r--fs/ext3/file.c6
-rw-r--r--fs/ext3/hash.c12
-rw-r--r--fs/ext3/ialloc.c8
-rw-r--r--fs/ext3/inode.c61
-rw-r--r--fs/ext3/ioctl.c6
-rw-r--r--fs/ext3/namei.c46
-rw-r--r--fs/ext3/super.c35
-rw-r--r--fs/ext3/xattr.c14
-rw-r--r--fs/fat/inode.c2
-rw-r--r--fs/freevxfs/vxfs_super.c4
-rw-r--r--fs/fs-writeback.c19
-rw-r--r--fs/hfs/super.c4
-rw-r--r--fs/hpfs/hpfs_fn.h2
-rw-r--r--fs/hpfs/super.c2
-rw-r--r--fs/hugetlbfs/inode.c237
-rw-r--r--fs/intermezzo/intermezzo_fs.h2
-rw-r--r--fs/isofs/inode.c4
-rw-r--r--fs/jbd/checkpoint.c9
-rw-r--r--fs/jbd/commit.c8
-rw-r--r--fs/jbd/journal.c38
-rw-r--r--fs/jbd/recovery.c62
-rw-r--r--fs/jbd/revoke.c60
-rw-r--r--fs/jbd/transaction.c55
-rw-r--r--fs/jffs2/dir.c6
-rw-r--r--fs/jffs2/fs.c2
-rw-r--r--fs/jffs2/os-linux.h4
-rw-r--r--fs/jffs2/scan.c4
-rw-r--r--fs/jfs/super.c2
-rw-r--r--fs/libfs.c2
-rw-r--r--fs/lockd/svc.c7
-rw-r--r--fs/minix/inode.c4
-rw-r--r--fs/ncpfs/inode.c4
-rw-r--r--fs/ncpfs/sock.c4
-rw-r--r--fs/nfs/inode.c4
-rw-r--r--fs/nfsd/nfs3xdr.c2
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/nfsxdr.c2
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/ntfs/super.c2
-rw-r--r--fs/open.c115
-rw-r--r--fs/partitions/Kconfig12
-rw-r--r--fs/partitions/acorn.c241
-rw-r--r--fs/partitions/acorn.h59
-rw-r--r--fs/partitions/check.c28
-rw-r--r--fs/proc/base.c6
-rw-r--r--fs/proc/kcore.c16
-rw-r--r--fs/proc/task_mmu.c6
-rw-r--r--fs/qnx4/inode.c4
-rw-r--r--fs/reiserfs/super.c6
-rw-r--r--fs/romfs/inode.c2
-rw-r--r--fs/smbfs/inode.c4
-rw-r--r--fs/smbfs/proc.c2
-rw-r--r--fs/smbfs/proto.h2
-rw-r--r--fs/super.c2
-rw-r--r--fs/sysv/inode.c2
-rw-r--r--fs/udf/super.c4
-rw-r--r--fs/ufs/super.c6
-rw-r--r--fs/xfs/linux/xfs_super.c4
-rw-r--r--fs/xfs/linux/xfs_vfs.c2
-rw-r--r--fs/xfs/linux/xfs_vfs.h6
-rw-r--r--fs/xfs/xfs_vfsops.c4
-rw-r--r--include/acpi/acconfig.h2
-rw-r--r--include/acpi/acglobal.h1
-rw-r--r--include/acpi/achware.h2
-rw-r--r--include/acpi/acpiosxf.h8
-rw-r--r--include/acpi/actypes.h19
-rw-r--r--include/asm-alpha/pci.h12
-rw-r--r--include/asm-alpha/smp.h9
-rw-r--r--include/asm-alpha/statfs.h21
-rw-r--r--include/asm-alpha/unistd.h8
-rw-r--r--include/asm-alpha/xor.h20
-rw-r--r--include/asm-arm/statfs.h21
-rw-r--r--include/asm-cris/statfs.h21
-rw-r--r--include/asm-generic/statfs.h37
-rw-r--r--include/asm-h8300/statfs.h21
-rw-r--r--include/asm-h8300/uaccess.h4
-rw-r--r--include/asm-i386/acpi.h5
-rw-r--r--include/asm-i386/genapic.h2
-rw-r--r--include/asm-i386/mach-default/mach_resources.h8
-rw-r--r--include/asm-i386/mach-generic/mach_apic.h1
-rw-r--r--include/asm-i386/mach-pc9800/setup_arch_pre.h4
-rw-r--r--include/asm-i386/processor.h1
-rw-r--r--include/asm-i386/smp.h4
-rw-r--r--include/asm-i386/statfs.h21
-rw-r--r--include/asm-i386/uaccess.h3
-rw-r--r--include/asm-i386/unistd.h4
-rw-r--r--include/asm-ia64/compat.h3
-rw-r--r--include/asm-ia64/pci.h10
-rw-r--r--include/asm-ia64/smp.h4
-rw-r--r--include/asm-ia64/statfs.h27
-rw-r--r--include/asm-ia64/unistd.h2
-rw-r--r--include/asm-m68k/statfs.h21
-rw-r--r--include/asm-m68knommu/uaccess.h4
-rw-r--r--include/asm-parisc/compat.h3
-rw-r--r--include/asm-parisc/smp.h4
-rw-r--r--include/asm-parisc/statfs.h21
-rw-r--r--include/asm-ppc/pci.h7
-rw-r--r--include/asm-ppc/smp.h4
-rw-r--r--include/asm-ppc/statfs.h22
-rw-r--r--include/asm-ppc64/compat.h3
-rw-r--r--include/asm-ppc64/pci.h7
-rw-r--r--include/asm-ppc64/statfs.h20
-rw-r--r--include/asm-s390/smp.h4
-rw-r--r--include/asm-sparc/statfs.h21
-rw-r--r--include/asm-sparc/unistd.h7
-rw-r--r--include/asm-sparc64/compat.h3
-rw-r--r--include/asm-sparc64/pci.h7
-rw-r--r--include/asm-sparc64/smp.h4
-rw-r--r--include/asm-sparc64/statfs.h17
-rw-r--r--include/asm-sparc64/unistd.h9
-rw-r--r--include/asm-x86_64/compat.h3
-rw-r--r--include/asm-x86_64/smp.h4
-rw-r--r--include/asm-x86_64/statfs.h21
-rw-r--r--include/linux/acpi.h4
-rw-r--r--include/linux/bitops.h2
-rw-r--r--include/linux/coda_psdev.h2
-rw-r--r--include/linux/efs_fs.h2
-rw-r--r--include/linux/ext3_fs.h2
-rw-r--r--include/linux/ext3_fs_i.h2
-rw-r--r--include/linux/firmware.h19
-rw-r--r--include/linux/fs.h8
-rw-r--r--include/linux/gfp.h2
-rw-r--r--include/linux/highmem.h2
-rw-r--r--include/linux/hugetlb.h23
-rw-r--r--include/linux/input.h1
-rw-r--r--include/linux/isdn.h2
-rw-r--r--include/linux/isdn_ppp.h3
-rw-r--r--include/linux/loop.h13
-rw-r--r--include/linux/msdos_fs.h2
-rw-r--r--include/linux/mtd/blktrans.h17
-rw-r--r--include/linux/mtd/doc2000.h4
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/linux/netfilter_arp.h3
-rw-r--r--include/linux/nfsd/nfsd.h2
-rw-r--r--include/linux/nfsd/xdr.h2
-rw-r--r--include/linux/nfsd/xdr3.h2
-rw-r--r--include/linux/pci.h46
-rw-r--r--include/linux/pci_ids.h7
-rw-r--r--include/linux/pnp.h127
-rw-r--r--include/linux/sched.h16
-rw-r--r--include/linux/sem.h4
-rw-r--r--include/linux/serio.h1
-rw-r--r--include/linux/skbuff.h23
-rw-r--r--include/linux/smbno.h4
-rw-r--r--include/linux/spinlock.h9
-rw-r--r--include/linux/statfs.h22
-rw-r--r--include/linux/sysdev.h1
-rw-r--r--include/linux/time.h3
-rw-r--r--include/linux/timex.h2
-rw-r--r--include/linux/vfs.h2
-rw-r--r--ipc/sem.c298
-rw-r--r--ipc/util.c8
-rw-r--r--kernel/acct.c14
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c10
-rw-r--r--kernel/kmod.c12
-rw-r--r--kernel/ksyms.c1
-rw-r--r--kernel/sched.c26
-rw-r--r--kernel/timer.c4
-rw-r--r--kernel/workqueue.c85
-rw-r--r--lib/kobject.c11
-rw-r--r--mm/page-writeback.c7
-rw-r--r--mm/shmem.c4
-rw-r--r--mm/slab.c28
-rw-r--r--mm/swap_state.c9
-rw-r--r--net/bridge/br_netfilter.c51
-rw-r--r--net/core/flow.c37
-rw-r--r--net/ethernet/eth.c8
-rw-r--r--net/ipv4/arp.c17
-rw-r--r--net/ipv4/ip_output.c5
-rw-r--r--net/ipv4/netfilter/arp_tables.c9
-rw-r--r--net/ipv4/netfilter/arptable_filter.c67
-rw-r--r--net/ipv4/netfilter/ipt_MIRROR.c5
-rw-r--r--net/ipv6/icmp.c6
-rw-r--r--net/ipv6/ip6_output.c5
-rw-r--r--net/ipv6/ndisc.c13
-rw-r--r--net/irda/irda_device.c4
-rw-r--r--net/irda/irnet/irnet_irda.c86
-rw-r--r--net/irda/irnet/irnet_ppp.c58
-rw-r--r--net/irda/irttp.c2
-rw-r--r--net/sched/sch_htb.c48
-rw-r--r--net/sunrpc/sched.c3
-rw-r--r--scripts/kconfig/mconf.c2
-rw-r--r--sound/pci/korg1212/korg1212.c13
-rw-r--r--usr/gen_init_cpio.c8
426 files changed, 7611 insertions, 4400 deletions
diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README
new file mode 100644
index 000000000000..4b2c74fd73de
--- /dev/null
+++ b/Documentation/firmware_class/README
@@ -0,0 +1,58 @@
+
+ request_firmware() hotplug interface:
+ ------------------------------------
+ Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
+
+ Why:
+ ---
+
+ Today, the most extended way to use firmware in the Linux kernel is linking
+ it statically in a header file. Which has political and technical issues:
+
+ 1) Some firmware is not legal to redistribute.
+ 2) The firmware occupies memory permanently, even though it often is just
+ used once.
+ 3) Some people, like the Debian crowd, don't consider some firmware free
+ enough and remove entire drivers (e.g.: keyspan).
+
+ about in-kernel persistence:
+ ---------------------------
+ Under some circumstances, as explained below, it would be interesting to keep
+ firmware images in non-swappable kernel memory or even in the kernel image
+ (probably within initramfs).
+
+ Note that this functionality has not been implemented.
+
+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
+
+ - If the device that needs the firmware is needed to access the
+ filesystem. When upon some error the device has to be reset and the
+ firmware reloaded, it won't be possible to get it from userspace.
+ e.g.:
+ - A diskless client with a network card that needs firmware.
+ - The filesystem is stored in a disk behind an scsi device
+ that needs firmware.
+ - Replacing buggy DSDT/SSDT ACPI tables on boot.
+ Note: this would require the persistent objects to be included
+ within the kernel image, probably within initramfs.
+
+ And the same device can be needed to access the filesystem or not depending
+ on the setup, so I think that the choice on what firmware to make
+ persistent should be left to userspace.
+
+ - Why register_firmware()+__init can be useful:
+ - For boot devices needing firmware.
+ - To make the transition easier:
+ The firmware can be declared __init and register_firmware()
+ called on module_init. Then the firmware is warranted to be
+ there even if "firmware hotplug userspace" is not there yet or
+ it doesn't yet provide the needed firmware.
+ Once the firmware is widely available in userspace, it can be
+ removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
+
+ In either case, if firmware hotplug support is there, it can move the
+ firmware out of kernel memory into the real filesystem for later
+ usage.
+
+ Note: If persistence is implemented on top of initramfs,
+ register_firmware() may not be appropriate.
diff --git a/Documentation/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c
new file mode 100644
index 000000000000..e1c56a7e6583
--- /dev/null
+++ b/Documentation/firmware_class/firmware_sample_driver.c
@@ -0,0 +1,126 @@
+/*
+ * firmware_sample_driver.c -
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * Sample code on how to use request_firmware() from drivers.
+ *
+ * Note that register_firmware() is currently useless.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include "linux/firmware.h"
+
+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+char __init inkernel_firmware[] = "let's say that this is firmware\n";
+#endif
+
+static struct device ghost_device = {
+ .name = "Ghost Device",
+ .bus_id = "ghost0",
+};
+
+
+static void sample_firmware_load(char *firmware, int size)
+{
+ u8 buf[size+1];
+ memcpy(buf, firmware, size);
+ buf[size] = '\0';
+ printk("firmware_sample_driver: firmware: %s\n", buf);
+}
+
+static void sample_probe_default(void)
+{
+ /* uses the default method to get the firmware */
+ const struct firmware *fw_entry;
+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
+
+ if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0)
+ {
+ printk(KERN_ERR
+ "firmware_sample_driver: Firmware not available\n");
+ return;
+ }
+
+ sample_firmware_load(fw_entry->data, fw_entry->size);
+
+ release_firmware(fw_entry);
+
+ /* finish setting up the device */
+}
+static void sample_probe_specific(void)
+{
+ /* Uses some specific hotplug support to get the firmware from
+ * userspace directly into the hardware, or via some sysfs file */
+
+ /* NOTE: This currently doesn't work */
+
+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
+
+ if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0)
+ {
+ printk(KERN_ERR
+ "firmware_sample_driver: Firmware load failed\n");
+ return;
+ }
+
+ /* request_firmware blocks until userspace finished, so at
+ * this point the firmware should be already in the device */
+
+ /* finish setting up the device */
+}
+static void sample_probe_async_cont(const struct firmware *fw, void *context)
+{
+ if(!fw){
+ printk(KERN_ERR
+ "firmware_sample_driver: firmware load failed\n");
+ return;
+ }
+
+ printk("firmware_sample_driver: device pointer \"%s\"\n",
+ (char *)context);
+ sample_firmware_load(fw->data, fw->size);
+}
+static void sample_probe_async(void)
+{
+ /* Let's say that I can't sleep */
+ int error;
+ error = request_firmware_nowait (THIS_MODULE,
+ "sample_driver_fw", &ghost_device,
+ "my device pointer",
+ sample_probe_async_cont);
+ if(error){
+ printk(KERN_ERR
+ "firmware_sample_driver:"
+ " request_firmware_nowait failed\n");
+ }
+}
+
+static int sample_init(void)
+{
+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+ register_firmware("sample_driver_fw", inkernel_firmware,
+ sizeof(inkernel_firmware));
+#endif
+ device_initialize(&ghost_device);
+ /* since there is no real hardware insertion I just call the
+ * sample probe functions here */
+ sample_probe_specific();
+ sample_probe_default();
+ sample_probe_async();
+ return 0;
+}
+static void __exit sample_exit(void)
+{
+}
+
+module_init (sample_init);
+module_exit (sample_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c
new file mode 100644
index 000000000000..037c0bed9eb2
--- /dev/null
+++ b/Documentation/firmware_class/firmware_sample_firmware_class.c
@@ -0,0 +1,205 @@
+/*
+ * firmware_sample_firmware_class.c -
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * NOTE: This is just a probe of concept, if you think that your driver would
+ * be well served by this mechanism please contact me first.
+ *
+ * DON'T USE THIS CODE AS IS
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <asm/hardirq.h>
+
+#include "linux/firmware.h"
+
+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
+MODULE_LICENSE("GPL");
+
+static inline struct class_device *to_class_dev(struct kobject *obj)
+{
+ return container_of(obj,struct class_device,kobj);
+}
+static inline
+struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
+{
+ return container_of(_attr,struct class_device_attribute,attr);
+}
+
+int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+
+struct firmware_priv {
+ char fw_id[FIRMWARE_NAME_MAX];
+ s32 loading:2;
+ u32 abort:1;
+};
+
+extern struct class firmware_class;
+
+static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ return sprintf(buf, "%d\n", fw_priv->loading);
+}
+static ssize_t firmware_loading_store(struct class_device *class_dev,
+ const char *buf, size_t count)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ int prev_loading = fw_priv->loading;
+
+ fw_priv->loading = simple_strtol(buf, NULL, 10);
+
+ switch(fw_priv->loading){
+ case -1:
+ /* abort load an panic */
+ break;
+ case 1:
+ /* setup load */
+ break;
+ case 0:
+ if(prev_loading==1){
+ /* finish load and get the device back to working
+ * state */
+ }
+ break;
+ }
+
+ return count;
+}
+static CLASS_DEVICE_ATTR(loading, 0644,
+ firmware_loading_show, firmware_loading_store);
+
+static ssize_t firmware_data_read(struct kobject *kobj,
+ char *buffer, loff_t offset, size_t count)
+{
+ struct class_device *class_dev = to_class_dev(kobj);
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+ /* read from the devices firmware memory */
+
+ return count;
+}
+static ssize_t firmware_data_write(struct kobject *kobj,
+ char *buffer, loff_t offset, size_t count)
+{
+ struct class_device *class_dev = to_class_dev(kobj);
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+ /* write to the devices firmware memory */
+
+ return count;
+}
+static struct bin_attribute firmware_attr_data = {
+ .attr = {.name = "data", .mode = 0644},
+ .size = 0,
+ .read = firmware_data_read,
+ .write = firmware_data_write,
+};
+static int fw_setup_class_device(struct class_device *class_dev,
+ const char *fw_name,
+ struct device *device)
+{
+ int retval = 0;
+ struct firmware_priv *fw_priv = kmalloc(sizeof(struct firmware_priv),
+ GFP_KERNEL);
+
+ if(!fw_priv){
+ retval = -ENOMEM;
+ goto out;
+ }
+ memset(fw_priv, 0, sizeof(*fw_priv));
+ memset(class_dev, 0, sizeof(*class_dev));
+
+ strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
+ fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0';
+
+ strncpy(class_dev->class_id, device->bus_id, BUS_ID_SIZE);
+ class_dev->class_id[BUS_ID_SIZE-1] = '\0';
+ class_dev->dev = device;
+
+ class_dev->class = &firmware_class,
+ class_set_devdata(class_dev, fw_priv);
+ retval = class_device_register(class_dev);
+ if (retval){
+ printk(KERN_ERR "%s: class_device_register failed\n",
+ __FUNCTION__);
+ goto error_free_fw_priv;
+ }
+
+ retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data);
+ if (retval){
+ printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
+ __FUNCTION__);
+ goto error_unreg_class_dev;
+ }
+
+ retval = class_device_create_file(class_dev,
+ &class_device_attr_loading);
+ if (retval){
+ printk(KERN_ERR "%s: class_device_create_file failed\n",
+ __FUNCTION__);
+ goto error_remove_data;
+ }
+
+ goto out;
+
+error_remove_data:
+ sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
+error_unreg_class_dev:
+ class_device_unregister(class_dev);
+error_free_fw_priv:
+ kfree(fw_priv);
+out:
+ return retval;
+}
+static void fw_remove_class_device(struct class_device *class_dev)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+ class_device_remove_file(class_dev, &class_device_attr_loading);
+ sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
+ class_device_unregister(class_dev);
+}
+
+static struct class_device *class_dev;
+
+static struct device my_device = {
+ .name = "Sample Device",
+ .bus_id = "my_dev0",
+};
+
+static int __init firmware_sample_init(void)
+{
+ int error;
+
+ device_initialize(&my_device);
+ class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+ if(!class_dev)
+ return -ENOMEM;
+
+ error = fw_setup_class_device(class_dev, "my_firmware_image",
+ &my_device);
+ if(error){
+ kfree(class_dev);
+ return error;
+ }
+ return 0;
+
+}
+static void __exit firmware_sample_exit(void)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ fw_remove_class_device(class_dev);
+ kfree(fw_priv);
+ kfree(class_dev);
+}
+module_init(firmware_sample_init);
+module_exit(firmware_sample_exit);
+
diff --git a/Documentation/firmware_class/hotplug-script b/Documentation/firmware_class/hotplug-script
new file mode 100644
index 000000000000..0a31bcd6fa93
--- /dev/null
+++ b/Documentation/firmware_class/hotplug-script
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Simple hotplug script sample:
+#
+# 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
+
+# To cancel the load in case of error:
+#
+# echo -1 > /sysfs/$DEVPATH/loading
+#
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index d05ead30ee11..799671277953 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -5,15 +5,8 @@ Patrick Mochel <mochel@osdl.org>
Updated: 3 June 2003
-Copyright (c) Patrick Mochel
-Copyright (c) Open Source Development Labs
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.2
-or any later version published by the Free Software Foundation;
-with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-A copy of the license is included in the section entitled "GNU
-Free Documentation License".
-
+Copyright (c) 2003 Patrick Mochel
+Copyright (c) 2003 Open Source Development Labs
0. Introduction
diff --git a/Documentation/sched-coding.txt b/Documentation/sched-coding.txt
index 585b302beb9d..385f9eff6534 100644
--- a/Documentation/sched-coding.txt
+++ b/Documentation/sched-coding.txt
@@ -103,7 +103,7 @@ void set_user_nice(task_t *p, long nice)
Sets the "nice" value of task p to the given value.
int setscheduler(pid_t pid, int policy, struct sched_param *param)
Sets the scheduling policy and parameters for the given pid.
-void set_cpus_allowed(task_t *p, unsigned long new_mask)
+int set_cpus_allowed(task_t *p, unsigned long new_mask)
Sets a given task's CPU affinity and migrates it to a proper cpu.
Callers must have a valid reference to the task and assure the
task not exit prematurely. No locks can be held during the call.
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
index f39e2bb310cb..55b3cc0efda3 100644
--- a/Documentation/vm/hugetlbpage.txt
+++ b/Documentation/vm/hugetlbpage.txt
@@ -68,14 +68,21 @@ call, then it is required that system administrator mount a file system of
type hugetlbfs:
mount none /mnt/huge -t hugetlbfs <uid=value> <gid=value> <mode=value>
+ <size=value> <nr_inodes=value>
This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
/mnt/huge. Any files created on /mnt/huge uses hugepages. The uid and gid
options sets the owner and group of the root of the file system. By default
the uid and gid of the current process are taken. The mode option sets the
mode of root of file system to value & 0777. This value is given in octal.
-By default the value 0755 is picked. An example is given at the end of this
-document.
+By default the value 0755 is picked. The size option sets the maximum value of
+memory (huge pages) allowed for that filesystem (/mnt/huge). The size is
+rounded down to HPAGE_SIZE. The option nr_inode sets the maximum number of
+inodes that /mnt/huge can use. If the size or nr_inode options are not
+provided on command line then no limits are set. For size and nr_inodes
+options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
+example, size=2K has the same meaning as size=2048. An example is given at
+the end of this document.
read and write system calls are not supported on files that reside on hugetlb
file systems.
diff --git a/MAINTAINERS b/MAINTAINERS
index 2c8f0c82a078..6aaa323462dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1429,10 +1429,10 @@ W: http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
S: Maintained
PCI SUBSYSTEM
-P: Martin Mares
-M: mj@ucw.cz
+P: Greg Kroah-Hartman
+M: greg@kroah.com
L: linux-kernel@vger.kernel.org
-S: Odd Fixes
+S: Supported
PCI HOTPLUG CORE
P: Greg Kroah-Hartman
diff --git a/Makefile b/Makefile
index 38ac2b284365..e8bbeff0975b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 2
PATCHLEVEL = 5
-SUBLEVEL = 72
+SUBLEVEL = 73
EXTRAVERSION =
# *DOCUMENTATION*
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 23c26b76709d..920e9e840a0a 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -653,6 +653,8 @@ source "drivers/parport/Kconfig"
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/pnp/Kconfig"
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index c9a1d55d0dbd..890bee0f1aa1 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -156,7 +156,7 @@ EXPORT_SYMBOL(sys_exit);
EXPORT_SYMBOL(sys_write);
EXPORT_SYMBOL(sys_read);
EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(__kernel_execve);
+EXPORT_SYMBOL(execve);
EXPORT_SYMBOL(sys_setsid);
EXPORT_SYMBOL(sys_wait4);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 0d8be8cca897..be1731104449 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -606,7 +606,8 @@ ret_from_fork:
.globl kernel_thread
.ent kernel_thread
kernel_thread:
- ldgp $gp, 0($27) /* we can be called from a module */
+ /* We can be called from a module. */
+ ldgp $gp, 0($27)
.prologue 1
subq $sp, SP_OFF+6*8, $sp
br $1, 2f /* load start address */
@@ -654,26 +655,56 @@ kernel_thread:
.end kernel_thread
/*
- * __kernel_execve(path, argv, envp, regs)
+ * execve(path, argv, envp)
*/
.align 4
- .globl __kernel_execve
- .ent __kernel_execve
-__kernel_execve:
- ldgp $gp, 0($27) /* we can be called from modules. */
- subq $sp, 16, $sp
- .frame $sp, 16, $26, 0
+ .globl execve
+ .ent execve
+execve:
+ /* We can be called from a module. */
+ ldgp $gp, 0($27)
+ lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
+ .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
stq $26, 0($sp)
- stq $19, 8($sp)
+ stq $16, 8($sp)
+ stq $17, 16($sp)
+ stq $18, 24($sp)
.prologue 1
- jsr $26, do_execve
- bne $0, 1f /* error! */
- ldq $sp, 8($sp)
+
+ lda $16, 32($sp)
+ lda $17, 0
+ lda $18, SIZEOF_PT_REGS
+ bsr $26, memset !samegp
+
+ /* Avoid the HAE being gratuitously wrong, which would cause us
+ to do the whole turn off interrupts thing and restore it. */
+ ldq $2, alpha_mv+HAE_CACHE
+ stq $2, 152+32($sp)
+
+ ldq $16, 8($sp)
+ ldq $17, 16($sp)
+ ldq $18, 24($sp)
+ lda $19, 32($sp)
+ bsr $26, do_execve !samegp
+
+ ldq $26, 0($sp)
+ bne $0, 1f /* error! */
+
+ /* Move the temporary pt_regs struct from its current location
+ to the top of the kernel stack frame. See copy_thread for
+ details for a normal process. */
+ lda $16, 0x4000 - SIZEOF_PT_REGS($8)
+ lda $17, 32($sp)
+ lda $18, SIZEOF_PT_REGS
+ bsr $26, memmove !samegp
+
+ /* Take that over as our new stack frame and visit userland! */
+ lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
br $31, ret_from_sys_call
-1: ldq $26, 0($sp)
- addq $sp, 16, $sp
+
+1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
ret
-.end __kernel_execve
+.end execve
/*
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index c42a9d7b84b0..cce7e0d07250 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -218,15 +218,14 @@ struct osf_statfs {
} *osf_stat;
static int
-linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat,
+linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs *osf_stat,
unsigned long bufsiz)
{
struct osf_statfs tmp_stat;
tmp_stat.f_type = linux_stat->f_type;
tmp_stat.f_flags = 0; /* mount flags */
- /* Linux doesn't provide a "fundamental filesystem block size": */
- tmp_stat.f_fsize = linux_stat->f_bsize;
+ tmp_stat.f_fsize = linux_stat->f_frsize;
tmp_stat.f_bsize = linux_stat->f_bsize;
tmp_stat.f_blocks = linux_stat->f_blocks;
tmp_stat.f_bfree = linux_stat->f_bfree;
@@ -243,7 +242,7 @@ static int
do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer,
unsigned long bufsiz)
{
- struct statfs linux_stat;
+ struct kstatfs linux_stat;
int error = vfs_statfs(dentry->d_inode->i_sb, &linux_stat);
if (!error)
error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 9fc63ee500fe..1a9b4c645935 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -291,6 +291,7 @@ srmcons_init(void)
driver->type = TTY_DRIVER_TYPE_SYSTEM;
driver->subtype = SYSTEM_TYPE_SYSCONS;
driver->init_termios = tty_std_termios;
+ tty_set_operations(driver, &srmcons_ops);
err = tty_register_driver(driver);
if (err) {
put_tty_driver(driver);
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index ddea651cb87e..412cd3672573 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -148,7 +148,7 @@ void show_trace_task(struct task_struct * tsk)
static int kstack_depth_to_print = 24;
-void show_stack(unsigned long *sp)
+void show_stack(struct task_struct *task, unsigned long *sp)
{
unsigned long *stack;
int i;
@@ -174,7 +174,7 @@ void show_stack(unsigned long *sp)
void dump_stack(void)
{
- show_stack(NULL);
+ show_stack(NULL, NULL);
}
void
diff --git a/arch/alpha/lib/memmove.S b/arch/alpha/lib/memmove.S
index a09e1d13bc6c..2f06e460392a 100644
--- a/arch/alpha/lib/memmove.S
+++ b/arch/alpha/lib/memmove.S
@@ -15,15 +15,23 @@
.globl bcopy
.ent bcopy
bcopy:
+ ldgp $29, 0($27)
+ .prologue 1
mov $16,$0
mov $17,$16
mov $0,$17
+ br $31, memmove !samegp
.end bcopy
.align 4
.globl memmove
.ent memmove
memmove:
+ ldgp $29, 0($27)
+ unop
+ nop
+ .prologue 1
+
addq $16,$18,$4
addq $17,$18,$5
cmpule $4,$17,$1 /* dest + n <= src */
@@ -32,7 +40,7 @@ memmove:
bis $1,$2,$1
mov $16,$0
xor $16,$17,$2
- bne $1,memcpy
+ bne $1,memcpy !samegp
and $2,7,$2 /* Test for src/dest co-alignment. */
and $16,7,$1
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c
index 0976ff84e33c..3ce73d577941 100644
--- a/arch/alpha/oprofile/common.c
+++ b/arch/alpha/oprofile/common.c
@@ -188,7 +188,7 @@ oprofile_arch_init(struct oprofile_operations **ops)
}
-void __exit
+void
oprofile_arch_exit(void)
{
}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e1a9318f4e8f..594d94c58890 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -703,6 +703,8 @@ endchoice
source "fs/Kconfig.binfmt"
+source "drivers/base/Kconfig"
+
config PM
bool "Power Management support"
---help---
diff --git a/arch/arm/kernel/pm.c b/arch/arm/kernel/pm.c
index e80142d9304b..f28e2ba66f5c 100644
--- a/arch/arm/kernel/pm.c
+++ b/arch/arm/kernel/pm.c
@@ -11,6 +11,8 @@
#include <linux/config.h>
#include <linux/pm.h>
#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
#include <asm/leds.h>
#include <asm/system.h>
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
index 815db7c8ee6a..e6aab5ceec14 100644
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -52,10 +52,6 @@ divisor .req r1
result .req r2
overdone .req r2
curbit .req r3
-ip .req r12
-sp .req r13
-lr .req r14
-pc .req r15
ENTRY(__udivsi3)
cmp divisor, #0
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3b6652427633..4a4238d5a102 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -138,11 +138,14 @@ static struct resource sa11x0udc_resources[] = {
},
};
+static u64 sa11x0udc_dma_mask = 0xffffffffUL;
+
static struct platform_device sa11x0udc_device = {
.name = "sa11x0-udc",
.id = 0,
.dev = {
.name = "Intel Corporation SA11x0 [UDC]",
+ .dma_mask = &sa11x0udc_dma_mask,
},
.num_resources = ARRAY_SIZE(sa11x0udc_resources),
.resource = sa11x0udc_resources,
@@ -166,6 +169,27 @@ static struct platform_device sa11x0mcp_device = {
.resource = sa11x0mcp_resources,
};
+static struct resource sa11x0ssp_resources[] = {
+ [0] = {
+ .start = 0x80070000,
+ .end = 0x8007ffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0ssp_device = {
+ .name = "sa11x0-ssp",
+ .id = 0,
+ .dev = {
+ .name = "Intel Corporation SA11x0 [SSP]",
+ .dma_mask = &sa11x0ssp_dma_mask,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0ssp_resources),
+ .resource = sa11x0ssp_resources,
+};
+
static struct resource sa11x0fb_resources[] = {
[0] = {
.start = 0xb0100000,
@@ -200,6 +224,7 @@ static struct platform_device sa11x0pcmcia_device = {
static struct platform_device *sa11x0_devices[] __initdata = {
&sa11x0udc_device,
&sa11x0mcp_device,
+ &sa11x0ssp_device,
&sa11x0pcmcia_device,
&sa11x0fb_device,
};
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 2749f7553703..7ef598839d16 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
-# Last update: Wed May 7 23:43:08 2003
+# Last update: Thu Jun 19 18:42:39 2003
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -259,7 +259,7 @@ stork_nest ARCH_STORK_NEST STORK_NEST 247
stork_egg ARCH_STORK_EGG STORK_EGG 248
wismo SA1100_WISMO WISMO 249
ezlinx ARCH_EZLINX EZLINX 250
-at91 ARCH_AT91 AT91 251
+at91rm9200 ARCH_AT91 AT91 251
orion ARCH_ORION ORION 252
neptune ARCH_NEPTUNE NEPTUNE 253
hackkit SA1100_HACKKIT HACKKIT 254
@@ -332,10 +332,26 @@ pxa_pooh ARCH_PXA_POOH PXA_POOH 320
bandon ARCH_BANDON BANDON 321
pcm7210 ARCH_PCM7210 PCM7210 322
nms9200 ARCH_NMS9200 NMS9200 323
-gealog ARCH_GEALOG GEALOG 324
+logodl ARCH_LOGODL LOGODL 324
m7140 SA1100_M7140 M7140 325
korebot ARCH_KOREBOT KOREBOT 326
iq31244 ARCH_IQ31244 IQ31244 327
koan393 SA1100_KOAN393 KOAN393 328
inhandftip3 ARCH_INHANDFTIP3 INHANDFTIP3 329
gonzo ARCH_GONZO GONZO 330
+bast ARCH_BAST BAST 331
+scanpass ARCH_SCANPASS SCANPASS 332
+ep7312_pooh ARCH_EP7312_POOH EP7312_POOH 333
+ta7s ARCH_TA7S TA7S 334
+ta7v ARCH_TA7V TA7V 335
+icarus SA1100_ICARUS ICARUS 336
+h1900 ARCH_H1900 H1900 337
+gemini SA1100_GEMINI GEMINI 338
+axim ARCH_AXIM AXIM 339
+audiotron ARCH_AUDIOTRON AUDIOTRON 340
+h2200 ARCH_H2200 H2200 341
+loox600 ARCH_LOOX600 LOOX600 342
+niop ARCH_NIOP NIOP 343
+dm310 ARCH_DM310 DM310 344
+seedpxa_c2 ARCH_SEEDPXA_C2 SEEDPXA_C2 345
+ixp4xx_mguardpci ARCH_IXP4XX_MGUARD_PCI IXP4XX_MGUARD_PCI 346
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index f071e0c713a1..b5dac8d6ba22 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -297,6 +297,8 @@ config CMDLINE
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/parport/Kconfig"
source "drivers/pnp/Kconfig"
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index f48cda0f22da..08ad94159072 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -515,6 +515,8 @@ config ETRAX_POWERBUTTON_BIT
endmenu
+source "drivers/base/Kconfig"
+
# bring in Etrax built-in drivers
source "arch/cris/drivers/Kconfig"
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 1e04b4192ed5..0720e0f693ee 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -145,6 +145,8 @@ source "fs/Kconfig.binfmt"
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/block/Kconfig"
source "drivers/ide/Kconfig"
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 7f09fbc1a895..1da9d947a598 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1194,6 +1194,8 @@ source "fs/Kconfig.binfmt"
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
index 2cf76a941847..41f9b6fa4987 100644
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_ACPI_HT_ONLY) := acpitable.o
obj-$(CONFIG_ACPI_BOOT) := boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
diff --git a/arch/i386/kernel/acpi/acpitable.c b/arch/i386/kernel/acpi/acpitable.c
new file mode 100644
index 000000000000..ebcde5af1b72
--- /dev/null
+++ b/arch/i386/kernel/acpi/acpitable.c
@@ -0,0 +1,553 @@
+/*
+ * 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 <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
+ * Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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 <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <asm/mpspec.h>
+#include <asm/io.h>
+#include <asm/apic.h>
+#include <asm/apicdef.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#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 --git a/arch/i386/kernel/acpi/acpitable.h b/arch/i386/kernel/acpi/acpitable.h
new file mode 100644
index 000000000000..ddf1c84a6549
--- /dev/null
+++ b/arch/i386/kernel/acpi/acpitable.h
@@ -0,0 +1,260 @@
+/*
+ * 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 <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
+ * Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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 --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index ad45189c98ce..5aef7a47a383 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -874,6 +874,7 @@ ENTRY(sys_call_table)
.long sys_clock_gettime /* 265 */
.long sys_clock_getres
.long sys_clock_nanosleep
-
+ .long sys_statfs64
+ .long sys_fstatfs64
nr_syscalls=(.-sys_call_table)/4
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8cb6adb50b8a..61bc3326e287 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -190,7 +190,7 @@ void show_regs(struct pt_regs * regs)
".previous \n"
: "=r" (cr4): "0" (0));
printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
- show_trace(&regs->esp);
+ show_trace(NULL, &regs->esp);
}
/*
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index b925d5fa9d9d..8eda5c87e8e1 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -61,7 +61,12 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
unsigned long mmu_cr4_features;
EXPORT_SYMBOL_GPL(mmu_cr4_features);
-int acpi_disabled __initdata = 0;
+#ifdef CONFIG_ACPI_HT_ONLY
+int acpi_disabled = 1;
+#else
+int acpi_disabled = 0;
+#endif
+EXPORT_SYMBOL(acpi_disabled);
int MCA_bus;
/* for MCA, but anyone else can use it if they want */
@@ -514,6 +519,10 @@ static void __init parse_cmdline_early (char ** cmdline_p)
if (c == ' ' && !memcmp(from, "acpi=off", 8))
acpi_disabled = 1;
+ /* "acpismp=force" turns on ACPI again */
+ else if (!memcmp(from, "acpismp=force", 14))
+ acpi_disabled = 0;
+
/*
* highmem=size forces highmem to be exactly 'size' bytes.
* This works even on boxes that have no highmem otherwise.
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 02f8e2512710..db98194645c3 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -281,19 +281,19 @@ unsigned long get_cmos_time(void)
return retval;
}
-static struct sysdev_class rtc_sysclass = {
- set_kset_name("rtc"),
+static struct sysdev_class pit_sysclass = {
+ set_kset_name("pit"),
};
/* XXX this driverfs stuff should probably go elsewhere later -john */
static struct sys_device device_i8253 = {
- .id = 0,
- .cls = &rtc_sysclass,
+ .id = 0,
+ .cls = &pit_sysclass,
};
static int time_init_device(void)
{
- int error = sysdev_class_register(&rtc_sysclass);
+ int error = sysdev_class_register(&pit_sysclass);
if (!error)
error = sys_device_register(&device_i8253);
return error;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index c6bc1936f45b..5a7a28deb04a 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -32,9 +32,9 @@
#ifdef CONFIG_MCA
#include <linux/mca.h>
-#include <asm/processor.h>
#endif
+#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -92,9 +92,8 @@ asmlinkage void machine_check(void);
static int kstack_depth_to_print = 24;
-void show_trace(unsigned long * stack)
+void show_trace(struct task_struct *task, unsigned long * stack)
{
- int i;
unsigned long addr;
if (!stack)
@@ -104,7 +103,6 @@ void show_trace(unsigned long * stack)
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
- i = 1;
while (((long) stack & (THREAD_SIZE-1)) != 0) {
addr = *stack++;
if (kernel_text_address(addr)) {
@@ -122,10 +120,10 @@ void show_trace_task(struct task_struct *tsk)
/* User space on another CPU? */
if ((esp ^ (unsigned long)tsk->thread_info) & (PAGE_MASK<<1))
return;
- show_trace((unsigned long *)esp);
+ show_trace(tsk, (unsigned long *)esp);
}
-void show_stack(unsigned long * esp)
+void show_stack(struct task_struct *task, unsigned long * esp)
{
unsigned long *stack;
int i;
@@ -145,7 +143,7 @@ void show_stack(unsigned long * esp)
printk("%08lx ", *stack++);
}
printk("\n");
- show_trace(esp);
+ show_trace(task, esp);
}
/*
@@ -155,7 +153,7 @@ void dump_stack(void)
{
unsigned long stack;
- show_trace(&stack);
+ show_trace(current, &stack);
}
void show_registers(struct pt_regs *regs)
@@ -192,7 +190,7 @@ void show_registers(struct pt_regs *regs)
if (in_kernel) {
printk("\nStack: ");
- show_stack((unsigned long*)esp);
+ show_stack(NULL, (unsigned long*)esp);
printk("Code: ");
if(regs->eip < PAGE_OFFSET)
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
index 78c81583dd13..f4e073471958 100644
--- a/arch/i386/mm/hugetlbpage.c
+++ b/arch/i386/mm/hugetlbpage.c
@@ -24,9 +24,41 @@ static long htlbpagemem;
int htlbpage_max;
static long htlbzone_pages;
-static LIST_HEAD(htlbpage_freelist);
+static struct list_head hugepage_freelists[MAX_NUMNODES];
static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
+static void enqueue_huge_page(struct page *page)
+{
+ list_add(&page->list,
+ &hugepage_freelists[page_zone(page)->zone_pgdat->node_id]);
+}
+
+static struct page *dequeue_huge_page(void)
+{
+ int nid = numa_node_id();
+ struct page *page = NULL;
+
+ if (list_empty(&hugepage_freelists[nid])) {
+ for (nid = 0; nid < MAX_NUMNODES; ++nid)
+ if (!list_empty(&hugepage_freelists[nid]))
+ break;
+ }
+ if (nid >= 0 && nid < MAX_NUMNODES && !list_empty(&hugepage_freelists[nid])) {
+ page = list_entry(hugepage_freelists[nid].next, struct page, list);
+ list_del(&page->list);
+ }
+ return page;
+}
+
+static struct page *alloc_fresh_huge_page(void)
+{
+ static int nid = 0;
+ struct page *page;
+ page = alloc_pages_node(nid, GFP_HIGHUSER, HUGETLB_PAGE_ORDER);
+ nid = (nid + 1) % numnodes;
+ return page;
+}
+
void free_huge_page(struct page *page);
static struct page *alloc_hugetlb_page(void)
@@ -35,13 +67,11 @@ static struct page *alloc_hugetlb_page(void)
struct page *page;
spin_lock(&htlbpage_lock);
- if (list_empty(&htlbpage_freelist)) {
+ page = dequeue_huge_page();
+ if (!page) {
spin_unlock(&htlbpage_lock);
return NULL;
}
-
- page = list_entry(htlbpage_freelist.next, struct page, list);
- list_del(&page->list);
htlbpagemem--;
spin_unlock(&htlbpage_lock);
set_page_count(page, 1);
@@ -253,7 +283,7 @@ void free_huge_page(struct page *page)
INIT_LIST_HEAD(&page->list);
spin_lock(&htlbpage_lock);
- list_add(&page->list, &htlbpage_freelist);
+ enqueue_huge_page(page);
htlbpagemem++;
spin_unlock(&htlbpage_lock);
}
@@ -369,7 +399,8 @@ int try_to_free_low(int count)
map = NULL;
spin_lock(&htlbpage_lock);
- list_for_each(p, &htlbpage_freelist) {
+ /* all lowmem is on node 0 */
+ list_for_each(p, &hugepage_freelists[0]) {
if (map) {
list_del(&map->list);
update_and_free_page(map);
@@ -406,11 +437,11 @@ int set_hugetlb_mem_size(int count)
return (int)htlbzone_pages;
if (lcount > 0) { /* Increase the mem size. */
while (lcount--) {
- page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
+ page = alloc_fresh_huge_page();
if (page == NULL)
break;
spin_lock(&htlbpage_lock);
- list_add(&page->list, &htlbpage_freelist);
+ enqueue_huge_page(page);
htlbpagemem++;
htlbzone_pages++;
spin_unlock(&htlbpage_lock);
@@ -451,12 +482,15 @@ static int __init hugetlb_init(void)
int i;
struct page *page;
+ for (i = 0; i < MAX_NUMNODES; ++i)
+ INIT_LIST_HEAD(&hugepage_freelists[i]);
+
for (i = 0; i < htlbpage_max; ++i) {
- page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
+ page = alloc_fresh_huge_page();
if (!page)
break;
spin_lock(&htlbpage_lock);
- list_add(&page->list, &htlbpage_freelist);
+ enqueue_huge_page(page);
spin_unlock(&htlbpage_lock);
}
htlbpage_max = htlbpagemem = htlbzone_pages = i;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index d1ac5318f2d7..19321ca55400 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -27,6 +27,7 @@
#include <linux/pagemap.h>
#include <linux/bootmem.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -425,6 +426,8 @@ static void __init set_max_mapnr_init(void)
extern void set_max_mapnr_init(void);
#endif /* !CONFIG_DISCONTIGMEM */
+static struct kcore_list kcore_mem, kcore_vmalloc;
+
void __init mem_init(void)
{
extern int ppro_with_ram_bug(void);
@@ -477,6 +480,10 @@ void __init mem_init(void)
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+ kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
+ kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
+ VMALLOC_END-VMALLOC_START);
+
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
num_physpages << (PAGE_SHIFT-10),
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 6c9fa8f376f7..3e9ed569c3a8 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -23,7 +23,24 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
int pcibios_last_bus = -1;
struct pci_bus *pci_root_bus = NULL;
-struct pci_ops *pci_root_ops = NULL;
+struct pci_raw_ops *raw_pci_ops;
+
+static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
+{
+ return raw_pci_ops->read(0, bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where, size, value);
+}
+
+static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+{
+ return raw_pci_ops->write(0, bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where, size, value);
+}
+
+struct pci_ops pci_root_ops = {
+ .read = pci_read,
+ .write = pci_write,
+};
/*
* legacy, numa, and acpi all want to call pcibios_scan_root
@@ -115,7 +132,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
- return pci_scan_bus(busnum, pci_root_ops, NULL);
+ return pci_scan_bus(busnum, &pci_root_ops, NULL);
}
extern u8 pci_cache_line_size;
@@ -124,7 +141,7 @@ static int __init pcibios_init(void)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
- if (!pci_root_ops) {
+ if (!raw_pci_ops) {
printk("PCI: System does not support PCI\n");
return 0;
}
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
index 039448ab26b9..b61223fe8438 100644
--- a/arch/i386/pci/direct.c
+++ b/arch/i386/pci/direct.c
@@ -13,7 +13,7 @@
#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
-static int __pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
@@ -41,7 +41,7 @@ static int __pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len
return 0;
}
-static int __pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
@@ -71,19 +71,7 @@ static int __pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int le
#undef PCI_CONF1_ADDRESS
-static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- return __pci_conf1_read(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- return __pci_conf1_write(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-struct pci_ops pci_direct_conf1 = {
+struct pci_raw_ops pci_direct_conf1 = {
.read = pci_conf1_read,
.write = pci_conf1_write,
};
@@ -95,7 +83,7 @@ struct pci_ops pci_direct_conf1 = {
#define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg)
-static int __pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
@@ -129,7 +117,7 @@ static int __pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len
return 0;
}
-static int __pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
@@ -165,19 +153,7 @@ static int __pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int le
#undef PCI_CONF2_ADDRESS
-static int pci_conf2_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- return __pci_conf2_read(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-static int pci_conf2_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- return __pci_conf2_write(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-static struct pci_ops pci_direct_conf2 = {
+static struct pci_raw_ops pci_direct_conf2 = {
.read = pci_conf2_read,
.write = pci_conf2_write,
};
@@ -193,38 +169,30 @@ static struct pci_ops pci_direct_conf2 = {
* This should be close to trivial, but it isn't, because there are buggy
* chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
*/
-static int __devinit pci_sanity_check(struct pci_ops *o)
+static int __devinit pci_sanity_check(struct pci_raw_ops *o)
{
u32 x = 0;
- int retval = 0;
- struct pci_bus *bus; /* Fake bus and device */
- struct pci_dev *dev;
+ int devfn;
if (pci_probe & PCI_NO_CHECKS)
return 1;
- bus = kmalloc(sizeof(*bus), GFP_ATOMIC);
- dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
- if (!bus || !dev) {
- printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
- goto exit;
+ for (devfn = 0; devfn < 0x100; devfn++) {
+ if (o->read(0, 0, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_CLASS_DEVICE, 2, &x))
+ continue;
+ if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
+ return 1;
+
+ if (o->read(0, 0, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_VENDOR_ID, 2, &x))
+ continue;
+ if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
+ return 1;
}
- bus->number = 0;
- dev->bus = bus;
- for(dev->devfn=0; dev->devfn < 0x100; dev->devfn++)
- if ((!o->read(bus, dev->devfn, PCI_CLASS_DEVICE, 2, &x) &&
- (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
- (!o->read(bus, dev->devfn, PCI_VENDOR_ID, 2, &x) &&
- (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) {
- retval = 1;
- goto exit;
- }
DBG("PCI: Sanity check failed\n");
-exit:
- kfree(dev);
- kfree(bus);
- return retval;
+ return 0;
}
static int __init pci_direct_init(void)
@@ -247,9 +215,9 @@ static int __init pci_direct_init(void)
local_irq_restore(flags);
printk(KERN_INFO "PCI: Using configuration type 1\n");
if (!request_region(0xCF8, 8, "PCI conf1"))
- pci_root_ops = NULL;
+ raw_pci_ops = NULL;
else
- pci_root_ops = &pci_direct_conf1;
+ raw_pci_ops = &pci_direct_conf1;
return 0;
}
outl (tmp, 0xCF8);
@@ -267,9 +235,9 @@ static int __init pci_direct_init(void)
local_irq_restore(flags);
printk(KERN_INFO "PCI: Using configuration type 2\n");
if (!request_region(0xCF8, 4, "PCI conf2"))
- pci_root_ops = NULL;
+ raw_pci_ops = NULL;
else
- pci_root_ops = &pci_direct_conf2;
+ raw_pci_ops = &pci_direct_conf2;
return 0;
}
}
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 7f47b5a5f004..8247ee721490 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -23,9 +23,9 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
pci_read_config_byte(d, reg++, &subb);
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
if (busno)
- pci_scan_bus(busno, pci_root_ops, NULL); /* Bus A */
+ pci_scan_bus(busno, &pci_root_ops, NULL); /* Bus A */
if (suba < subb)
- pci_scan_bus(suba+1, pci_root_ops, NULL); /* Bus B */
+ pci_scan_bus(suba+1, &pci_root_ops, NULL); /* Bus B */
}
pcibios_last_bus = -1;
}
@@ -39,7 +39,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d)
u8 busno;
pci_read_config_byte(d, 0x4a, &busno);
printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", d->slot_name, busno);
- pci_scan_bus(busno, pci_root_ops, NULL);
+ pci_scan_bus(busno, &pci_root_ops, NULL);
pcibios_last_bus = -1;
}
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index e35674679dfe..53db10c42fea 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -107,7 +107,7 @@ static void __init pirq_peer_trick(void)
* It might be a secondary bus, but in this case its parent is already
* known (ascending bus order) and therefore pci_scan_bus returns immediately.
*/
- if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
+ if (busmap[i] && pci_scan_bus(i, &pci_root_ops, NULL))
printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
pcibios_last_bus = -1;
}
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
index 7e7f9120df85..29fea7d6ad6c 100644
--- a/arch/i386/pci/legacy.c
+++ b/arch/i386/pci/legacy.c
@@ -31,14 +31,14 @@ static void __devinit pcibios_fixup_peer_bridges(void)
if (pci_bus_exists(&pci_root_buses, n))
continue;
bus->number = n;
- bus->ops = pci_root_ops;
+ bus->ops = &pci_root_ops;
dev->bus = bus;
for (dev->devfn=0; dev->devfn<256; dev->devfn += 8)
if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
l != 0x0000 && l != 0xffff) {
DBG("Found device at %02x:%02x [%04x]\n", n, dev->devfn, l);
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
- pci_scan_bus(n, pci_root_ops, NULL);
+ pci_scan_bus(n, &pci_root_ops, NULL);
break;
}
}
@@ -49,7 +49,7 @@ exit:
static int __init pci_legacy_init(void)
{
- if (!pci_root_ops) {
+ if (!raw_pci_ops) {
printk("PCI: System does not support PCI\n");
return 0;
}
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
index 0a184f2c7b57..80a093f06a85 100644
--- a/arch/i386/pci/numa.c
+++ b/arch/i386/pci/numa.c
@@ -13,7 +13,7 @@
#define PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
-static int __pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+static int pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
@@ -41,7 +41,7 @@ static int __pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int
return 0;
}
-static int __pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+static int pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
@@ -71,19 +71,7 @@ static int __pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int
#undef PCI_CONF1_MQ_ADDRESS
-static int pci_conf1_mq_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- return __pci_conf1_mq_read(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-static int pci_conf1_mq_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- return __pci_conf1_mq_write(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-static struct pci_ops pci_direct_conf1_mq = {
+static struct pci_raw_ops pci_direct_conf1_mq = {
.read = pci_conf1_mq_read,
.write = pci_conf1_mq_write
};
@@ -106,9 +94,9 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
pci_read_config_byte(d, reg++, &subb);
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
if (busno)
- pci_scan_bus(QUADLOCAL2BUS(quad,busno), pci_root_ops, NULL); /* Bus A */
+ pci_scan_bus(QUADLOCAL2BUS(quad,busno), &pci_root_ops, NULL); /* Bus A */
if (suba < subb)
- pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), pci_root_ops, NULL); /* Bus B */
+ pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), &pci_root_ops, NULL); /* Bus B */
}
pcibios_last_bus = -1;
}
@@ -121,7 +109,7 @@ static int __init pci_numa_init(void)
{
int quad;
- pci_root_ops = &pci_direct_conf1_mq;
+ raw_pci_ops = &pci_direct_conf1_mq;
if (pcibios_scanned++)
return 0;
@@ -132,7 +120,7 @@ static int __init pci_numa_init(void)
printk("Scanning PCI bus %d for quad %d\n",
QUADLOCAL2BUS(quad,0), quad);
pci_scan_bus(QUADLOCAL2BUS(quad,0),
- pci_root_ops, NULL);
+ &pci_root_ops, NULL);
}
}
return 0;
diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
index 1a21e2600964..06557dd705e9 100644
--- a/arch/i386/pci/pcbios.c
+++ b/arch/i386/pci/pcbios.c
@@ -172,7 +172,7 @@ static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short
return (int) (ret & 0xff00) >> 8;
}
-static int __pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long result = 0;
unsigned long flags;
@@ -227,7 +227,7 @@ static int __pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len,
return (int)((result & 0xff00) >> 8);
}
-static int __pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long result = 0;
unsigned long flags;
@@ -282,24 +282,12 @@ static int __pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len
return (int)((result & 0xff00) >> 8);
}
-static int pci_bios_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- return __pci_bios_read(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
-static int pci_bios_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- return __pci_bios_write(0, bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size, value);
-}
-
/*
* Function table for BIOS32 access
*/
-static struct pci_ops pci_bios_access = {
+static struct pci_raw_ops pci_bios_access = {
.read = pci_bios_read,
.write = pci_bios_write
};
@@ -308,7 +296,7 @@ static struct pci_ops pci_bios_access = {
* Try to find PCI BIOS.
*/
-static struct pci_ops * __devinit pci_find_bios(void)
+static struct pci_raw_ops * __devinit pci_find_bios(void)
{
union bios32 *check;
unsigned char sum;
@@ -484,7 +472,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
static int __init pci_pcbios_init(void)
{
if ((pci_probe & PCI_PROBE_BIOS)
- && ((pci_root_ops = pci_find_bios()))) {
+ && ((raw_pci_ops = pci_find_bios()))) {
pci_probe |= PCI_BIOS_SORT;
pci_bios_present = 1;
}
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index 68100f53ecb5..6f3786334bf6 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -37,7 +37,7 @@ int pcibios_enable_resources(struct pci_dev *, int);
extern int pcibios_last_bus;
extern struct pci_bus *pci_root_bus;
-extern struct pci_ops *pci_root_ops;
+extern struct pci_ops pci_root_ops;
/* pci-irq.c */
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 4b301892f4c3..a3a0c31dd1be 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -534,6 +534,8 @@ endif
endmenu
+source "drivers/base/Kconfig"
+
if !IA64_HP_SIM
source "drivers/mtd/Kconfig"
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index 200add0897e5..17ec2150ffbe 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -436,6 +436,28 @@ ia32_syscall_table:
data8 sys_ni_syscall
data8 sys_ni_syscall
data8 sys_ni_syscall
+ data8 sys_ni_syscall /* 250 */
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall /*255*/
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall /* 260 */
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall /* 265 */
+ data8 sys_ni_syscall
+ data8 sys_ni_syscall
+ data8 sys_statfs64
+ data8 sys_fstatfs64
+ data8 sys_ni_syscall
+
/*
* CAUTION: If any system calls are added beyond this point
* then the check in `arch/ia64/kernel/ivt.S' will have
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index b7e92042b522..ba2bcfc717b9 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1430,8 +1430,8 @@ sys_call_table:
data8 sys_clock_gettime
data8 sys_clock_getres // 1255
data8 sys_clock_nanosleep
- data8 ia64_ni_syscall
- data8 ia64_ni_syscall
+ data8 sys_fstatfs64
+ data8 sys_statfs64
data8 ia64_ni_syscall
data8 ia64_ni_syscall // 1260
data8 ia64_ni_syscall
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index b57e638f6ed5..db9500165ab8 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -1513,7 +1513,7 @@ ENTRY(dispatch_to_ia32_handler)
alloc r15=ar.pfs,0,0,6,0 // must first in an insn group
;;
ld4 r8=[r14],8 // r8 == eax (syscall number)
- mov r15=250 // number of entries in ia32 system call table
+ mov r15=270 // number of entries in ia32 system call table
;;
cmp.ltu.unc p6,p7=r8,r15
ld4 out1=[r14],8 // r9 == ecx
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 3a5cbbef532e..58ff5b17a038 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -59,7 +59,7 @@ struct pci_fixup pcibios_fixups[1];
static int
-__pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
int result = 0;
u64 data = 0;
@@ -75,7 +75,7 @@ __pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
}
static int
-__pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
return -EINVAL;
@@ -83,28 +83,33 @@ __pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
}
+struct pci_raw_ops pci_sal_ops = {
+ .read = pci_sal_read,
+ .write = pci_sal_write
+};
+
+struct pci_raw_ops *raw_pci_ops = &pci_sal_ops; /* default to SAL */
+
static int
-pci_sal_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
+pci_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
- return __pci_sal_read(pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
- where, size, value);
+ return raw_pci_ops->read(pci_domain_nr(bus), bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, value);
}
static int
-pci_sal_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+pci_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
- return __pci_sal_write(pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
- where, size, value);
+ return raw_pci_ops->write(pci_domain_nr(bus), bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, value);
}
-struct pci_ops pci_sal_ops = {
- .read = pci_sal_read,
- .write = pci_sal_write
+static struct pci_ops pci_root_ops = {
+ .read = pci_read,
+ .write = pci_write,
};
-struct pci_ops *pci_root_ops = &pci_sal_ops; /* default to SAL */
-
static int __init
pci_acpi_init (void)
{
@@ -307,7 +312,7 @@ pcibios_scan_root (void *handle, int seg, int bus)
info.name = name;
acpi_walk_resources(handle, METHOD_NAME__CRS, add_window, &info);
- return scan_root_bus(bus, pci_root_ops, controller);
+ return scan_root_bus(bus, &pci_root_ops, controller);
out3:
kfree(controller->window);
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 04f46ff5c0dc..072625710e24 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -573,6 +573,8 @@ endif
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/block/Kconfig"
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index f81ed83ec3bc..52f2b9707051 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -515,6 +515,8 @@ config PM
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S
index c9ac716240ab..fa0152a1ab01 100644
--- a/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S
+++ b/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S
@@ -174,6 +174,7 @@ _start:
nop
+#ifdef CONFIG_ROMFS_FS
/*
* Move ROM filesystem above bss :-)
*/
@@ -195,6 +196,12 @@ _copy_romfs:
cmp.l %a0, %a2 /* Check if at end */
bne _copy_romfs
+#else /* CONFIG_ROMFS_FS */
+ lea.l _ebss, %a1
+ move.l %a1, _ramstart
+#endif /* CONFIG_ROMFS_FS */
+
+
/*
* Zero out the bss region.
*/
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index 5d09dcf110b7..a038092a2e47 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -95,7 +95,13 @@ int mcf_timerirqpending(int timer)
void config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
+
+#if defined(CONFIG_BOOTPARAM)
+ strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+ commandp[size-1] = 0;
+#else
memset(commandp, 0, size);
+#endif
mach_sched_init = coldfire_timer_init;
mach_tick = coldfire_tick;
diff --git a/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S
index c2905669e9fb..c5aad9dc5f5a 100644
--- a/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S
+++ b/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S
@@ -103,6 +103,7 @@ _start:
move.l #0x80000100, %d0 /* Setup cache mask */
movec %d0, %CACR /* Enable cache */
+#ifdef CONFIG_ROMFS_FS
/*
* Move ROM filesystem above bss :-)
*/
@@ -124,6 +125,12 @@ _copy_romfs:
cmp.l %a0, %a2 /* Check if at end */
bne _copy_romfs
+#else /* CONFIG_ROMFS_FS */
+ lea.l _ebss, %a1
+ move.l %a1, _ramstart
+#endif /* CONFIG_ROMFS_FS */
+
+
/*
* Zero out the bss region.
*/
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 78dbaac8c5a3..1809554f0e26 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -104,7 +104,10 @@ void config_BSP(char *commandp, int size)
mcf_disableall();
-#if defined(CONFIG_NETtel)
+#if defined(CONFIG_BOOTPARAM)
+ strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+ commandp[size-1] = 0;
+#elif defined(CONFIG_NETtel)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0004000, size);
commandp[size-1] = 0;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 76f6b048226a..f79d1fb79351 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -744,6 +744,8 @@ if ISA
source "drivers/pnp/Kconfig"
endif
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/mips64/Kconfig b/arch/mips64/Kconfig
index 577bd47b8465..49e56e854ed7 100644
--- a/arch/mips64/Kconfig
+++ b/arch/mips64/Kconfig
@@ -361,6 +361,8 @@ endmenu
source "drivers/pci/Kconfig"
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 3372da034b6e..8d4a3849d168 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -170,6 +170,8 @@ source "fs/Kconfig.binfmt"
endmenu
+source "drivers/base/Kconfig"
+
# source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 5c2b39242e01..ba7e4cb86f55 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1163,6 +1163,8 @@ config PIN_TLB
depends on ADVANCED_OPTIONS && 8xx
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/pnp/Kconfig"
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 22324d875852..5aec043dad47 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -241,6 +241,8 @@ config CMDLINE
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index 949425d44cb3..c22a54fe544f 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -129,7 +129,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
return last;
}
-static void show_tsk_stack(struct task_struct *p, unsigned long sp);
char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
void show_regs(struct pt_regs * regs)
@@ -172,7 +171,7 @@ void show_regs(struct pt_regs * regs)
printk("NIP [%016lx] ", regs->nip);
printk("%s\n", ppc_find_proc_name((unsigned *)regs->nip,
name_buf, 256));
- show_tsk_stack(current, regs->gpr[1]);
+ show_stack(current, (unsigned long *)regs->gpr[1]);
}
void exit_thread(void)
@@ -517,22 +516,26 @@ unsigned long get_wchan(struct task_struct *p)
return 0;
}
-static void show_tsk_stack(struct task_struct *p, unsigned long sp)
+void show_stack(struct task_struct *p, unsigned long *_sp)
{
unsigned long ip;
unsigned long stack_page = (unsigned long)p->thread_info;
int count = 0;
char name_buf[256];
+ unsigned long sp = (unsigned long)_sp;
if (!p)
return;
+ if (sp == 0)
+ sp = p->thread.ksp;
printk("Call Trace:\n");
do {
if (__get_user(sp, (unsigned long *)sp))
break;
- if (sp < (stack_page + sizeof(struct thread_struct)) ||
- sp >= (stack_page + THREAD_SIZE))
+ if (sp < stack_page + sizeof(struct thread_struct))
+ break;
+ if (sp >= stack_page + THREAD_SIZE)
break;
if (__get_user(ip, (unsigned long *)(sp + 16)))
break;
@@ -544,10 +547,10 @@ static void show_tsk_stack(struct task_struct *p, unsigned long sp)
void dump_stack(void)
{
- show_tsk_stack(current, (unsigned long)_get_SP());
+ show_stack(current, (unsigned long *)_get_SP());
}
void show_trace_task(struct task_struct *tsk)
{
- show_tsk_stack(tsk, tsk->thread.ksp);
+ show_stack(tsk, (unsigned long *)tsk->thread.ksp);
}
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index e5cbfea7c0a1..bb9d80875721 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -229,6 +229,8 @@ config PCMCIA
bool
default n
+source "drivers/base/Kconfig"
+
menu "SCSI support"
config SCSI
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 16aeba5fc42b..024e44605cbb 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -767,6 +767,8 @@ source "fs/Kconfig.binfmt"
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 93cef3990287..2c001bf47c0e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -319,6 +319,8 @@ config PRINTER
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/video/Kconfig"
source "drivers/mtd/Kconfig"
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 3608f9408eb8..7bb83864ab35 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -287,17 +287,14 @@ void show_regs(struct pt_regs *r)
rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
}
-void show_trace_task(struct task_struct *tsk)
+void show_stack(struct task_struct *tsk, unsigned long *_ksp)
{
unsigned long pc, fp;
unsigned long task_base = (unsigned long) tsk;
struct reg_window *rw;
int count = 0;
- if (!tsk)
- return;
-
- fp = tsk->thread_info->ksp;
+ fp = (unsigned long) _ksp;
do {
/* Bogus frame pointer? */
if (fp < (task_base + sizeof(struct task_struct)) ||
@@ -311,6 +308,13 @@ void show_trace_task(struct task_struct *tsk)
printk("\n");
}
+void show_trace_task(struct task_struct *tsk)
+{
+ if (tsk)
+ show_stack(tsk,
+ (unsigned long *) tsk->thread_info->ksp);
+}
+
/*
* Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
*/
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index fcacc76720a0..274178e2c7d8 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -64,9 +64,9 @@ sys_call_table:
/*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
-/*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_nis_syscall
+/*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64
/* "We are the Knights of the Forest of Ni!!" */
-/*235*/ .long sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
+/*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*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
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 196510982fb0..f82247c54708 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -521,6 +521,8 @@ config WATCHDOG_RIO
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/video/Kconfig"
source "drivers/serial/Kconfig"
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 91854621d0a4..f4ffbef00474 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -90,6 +90,11 @@ CONFIG_WATCHDOG_CP1XXX=m
CONFIG_WATCHDOG_RIO=m
#
+# Generic Driver Options
+#
+CONFIG_FW_LOADER=m
+
+#
# Graphics support
#
CONFIG_FB=y
@@ -266,39 +271,72 @@ CONFIG_BLK_DEV_IDE_MODES=y
CONFIG_SCSI=y
#
-# SCSI support type (disk, tape, CDrom)
+# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_REPORT_LUNS=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
#
# SCSI low-level drivers
#
-CONFIG_SCSI_SUNESP=y
-CONFIG_SCSI_QLOGICPTI=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+CONFIG_SCSI_DMX3191D=m
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_EATA_PIO=m
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_INITIO is not set
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
CONFIG_SCSI_QLOGIC_ISP=m
CONFIG_SCSI_QLOGIC_FC=y
CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLOGICPTI=m
+CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_SUNESP=y
#
# Fibre Channel support
@@ -966,17 +1004,19 @@ CONFIG_RAMFS=y
#
# Miscellaneous filesystems
#
-# CONFIG_ADFS_FS is not set
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=m
-# CONFIG_HFS_FS is not set
+CONFIG_HFS_FS=m
CONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
CONFIG_HPFS_FS=m
-# CONFIG_QNX4FS_FS is not set
+CONFIG_QNX4FS_FS=m
+# CONFIG_QNX4FS_RW is not set
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_UFS_FS_WRITE=y
@@ -997,12 +1037,22 @@ CONFIG_EXPORTFS=m
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_SMB_FS is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
CONFIG_CIFS=m
-# CONFIG_NCP_FS is not set
+CONFIG_NCP_FS=m
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
CONFIG_CODA_FS=m
# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_AFS_FS is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
#
# Partition Types
@@ -1010,6 +1060,7 @@ CONFIG_CODA_FS=m
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_SUN_PARTITION=y
+CONFIG_SMB_NLS=y
CONFIG_NLS=y
#
@@ -1210,6 +1261,7 @@ CONFIG_USB_HPUSBSCSI=m
#
# USB Network adaptors
#
+CONFIG_USB_AX8817X=m
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index ce2d74694d53..371c042a2e8d 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -65,8 +65,8 @@ sys_call_table32:
.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
-/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_ni_syscall
- .word sys_ni_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
+/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64
+ .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*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
@@ -124,11 +124,8 @@ sys_call_table:
.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
-
- /* 234 and 235 were for the hugetlb syscalls. They can be reused */
-
-/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_nis_syscall
- .word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
+/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64
+ .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*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
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 1a90f437d5a6..bfeedd653c24 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1569,12 +1569,15 @@ void user_instruction_dump (unsigned int *pc)
printk("\n");
}
-void show_trace_raw(struct thread_info *tp, unsigned long ksp)
+void show_stack(struct task_struct *tsk, unsigned long *_ksp)
{
- unsigned long pc, fp, thread_base;
+ unsigned long pc, fp, thread_base, ksp;
+ struct thread_info *tp = tsk->thread_info;
struct reg_window *rw;
int count = 0;
+ ksp = (unsigned long) _ksp;
+
if (tp == current_thread_info())
flushw_all();
@@ -1596,17 +1599,17 @@ void show_trace_raw(struct thread_info *tp, unsigned long ksp)
void show_trace_task(struct task_struct *tsk)
{
if (tsk)
- show_trace_raw(tsk->thread_info,
- tsk->thread_info->ksp);
+ show_stack(tsk,
+ (unsigned long *) tsk->thread_info->ksp);
}
void dump_stack(void)
{
- unsigned long ksp;
+ unsigned long *ksp;
__asm__ __volatile__("mov %%fp, %0"
: "=r" (ksp));
- show_trace_raw(current_thread_info(), ksp);
+ show_stack(current, ksp);
}
void die_if_kernel(char *str, struct pt_regs *regs)
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 5c4a56023668..e0a9cc52b831 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -149,16 +149,14 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk,
die_if_kernel("Oops", regs);
}
-extern void show_trace_raw(struct thread_info *, unsigned long);
-
static void bad_kernel_pc(struct pt_regs *regs)
{
- unsigned long ksp;
+ unsigned long *ksp;
printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
regs->tpc);
__asm__("mov %%sp, %0" : "=r" (ksp));
- show_trace_raw(current_thread_info(), ksp);
+ show_stack(current, ksp);
unhandled_fault(regs->tpc, current, regs);
}
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index b20061522f93..5182d6573c16 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -390,7 +390,7 @@ struct sol_statvfs64 {
static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
{
- struct statfs s;
+ struct kstatfs s;
int error;
struct sol_statvfs *ss = (struct sol_statvfs *)A(buf);
@@ -424,7 +424,7 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
{
- struct statfs s;
+ struct kstatfs s;
int error;
struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf);
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index da03392ffe8e..44dd2f0ff75e 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -171,6 +171,8 @@ endmenu
source "init/Kconfig"
+source "drivers/base/Kconfig"
+
source "arch/um/Kconfig_char"
source "arch/um/Kconfig_block"
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index f121945fbae2..6b16845261fa 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -249,6 +249,8 @@ endmenu
#############################################################################
+source "drivers/base/Kconfig"
+
source drivers/mtd/Kconfig
source drivers/parport/Kconfig
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index d71ab99ac779..f264d889d13a 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -397,6 +397,8 @@ config UID16
endmenu
+source "drivers/base/Kconfig"
+
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 6a53ca726f0d..08d5301c5d7c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -49,12 +49,12 @@ config ACPI_HT_ONLY
Full ACPI support (CONFIG_ACPI) is preferred. Use this option
only if you wish to limit ACPI's role to processor enumeration.
- There is no command-line option to disable this, but the kernel
- will fall back to the MPS table if the MADT is not present.
+ 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 || X86 && ACPI
+ depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) || X86 && ACPI && !ACPI_HT_ONLY
default y
config ACPI_SLEEP
@@ -135,6 +135,31 @@ 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
+config ACPI_ASUS
+ tristate "ASUS/Medion Laptop Extras"
+ depends on X86 && ACPI && !ACPI_HT_ONLY
+ ---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
+ support some Medion laptops (such as 9675 for example). It makes all
+ the extra buttons generate standard ACPI events that go through
+ /proc/acpi/events, and (on some models) adds support for changing the
+ display brightness and output, switching the LCD backlight on and off,
+ and most importantly, allows you to blink those fancy LEDs intended
+ for reporting mail and wireless status.
+
+ All settings are changed via /proc/acpi/asus directory entries. Owner
+ and group for these entries can be set with asus_uid and asus_gid
+ parameters.
+
+ More information and a userspace daemon for handling the extra buttons
+ at <http://sourceforge.net/projects/acpi4asus/>.
+
+ If you have an ACPI-compatible ASUS laptop, say Y or M here. This
+ driver is still under development, so if your laptop is unsupported or
+ something works not quite as expected, please use the mailing list
+ available on the above page (acpi4asus-user@lists.sourceforge.net)
+
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86 && ACPI && !ACPI_HT_ONLY
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 5db5f58e152f..f5f7c06e2a51 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -44,5 +44,6 @@ obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
obj-$(CONFIG_ACPI_DEBUG) += debug.o
obj-$(CONFIG_ACPI_NUMA) += numa.o
+obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_ACPI_BUS) += scan.o
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
new file mode 100644
index 000000000000..bb9c1a32927d
--- /dev/null
+++ b/drivers/acpi/asus_acpi.c
@@ -0,0 +1,951 @@
+/*
+ * asus_acpi.c - Asus Laptop ACPI Extras
+ *
+ *
+ * Copyright (C) 2002, 2003 Julien Lerouge, Karol Kozimor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * The development page for this driver is located at
+ * http://sourceforge.net/projects/acpi4asus/
+ *
+ * Credits:
+ * Johann Wiesner - Small compile fixes
+ * John Belmonte - ACPI code for Toshiba laptop was a good starting point.
+ *
+ * TODO
+ * add Fn key status
+ * Add mode selection on module loading (parameter) -> still necessary ?
+ * Complete display switching -- may require dirty hacks?
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+#define ASUS_ACPI_VERSION "0.24a"
+
+#define PROC_ASUS "asus" //the directory
+#define PROC_MLED "mled"
+#define PROC_WLED "wled"
+#define PROC_INFOS "info"
+#define PROC_LCD "lcd"
+#define PROC_BRN "brn"
+#define PROC_DISP "disp"
+
+#define ACPI_HOTK_NAME "Asus Laptop ACPI Extras Driver"
+#define ACPI_HOTK_CLASS "hotkey"
+#define ACPI_HOTK_DEVICE_NAME "Hotkey"
+#define ACPI_HOTK_HID "ATK0100"
+
+/*
+ * Some events we use, same for all Asus
+ */
+#define BR_UP 0x10
+#define BR_DOWN 0x20
+
+/*
+ * Flags for hotk status
+ */
+#define MLED_ON 0x01 //is MLED ON ?
+#define WLED_ON 0x02
+
+MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
+MODULE_DESCRIPTION(ACPI_HOTK_NAME);
+MODULE_LICENSE("GPL");
+
+
+static uid_t asus_uid = 0;
+static gid_t asus_gid = 0;
+MODULE_PARM(asus_uid, "i");
+MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n");
+MODULE_PARM(asus_gid, "i");
+MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n");
+
+
+/* For each model, all features implemented */
+struct model_data {
+ char *name; //name of the laptop
+ char *mt_mled; //method to handle mled
+ char *mled_status; //node to handle mled reading
+ char *mt_wled; //method to handle wled
+ char *wled_status; //node to handle wled reading
+ char *mt_lcd_switch; //method to turn LCD ON/OFF
+ char *lcd_status; //node to read LCD panel state
+ char *brightness_up; //method to set brightness up
+ char *brightness_down; //guess what ?
+ char *brightness_set; //method to set absolute brightness
+ char *brightness_get; //method to get absolute brightness
+ char *brightness_status;//node to get brightness
+ char *display_set; //method to set video output
+ char *display_get; //method to get video output
+};
+
+/*
+ * This is the main structure, we can use it to store anything interesting
+ * about the hotk device
+ */
+struct asus_hotk {
+ struct acpi_device *device; //the device we are in
+ acpi_handle handle; //the handle of the hotk device
+ char status; //status of the hotk, for LEDs, ...
+ struct model_data *methods; //methods available on the laptop
+ u8 brightness; //brighness level
+ enum {
+ L2X = 0, //L200D -> TODO check Q11 (Fn+F8)
+ // Calling this method simply hang the
+ // computer, ISMI method hangs the laptop.
+ L3X, //L3C
+ L3D, //L3400D
+ M2X, //M2400E
+ S1X, //S1300A -> TODO special keys do not work ?
+ D1X, //D1
+ L1X, //L1400B
+ A1X, //A1340D, A1300F
+ J1X, //S200 (J1)
+ //TODO A1370D does not seems to have a ATK device
+ // L8400 model doesn't have ATK
+ END_MODEL,
+ } model; //Models currently supported
+ u16 event_count[128]; //count for each event TODO make this better
+};
+
+/* Here we go */
+#define L3X_PREFIX "\\_SB.PCI0.PX40.ECD0."
+#define S1X_PREFIX "\\_SB.PCI0.PX40."
+#define L1X_PREFIX S1X_PREFIX
+#define A1X_PREFIX "\\_SB.PCI0.ISA.EC0."
+#define J1X_PREFIX A1X_PREFIX
+
+static struct model_data model_conf[END_MODEL] = {
+ /*
+ * name| mled |mled read| wled |wled read| lcd sw |lcd read |
+ * br up|br down | br set | br read | br status|set disp | get disp
+ *
+ * br set and read shall be in hotk device !
+ * same for set disp
+ *
+ * TODO I have seen a SWBX and AIBX method on some models, like L1400B,
+ * it seems to be a kind of switch, but what for ?
+ *
+ */
+ {"L2X", "MLED", "\\SGP6", "WLED", "\\RCP3", "\\Q10", "\\SGP0",
+ "\\Q0E", "\\Q0F", NULL, NULL, NULL, "SDSP", "\\INFB"},
+
+ {"L3X", "MLED", NULL, "WLED", NULL, L3X_PREFIX "_Q10", "\\GL32",
+ L3X_PREFIX "_Q0F", L3X_PREFIX "_Q0E", "SPLV", "GPLV", "\\BLVL", "SDSP",
+ "\\_SB.PCI0.PCI1.VGAC.NMAP"},
+
+ {"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG",
+ "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"},
+
+ {"M2X", "MLED", NULL, "WLED", NULL, "\\Q10", "\\GP06",
+ "\\Q0E","\\Q0F", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"},
+
+ {"S1X", "MLED", "\\EMLE", "WLED", NULL, S1X_PREFIX "Q10", "\\PNOF",
+ S1X_PREFIX "Q0F", S1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
+
+ {"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11",
+ "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"},
+
+ {"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF",
+ L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
+
+ {"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI",
+ A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL},
+
+ {"J1X", "MLED", "\\MAIL", NULL, NULL, J1X_PREFIX "_Q10", "\\BKLI",
+ J1X_PREFIX "_Q0B", J1X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL}
+};
+
+/* procdir we use */
+static struct proc_dir_entry *asus_proc_dir = NULL;
+
+/*
+ * This header is made available to allow proper configuration given model,
+ * revision number , ... this info cannot go in struct asus_hotk because it is
+ * available before the hotk
+ */
+static struct acpi_table_header *asus_info = NULL;
+
+/*
+ * The hotkey driver declaration
+ */
+static int asus_hotk_add(struct acpi_device *device);
+static int asus_hotk_remove(struct acpi_device *device, int type);
+static struct acpi_driver asus_hotk_driver = {
+ .name = ACPI_HOTK_NAME,
+ .class = ACPI_HOTK_CLASS,
+ .ids = ACPI_HOTK_HID,
+ .ops = {
+ .add = asus_hotk_add,
+ .remove = asus_hotk_remove,
+ },
+};
+
+/*
+ * This function evaluates an ACPI method, given an int as parameter, the
+ * method is searched within the scope of the handle, can be NULL. The output
+ * of the method is written is output, which can also be NULL
+ *
+ * returns 1 if write is successful, 0 else.
+ */
+static int write_acpi_int(acpi_handle handle, const char *method, int val,
+ struct acpi_buffer *output)
+{
+ struct acpi_object_list params; //list of input parameters (an int here)
+ union acpi_object in_obj; //the only param we use
+ acpi_status status;
+
+ params.count = 1;
+ params.pointer = &in_obj;
+ in_obj.type = ACPI_TYPE_INTEGER;
+ in_obj.integer.value = val;
+
+ status = acpi_evaluate_object(handle, (char *) method, &params, output);
+ return (status == AE_OK);
+}
+
+
+static int read_acpi_int(acpi_handle handle, const char *method, int *val)
+{
+ struct acpi_buffer output;
+ union acpi_object out_obj;
+ acpi_status status;
+
+ output.length = sizeof(out_obj);
+ output.pointer = &out_obj;
+
+ status = acpi_evaluate_object(handle, (char*) method, NULL, &output);
+ *val = out_obj.integer.value;
+ return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
+}
+
+/*
+ * We write our info in page, we begin at offset off and cannot write more
+ * than count bytes. We set eof to 1 if we handle those 2 values. We return the
+ * number of bytes written in page
+ */
+static int
+proc_read_info(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ int len = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+ char buf[16]; //enough for all info
+ /*
+ * We use the easy way, we don't care of off and count, so we don't set eof
+ * to 1
+ */
+
+ len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
+ len +=
+ sprintf(page + len, "Model reference : %s\n",
+ hotk->methods->name);
+ if (asus_info) {
+ snprintf(buf, 5, "%s", asus_info->signature);
+ len += sprintf(page + len, "ACPI signature : %s\n", buf);
+ snprintf(buf, 16, "%d", asus_info->length);
+ len += sprintf(page + len, "Table length : %s\n", buf);
+ snprintf(buf, 16, "%d", asus_info->revision);
+ len += sprintf(page + len, "ACPI minor version : %s\n", buf);
+ snprintf(buf, 16, "%d", asus_info->checksum);
+ len += sprintf(page + len, "Checksum : %s\n", buf);
+ snprintf(buf, 7, "%s", asus_info->oem_id);
+ len += sprintf(page + len, "OEM identification : %s\n", buf);
+ snprintf(buf, 9, "%s", asus_info->oem_table_id);
+ len += sprintf(page + len, "OEM table id : %s\n", buf);
+ snprintf(buf, 16, "%x", asus_info->oem_revision);
+ len += sprintf(page + len, "OEM rev number : 0x%s\n", buf);
+ snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
+ len += sprintf(page + len, "ASL comp vendor ID : %s\n", buf);
+ snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
+ len += sprintf(page + len, "ASL comp rev number: 0x%s\n", buf);
+ }
+
+ return len;
+}
+
+
+/*
+ * proc file handlers
+ */
+static int
+proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ int len = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+ int led_status = 0;
+ /*
+ * We use the easy way, we don't care of off and count, so we don't set eof
+ * to 1
+ */
+ if (hotk->methods->mled_status) {
+ if (read_acpi_int(NULL, hotk->methods->mled_status,
+ &led_status))
+ len = sprintf(page, "%d\n", led_status);
+ else
+ printk(KERN_NOTICE "Asus ACPI: Error reading MLED "
+ "status\n");
+ } else {
+ len = sprintf(page, "%d\n", (hotk->status & MLED_ON) ? 1 : 0);
+ }
+
+ return len;
+}
+
+
+static int
+proc_write_mled(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int value;
+ int led_out = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+
+
+ /* scan expression. Multiple expressions may be delimited with ; */
+ if (sscanf(buffer, "%i", &value) == 1)
+ led_out = ~value & 1;
+
+ hotk->status =
+ (value) ? (hotk->status | MLED_ON) : (hotk->status & ~MLED_ON);
+
+ /* We don't have to check mt_mled exists if we are here :) */
+ if (!write_acpi_int(hotk->handle, hotk->methods->mt_mled, led_out,
+ NULL))
+ printk(KERN_NOTICE "Asus ACPI: MLED write failed\n");
+
+
+
+ return count;
+}
+
+/*
+ * We write our info in page, we begin at offset off and cannot write more
+ * than count bytes. We set eof to 1 if we handle those 2 values. We return the
+ * number of bytes written in page
+ */
+static int
+proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ int len = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+ int led_status;
+
+ if (hotk->methods->wled_status) {
+ if (read_acpi_int(NULL, hotk->methods->mled_status,
+ &led_status))
+ len = sprintf(page, "%d\n", led_status);
+ else
+ printk(KERN_NOTICE "Asus ACPI: Error reading WLED "
+ "status\n");
+ } else {
+ len = sprintf(page, "%d\n", (hotk->status & WLED_ON) ? 1 : 0);
+ }
+
+ return len;
+}
+
+static int
+proc_write_wled(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int value;
+ int led_out = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+ /* scan expression. Multiple expressions may be delimited with ; */
+ if (sscanf(buffer, "%i", &value) == 1)
+ led_out = value & 1;
+
+ hotk->status =
+ (value) ? (hotk->status | WLED_ON) : (hotk->status & ~WLED_ON);
+
+ /* We don't have to check if mt_wled exists if we are here :) */
+ if (!write_acpi_int(hotk->handle, hotk->methods->mt_wled, led_out,
+ NULL))
+ printk(KERN_NOTICE "Asus ACPI: WLED write failed\n");
+
+
+ return count;
+}
+
+
+static int get_lcd_state(struct asus_hotk *hotk)
+{
+ int lcd = 0;
+
+ /* We don't have to check anything, if we are here */
+ if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
+ printk(KERN_NOTICE "Asus ACPI: Error reading LCD status\n");
+
+ if (hotk->model == L2X)
+ lcd = ~lcd;
+
+ return (lcd & 1);
+}
+
+
+static int
+proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ return sprintf(page, "%d\n", get_lcd_state((struct asus_hotk *) data));
+}
+
+
+static int
+proc_write_lcd(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int value;
+ int lcd = 0;
+ acpi_status status = 0;
+ int lcd_status = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+ /* scan expression. Multiple expressions may be delimited with ; */
+ if (sscanf(buffer, "%i", &value) == 1)
+ lcd = value & 1;
+
+ lcd_status = get_lcd_state(hotk);
+
+ if (lcd_status != lcd) {
+ /* switch */
+ status =
+ acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch,
+ NULL, NULL);
+ if (ACPI_FAILURE(status))
+ printk(KERN_NOTICE "Asus ACPI: Error switching LCD\n");
+ }
+
+ return count;
+}
+
+
+/*
+ * Change the brightness level
+ */
+static void set_brightness(int value, struct asus_hotk *hotk)
+{
+ acpi_status status = 0;
+
+ /* ATKD laptop */
+ if(hotk->methods->brightness_set) {
+ if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
+ value, NULL))
+ printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n");
+ return;
+ }
+
+ /* HOTK laptop if we are here, act as appropriate */
+ value -= hotk->brightness;
+ while (value != 0) {
+ status = acpi_evaluate_object(NULL, (value > 0) ?
+ hotk->methods->brightness_up :
+ hotk->methods->brightness_down,
+ NULL, NULL);
+ (value > 0) ? value-- : value++;
+ if (ACPI_FAILURE(status))
+ printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n");
+ }
+ return;
+}
+
+static int read_brightness(struct asus_hotk *hotk)
+{
+ int value;
+
+ if(hotk->methods->brightness_get) { /* ATKD laptop */
+ if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get,
+ &value))
+ printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n");
+ } else if (hotk->methods->brightness_status) { /* For D1 for example */
+ if (!read_acpi_int(NULL, hotk->methods->brightness_status,
+ &value))
+ printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n");
+ } else /* HOTK laptop */
+ value = hotk->brightness;
+ return value;
+}
+
+static int
+proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+ return sprintf(page, "%d\n", read_brightness(hotk));
+}
+
+static int
+proc_write_brn(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int value;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+ /* scan expression. Multiple expressions may be delimited with ; */
+ if (sscanf(buffer, "%d", &value) == 1) {
+ value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
+ /* 0 <= value <= 15 */
+ set_brightness(value, hotk);
+ } else {
+ printk(KERN_NOTICE "Asus ACPI: Error reading user input\n");
+ }
+
+ return count;
+}
+
+static void set_display(int value, struct asus_hotk *hotk)
+{
+ /* no sanity check needed for now */
+ if (!write_acpi_int(hotk->handle, hotk->methods->display_set,
+ value, NULL))
+ printk(KERN_NOTICE "Asus ACPI: Error setting display\n");
+ return;
+}
+
+/*
+ * Now, *this* one could be more user-friendly, but so far, no-one has
+ * complained. The significance of bits is the same as in proc_write_disp()
+ */
+
+static int
+proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ int value = 0;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+ if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
+ printk(KERN_NOTICE "Asus ACPI: Error reading display status\n");
+ return sprintf(page, "%d\n", value);
+}
+
+/*
+ * Preliminary support for display switching. As of now: 0x01 should activate
+ * the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination
+ * (bitwise) of these will suffice. I never actually tested 3 displays hooked up
+ * simultaneously, so be warned.
+ */
+
+static int
+proc_write_disp(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int value;
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+ /* scan expression. Multiple expressions may be delimited with ; */
+ if (sscanf(buffer, "%d", &value) == 1)
+ set_display(value, hotk);
+ else {
+ printk(KERN_NOTICE "Asus ACPI: Error reading user input\n");
+ }
+
+ return count;
+}
+
+static int asus_hotk_add_fs(struct acpi_device *device)
+{
+ struct proc_dir_entry *proc;
+ struct asus_hotk *hotk = acpi_driver_data(device);
+ mode_t mode;
+
+ /*
+ * If parameter uid or gid is not changed, keep the default setting for
+ * our proc entries (-rw-rw-rw-) else, it means we care about security,
+ * and then set to -rw-rw----
+ */
+
+ if ((asus_uid == 0) && (asus_gid == 0)){
+ mode = S_IFREG | S_IRUGO | S_IWUGO;
+ }else{
+ mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
+ }
+
+ acpi_device_dir(device) = asus_proc_dir;
+ if (!acpi_device_dir(device))
+ return(-ENODEV);
+
+ proc = create_proc_entry(PROC_INFOS, mode, acpi_device_dir(device));
+ if (proc) {
+ proc->read_proc = proc_read_info;
+ proc->data = acpi_driver_data(device);
+ proc->owner = THIS_MODULE;
+ proc->uid = asus_uid;
+ proc->gid = asus_gid;;
+ } else {
+ printk(KERN_NOTICE " Unable to create " PROC_INFOS
+ " fs entry\n");
+ }
+
+ if (hotk->methods->mt_wled) {
+ proc = create_proc_entry(PROC_WLED, mode, acpi_device_dir(device));
+ if (proc) {
+ proc->write_proc = proc_write_wled;
+ proc->read_proc = proc_read_wled;
+ proc->data = acpi_driver_data(device);
+ proc->owner = THIS_MODULE;
+ proc->uid = asus_uid;
+ proc->gid = asus_gid;;
+ } else {
+ printk(KERN_NOTICE " Unable to create " PROC_WLED
+ " fs entry\n");
+ }
+ }
+
+ if (hotk->methods->mt_mled) {
+ proc = create_proc_entry(PROC_MLED, mode, acpi_device_dir(device));
+ if (proc) {
+ proc->write_proc = proc_write_mled;
+ proc->read_proc = proc_read_mled;
+ proc->data = acpi_driver_data(device);
+ proc->owner = THIS_MODULE;
+ proc->uid = asus_uid;
+ proc->gid = asus_gid;;
+ } else {
+ printk(KERN_NOTICE " Unable to create " PROC_MLED
+ " fs entry\n");
+ }
+ }
+
+ /*
+ * We need both read node and write method as LCD switch is also accessible
+ * from keyboard
+ */
+ if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
+ proc = create_proc_entry(PROC_LCD, mode, acpi_device_dir(device));
+ if (proc) {
+ proc->write_proc = proc_write_lcd;
+ proc->read_proc = proc_read_lcd;
+ proc->data = acpi_driver_data(device);
+ proc->owner = THIS_MODULE;
+ proc->uid = asus_uid;
+ proc->gid = asus_gid;;
+ } else {
+ printk(KERN_NOTICE " Unable to create " PROC_LCD
+ " fs entry\n");
+ }
+ }
+
+ if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
+ (hotk->methods->brightness_get && hotk->methods->brightness_get)) {
+ proc = create_proc_entry(PROC_BRN, mode, acpi_device_dir(device));
+ if (proc) {
+ proc->write_proc = proc_write_brn;
+ proc->read_proc = proc_read_brn;
+ proc->data = acpi_driver_data(device);
+ proc->owner = THIS_MODULE;
+ proc->uid = asus_uid;
+ proc->gid = asus_gid;;
+ } else {
+ printk(KERN_NOTICE " Unable to create " PROC_BRN
+ " fs entry\n");
+ }
+ }
+
+ if (hotk->methods->display_set) {
+ proc = create_proc_entry(PROC_DISP, mode, acpi_device_dir(device));
+ if (proc) {
+ proc->write_proc = proc_write_disp;
+ proc->read_proc = proc_read_disp;
+ proc->data = acpi_driver_data(device);
+ proc->owner = THIS_MODULE;
+ proc->uid = asus_uid;
+ proc->gid = asus_gid;;
+ } else {
+ printk(KERN_NOTICE " Unable to create " PROC_DISP
+ " fs entry\n");
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
+{
+ /* TODO Find a better way to handle events count. Here, in data, we receive
+ * the hotk, so we can make anything !!
+ */
+ struct asus_hotk *hotk = (struct asus_hotk *) data;
+
+ if (!hotk)
+ return;
+
+ if ((event & ~((u32) BR_UP)) < 16) {
+ hotk->brightness = (event & ~((u32) BR_UP));
+ } else if ((event & ~((u32) BR_DOWN)) < 16 ) {
+ hotk->brightness = (event & ~((u32) BR_DOWN));
+ }
+
+ acpi_bus_generate_event(hotk->device, event,
+ hotk->event_count[event % 128]++);
+
+ return;
+}
+
+/*
+ * This function is used to initialize the hotk with right values. In this
+ * method, we can make all the detection we want, and modify the hotk struct
+ */
+static int asus_hotk_get_info(struct asus_hotk *hotk)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *model = NULL;
+
+ /*
+ * We have to write 0 on init this far for all ASUS models
+ */
+ if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
+ printk(KERN_NOTICE " Hotkey initialization failed\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Here, we also use asus_info to make decision. For example, on INIT
+ * method, S1X and L1X models both reports to be L84F, but they don't
+ * have the same methods (L1X has WLED, S1X don't)
+ */
+ model = (union acpi_object *) buffer.pointer;
+ if (model->type == ACPI_TYPE_STRING) {
+ printk(KERN_NOTICE " %s model detected, ", model->string.pointer);
+ }
+
+ hotk->model = END_MODEL;
+ if (strncmp(model->string.pointer, "L3D", 3) == 0)
+ hotk->model = L3D;
+ /*
+ * L2B has same settings that L3X, except for GL32, but as
+ * there is no node to get the LCD status, and as GL32 is never
+ * used anywhere else, I assume it's safe, even if lcd get is
+ * broken for this model (TODO fix it ?)
+ */
+ else if (strncmp(model->string.pointer, "L3", 2) == 0 ||
+ strncmp(model->string.pointer, "L2B", 3) == 0)
+ hotk->model = L3X;
+ else if (strncmp(model->string.pointer, "M2", 2) == 0)
+ hotk->model = M2X;
+ else if (strncmp(model->string.pointer, "L2", 2) == 0)
+ hotk->model = L2X;
+ else if (strncmp(model->string.pointer, "L8", 2) == 0)
+ /* S1300A reports L84F, but L1400B too */
+ if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
+ hotk->model = L1X;
+ else
+ hotk->model = S1X;
+ else if (strncmp(model->string.pointer, "D1", 2) == 0)
+ hotk->model = D1X;
+ else if (strncmp(model->string.pointer, "A1", 2) == 0)
+ hotk->model = A1X;
+ else if (strncmp(model->string.pointer, "J1", 2) == 0)
+ hotk->model = J1X;
+
+
+ if (hotk->model == END_MODEL) {
+ /* By default use the same values, as I don't know others */
+ printk("unsupported, trying default values, contact the "
+ "developers\n");
+ hotk->model = L2X;
+ } else {
+ printk("supported\n");
+ }
+
+ hotk->methods = &model_conf[hotk->model];
+
+ acpi_os_free(model);
+
+ return AE_OK;
+}
+
+
+
+static int asus_hotk_check(struct asus_hotk *hotk)
+{
+ int result = 0;
+
+ if (!hotk)
+ return(-EINVAL);
+
+ result = acpi_bus_get_status(hotk->device);
+ if (result)
+ return(result);
+
+ if (hotk->device->status.present) {
+ result = asus_hotk_get_info(hotk);
+ } else {
+ printk(KERN_NOTICE " Hotkey device not present, aborting\n");
+ return(-EINVAL);
+ }
+
+ return(result);
+}
+
+
+
+static int asus_hotk_add(struct acpi_device *device)
+{
+ struct asus_hotk *hotk = NULL;
+ acpi_status status = AE_OK;
+ int result;
+
+ if (!device)
+ return(-EINVAL);
+
+ hotk =
+ (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+ if (!hotk)
+ return(-ENOMEM);
+ memset(hotk, 0, sizeof(struct asus_hotk));
+
+ hotk->handle = device->handle;
+ sprintf(acpi_device_name(device), "%s", ACPI_HOTK_DEVICE_NAME);
+ sprintf(acpi_device_class(device), "%s", ACPI_HOTK_CLASS);
+ acpi_driver_data(device) = hotk;
+ hotk->device = device;
+
+
+ result = asus_hotk_check(hotk);
+ if (result)
+ goto end;
+
+ result = asus_hotk_add_fs(device);
+ if (result)
+ goto end;
+
+ /*
+ * We install the handler, it will receive the hotk in parameter, so, we
+ * could add other data to the hotk struct
+ */
+ status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
+ asus_hotk_notify, hotk);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_NOTICE
+ " Error installing notify handler\n");
+ } else {
+ printk(KERN_DEBUG
+ " Notify Handler installed successfully\n");
+ }
+
+ /* For HOTK laptops: init the hotk->brightness value */
+ if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) &&
+ (hotk->methods->brightness_up && hotk->methods->brightness_down)) {
+ status = acpi_evaluate_object(NULL, hotk->methods->brightness_down,
+ NULL, NULL);
+ if (ACPI_FAILURE(status))
+ printk(KERN_NOTICE " Error changing brightness\n");
+ status = acpi_evaluate_object(NULL, hotk->methods->brightness_up,
+ NULL, NULL);
+ if (ACPI_FAILURE(status))
+ printk(KERN_NOTICE " Error changing brightness\n");
+ }
+
+ end:
+ if (result) {
+ kfree(hotk);
+ }
+
+ return(result);
+}
+
+
+
+
+static int asus_hotk_remove(struct acpi_device *device, int type)
+{
+ acpi_status status = 0;
+ struct asus_hotk *hotk = NULL;
+
+ if (!device || !acpi_driver_data(device))
+ return(-EINVAL);
+
+ hotk = (struct asus_hotk *) acpi_driver_data(device);
+
+ status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
+ asus_hotk_notify);
+ if (ACPI_FAILURE(status))
+ printk(KERN_NOTICE "Error removing notify handler\n");
+
+ kfree(hotk);
+
+ return(0);
+}
+
+
+
+
+static int __init asus_acpi_init(void)
+{
+ int result = 0;
+ acpi_status status = 0;
+ struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
+ ASUS_ACPI_VERSION);
+ /*
+ * Here is the code to know the model we are running on. We need to
+ * know this before calling the acpi_bus_register_driver function, in
+ * case the HID for the laptop we are running on is different from
+ * ACPI_HOTK_HID, which I have never seen yet :)
+ *
+ * This information is then available in the global var asus_info
+ */
+ status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_NOTICE " Couldn't get the DSDT table header\n");
+ } else {
+ asus_info = (struct acpi_table_header *) dsdt.pointer;
+ }
+
+ asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
+ if (!asus_proc_dir)
+ return(-ENODEV);
+ asus_proc_dir->owner = THIS_MODULE;
+
+ result = acpi_bus_register_driver(&asus_hotk_driver);
+ if (result < 0) {
+ printk(KERN_NOTICE " Error registering " ACPI_HOTK_NAME " \n");
+ remove_proc_entry(PROC_ASUS, acpi_root_dir);
+ return(-ENODEV);
+ }
+
+ return(0);
+}
+
+
+
+static void __exit asus_acpi_exit(void)
+{
+ acpi_bus_unregister_driver(&asus_hotk_driver);
+ remove_proc_entry(PROC_ASUS, acpi_root_dir);
+
+ acpi_os_free(asus_info);
+
+ return;
+}
+
+module_init(asus_acpi_init);
+module_exit(asus_acpi_exit);
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index 55495cc50518..0c47ecea305d 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -306,7 +306,6 @@ acpi_ds_method_data_set_value (
{
acpi_status status;
struct acpi_namespace_node *node;
- union acpi_operand_object *new_desc = object;
ACPI_FUNCTION_TRACE ("ds_method_data_set_value");
@@ -325,28 +324,16 @@ acpi_ds_method_data_set_value (
}
/*
- * If the object has just been created and is not attached to anything,
- * (the reference count is 1), then we can just store it directly into
- * the arg/local. Otherwise, we must copy it.
+ * Increment ref count so object can't be deleted while installed.
+ * NOTE: We do not copy the object in order to preserve the call by
+ * reference semantics of ACPI Control Method invocation.
+ * (See ACPI specification 2.0_c)
*/
- if (object->common.reference_count > 1) {
- status = acpi_ut_copy_iobject_to_iobject (object, &new_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object Copied %p, new %p\n",
- object, new_desc));
- }
- else {
- /* Increment ref count so object can't be deleted while installed */
-
- acpi_ut_add_reference (new_desc);
- }
+ acpi_ut_add_reference (object);
/* Install the object */
- node->object = new_desc;
+ node->object = object;
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 4cb089d54c67..0108b47fadff 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -186,11 +186,13 @@ acpi_ev_gpe_detect (
}
ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
- "GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
+ "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
+ ACPI_HIDWORD (gpe_register_info->status_address.address),
+ ACPI_LODWORD (gpe_register_info->status_address.address),
+ gpe_register_info->status,
ACPI_HIDWORD (gpe_register_info->enable_address.address),
ACPI_LODWORD (gpe_register_info->enable_address.address),
- gpe_register_info->enable,
- gpe_register_info->status));
+ gpe_register_info->enable));
/* First check if there is anything active at all in this register */
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index c24a11d9aaec..0849a14560c8 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -76,9 +76,14 @@ acpi_ev_valid_gpe_event (
/* No need for spin lock since we are not changing any list elements */
+ /* Walk the GPE interrupt levels */
+
gpe_xrupt_block = acpi_gbl_gpe_xrupt_list_head;
while (gpe_xrupt_block) {
gpe_block = gpe_xrupt_block->gpe_block_list_head;
+
+ /* Walk the GPE blocks on this interrupt level */
+
while (gpe_block) {
if ((&gpe_block->event_info[0] <= gpe_event_info) &&
(&gpe_block->event_info[((acpi_size) gpe_block->register_count) * 8] > gpe_event_info)) {
@@ -155,7 +160,7 @@ unlock_and_exit:
*
* PARAMETERS: Callback from walk_namespace
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
* control method under the _GPE portion of the namespace.
@@ -164,10 +169,10 @@ unlock_and_exit:
*
* The name of each GPE control method is of the form:
* "_Lnn" or "_Enn"
- * Where:
- * L - means that the GPE is level triggered
- * E - means that the GPE is edge triggered
- * nn - is the GPE number [in HEX]
+ * Where:
+ * L - means that the GPE is level triggered
+ * E - means that the GPE is edge triggered
+ * nn - is the GPE number [in HEX]
*
******************************************************************************/
@@ -196,7 +201,8 @@ acpi_ev_save_method_info (
name[ACPI_NAME_SIZE] = 0;
/*
- * Edge/Level determination is based on the 2nd character of the method name
+ * Edge/Level determination is based on the 2nd character
+ * of the method name
*/
switch (name[1]) {
case 'L':
@@ -249,15 +255,14 @@ acpi_ev_save_method_info (
gpe_event_info->flags = type;
gpe_event_info->method_node = (struct acpi_namespace_node *) obj_handle;
- /*
- * Enable the GPE (SCIs should be disabled at this point)
- */
+ /* Enable the GPE (SCIs should be disabled at this point) */
+
status = acpi_hw_enable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n",
name, gpe_number));
return_ACPI_STATUS (AE_OK);
@@ -867,8 +872,8 @@ acpi_ev_gpe_initialize (void)
}
/*
- * GPE0 and GPE1 do not have to be contiguous in the GPE number space,
- * But, GPE0 always starts at zero.
+ * GPE0 and GPE1 do not have to be contiguous in the GPE number
+ * space. However, GPE0 always starts at GPE number zero.
*/
gpe_number_max = acpi_gbl_FADT->gpe1_base +
((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 757ef213ede5..85e2acdf3c12 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -222,7 +222,7 @@ acpi_ex_opcode_1A_1T_1R (
union acpi_operand_object *return_desc2 = NULL;
u32 temp32;
u32 i;
- u32 j;
+ u32 power_of_ten;
acpi_integer digit;
@@ -291,61 +291,70 @@ acpi_ex_opcode_1A_1T_1R (
case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */
/*
- * The 64-bit ACPI integer can hold 16 4-bit BCD integers
+ * The 64-bit ACPI integer can hold 16 4-bit BCD characters
+ * (if table is 32-bit, integer can hold 8 BCD characters)
+ * Convert each 4-bit BCD value
*/
+ power_of_ten = 1;
return_desc->integer.value = 0;
- for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
- /* Get one BCD digit */
+ digit = operand[0]->integer.value;
- digit = (acpi_integer) ((operand[0]->integer.value >> (i * 4)) & 0xF);
+ /* Convert each BCD digit (each is one nybble wide) */
+
+ for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
+ /* Get the least significant 4-bit BCD digit */
+
+ temp32 = ((u32) digit) & 0xF;
/* Check the range of the digit */
- if (digit > 9) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: %d\n",
- (u32) digit));
+ if (temp32 > 9) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "BCD digit too large (not decimal): 0x%X\n",
+ temp32));
+
status = AE_AML_NUMERIC_OVERFLOW;
goto cleanup;
}
- if (digit > 0) {
- /* Sum into the result with the appropriate power of 10 */
+ /* Sum the digit into the result with the current power of 10 */
- for (j = 0; j < i; j++) {
- digit *= 10;
- }
+ return_desc->integer.value += (((acpi_integer) temp32) * power_of_ten);
- return_desc->integer.value += digit;
- }
+ /* Shift to next BCD digit */
+
+ digit >>= 4;
+
+ /* Next power of 10 */
+
+ power_of_ten *= 10;
}
break;
case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */
- if (operand[0]->integer.value > ACPI_MAX_BCD_VALUE) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %8.8X%8.8X\n",
- ACPI_HIDWORD(operand[0]->integer.value),
- ACPI_LODWORD(operand[0]->integer.value)));
- status = AE_AML_NUMERIC_OVERFLOW;
- goto cleanup;
- }
-
return_desc->integer.value = 0;
- for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
- /* Divide by nth factor of 10 */
+ digit = operand[0]->integer.value;
- temp32 = 0;
- digit = operand[0]->integer.value;
- for (j = 0; j < i; j++) {
- (void) acpi_ut_short_divide (&digit, 10, &digit, &temp32);
- }
+ /* Each BCD digit is one nybble wide */
- /* Create the BCD digit from the remainder above */
+ for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
+ (void) acpi_ut_short_divide (&digit, 10, &digit, &temp32);
- if (digit > 0) {
- return_desc->integer.value += ((acpi_integer) temp32 << (i * 4));
- }
+ /* Insert the BCD digit that resides in the remainder from above */
+
+ return_desc->integer.value |= (((acpi_integer) temp32) << (i * 4));
+ }
+
+ /* Overflow if there is any data left in Digit */
+
+ if (digit > 0) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n",
+ ACPI_HIDWORD(operand[0]->integer.value),
+ ACPI_LODWORD(operand[0]->integer.value)));
+ status = AE_AML_NUMERIC_OVERFLOW;
+ goto cleanup;
}
break;
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index acd9da27a3ac..517dbaec6227 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -190,8 +190,8 @@ acpi_ex_store (
case ACPI_TYPE_INTEGER:
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n",
- ACPI_HIWORD (source_desc->integer.value),
- ACPI_LOWORD (source_desc->integer.value)));
+ ACPI_HIDWORD (source_desc->integer.value),
+ ACPI_LODWORD (source_desc->integer.value)));
break;
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index ea3dbe74ef58..8d4c003ac195 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -134,7 +134,7 @@ acpi_ex_system_do_stall (
acpi_ex_exit_interpreter ();
- acpi_os_stall (how_long);
+ acpi_os_sleep (0, (how_long / 1000) + 1);
/* And now we must get the interpreter again */
@@ -142,7 +142,7 @@ acpi_ex_system_do_stall (
}
else {
- acpi_os_sleep (0, (how_long / 1000) + 1);
+ acpi_os_stall (how_long);
}
return (status);
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 090684c6ea16..d58e97e3e724 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -289,7 +289,10 @@ acpi_ex_digits_needed (
/*
* acpi_integer is unsigned, so we don't worry about a '-'
*/
- current_value = value;
+ if ((current_value = value) == 0) {
+ return_VALUE (1);
+ }
+
num_digits = 0;
while (current_value) {
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 25e05b138443..b18cbfa6bef4 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -56,7 +56,7 @@
*
* FUNCTION: acpi_hw_clear_acpi_status
*
- * PARAMETERS: none
+ * PARAMETERS: Flags - Lock the hardware or not
*
* RETURN: none
*
@@ -65,7 +65,8 @@
******************************************************************************/
acpi_status
-acpi_hw_clear_acpi_status (void)
+acpi_hw_clear_acpi_status (
+ u32 flags)
{
acpi_status status;
@@ -77,10 +78,11 @@ acpi_hw_clear_acpi_status (void)
ACPI_BITMASK_ALL_FIXED_STATUS,
(u16) acpi_gbl_FADT->xpm1a_evt_blk.address));
-
- status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ if (flags & ACPI_MTX_LOCK) {
+ status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
}
status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
@@ -104,7 +106,9 @@ acpi_hw_clear_acpi_status (void)
status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block);
unlock_and_exit:
- (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ if (flags & ACPI_MTX_LOCK) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+ }
return_ACPI_STATUS (status);
}
@@ -237,8 +241,9 @@ acpi_hw_get_bit_register_info (
*
* FUNCTION: acpi_get_register
*
- * PARAMETERS: register_id - Index of ACPI Register to access
- * use_lock - Lock the hardware
+ * PARAMETERS: register_id - ID of ACPI bit_register to access
+ * return_value - Value that was read from the register
+ * Flags - Lock the hardware or not
*
* RETURN: Value is read from specified Register. Value returned is
* normalized to bit0 (is shifted all the way right)
@@ -290,7 +295,8 @@ acpi_get_register (
*return_value = register_value;
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %X\n", register_value));
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %8.8X register %X\n",
+ register_value, bit_reg_info->parent_register));
}
return_ACPI_STATUS (status);
@@ -443,7 +449,8 @@ unlock_and_exit:
ACPI_DEBUG_EXEC (register_value = ((register_value & bit_reg_info->access_bit_mask) >> bit_reg_info->bit_position));
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "ACPI Register Write actual %X\n", register_value));
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n",
+ value, register_value, bit_reg_info->parent_register));
return_ACPI_STATUS (status);
}
@@ -751,10 +758,15 @@ acpi_hw_low_level_read (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unsupported address space: %X\n", reg->address_space_id));
- status = AE_BAD_PARAMETER;
- break;
+ return (AE_BAD_PARAMETER);
}
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
+ *value, width,
+ ACPI_HIDWORD (reg->address),
+ ACPI_LODWORD (reg->address),
+ acpi_ut_get_region_name (reg->address_space_id)));
+
return (status);
}
@@ -832,9 +844,14 @@ acpi_hw_low_level_write (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unsupported address space: %X\n", reg->address_space_id));
- status = AE_BAD_PARAMETER;
- break;
+ return (AE_BAD_PARAMETER);
}
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
+ value, width,
+ ACPI_HIDWORD (reg->address),
+ ACPI_LODWORD (reg->address),
+ acpi_ut_get_region_name (reg->address_space_id)));
+
return (status);
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 37dc30a49bde..87642c756865 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -231,7 +231,7 @@ acpi_enter_sleep_state (
return_ACPI_STATUS (status);
}
- status = acpi_hw_clear_acpi_status();
+ status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -355,7 +355,7 @@ acpi_enter_sleep_state_s4bios (
ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
- acpi_hw_clear_acpi_status();
+ acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
acpi_hw_disable_non_wakeup_gpes();
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 10a02822ef56..5caecd1a7d7c 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -69,8 +69,6 @@ static int acpi_irq_irq = 0;
static OSD_HANDLER acpi_irq_handler = NULL;
static void *acpi_irq_context = NULL;
-extern struct pci_ops *pci_root_ops;
-
acpi_status
acpi_os_initialize(void)
{
@@ -79,7 +77,7 @@ acpi_os_initialize(void)
* it while walking the namespace (bus 0 and root bridges w/ _BBNs).
*/
#ifdef CONFIG_ACPI_PCI
- if (!pci_root_ops) {
+ if (!raw_pci_ops) {
printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n");
return AE_NULL_ENTRY;
}
@@ -446,15 +444,9 @@ acpi_os_write_memory(
#ifdef CONFIG_ACPI_PCI
acpi_status
-acpi_os_read_pci_configuration (
- struct acpi_pci_id *pci_id,
- u32 reg,
- void *value,
- u32 width)
+acpi_os_read_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, void *value, u32 width)
{
- int result = 0;
- int size = 0;
- struct pci_bus bus;
+ int result, size;
if (!value)
return AE_BAD_PARAMETER;
@@ -470,27 +462,19 @@ acpi_os_read_pci_configuration (
size = 4;
break;
default:
- BUG();
+ return AE_ERROR;
}
- bus.number = pci_id->bus;
- result = pci_root_ops->read(&bus, PCI_DEVFN(pci_id->device,
- pci_id->function),
- reg, size, value);
+ result = raw_pci_ops->read(pci_id->segment, pci_id->bus,
+ pci_id->device, pci_id->function, reg, size, value);
return (result ? AE_ERROR : AE_OK);
}
acpi_status
-acpi_os_write_pci_configuration (
- struct acpi_pci_id *pci_id,
- u32 reg,
- acpi_integer value,
- u32 width)
+acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integer value, u32 width)
{
- int result = 0;
- int size = 0;
- struct pci_bus bus;
+ int result, size;
switch (width) {
case 8:
@@ -503,13 +487,12 @@ acpi_os_write_pci_configuration (
size = 4;
break;
default:
- BUG();
+ return AE_ERROR;
}
- bus.number = pci_id->bus;
- result = pci_root_ops->write(&bus, PCI_DEVFN(pci_id->device,
- pci_id->function),
- reg, size, value);
+ result = raw_pci_ops->write(pci_id->segment, pci_id->bus,
+ pci_id->device, pci_id->function, reg, size, value);
+
return (result ? AE_ERROR : AE_OK);
}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 20a1a9fecc72..ce3d0f9a25bd 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -44,8 +44,6 @@ ACPI_MODULE_NAME ("pci_root")
#define ACPI_PCI_ROOT_DRIVER_NAME "ACPI PCI Root Bridge Driver"
#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge"
-extern struct pci_ops *pci_root_ops;
-
static int acpi_pci_root_add (struct acpi_device *device);
static int acpi_pci_root_remove (struct acpi_device *device, int type);
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index 4b412360e417..099eb723b64e 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -287,10 +287,14 @@ acpi_tb_convert_fadt1 (
(acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
- acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
- (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
- ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ /* PM1B is optional; leave null if not present */
+
+ if (local_fadt->xpm1b_evt_blk.address) {
+ acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+ (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+ (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+ ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ }
}
@@ -379,11 +383,15 @@ acpi_tb_convert_fadt2 (
ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
- acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
- (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
- ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
- acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
+ /* PM1B is optional; leave null if not present */
+
+ if (local_fadt->xpm1b_evt_blk.address) {
+ acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+ (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+ (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+ ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+ acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
+ }
}
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index b16c01e83559..5012037926cb 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -203,10 +203,12 @@ acpi_ut_set_integer_width (
if (revision <= 1) {
acpi_gbl_integer_bit_width = 32;
+ acpi_gbl_integer_nybble_width = 8;
acpi_gbl_integer_byte_width = 4;
}
else {
acpi_gbl_integer_bit_width = 64;
+ acpi_gbl_integer_nybble_width = 16;
acpi_gbl_integer_byte_width = 8;
}
}
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
new file mode 100644
index 000000000000..6d06c9f16d5e
--- /dev/null
+++ b/drivers/base/Kconfig
@@ -0,0 +1,10 @@
+menu "Generic Driver Options"
+
+config FW_LOADER
+ tristate "Hotplug firmware loading support"
+ ---help---
+ This option is provided for the case where no in-kernel-tree modules
+ require hotplug firmware loading support, but a module built outside
+ the kernel tree does.
+
+endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 800228c16081..334fcc6c6ee6 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -3,4 +3,5 @@
obj-y := core.o sys.o interface.o power.o bus.o \
driver.o class.o platform.o \
cpu.o firmware.o init.o map.o
+obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o memblk.o
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
new file mode 100644
index 000000000000..b186dba8d2d8
--- /dev/null
+++ b/drivers/base/firmware_class.c
@@ -0,0 +1,505 @@
+/*
+ * firmware_class.c - Multi purpose firmware loading support
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * Please see Documentation/firmware_class/ for more information.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/vmalloc.h>
+#include <asm/hardirq.h>
+
+#include <linux/firmware.h>
+#include "base.h"
+
+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_DESCRIPTION("Multi purpose firmware loading support");
+MODULE_LICENSE("GPL");
+
+static int loading_timeout = 10; /* In seconds */
+
+struct firmware_priv {
+ char fw_id[FIRMWARE_NAME_MAX];
+ struct completion completion;
+ struct bin_attribute attr_data;
+ struct firmware *fw;
+ int loading;
+ int abort;
+ int alloc_size;
+ struct timer_list timeout;
+};
+
+static ssize_t
+firmware_timeout_show(struct class *class, char *buf)
+{
+ return sprintf(buf, "%d\n", loading_timeout);
+}
+
+/**
+ * firmware_timeout_store:
+ * Description:
+ * Sets the number of seconds to wait for the firmware. Once
+ * this expires an error will be return to the driver and no
+ * firmware will be provided.
+ *
+ * Note: zero means 'wait for ever'
+ *
+ **/
+static ssize_t
+firmware_timeout_store(struct class *class, const char *buf, size_t count)
+{
+ loading_timeout = simple_strtol(buf, NULL, 10);
+ return count;
+}
+
+static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
+
+static void fw_class_dev_release(struct class_device *class_dev);
+int firmware_class_hotplug(struct class_device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
+
+static struct class firmware_class = {
+ .name = "firmware",
+ .hotplug = firmware_class_hotplug,
+ .release = fw_class_dev_release,
+};
+
+int
+firmware_class_hotplug(struct class_device *class_dev, char **envp,
+ int num_envp, char *buffer, int buffer_size)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ int i = 0;
+ char *scratch = buffer;
+
+ if (buffer_size < (FIRMWARE_NAME_MAX + 10))
+ return -ENOMEM;
+ if (num_envp < 1)
+ return -ENOMEM;
+
+ envp[i++] = scratch;
+ scratch += sprintf(scratch, "FIRMWARE=%s", fw_priv->fw_id) + 1;
+ return 0;
+}
+
+static ssize_t
+firmware_loading_show(struct class_device *class_dev, char *buf)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ return sprintf(buf, "%d\n", fw_priv->loading);
+}
+
+/**
+ * firmware_loading_store: - loading control file
+ * Description:
+ * The relevant values are:
+ *
+ * 1: Start a load, discarding any previous partial load.
+ * 0: Conclude the load and handle the data to the driver code.
+ * -1: Conclude the load with an error and discard any written data.
+ **/
+static ssize_t
+firmware_loading_store(struct class_device *class_dev,
+ const char *buf, size_t count)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ int prev_loading = fw_priv->loading;
+
+ fw_priv->loading = simple_strtol(buf, NULL, 10);
+
+ switch (fw_priv->loading) {
+ case -1:
+ fw_priv->abort = 1;
+ wmb();
+ complete(&fw_priv->completion);
+ break;
+ case 1:
+ kfree(fw_priv->fw->data);
+ fw_priv->fw->data = NULL;
+ fw_priv->fw->size = 0;
+ fw_priv->alloc_size = 0;
+ break;
+ case 0:
+ if (prev_loading == 1)
+ complete(&fw_priv->completion);
+ break;
+ }
+
+ return count;
+}
+
+static CLASS_DEVICE_ATTR(loading, 0644,
+ firmware_loading_show, firmware_loading_store);
+
+static ssize_t
+firmware_data_read(struct kobject *kobj,
+ char *buffer, loff_t offset, size_t count)
+{
+ struct class_device *class_dev = to_class_dev(kobj);
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ struct firmware *fw = fw_priv->fw;
+
+ if (offset > fw->size)
+ return 0;
+ if (offset + count > fw->size)
+ count = fw->size - offset;
+
+ memcpy(buffer, fw->data + offset, count);
+ return count;
+}
+static int
+fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
+{
+ u8 *new_data;
+
+ if (min_size <= fw_priv->alloc_size)
+ return 0;
+
+ new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE);
+ if (!new_data) {
+ printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
+ /* Make sure that we don't keep incomplete data */
+ fw_priv->abort = 1;
+ return -ENOMEM;
+ }
+ fw_priv->alloc_size += PAGE_SIZE;
+ if (fw_priv->fw->data) {
+ memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
+ vfree(fw_priv->fw->data);
+ }
+ fw_priv->fw->data = new_data;
+ BUG_ON(min_size > fw_priv->alloc_size);
+ return 0;
+}
+
+/**
+ * firmware_data_write:
+ *
+ * Description:
+ *
+ * Data written to the 'data' attribute will be later handled to
+ * the driver as a firmware image.
+ **/
+static ssize_t
+firmware_data_write(struct kobject *kobj,
+ char *buffer, loff_t offset, size_t count)
+{
+ struct class_device *class_dev = to_class_dev(kobj);
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+ struct firmware *fw = fw_priv->fw;
+ int retval;
+
+ retval = fw_realloc_buffer(fw_priv, offset + count);
+ if (retval)
+ return retval;
+
+ memcpy(fw->data + offset, buffer, count);
+
+ fw->size = max_t(size_t, offset + count, fw->size);
+
+ return count;
+}
+static struct bin_attribute firmware_attr_data_tmpl = {
+ .attr = {.name = "data", .mode = 0644},
+ .size = 0,
+ .read = firmware_data_read,
+ .write = firmware_data_write,
+};
+
+static void
+fw_class_dev_release(struct class_device *class_dev)
+{
+ kfree(class_dev);
+}
+
+static void
+firmware_class_timeout(u_long data)
+{
+ struct firmware_priv *fw_priv = (struct firmware_priv *) data;
+ fw_priv->abort = 1;
+ wmb();
+ complete(&fw_priv->completion);
+}
+
+static inline void
+fw_setup_class_device_id(struct class_device *class_dev, struct device *dev)
+{
+ /* XXX warning we should watch out for name collisions */
+ strncpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE);
+ class_dev->class_id[BUS_ID_SIZE - 1] = '\0';
+}
+static int
+fw_setup_class_device(struct class_device **class_dev_p,
+ const char *fw_name, struct device *device)
+{
+ int retval = 0;
+ struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
+ GFP_KERNEL);
+ struct class_device *class_dev = kmalloc(sizeof (struct class_device),
+ GFP_KERNEL);
+
+ if (!fw_priv || !class_dev) {
+ retval = -ENOMEM;
+ goto error_kfree;
+ }
+ memset(fw_priv, 0, sizeof (*fw_priv));
+ memset(class_dev, 0, sizeof (*class_dev));
+
+ init_completion(&fw_priv->completion);
+ memcpy(&fw_priv->attr_data, &firmware_attr_data_tmpl,
+ sizeof (firmware_attr_data_tmpl));
+
+ strncpy(&fw_priv->fw_id[0], fw_name, FIRMWARE_NAME_MAX);
+ fw_priv->fw_id[FIRMWARE_NAME_MAX - 1] = '\0';
+
+ fw_setup_class_device_id(class_dev, device);
+ class_dev->dev = device;
+
+ fw_priv->timeout.function = firmware_class_timeout;
+ fw_priv->timeout.data = (u_long) fw_priv;
+ init_timer(&fw_priv->timeout);
+
+ class_dev->class = &firmware_class;
+ class_set_devdata(class_dev, fw_priv);
+ retval = class_device_register(class_dev);
+ if (retval) {
+ printk(KERN_ERR "%s: class_device_register failed\n",
+ __FUNCTION__);
+ goto error_kfree;
+ }
+
+ retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data);
+ if (retval) {
+ printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
+ __FUNCTION__);
+ goto error_unreg_class_dev;
+ }
+
+ retval = class_device_create_file(class_dev,
+ &class_device_attr_loading);
+ if (retval) {
+ printk(KERN_ERR "%s: class_device_create_file failed\n",
+ __FUNCTION__);
+ goto error_remove_data;
+ }
+
+ fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
+ if (!fw_priv->fw) {
+ printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
+ __FUNCTION__);
+ retval = -ENOMEM;
+ goto error_remove_loading;
+ }
+ memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
+
+ goto out;
+
+error_remove_loading:
+ class_device_remove_file(class_dev, &class_device_attr_loading);
+error_remove_data:
+ sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data);
+error_unreg_class_dev:
+ class_device_unregister(class_dev);
+error_kfree:
+ kfree(fw_priv);
+ kfree(class_dev);
+ *class_dev_p = NULL;
+out:
+ *class_dev_p = class_dev;
+ return retval;
+}
+static void
+fw_remove_class_device(struct class_device *class_dev)
+{
+ struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+ class_device_remove_file(class_dev, &class_device_attr_loading);
+ sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data);
+ class_device_unregister(class_dev);
+}
+
+/**
+ * request_firmware: - request firmware to hotplug and wait for it
+ * Description:
+ * @firmware will be used to return a firmware image by the name
+ * of @name for device @device.
+ *
+ * Should be called from user context where sleeping is allowed.
+ *
+ * @name will be use as $FIRMWARE in the hotplug environment and
+ * should be distinctive enough not to be confused with any other
+ * firmware image for this or any other device.
+ **/
+int
+request_firmware(const struct firmware **firmware, const char *name,
+ struct device *device)
+{
+ struct class_device *class_dev;
+ struct firmware_priv *fw_priv;
+ int retval;
+
+ if (!firmware)
+ return -EINVAL;
+
+ *firmware = NULL;
+
+ retval = fw_setup_class_device(&class_dev, name, device);
+ if (retval)
+ goto out;
+
+ fw_priv = class_get_devdata(class_dev);
+
+ if (loading_timeout) {
+ fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
+ add_timer(&fw_priv->timeout);
+ }
+
+ wait_for_completion(&fw_priv->completion);
+
+ del_timer(&fw_priv->timeout);
+ fw_remove_class_device(class_dev);
+
+ if (fw_priv->fw->size && !fw_priv->abort) {
+ *firmware = fw_priv->fw;
+ } else {
+ retval = -ENOENT;
+ vfree(fw_priv->fw->data);
+ kfree(fw_priv->fw);
+ }
+ kfree(fw_priv);
+out:
+ return retval;
+}
+
+/**
+ * release_firmware: - release the resource associated with a firmware image
+ **/
+void
+release_firmware(const struct firmware *fw)
+{
+ if (fw) {
+ vfree(fw->data);
+ kfree(fw);
+ }
+}
+
+/**
+ * register_firmware: - provide a firmware image for later usage
+ *
+ * Description:
+ * Make sure that @data will be available by requesting firmware @name.
+ *
+ * Note: This will not be possible until some kind of persistence
+ * is available.
+ **/
+void
+register_firmware(const char *name, const u8 *data, size_t size)
+{
+ /* This is meaningless without firmware caching, so until we
+ * decide if firmware caching is reasonable just leave it as a
+ * noop */
+}
+
+/* Async support */
+struct firmware_work {
+ struct work_struct work;
+ struct module *module;
+ const char *name;
+ struct device *device;
+ void *context;
+ void (*cont)(const struct firmware *fw, void *context);
+};
+
+static void
+request_firmware_work_func(void *arg)
+{
+ struct firmware_work *fw_work = arg;
+ const struct firmware *fw;
+ if (!arg)
+ return;
+ request_firmware(&fw, fw_work->name, fw_work->device);
+ fw_work->cont(fw, fw_work->context);
+ release_firmware(fw);
+ module_put(fw_work->module);
+ kfree(fw_work);
+}
+
+/**
+ * request_firmware_nowait:
+ *
+ * Description:
+ * Asynchronous variant of request_firmware() for contexts where
+ * it is not possible to sleep.
+ *
+ * @cont will be called asynchronously when the firmware request is over.
+ *
+ * @context will be passed over to @cont.
+ *
+ * @fw may be %NULL if firmware request fails.
+ *
+ **/
+int
+request_firmware_nowait(
+ struct module *module,
+ const char *name, struct device *device, void *context,
+ void (*cont)(const struct firmware *fw, void *context))
+{
+ struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
+ GFP_ATOMIC);
+ if (!fw_work)
+ return -ENOMEM;
+ if (!try_module_get(module)) {
+ kfree(fw_work);
+ return -EFAULT;
+ }
+
+ *fw_work = (struct firmware_work) {
+ .module = module,
+ .name = name,
+ .device = device,
+ .context = context,
+ .cont = cont,
+ };
+ INIT_WORK(&fw_work->work, request_firmware_work_func, fw_work);
+
+ schedule_work(&fw_work->work);
+ return 0;
+}
+
+static int __init
+firmware_class_init(void)
+{
+ int error;
+ error = class_register(&firmware_class);
+ if (error) {
+ printk(KERN_ERR "%s: class_register failed\n", __FUNCTION__);
+ }
+ error = class_create_file(&firmware_class, &class_attr_timeout);
+ if (error) {
+ printk(KERN_ERR "%s: class_create_file failed\n",
+ __FUNCTION__);
+ class_unregister(&firmware_class);
+ }
+ return error;
+
+}
+static void __exit
+firmware_class_exit(void)
+{
+ class_remove_file(&firmware_class, &class_attr_timeout);
+ class_unregister(&firmware_class);
+}
+
+module_init(firmware_class_init);
+module_exit(firmware_class_exit);
+
+EXPORT_SYMBOL(release_firmware);
+EXPORT_SYMBOL(request_firmware);
+EXPORT_SYMBOL(request_firmware_nowait);
+EXPORT_SYMBOL(register_firmware);
+EXPORT_SYMBOL(firmware_class);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index e8a4daa442e8..e306d2e26363 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -74,6 +74,8 @@ void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
sysfs_remove_file(&s->kobj,&a->attr);
}
+EXPORT_SYMBOL(sysdev_create_file);
+EXPORT_SYMBOL(sysdev_remove_file);
/*
* declare system_subsys
@@ -171,6 +173,9 @@ int sys_device_register(struct sys_device * sysdev)
/* Make sure the kset is set */
sysdev->kobj.kset = &cls->kset;
+ /* But make sure we point to the right type for sysfs translation */
+ sysdev->kobj.ktype = &ktype_sysdev;
+
/* set the kobject name */
snprintf(sysdev->kobj.name,KOBJ_NAME_LEN,"%s%d",
cls->kset.kobj.name,sysdev->id);
@@ -218,9 +223,6 @@ void sys_device_unregister(struct sys_device * sysdev)
if (drv->remove)
drv->remove(sysdev);
}
-
- list_del_init(&sysdev->entry);
-
up_write(&system_subsys.rwsem);
kobject_unregister(&sysdev->kobj);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b0fefe1460cc..5e08a760f1d9 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -2,7 +2,7 @@
* linux/drivers/block/loop.c
*
* Written by Theodore Ts'o, 3/29/93
- *
+ *
* Copyright 1993 by Theodore Ts'o. Redistribution of this file is
* permitted under the GNU General Public License.
*
@@ -21,12 +21,12 @@
* Loadable modules and other fixes by AK, 1998
*
* Make real block number available to downstream transfer functions, enables
- * CBC (and relatives) mode encryption requiring unique IVs per data block.
+ * CBC (and relatives) mode encryption requiring unique IVs per data block.
* Reed H. Petty, rhp@draper.net
*
* Maximum number of loop devices now dynamic via max_loop module parameter.
* Russell Kroll <rkroll@exploits.org> 19990701
- *
+ *
* Maximum number of loop devices when compiled-in now selectable by passing
* max_loop=<1-255> to the kernel on boot.
* Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
@@ -40,19 +40,19 @@
* Heinz Mauelshagen <mge@sistina.com>, Feb 2002
*
* Still To Fix:
- * - Advisory locking is ignored here.
- * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
+ * - Advisory locking is ignored here.
+ * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
*
* WARNING/FIXME:
* - The block number as IV passing to low level transfer functions is broken:
* it passes the underlying device's block number instead of the
- * offset. This makes it change for a given block when the file is
- * moved/restored/copied and also doesn't work over NFS.
+ * offset. This makes it change for a given block when the file is
+ * moved/restored/copied and also doesn't work over NFS.
* AV, Feb 12, 2000: we pass the logical block number now. It fixes the
* problem above. Encryption modules that used to rely on the old scheme
* should just call ->i_mapping->bmap() to calculate the physical block
* number.
- */
+ */
#include <linux/config.h>
#include <linux/module.h>
@@ -60,12 +60,10 @@
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/file.h>
-#include <linux/bio.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/wait.h>
-#include <linux/blk.h>
#include <linux/blkpg.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
@@ -127,24 +125,25 @@ static int xor_status(struct loop_device *lo, const struct loop_info64 *info)
return 0;
}
-struct loop_func_table none_funcs = {
+struct loop_func_table none_funcs = {
.number = LO_CRYPT_NONE,
.transfer = transfer_none,
};
-struct loop_func_table xor_funcs = {
+struct loop_func_table xor_funcs = {
.number = LO_CRYPT_XOR,
.transfer = transfer_xor,
.init = xor_status
};
-/* xfer_funcs[0] is special - its release function is never called */
+/* xfer_funcs[0] is special - its release function is never called */
struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
&none_funcs,
- &xor_funcs
+ &xor_funcs
};
-static int figure_loop_size(struct loop_device *lo)
+static int
+figure_loop_size(struct loop_device *lo)
{
loff_t size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size;
sector_t x;
@@ -154,15 +153,17 @@ static int figure_loop_size(struct loop_device *lo)
*/
size = (size - lo->lo_offset) >> 9;
x = (sector_t)size;
+
if ((loff_t)x != size)
return -EFBIG;
- set_capacity(disks[lo->lo_number], size);
+ set_capacity(disks[lo->lo_number], x);
return 0;
}
-static inline int lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
- char *lbuf, int size, sector_t rblock)
+static inline int
+lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
+ char *lbuf, int size, sector_t rblock)
{
if (!lo->transfer)
return 0;
@@ -614,9 +615,12 @@ static int loop_thread(void *data)
daemonize("loop%d", lo->lo_number);
- current->flags |= PF_IOTHREAD; /* loop can be used in an encrypted device
- hence, it mustn't be stopped at all because it could
- be indirectly used during suspension */
+ /*
+ * loop can be used in an encrypted device,
+ * hence, it mustn't be stopped at all
+ * because it could be indirectly used during suspension
+ */
+ current->flags |= PF_IOTHREAD;
set_user_nice(current, -20);
@@ -771,36 +775,42 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
return error;
}
-static int loop_release_xfer(struct loop_device *lo)
+static int
+loop_release_xfer(struct loop_device *lo)
{
- int err = 0;
- if (lo->lo_encrypt_type) {
- struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type];
- if (xfer && xfer->release)
- err = xfer->release(lo);
- if (xfer && xfer->unlock)
- xfer->unlock(lo);
- lo->lo_encrypt_type = 0;
+ int err = 0;
+ struct loop_func_table *xfer = lo->lo_encryption;
+
+ if (xfer) {
+ if (xfer->release)
+ err = xfer->release(lo);
+ lo->transfer = NULL;
+ lo->lo_encryption = NULL;
+ module_put(xfer->owner);
}
return err;
}
static int
-loop_init_xfer(struct loop_device *lo, int type, const struct loop_info64 *i)
+loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
+ const struct loop_info64 *i)
{
- int err = 0;
- if (type) {
- struct loop_func_table *xfer = xfer_funcs[type];
+ int err = 0;
+
+ if (xfer) {
+ struct module *owner = xfer->owner;
+
+ if (!try_module_get(owner))
+ return -EINVAL;
if (xfer->init)
err = xfer->init(lo, i);
- if (!err) {
- lo->lo_encrypt_type = type;
- if (xfer->lock)
- xfer->lock(lo);
- }
+ if (err)
+ module_put(owner);
+ else
+ lo->lo_encryption = xfer;
}
return err;
-}
+}
static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
{
@@ -809,9 +819,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
if (lo->lo_state != Lo_bound)
return -ENXIO;
+
if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */
return -EBUSY;
- if (filp==NULL)
+
+ if (filp == NULL)
return -EINVAL;
spin_lock_irq(&lo->lo_lock);
@@ -828,7 +840,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
lo->transfer = NULL;
lo->ioctl = NULL;
lo->lo_device = NULL;
- lo->lo_encrypt_type = 0;
+ lo->lo_encryption = NULL;
lo->lo_offset = 0;
lo->lo_encrypt_key_size = 0;
lo->lo_flags = 0;
@@ -849,49 +861,55 @@ static int
loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
{
int err;
- unsigned int type;
- loff_t offset;
+ struct loop_func_table *xfer;
- if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
+ if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
!capable(CAP_SYS_ADMIN))
return -EPERM;
if (lo->lo_state != Lo_bound)
return -ENXIO;
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
return -EINVAL;
- type = info->lo_encrypt_type;
- if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
- return -EINVAL;
- if (type == LO_CRYPT_XOR && info->lo_encrypt_key_size == 0)
- return -EINVAL;
err = loop_release_xfer(lo);
- if (!err)
- err = loop_init_xfer(lo, type, info);
+ if (err)
+ return err;
- offset = lo->lo_offset;
- if (offset != info->lo_offset) {
- lo->lo_offset = info->lo_offset;
- if (figure_loop_size(lo)){
- err = -EFBIG;
- lo->lo_offset = offset;
- }
- }
+ if (info->lo_encrypt_type) {
+ unsigned int type = info->lo_encrypt_type;
+ if (type >= MAX_LO_CRYPT)
+ return -EINVAL;
+ xfer = xfer_funcs[type];
+ if (xfer == NULL)
+ return -EINVAL;
+ } else
+ xfer = NULL;
+
+ err = loop_init_xfer(lo, xfer, info);
if (err)
- return err;
+ return err;
+
+ if (lo->lo_offset != info->lo_offset) {
+ lo->lo_offset = info->lo_offset;
+ if (figure_loop_size(lo))
+ return -EFBIG;
+ }
strlcpy(lo->lo_name, info->lo_name, LO_NAME_SIZE);
- lo->transfer = xfer_funcs[type]->transfer;
- lo->ioctl = xfer_funcs[type]->ioctl;
+ if (!xfer)
+ xfer = &none_funcs;
+ lo->transfer = xfer->transfer;
+ lo->ioctl = xfer->ioctl;
+
lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
lo->lo_init[0] = info->lo_init[0];
lo->lo_init[1] = info->lo_init[1];
if (info->lo_encrypt_key_size) {
- memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
+ memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
info->lo_encrypt_key_size);
- lo->lo_key_owner = current->uid;
+ lo->lo_key_owner = current->uid;
}
return 0;
@@ -917,7 +935,8 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
info->lo_offset = lo->lo_offset;
info->lo_flags = lo->lo_flags;
strlcpy(info->lo_name, lo->lo_name, LO_NAME_SIZE);
- info->lo_encrypt_type = lo->lo_encrypt_type;
+ info->lo_encrypt_type =
+ lo->lo_encryption ? lo->lo_encryption->number : 0;
if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
@@ -1060,30 +1079,22 @@ static int lo_ioctl(struct inode * inode, struct file * file,
static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
- int type;
down(&lo->lo_ctl_mutex);
-
- type = lo->lo_encrypt_type;
- if (type && xfer_funcs[type] && xfer_funcs[type]->lock)
- xfer_funcs[type]->lock(lo);
lo->lo_refcnt++;
up(&lo->lo_ctl_mutex);
+
return 0;
}
static int lo_release(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
- int type;
down(&lo->lo_ctl_mutex);
- type = lo->lo_encrypt_type;
--lo->lo_refcnt;
- if (xfer_funcs[type] && xfer_funcs[type]->unlock)
- xfer_funcs[type]->unlock(lo);
-
up(&lo->lo_ctl_mutex);
+
return 0;
}
@@ -1103,34 +1114,41 @@ MODULE_LICENSE("GPL");
int loop_register_transfer(struct loop_func_table *funcs)
{
- if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number])
+ unsigned int n = funcs->number;
+
+ if (n >= MAX_LO_CRYPT || xfer_funcs[n])
return -EINVAL;
- xfer_funcs[funcs->number] = funcs;
- return 0;
+ xfer_funcs[n] = funcs;
+ return 0;
}
int loop_unregister_transfer(int number)
{
- struct loop_device *lo;
-
- if ((unsigned)number >= MAX_LO_CRYPT)
- return -EINVAL;
- for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
- int type = lo->lo_encrypt_type;
- if (type == number) {
- xfer_funcs[type]->release(lo);
- lo->transfer = NULL;
- lo->lo_encrypt_type = 0;
- }
+ unsigned int n = number;
+ struct loop_device *lo;
+ struct loop_func_table *xfer;
+
+ if (n == 0 || n >= MAX_LO_CRYPT || (xfer = xfer_funcs[n]) == NULL)
+ return -EINVAL;
+
+ xfer_funcs[n] = NULL;
+
+ for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
+ down(&lo->lo_ctl_mutex);
+
+ if (lo->lo_encryption == xfer)
+ loop_release_xfer(lo);
+
+ up(&lo->lo_ctl_mutex);
}
- xfer_funcs[number] = NULL;
- return 0;
+
+ return 0;
}
EXPORT_SYMBOL(loop_register_transfer);
EXPORT_SYMBOL(loop_unregister_transfer);
-int __init loop_init(void)
+int __init loop_init(void)
{
int i;
@@ -1190,9 +1208,10 @@ out_mem:
return -ENOMEM;
}
-void loop_exit(void)
+void loop_exit(void)
{
int i;
+
for (i = 0; i < max_loop; i++) {
del_gendisk(disks[i]);
put_disk(disks[i]);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 011f6ac84430..55cde8caf8a8 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -28,6 +28,9 @@
* the transmit lock. <steve@chygwyn.com>
* 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes.
* <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com>
+ * 03-06-22 Make nbd work with new linux 2.5 block layer design. This fixes
+ * memory corruption from module removal and possible memory corruption
+ * from sending/receiving disk data. <ldl@aros.net>
*
* possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
* why not: would need verify_area and friends, would share yet another
@@ -63,6 +66,16 @@
static struct nbd_device nbd_dev[MAX_NBD];
+/*
+ * Use just one lock (or at most 1 per NIC). Two arguments for this:
+ * 1. Each NIC is essentially a synchronization point for all servers
+ * accessed through that NIC so there's no need to have more locks
+ * than NICs anyway.
+ * 2. More locks lead to more "Dirty cache line bouncing" which will slow
+ * down each lock to the point where they're actually slower than just
+ * a single lock.
+ * Thanks go to Jens Axboe and Al Viro for their LKML emails explaining this!
+ */
static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED;
#define DEBUG( s )
@@ -168,6 +181,17 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
return result;
}
+static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec,
+ int flags)
+{
+ int result;
+ void *kaddr = kmap(bvec->bv_page);
+ result = nbd_xmit(1, sock, kaddr + bvec->bv_offset, bvec->bv_len,
+ flags);
+ kunmap(bvec->bv_page);
+ return result;
+}
+
#define FAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); goto error_out; }
void nbd_send_req(struct nbd_device *lo, struct request *req)
@@ -209,7 +233,7 @@ void nbd_send_req(struct nbd_device *lo, struct request *req)
if ((i < (bio->bi_vcnt - 1)) || bio->bi_next)
flags = MSG_MORE;
DEBUG("data, ");
- result = nbd_xmit(1, sock, page_address(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, flags);
+ result = sock_send_bvec(sock, bvec, flags);
if (result <= 0)
FAIL("Send data failed.");
}
@@ -244,6 +268,16 @@ static struct request *nbd_find_request(struct nbd_device *lo, char *handle)
return NULL;
}
+static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec)
+{
+ int result;
+ void *kaddr = kmap(bvec->bv_page);
+ result = nbd_xmit(0, sock, kaddr + bvec->bv_offset, bvec->bv_len,
+ MSG_WAITALL);
+ kunmap(bvec->bv_page);
+ return result;
+}
+
#define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; }
struct request *nbd_read_stat(struct nbd_device *lo)
/* NULL returned = something went wrong, inform userspace */
@@ -251,10 +285,11 @@ struct request *nbd_read_stat(struct nbd_device *lo)
int result;
struct nbd_reply reply;
struct request *req;
+ struct socket *sock = lo->sock;
DEBUG("reading control, ");
reply.magic = 0;
- result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply), MSG_WAITALL);
+ result = nbd_xmit(0, sock, (char *) &reply, sizeof(reply), MSG_WAITALL);
if (result <= 0)
HARDFAIL("Recv control failed.");
req = nbd_find_request(lo, reply.handle);
@@ -268,14 +303,17 @@ struct request *nbd_read_stat(struct nbd_device *lo)
FAIL("Other side returned error.");
if (nbd_cmd(req) == NBD_CMD_READ) {
- struct bio *bio = req->bio;
+ int i;
+ struct bio *bio;
DEBUG("data, ");
- do {
- result = nbd_xmit(0, lo->sock, bio_data(bio), bio->bi_size, MSG_WAITALL);
- if (result <= 0)
- HARDFAIL("Recv data failed.");
- bio = bio->bi_next;
- } while(bio);
+ rq_for_each_bio(bio, req) {
+ struct bio_vec *bvec;
+ bio_for_each_segment(bvec, bio, i) {
+ result = sock_recv_bvec(sock, bvec);
+ if (result <= 0)
+ HARDFAIL("Recv data failed.");
+ }
+ }
}
DEBUG("done.\n");
return req;
@@ -538,8 +576,6 @@ static struct block_device_operations nbd_fops =
* (Just smiley confuses emacs :-)
*/
-static struct request_queue nbd_queue;
-
static int __init nbd_init(void)
{
int err = -ENOMEM;
@@ -555,6 +591,17 @@ static int __init nbd_init(void)
if (!disk)
goto out;
nbd_dev[i].disk = disk;
+ /*
+ * The new linux 2.5 block layer implementation requires
+ * every gendisk to have its very own request_queue struct.
+ * These structs are big so we dynamically allocate them.
+ */
+ disk->queue = kmalloc(sizeof(struct request_queue), GFP_KERNEL);
+ if (!disk->queue) {
+ put_disk(disk);
+ goto out;
+ }
+ blk_init_queue(disk->queue, do_nbd_request, &nbd_lock);
}
if (register_blkdev(NBD_MAJOR, "nbd")) {
@@ -564,7 +611,6 @@ static int __init nbd_init(void)
#ifdef MODULE
printk("nbd: registered device at major %d\n", NBD_MAJOR);
#endif
- blk_init_queue(&nbd_queue, do_nbd_request, &nbd_lock);
devfs_mk_dir("nbd");
for (i = 0; i < MAX_NBD; i++) {
struct gendisk *disk = nbd_dev[i].disk;
@@ -582,7 +628,6 @@ static int __init nbd_init(void)
disk->first_minor = i;
disk->fops = &nbd_fops;
disk->private_data = &nbd_dev[i];
- disk->queue = &nbd_queue;
sprintf(disk->disk_name, "nbd%d", i);
sprintf(disk->devfs_name, "nbd/%d", i);
set_capacity(disk, 0x3ffffe);
@@ -591,8 +636,10 @@ static int __init nbd_init(void)
return 0;
out:
- while (i--)
+ while (i--) {
+ kfree(nbd_dev[i].disk->queue);
put_disk(nbd_dev[i].disk);
+ }
return err;
}
@@ -600,12 +647,22 @@ static void __exit nbd_cleanup(void)
{
int i;
for (i = 0; i < MAX_NBD; i++) {
- del_gendisk(nbd_dev[i].disk);
- put_disk(nbd_dev[i].disk);
+ struct gendisk *disk = nbd_dev[i].disk;
+ if (disk) {
+ if (disk->queue) {
+ blk_cleanup_queue(disk->queue);
+ kfree(disk->queue);
+ disk->queue = NULL;
+ }
+ del_gendisk(disk);
+ put_disk(disk);
+ }
}
devfs_remove("nbd");
- blk_cleanup_queue(&nbd_queue);
unregister_blkdev(NBD_MAJOR, "nbd");
+#ifdef MODULE
+ printk("nbd: unregistered device at major %d\n", NBD_MAJOR);
+#endif
}
module_init(nbd_init);
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 0509a67c2eb8..bbfc4eaa3927 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -269,7 +269,10 @@ static struct backing_dev_info rd_backing_dev_info = {
static int rd_open(struct inode * inode, struct file * filp)
{
- int unit = minor(inode->i_rdev);
+ unsigned unit = minor(inode->i_rdev);
+
+ if (unit >= NUM_RAMDISKS)
+ return -ENODEV;
/*
* Immunize device against invalidate_buffers() and prune_icache().
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 3e5b1fe6452b..fba8f81379ef 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -242,7 +242,7 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
del_timer(&kd_mksound_timer);
if (hz) {
- list_for_each(node,&kbd_handler.h_list) {
+ list_for_each_prev(node,&kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit)) {
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 3080b464e951..8aeb7cbbe9b8 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/fs.h>
+#include <linux/devfs_fs_kernel.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/module.h>
@@ -258,12 +259,27 @@ static struct file_operations raw_ctl_fops = {
static int __init raw_init(void)
{
+ int i;
+
register_chrdev(RAW_MAJOR, "raw", &raw_fops);
+ devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
+ S_IFCHR | S_IRUGO | S_IWUGO,
+ "raw/rawctl");
+ for (i = 1; i < MAX_RAW_MINORS; i++)
+ devfs_mk_cdev(MKDEV(RAW_MAJOR, i),
+ S_IFCHR | S_IRUGO | S_IWUGO,
+ "raw/raw%d", i);
return 0;
}
static void __exit raw_exit(void)
{
+ int i;
+
+ for (i = 1; i < MAX_RAW_MINORS; i++)
+ devfs_remove("raw/raw%d", i);
+ devfs_remove("raw/rawctl");
+ devfs_remove("raw");
unregister_chrdev(RAW_MAJOR, "raw");
}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index ca5ad249ab8c..a24ada1612f6 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -75,6 +75,7 @@
*/
#include <linux/module.h>
+#include <linux/types.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -2279,7 +2280,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
ret = fg_console;
break;
case TIOCL_SCROLLCONSOLE:
- if (get_user(lines, (char *)arg+1)) {
+ if (get_user(lines, (s32 *)((char *)arg+4))) {
ret = -EFAULT;
} else {
scrollfront(lines);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index e5de162fbd87..0b985c9d3ed0 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -872,6 +872,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -EINVAL;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ if (!vc_cons[i].d)
+ continue;
if (vlin)
vc_cons[i].d->vc_scan_lines = vlin;
if (clin)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 5b7d079bf96a..3f2405966a15 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,8 +1,9 @@
/*
- * linux/drivers/ide/pci/sis5513.c Version 0.14ac Sept 11, 2002
+ * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003
*
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
+ * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz>
* May be copied or modified under the terms of the GNU General Public License
*
*
@@ -14,31 +15,33 @@
* for checking code correctness, providing patches.
*
*
- * Original tests and design on the SiS620/5513 chipset.
- * ATA100 tests and design on the SiS735/5513 chipset.
+ * Original tests and design on the SiS620 chipset.
+ * ATA100 tests and design on the SiS735 chipset.
* ATA16/33 support from specs
* ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw>
+ * ATA133 961/962/963 fixes by Vojtech Pavlik <vojtech@suse.cz>
*
* Documentation:
- * SiS chipset documentation available under NDA to companies not
- * individuals only.
+ * SiS chipset documentation available under NDA to companies only
+ * (not to individuals).
*/
/*
- * Notes/Special cases:
- * - SiS5513 derivatives usually have the same PCI IDE register layout when
- * supporting the same UDMA modes.
- * - There are exceptions :
- * . SiS730 and SiS550 use the same layout than ATA_66 chipsets but support
- * ATA_100
- * . ATA_133 capable chipsets mark a shift in SiS chipset designs : previously
- * south and northbridge were integrated, making IDE (a southbridge function)
- * capabilities easily deduced from the northbridge PCI id. With ATA_133,
- * chipsets started to be split in the usual north/south bridges chips
- * -> the driver needs to detect the correct southbridge when faced to newest
- * northbridges.
- * . On ATA133 capable chipsets when bit 30 of dword at 0x54 is 1 the
- * configuration space is moved from 0x40 to 0x70.
+ * The original SiS5513 comes from a SiS5511/55112/5513 chipset. The original
+ * SiS5513 was also used in the SiS5596/5513 chipset. Thus if we see a SiS5511
+ * or SiS5596, we can assume we see the first MWDMA-16 capable SiS5513 chip.
+ *
+ * Later SiS chipsets integrated the 5513 functionality into the NorthBridge,
+ * starting with SiS5571 and up to SiS745. The PCI ID didn't change, though. We
+ * can figure out that we have a more modern and more capable 5513 by looking
+ * for the respective NorthBridge IDs.
+ *
+ * Even later (96x family) SiS chipsets use the MuTIOL link and place the 5513
+ * into the SouthBrige. Here we cannot rely on looking up the NorthBridge PCI
+ * ID, while the now ATA-133 capable 5513 still has the same PCI ID.
+ * Fortunately the 5513 can be 'unmasked' by fiddling with some config space
+ * bits, changing its device id to the true one - 5517 for 961 and 5518 for
+ * 962/963.
*/
#include <linux/config.h>
@@ -57,94 +60,23 @@
#include <linux/init.h>
#include <linux/ide.h>
-#include <asm/io.h>
#include <asm/irq.h>
+#include "ide-timing.h"
#include "ide_modes.h"
#include "sis5513.h"
-/* When DEBUG is defined it outputs initial PCI config register
- values and changes made to them by the driver */
-// #define DEBUG
-/* When BROKEN_LEVEL is defined it limits the DMA mode
- at boot time to its value */
-// #define BROKEN_LEVEL XFER_SW_DMA_0
-
-/* Miscellaneous flags */
-#define SIS5513_LATENCY 0x01
-
/* registers layout and init values are chipset family dependant */
-/* 1/ define families */
-#define ATA_00 0x00
+
#define ATA_16 0x01
#define ATA_33 0x02
#define ATA_66 0x03
-#define ATA_100a 0x04 // SiS730 is ATA100 with ATA66 layout
+#define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout
#define ATA_100 0x05
#define ATA_133a 0x06 // SiS961b with 133 support
-#define ATA_133 0x07 // SiS962
-/* 2/ variable holding the controller chipset family value */
-static u8 chipset_family;
-
-
-/*
- * Debug code: following IDE config registers' changes
- */
-#ifdef DEBUG
-/* Copy of IDE Config registers fewer will be used
- * Some odd chipsets hang if unused registers are accessed
- * -> We only access them in #DEBUG code (then we'll see if SiS did
- * it right from day one) */
-static u8 ide_regs_copy[0xff];
-
-/* Read config registers, print differences from previous read */
-static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) {
- int i;
- u8 reg_val;
- u8 changed=0;
-
- printk("SIS5513: %s, changed registers:\n", info);
- for(i=0; i<=0xff; i++) {
- pci_read_config_byte(dev, i, &reg_val);
- if (reg_val != ide_regs_copy[i]) {
- printk("%02x: %02x -> %02x\n",
- i, ide_regs_copy[i], reg_val);
- ide_regs_copy[i]=reg_val;
- changed=1;
- }
- }
-
- if (!changed) {
- printk("none\n");
- }
-}
-
-/* Load config registers, no printing */
-static void sis5513_load_registers(struct pci_dev* dev) {
- int i;
-
- for(i=0; i<=0xff; i++) {
- pci_read_config_byte(dev, i, &(ide_regs_copy[i]));
- }
-}
-
-/* Print config space registers a la "lspci -vxxx" */
-static void sis5513_print_registers(struct pci_dev* dev, char* marker) {
- int i,j;
-
- sis5513_load_registers(dev);
- printk("SIS5513 %s\n", marker);
-
- for(i=0; i<=0xf; i++) {
- printk("SIS5513 dump: %d" "0:", i);
- for(j=0; j<=0xf; j++) {
- printk(" %02x", ide_regs_copy[(i<<16)+j]);
- }
- printk("\n");
- }
-}
-#endif
+#define ATA_133 0x07 // SiS962/963
+static u8 chipset_family;
/*
* Devices supported
@@ -155,42 +87,38 @@ static const struct {
u8 chipset_family;
u8 flags;
} SiSHostChipInfo[] = {
- { "SiS752", PCI_DEVICE_ID_SI_752, ATA_133, 0 },
- { "SiS751", PCI_DEVICE_ID_SI_751, ATA_133, 0 },
- { "SiS750", PCI_DEVICE_ID_SI_750, ATA_133, 0 },
- { "SiS748", PCI_DEVICE_ID_SI_748, ATA_133, 0 },
- { "SiS746", PCI_DEVICE_ID_SI_746, ATA_133, 0 },
- { "SiS745", PCI_DEVICE_ID_SI_745, ATA_133, 0 },
- { "SiS740", PCI_DEVICE_ID_SI_740, ATA_133, 0 },
- { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100, SIS5513_LATENCY },
- { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a, SIS5513_LATENCY },
- { "SiS655", PCI_DEVICE_ID_SI_655, ATA_133, 0 },
- { "SiS652", PCI_DEVICE_ID_SI_652, ATA_133, 0 },
- { "SiS651", PCI_DEVICE_ID_SI_651, ATA_133, 0 },
- { "SiS650", PCI_DEVICE_ID_SI_650, ATA_133, 0 },
- { "SiS648", PCI_DEVICE_ID_SI_648, ATA_133, 0 },
- { "SiS646", PCI_DEVICE_ID_SI_646, ATA_133, 0 },
- { "SiS645", PCI_DEVICE_ID_SI_645, ATA_133, 0 },
- { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100, SIS5513_LATENCY },
- { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66, SIS5513_LATENCY },
- { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66, SIS5513_LATENCY },
- { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66, SIS5513_LATENCY },
- { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a, 0},
- { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66, 0},
- { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66, 0},
- { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33, 0},
- { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33, 0},
- { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33, 0},
- { "SiS5591", PCI_DEVICE_ID_SI_5591, ATA_33, 0},
- { "SiS5513", PCI_DEVICE_ID_SI_5513, ATA_16, 0},
- { "SiS5511", PCI_DEVICE_ID_SI_5511, ATA_16, 0},
+ { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 },
+ { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 },
+ { "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 },
+ { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100 },
+ { "SiS633", PCI_DEVICE_ID_SI_633, ATA_100 },
+
+ { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a },
+ { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a },
+
+ { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66 },
+ { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66 },
+ { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66 },
+ { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66 },
+ { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66 },
+
+ { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33 },
+ { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33 },
+ { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33 },
+ { "SiS5591/2", PCI_DEVICE_ID_SI_5591, ATA_33 },
+ { "SiS5582", PCI_DEVICE_ID_SI_5582, ATA_33 },
+ { "SiS5581", PCI_DEVICE_ID_SI_5581, ATA_33 },
+
+ { "SiS5596", PCI_DEVICE_ID_SI_5596, ATA_16 },
+ { "SiS5571", PCI_DEVICE_ID_SI_5571, ATA_16 },
+ { "SiS551x", PCI_DEVICE_ID_SI_5511, ATA_16 },
};
/* Cycle time bits and values vary across chip dma capabilities
These three arrays hold the register layout and the values to set.
Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
-/* {ATA_00, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
+/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
static u8 cycle_time_offset[] = {0,0,5,4,4,0,0};
static u8 cycle_time_range[] = {0,0,2,3,3,4,4};
static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
@@ -249,8 +177,6 @@ static u8 rco_time_value[][8] = {
{40,12,4,12,5,34,12,5},
};
-static struct pci_dev *host_dev = NULL;
-
/*
* Printing configuration
*/
@@ -334,6 +260,7 @@ static char* get_drives_info (char *buffer, u8 pos)
}
pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, &regdw0);
pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, &regdw1);
+
p += sprintf(p, "Drive %d:\n", pos);
}
@@ -372,11 +299,12 @@ static char* get_drives_info (char *buffer, u8 pos)
p += sprintf(p, "\n");
}
- if (chipset_family < ATA_133) { /* else case TODO */
+
+ if (chipset_family < ATA_133) { /* else case TODO */
+
/* Data Active */
p += sprintf(p, " Data Active Time ");
switch(chipset_family) {
- case ATA_00:
case ATA_16: /* confirmed */
case ATA_33:
case ATA_66:
@@ -387,7 +315,6 @@ static char* get_drives_info (char *buffer, u8 pos)
}
p += sprintf(p, " \t Data Active Time ");
switch(chipset_family) {
- case ATA_00:
case ATA_16:
case ATA_33:
case ATA_66:
@@ -493,39 +420,16 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
len = (p - buffer) - offset;
*addr = buffer + offset;
-
+
return len > count ? count : len;
}
#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
static u8 sis5513_ratemask (ide_drive_t *drive)
{
-#if 0
u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 };
u8 mode = rates[chipset_family];
-#else
- u8 mode;
- switch(chipset_family) {
- case ATA_133:
- case ATA_133a:
- mode = 4;
- break;
- case ATA_100:
- case ATA_100a:
- mode = 3;
- break;
- case ATA_66:
- mode = 2;
- break;
- case ATA_33:
- return 1;
- case ATA_16:
- case ATA_00:
- default:
- return 0;
- }
-#endif
if (!eighty_ninty_three(drive))
mode = min(mode, (u8)1);
return mode;
@@ -543,20 +447,12 @@ static void config_drive_art_rwp (ide_drive_t *drive)
u8 reg4bh = 0;
u8 rw_prefetch = (0x11 << drive->dn);
-#ifdef DEBUG
- printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn);
- sis5513_load_verify_registers(dev, "config_drive_art_rwp start");
-#endif
-
if (drive->media != ide_disk)
return;
pci_read_config_byte(dev, 0x4b, &reg4bh);
if ((reg4bh & rw_prefetch) != rw_prefetch)
pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
-#ifdef DEBUG
- sis5513_load_verify_registers(dev, "config_drive_art_rwp end");
-#endif
}
@@ -571,10 +467,6 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
u16 xfer_pio = drive->id->eide_pio_modes;
-#ifdef DEBUG
- sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
-#endif
-
config_drive_art_rwp(drive);
pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
@@ -594,12 +486,6 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
timing = (xfer_pio >= pio) ? xfer_pio : pio;
-#ifdef DEBUG
- printk("SIS5513: config_drive_art_rwp_pio, "
- "drive %d, pio %d, timing %d\n",
- drive->dn, pio, timing);
-#endif
-
/* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
drive_pci = 0x40;
/* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */
@@ -645,41 +531,24 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
pci_read_config_dword(dev, drive_pci, &test3);
test3 &= 0xc0c00fff;
if (test3 & 0x08) {
- test3 |= (unsigned long)ini_time_value[ATA_133-ATA_00][timing] << 12;
- test3 |= (unsigned long)act_time_value[ATA_133-ATA_00][timing] << 16;
- test3 |= (unsigned long)rco_time_value[ATA_133-ATA_00][timing] << 24;
+ test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12;
+ test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16;
+ test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24;
} else {
- test3 |= (unsigned long)ini_time_value[ATA_100-ATA_00][timing] << 12;
- test3 |= (unsigned long)act_time_value[ATA_100-ATA_00][timing] << 16;
- test3 |= (unsigned long)rco_time_value[ATA_100-ATA_00][timing] << 24;
+ test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12;
+ test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16;
+ test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24;
}
pci_write_config_dword(dev, drive_pci, test3);
}
-
-#ifdef DEBUG
- sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
-#endif
}
static int config_chipset_for_pio (ide_drive_t *drive, u8 pio)
{
-#if 0
- config_art_rwp_pio(drive, pio);
- return ide_config_drive_speed(drive, (XFER_PIO_0 + pio));
-#else
- u8 speed;
-
- switch(pio) {
- case 4: speed = XFER_PIO_4; break;
- case 3: speed = XFER_PIO_3; break;
- case 2: speed = XFER_PIO_2; break;
- case 1: speed = XFER_PIO_1; break;
- default: speed = XFER_PIO_0; break;
- }
-
+ if (pio == 255)
+ pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
config_art_rwp_pio(drive, pio);
- return ide_config_drive_speed(drive, speed);
-#endif
+ return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4));
}
static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
@@ -690,24 +559,8 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
u8 drive_pci, reg, speed;
u32 regdw;
-#ifdef DEBUG
- sis5513_load_verify_registers(dev, "sis5513_tune_chipset start");
-#endif
-
-#ifdef BROKEN_LEVEL
-#ifdef DEBUG
- printk("SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d\n", xferspeed, BROKEN_LEVEL);
-#endif
- if (xferspeed > BROKEN_LEVEL) xferspeed = BROKEN_LEVEL;
-#endif
-
speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed);
-#ifdef DEBUG
- printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n",
- drive->dn, xferspeed);
-#endif
-
/* See config_art_rwp_pio for drive pci config registers */
drive_pci = 0x40;
if (chipset_family >= ATA_133) {
@@ -746,14 +599,14 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
regdw &= 0xfffff00f;
/* check if ATA133 enable */
if (regdw & 0x08) {
- regdw |= (unsigned long)cycle_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 4;
- regdw |= (unsigned long)cvs_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 8;
+ regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4;
+ regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8;
} else {
/* if ATA133 disable, we should not set speed above UDMA5 */
if (speed > XFER_UDMA_5)
speed = XFER_UDMA_5;
- regdw |= (unsigned long)cycle_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 4;
- regdw |= (unsigned long)cvs_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 8;
+ regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4;
+ regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8;
}
pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
} else {
@@ -763,7 +616,7 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family]))
<< cycle_time_offset[chipset_family]);
/* set reg cycle time bits */
- reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0]
+ reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0]
<< cycle_time_offset[chipset_family];
pci_write_config_byte(dev, drive_pci+1, reg);
}
@@ -782,9 +635,7 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_PIO_0:
default: return((int) config_chipset_for_pio(drive, 0));
}
-#ifdef DEBUG
- sis5513_load_verify_registers(dev, "sis5513_tune_chipset end");
-#endif
+
return ((int) ide_config_drive_speed(drive, speed));
}
@@ -863,18 +714,34 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive)
return sis5513_config_drive_xfer_rate(drive);
}
-/* Helper function used at init time
- * returns a PCI device revision ID
- * (used to detect different IDE controller versions)
- */
-static u8 __init devfn_rev(int device, int function)
+/*
+ Future simpler config_xfer_rate :
+ When ide_find_best_mode is made bad-drive aware
+ - remove config_drive_xfer_rate and config_chipset_for_dma,
+ - replace config_xfer_rate with the following
+
+static int sis5513_config_xfer_rate (ide_drive_t *drive)
{
- u8 revision;
- /* Find device */
- struct pci_dev* dev = pci_find_slot(0,PCI_DEVFN(device,function));
- pci_read_config_byte(dev, PCI_REVISION_ID, &revision);
- return revision;
+ u16 w80 = HWIF(drive)->udma_four;
+ u16 speed;
+
+ config_drive_art_rwp(drive);
+ config_art_rwp_pio(drive, 5);
+
+ speed = ide_find_best_mode(drive,
+ XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
+ (chipset_family >= ATA_33 ? XFER_UDMA : 0) |
+ (w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) |
+ (w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) |
+ (w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0));
+
+ sis5513_tune_chipset(drive, speed);
+
+ if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+ return HWIF(drive)->ide_dma_on(drive);
+ return HWIF(drive)->ide_dma_off_quietly(drive);
}
+*/
/* Chip detection and general config */
static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
@@ -882,71 +749,86 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
struct pci_dev *host;
int i = 0;
- /* Find the chip */
- for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) {
- host = pci_find_device (PCI_VENDOR_ID_SI,
- SiSHostChipInfo[i].host_id,
- NULL);
+ chipset_family = 0;
+
+ for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) {
+
+ host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL);
+
if (!host)
continue;
- host_dev = host;
chipset_family = SiSHostChipInfo[i].chipset_family;
+
+ /* Special case for SiS630 : 630S/ET is ATA_100a */
+ if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
+ u8 hostrev;
+ pci_read_config_byte(host, PCI_REVISION_ID, &hostrev);
+ if (hostrev >= 0x30)
+ chipset_family = ATA_100a;
+ }
- /* check 100/133 chipset family */
- if (chipset_family == ATA_133) {
- u32 reg54h;
- u16 devid;
- pci_read_config_dword(dev, 0x54, &reg54h);
- /* SiS962 and above report 0x5518 dev id if high bit is cleared */
- pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff));
- pci_read_config_word(dev, 0x02, &devid);
- /* restore register 0x54 */
- pci_write_config_dword(dev, 0x54, reg54h);
-
- /* devid 5518 here means SiS962 or later
- which supports ATA133.
- These are refered by chipset_family = ATA133
- */
- if (devid != 0x5518) {
- u8 reg49h;
- /* SiS961 family */
- pci_read_config_byte(dev, 0x49, &reg49h);
- /* check isa bridge device rev id */
- if (((devfn_rev(2,0) & 0xff) == 0x10) && (reg49h & 0x80))
- chipset_family = ATA_133a;
- else
- chipset_family = ATA_100;
+ printk(KERN_INFO "SIS5513: %s %s controller\n",
+ SiSHostChipInfo[i].name, chipset_capability[chipset_family]);
+ }
+
+ if (!chipset_family) { /* Belongs to pci-quirks */
+
+ u32 idemisc;
+ u16 trueid;
+
+ /* Disable ID masking and register remapping */
+ pci_read_config_dword(dev, 0x54, &idemisc);
+ pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff));
+ pci_read_config_word(dev, PCI_DEVICE_ID, &trueid);
+ pci_write_config_dword(dev, 0x54, idemisc);
+
+ if (trueid == 0x5518) {
+ printk(KERN_INFO "SIS5513: SiS 962/963 MuTIOL IDE UDMA133 controller\n");
+ chipset_family = ATA_133;
}
- }
- printk(SiSHostChipInfo[i].name);
- printk(" %s controller", chipset_capability[chipset_family]);
- printk("\n");
+ }
-#ifdef DEBUG
- sis5513_print_registers(dev, "pci_init_sis5513 start");
-#endif
+ if (!chipset_family) { /* Belongs to pci-quirks */
- if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) {
- u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
- }
+ struct pci_dev *lpc_bridge;
+ u16 trueid;
+ u8 prefctl;
+ u8 idecfg;
+ u8 sbrev;
- /* Special case for SiS630 : 630S/ET is ATA_100a */
- if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
- /* check host device rev id */
- if (devfn_rev(0,0) >= 0x30) {
- chipset_family = ATA_100a;
+ pci_read_config_byte(dev, 0x4a, &idecfg);
+ pci_write_config_byte(dev, 0x4a, idecfg | 0x10);
+ pci_read_config_word(dev, PCI_DEVICE_ID, &trueid);
+ pci_write_config_byte(dev, 0x4a, idecfg);
+
+ if (trueid == 0x5517) { /* SiS 961/961B */
+
+ lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */
+ pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev);
+ pci_read_config_byte(dev, 0x49, &prefctl);
+
+ if (sbrev == 0x10 && (prefctl & 0x80)) {
+ printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n");
+ chipset_family = ATA_133a;
+ } else {
+ printk(KERN_INFO "SIS5513: SiS 961 MuTIOL IDE UDMA100 controller\n");
+ chipset_family = ATA_100;
+ }
}
- }
}
+ if (!chipset_family)
+ return -1;
+
/* Make general config ops here
1/ tell IDE channels to operate in Compatibility mode only
2/ tell old chips to allow per drive IDE timings */
- if (host_dev) {
+
+ {
u8 reg;
u16 regw;
+
switch(chipset_family) {
case ATA_133:
/* SiS962 operation mode */
@@ -959,6 +841,8 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
break;
case ATA_133a:
case ATA_100:
+ /* Fixup latency */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
/* Set compatibility bit */
pci_read_config_byte(dev, 0x49, &reg);
if (!(reg & 0x01)) {
@@ -967,6 +851,9 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
break;
case ATA_100a:
case ATA_66:
+ /* Fixup latency */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
+
/* On ATA_66 chips the bit was elsewhere */
pci_read_config_byte(dev, 0x52, &reg);
if (!(reg & 0x04)) {
@@ -987,8 +874,6 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
pci_write_config_byte(dev, 0x52, reg|0x08);
}
break;
- case ATA_00:
- default: break;
}
#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
@@ -999,9 +884,7 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
}
#endif
}
-#ifdef DEBUG
- sis5513_load_verify_registers(dev, "pci_init_sis5513 end");
-#endif
+
return 0;
}
@@ -1044,7 +927,7 @@ static void __init init_hwif_sis5513 (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
- if (!host_dev)
+ if (!chipset_family)
return;
if (!(hwif->udma_four))
@@ -1102,19 +985,16 @@ static void sis5513_ide_exit(void)
module_init(sis5513_ide_init);
module_exit(sis5513_ide_exit);
-MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick");
+MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik");
MODULE_DESCRIPTION("PCI driver module for SIS IDE");
MODULE_LICENSE("GPL");
/*
* TODO:
- * - Get ridden of SisHostChipInfo[] completness dependancy.
- * - Study drivers/ide/ide-timing.h.
- * - Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them
- * or remove ATA_00 define
+ * - CLEANUP
+ * - Use drivers/ide/ide-timing.h !
* - More checks in the config registers (force values instead of
* relying on the BIOS setting them correctly).
* - Further optimisations ?
* . for example ATA66+ regs 0x48 & 0x4A
*/
-
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index c26dea75fb70..431883c5faa6 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -84,6 +84,7 @@ static int gameport_measure_speed(struct gameport *gameport)
if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t;
}
+ gameport_close(gameport);
return 59659 / (tx < 1 ? 1 : tx);
#else
@@ -93,11 +94,10 @@ static int gameport_measure_speed(struct gameport *gameport)
j = jiffies; while (j == jiffies);
j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); }
+ gameport_close(gameport);
return t * HZ / 1000;
#endif
-
- gameport_close(gameport);
}
static void gameport_find_dev(struct gameport *gameport)
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index f8245f98d76e..ec5ece71ab62 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -46,6 +46,7 @@ MODULE_LICENSE("GPL");
MODULE_PARM(gc, "2-6i");
MODULE_PARM(gc_2,"2-6i");
MODULE_PARM(gc_3,"2-6i");
+MODULE_PARM(gc_psx_delay, "i");
#define GC_SNES 1
#define GC_NES 2
@@ -213,7 +214,7 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
*
*/
-#define GC_PSX_DELAY 60 /* 60 usec */
+#define GC_PSX_DELAY 25 /* 25 usec */
#define GC_PSX_LENGTH 8 /* talk to the controller in bytes */
#define GC_PSX_MOUSE 1 /* Mouse */
@@ -230,6 +231,7 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
#define GC_PSX_ID(x) ((x) >> 4) /* High nibble is device type */
#define GC_PSX_LEN(x) ((x) & 0xf) /* Low nibble is length in words */
+static int gc_psx_delay = GC_PSX_DELAY;
static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
@@ -246,10 +248,10 @@ static int gc_psx_command(struct gc *gc, int b)
for (i = 0; i < 8; i++, b >>= 1) {
cmd = (b & 1) ? GC_PSX_COMMAND : 0;
parport_write_data(gc->pd->port, cmd | GC_PSX_POWER);
- udelay(GC_PSX_DELAY);
+ udelay(gc_psx_delay);
data |= ((parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) ? (1 << i) : 0;
parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
- udelay(GC_PSX_DELAY);
+ udelay(gc_psx_delay);
}
return data;
}
@@ -265,9 +267,9 @@ static int gc_psx_read_packet(struct gc *gc, unsigned char *data)
unsigned long flags;
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */
- udelay(GC_PSX_DELAY * 2);
+ udelay(gc_psx_delay * 2);
parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */
- udelay(GC_PSX_DELAY * 2);
+ udelay(gc_psx_delay * 2);
local_irq_save(flags);
@@ -649,9 +651,15 @@ static int __init gc_setup_3(char *str)
for (i = 0; i <= ints[0] && i < 6; i++) gc_3[i] = ints[i + 1];
return 1;
}
+static int __init gc_psx_setup(char *str)
+{
+ get_option(&str, &gc_psx_delay);
+ return 1;
+}
__setup("gc=", gc_setup);
__setup("gc_2=", gc_setup_2);
__setup("gc_3=", gc_setup_3);
+__setup("gc_psx_delay=", gc_psx_setup);
#endif
int __init gc_init(void)
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 23bc5f96a908..af8263e0221c 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -378,10 +378,10 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
for (j = 0; j < 6; j++)
input_report_key(dev, sw_btn[SW_ID_FSP][j], !GB(j+10,1));
- input_report_key(dev, BTN_TR, GB(26,1));
- input_report_key(dev, BTN_START, GB(27,1));
- input_report_key(dev, BTN_MODE, GB(38,1));
- input_report_key(dev, BTN_SELECT, GB(39,1));
+ input_report_key(dev, BTN_TR, !GB(26,1));
+ input_report_key(dev, BTN_START, !GB(27,1));
+ input_report_key(dev, BTN_MODE, !GB(38,1));
+ input_report_key(dev, BTN_SELECT, !GB(39,1));
input_sync(dev);
@@ -602,7 +602,6 @@ static void sw_connect(struct gameport *gameport, struct gameport_dev *dev)
gameport->phys, gameport->io, gameport->speed);
i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Read normal packet */
- m |= sw_guess_mode(buf, i); /* Data packet (1-bit) can carry mode info [FSP] */
udelay(SW_TIMEOUT);
dbg("Init 1: Mode %d. Length %d.", m , i);
@@ -676,6 +675,8 @@ static void sw_connect(struct gameport *gameport, struct gameport_dev *dev)
} else
sw->type = SW_ID_PP;
break;
+ case 66:
+ sw->bits = 3;
case 198:
sw->length = 22;
case 64:
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 367587382e23..56a514ae145b 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -89,7 +89,7 @@ static unsigned char atkbd_set3_keycode[512] = {
#define ATKBD_CMD_GETID 0x02f2
#define ATKBD_CMD_ENABLE 0x00f4
#define ATKBD_CMD_RESET_DIS 0x00f5
-#define ATKBD_CMD_RESET_BAT 0x01ff
+#define ATKBD_CMD_RESET_BAT 0x02ff
#define ATKBD_CMD_SETALL_MB 0x00f8
#define ATKBD_CMD_RESEND 0x00fe
#define ATKBD_CMD_EX_ENABLE 0x10ea
@@ -255,7 +255,8 @@ static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
while (atkbd->cmdcnt && timeout--) {
- if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_RESET_BAT)
+ if (atkbd->cmdcnt == 1 &&
+ command == ATKBD_CMD_RESET_BAT && timeout > 100000)
timeout = 100000;
if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID &&
@@ -271,6 +272,9 @@ static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
for (i = 0; i < receive; i++)
param[i] = atkbd->cmdbuf[(receive - 1) - i];
+ if (command == ATKBD_CMD_RESET_BAT && atkbd->cmdcnt == 1)
+ atkbd->cmdcnt = 0;
+
if (atkbd->cmdcnt) {
atkbd->cmdcnt = 0;
return -1;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 2d10fcffdd6a..bcf30aa59303 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -49,11 +49,11 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i
udev = (struct uinput_device *)dev->private;
- udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
udev->buff[udev->head].type = type;
udev->buff[udev->head].code = code;
udev->buff[udev->head].value = value;
do_gettimeofday(&udev->buff[udev->head].time);
+ udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
wake_up_interruptible(&udev->waitq);
@@ -82,6 +82,7 @@ static int uinput_create_device(struct uinput_device *udev)
udev->dev->event = uinput_dev_event;
udev->dev->upload_effect = uinput_dev_upload_effect;
udev->dev->erase_effect = uinput_dev_erase_effect;
+ udev->dev->private = udev;
init_waitqueue_head(&(udev->waitq));
@@ -264,7 +265,7 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t
return -ENODEV;
while ((udev->head != udev->tail) &&
- (retval + sizeof(struct uinput_device) <= count)) {
+ (retval + sizeof(struct input_event) <= count)) {
if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
sizeof(struct input_event))) return -EFAULT;
udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 31de187d173d..a6b481994163 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -19,7 +19,9 @@ config MOUSE_PS2
Say Y here if you have a PS/2 mouse connected to your system. This
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
mice with wheels and extra buttons, Microsoft, Logitech or Genius
- compatible.
+ compatible. Support for Synaptics TouchPads is also included.
+ For Synaptics TouchPad support in XFree86 you'll need this XFree86
+ driver: http://w1.894.telia.com/~u89404340/touchpad/index.html
If unsure, say Y.
@@ -28,19 +30,6 @@ config MOUSE_PS2
The module will be called psmouse. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
-config MOUSE_PS2_SYNAPTICS
- bool "Synaptics TouchPad"
- default n
- depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
- ---help---
- Say Y here if you have a Synaptics TouchPad connected to your system.
- This touchpad is found on many modern laptop computers.
- Note that you also need a user space driver to interpret the data
- generated by the kernel. A compatible driver for XFree86 is available
- from http://...
-
- If unsure, say Y.
-
config MOUSE_SERIAL
tristate "Serial mouse"
depends on INPUT && INPUT_MOUSE && SERIO
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 6a52702cb1cc..8c1b90087721 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -14,7 +14,4 @@ obj-$(CONFIG_MOUSE_PC9800) += 98busmouse.o
obj-$(CONFIG_MOUSE_PS2) += psmouse.o
obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
-psmouse-objs := psmouse-base.o
-ifeq ($(CONFIG_MOUSE_PS2_SYNAPTICS),y)
- psmouse-objs += synaptics.o
-endif
+psmouse-objs := psmouse-base.o logips2pp.o synaptics.o
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
new file mode 100644
index 000000000000..ce5d80c854f1
--- /dev/null
+++ b/drivers/input/mouse/logips2pp.c
@@ -0,0 +1,228 @@
+/*
+ * Logitech PS/2++ mouse driver
+ *
+ * Copyright (c) 1999-2003 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2003 Eric Wong <eric@yhbt.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+#include "psmouse.h"
+#include "logips2pp.h"
+
+/*
+ * Process a PS2++ or PS2T++ packet.
+ */
+
+void ps2pp_process_packet(struct psmouse *psmouse)
+{
+ struct input_dev *dev = &psmouse->dev;
+ unsigned char *packet = psmouse->packet;
+
+ if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) {
+
+ switch ((packet[1] >> 4) | (packet[0] & 0x30)) {
+
+ case 0x0d: /* Mouse extra info */
+
+ input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+ (int) (packet[2] & 8) - (int) (packet[2] & 7));
+ input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
+ input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+
+ break;
+
+ case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
+
+ input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
+ input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
+ input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1);
+ input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1);
+ input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+
+ break;
+
+ case 0x0f: /* TouchPad extra info */
+
+ input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
+ (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7));
+ packet[0] = packet[2] | 0x08;
+ break;
+
+#ifdef DEBUG
+ default:
+ printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
+ (packet[1] >> 4) | (packet[0] & 0x30));
+#endif
+ }
+
+ packet[0] &= 0x0f;
+ packet[1] = 0;
+ packet[2] = 0;
+
+ }
+}
+
+/*
+ * ps2pp_cmd() sends a PS2++ command, sliced into two bit
+ * pieces through the SETRES command. This is needed to send extended
+ * commands to mice on notebooks that try to understand the PS/2 protocol
+ * Ugly.
+ */
+
+static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
+{
+ unsigned char d;
+ int i;
+
+ if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
+ return -1;
+
+ for (i = 6; i >= 0; i -= 2) {
+ d = (command >> i) & 3;
+ if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
+ return -1;
+ }
+
+ if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
+ return -1;
+
+ return 0;
+}
+
+/*
+ * SmartScroll / CruiseControl for some newer Logitech mice Defaults to
+ * enabled if we do nothing to it. Of course I put this in because I want it
+ * disabled :P
+ * 1 - enabled (if previously disabled, also default)
+ * 0/2 - disabled
+ */
+
+static void ps2pp_set_smartscroll(struct psmouse *psmouse)
+{
+ unsigned char param[4];
+
+ ps2pp_cmd(psmouse, param, 0x32);
+
+ param[0] = 0;
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+
+ if (psmouse_smartscroll == 1)
+ param[0] = 1;
+ else
+ if (psmouse_smartscroll > 2)
+ return;
+
+ /* else leave param[0] == 0 to disable */
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Support 800 dpi resolution _only_ if the user wants it (there are good
+ * reasons to not use it even if the mouse supports it, and of course there are
+ * also good reasons to use it, let the user decide).
+ */
+
+void ps2pp_set_800dpi(struct psmouse *psmouse)
+{
+ unsigned char param = 3;
+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
+}
+
+/*
+ * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or
+ * touchpad.
+ */
+
+int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
+{
+ int i;
+ static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
+ static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
+ static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
+ 76, 80, 81, 83, 88, 96, 97, 112, -1 };
+ static int logitech_mx[] = { 112, -1 };
+
+ psmouse->vendor = "Logitech";
+ psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+
+ if (param[1] < 3)
+ clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
+ if (param[1] < 2)
+ clear_bit(BTN_RIGHT, psmouse->dev.keybit);
+
+ psmouse->type = PSMOUSE_PS2;
+
+ for (i = 0; logitech_ps2pp[i] != -1; i++)
+ if (logitech_ps2pp[i] == psmouse->model)
+ psmouse->type = PSMOUSE_PS2PP;
+
+ if (psmouse->type == PSMOUSE_PS2PP) {
+
+ for (i = 0; logitech_4btn[i] != -1; i++)
+ if (logitech_4btn[i] == psmouse->model)
+ set_bit(BTN_SIDE, psmouse->dev.keybit);
+
+ for (i = 0; logitech_wheel[i] != -1; i++)
+ if (logitech_wheel[i] == psmouse->model) {
+ set_bit(REL_WHEEL, psmouse->dev.relbit);
+ psmouse->name = "Wheel Mouse";
+ }
+
+ for (i = 0; logitech_mx[i] != -1; i++)
+ if (logitech_mx[i] == psmouse->model) {
+ set_bit(BTN_SIDE, psmouse->dev.keybit);
+ set_bit(BTN_EXTRA, psmouse->dev.keybit);
+ set_bit(BTN_BACK, psmouse->dev.keybit);
+ set_bit(BTN_FORWARD, psmouse->dev.keybit);
+ set_bit(BTN_TASK, psmouse->dev.keybit);
+ psmouse->name = "MX Mouse";
+ }
+
+/*
+ * Do Logitech PS2++ / PS2T++ magic init.
+ */
+
+ if (psmouse->model == 97) { /* TouchPad 3 */
+
+ set_bit(REL_WHEEL, psmouse->dev.relbit);
+ set_bit(REL_HWHEEL, psmouse->dev.relbit);
+
+ param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
+ psmouse_command(psmouse, param, 0x30d1);
+ param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
+ psmouse_command(psmouse, param, 0x30d1);
+ param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
+ psmouse_command(psmouse, param, 0x30d1);
+
+ param[0] = 0;
+ if (!psmouse_command(psmouse, param, 0x13d1) &&
+ param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+ psmouse->name = "TouchPad 3";
+ return PSMOUSE_PS2TPP;
+ }
+
+ } else {
+
+ param[0] = param[1] = param[2] = 0;
+ ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
+ ps2pp_cmd(psmouse, param, 0xDB);
+
+ if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
+ (param[2] & 3) == ((param[1] >> 2) & 3)) {
+ ps2pp_set_smartscroll(psmouse);
+ return PSMOUSE_PS2PP;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
new file mode 100644
index 000000000000..8eb50abefb0a
--- /dev/null
+++ b/drivers/input/mouse/logips2pp.h
@@ -0,0 +1,17 @@
+/*
+ * Logitech PS/2++ mouse driver header
+ *
+ * Copyright (c) 2003 Vojtech Pavlik <vojtech@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _LOGIPS2PP_H
+#define _LOGIPS2PP_H
+struct psmouse;
+void ps2pp_process_packet(struct psmouse *psmouse);
+void ps2pp_set_800dpi(struct psmouse *psmouse);
+int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param);
+#endif
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index e7d699c52fc5..030d23149e2e 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -19,13 +19,23 @@
#include <linux/init.h>
#include "psmouse.h"
#include "synaptics.h"
+#include "logips2pp.h"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("PS/2 mouse driver");
MODULE_PARM(psmouse_noext, "1i");
+MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches.");
+MODULE_PARM(psmouse_resolution, "i");
+MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
+MODULE_PARM(psmouse_smartscroll, "i");
+MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
MODULE_LICENSE("GPL");
+#define PSMOUSE_LOGITECH_SMARTSCROLL 1
+
static int psmouse_noext;
+int psmouse_resolution;
+int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "Synaptics"};
@@ -45,43 +55,8 @@ static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs
* The PS2++ protocol is a little bit complex
*/
- if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
-
- if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
-
- switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c)) {
-
- case 1: /* Mouse extra info */
-
- input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
- (int) (packet[2] & 8) - (int) (packet[2] & 7));
- input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
- input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
-
- break;
-
- case 3: /* TouchPad extra info */
-
- input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
- (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7));
- packet[0] = packet[2] | 0x08;
-
- break;
-
-#ifdef DEBUG
- default:
- printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
- ((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
-#endif
-
- }
-
- packet[0] &= 0x0f;
- packet[1] = 0;
- packet[2] = 0;
-
- }
- }
+ if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP)
+ ps2pp_process_packet(psmouse);
/*
* Scroll wheel on IntelliMice, scroll buttons on NetMice
@@ -259,33 +234,6 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
}
/*
- * psmouse_ps2pp_cmd() sends a PS2++ command, sliced into two bit
- * pieces through the SETRES command. This is needed to send extended
- * commands to mice on notebooks that try to understand the PS/2 protocol
- * Ugly.
- */
-
-static int psmouse_ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
-{
- unsigned char d;
- int i;
-
- if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
- return -1;
-
- for (i = 6; i >= 0; i -= 2) {
- d = (command >> i) & 3;
- if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
- return -1;
- }
-
- if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
- return -1;
-
- return 0;
-}
-
-/*
* psmouse_extensions() probes for any extensions to the basic PS/2 protocol
* the mouse may have.
*/
@@ -353,73 +301,13 @@ static int psmouse_extensions(struct psmouse *psmouse)
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ param[1] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
if (param[1]) {
-
- int i;
- static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
- static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, -1 };
- static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
- 76, 80, 81, 83, 88, 96, 97, -1 };
- psmouse->vendor = "Logitech";
- psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
-
- if (param[1] < 3)
- clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
- if (param[1] < 2)
- clear_bit(BTN_RIGHT, psmouse->dev.keybit);
-
- psmouse->type = PSMOUSE_PS2;
-
- for (i = 0; logitech_ps2pp[i] != -1; i++)
- if (logitech_ps2pp[i] == psmouse->model)
- psmouse->type = PSMOUSE_PS2PP;
-
- if (psmouse->type == PSMOUSE_PS2PP) {
-
- for (i = 0; logitech_4btn[i] != -1; i++)
- if (logitech_4btn[i] == psmouse->model)
- set_bit(BTN_SIDE, psmouse->dev.keybit);
-
- for (i = 0; logitech_wheel[i] != -1; i++)
- if (logitech_wheel[i] == psmouse->model) {
- set_bit(REL_WHEEL, psmouse->dev.relbit);
- psmouse->name = "Wheel Mouse";
- }
-
-/*
- * Do Logitech PS2++ / PS2T++ magic init.
- */
-
- if (psmouse->model == 97) { /* TouchPad 3 */
-
- set_bit(REL_WHEEL, psmouse->dev.relbit);
- set_bit(REL_HWHEEL, psmouse->dev.relbit);
-
- param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
- psmouse_command(psmouse, param, 0x30d1);
- param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
- psmouse_command(psmouse, param, 0x30d1);
- param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
- psmouse_command(psmouse, param, 0x30d1);
-
- param[0] = 0;
- if (!psmouse_command(psmouse, param, 0x13d1) &&
- param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14)
- return PSMOUSE_PS2TPP;
-
- } else {
- param[0] = param[1] = param[2] = 0;
-
- psmouse_ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
- psmouse_ps2pp_cmd(psmouse, param, 0xDB);
-
- if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
- (param[2] & 3) == ((param[1] >> 2) & 3))
- return PSMOUSE_PS2PP;
- }
- }
+ int type = ps2pp_detect_model(psmouse, param);
+ if (type)
+ return type;
}
/*
@@ -508,6 +396,31 @@ static int psmouse_probe(struct psmouse *psmouse)
}
/*
+ * Here we set the mouse resolution.
+ */
+
+static void psmouse_set_resolution(struct psmouse *psmouse)
+{
+ unsigned char param[1];
+
+ if (psmouse->type == PSMOUSE_PS2PP && psmouse_resolution > 400) {
+ ps2pp_set_800dpi(psmouse);
+ return;
+ }
+
+ if (!psmouse_resolution || psmouse_resolution >= 200)
+ param[0] = 3;
+ else if (psmouse_resolution >= 100)
+ param[0] = 2;
+ else if (psmouse_resolution >= 50)
+ param[0] = 1;
+ else if (psmouse_resolution)
+ param[0] = 0;
+
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+}
+
+/*
* psmouse_initialize() initializes the mouse to a sane state.
*/
@@ -519,7 +432,6 @@ static void psmouse_initialize(struct psmouse *psmouse)
* We set the mouse report rate to a highest possible value.
* We try 100 first in case mouse fails to set 200.
*/
-
param[0] = 100;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
@@ -530,8 +442,7 @@ static void psmouse_initialize(struct psmouse *psmouse)
* We also set the resolution and scaling.
*/
- param[0] = 3;
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_set_resolution(psmouse);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
/*
@@ -638,12 +549,28 @@ static struct serio_dev psmouse_dev = {
};
#ifndef MODULE
-static int __init psmouse_setup(char *str)
+static int __init psmouse_noext_setup(char *str)
{
psmouse_noext = 1;
return 1;
}
-__setup("psmouse_noext", psmouse_setup);
+
+static int __init psmouse_resolution_setup(char *str)
+{
+ get_option(&str, &psmouse_resolution);
+ return 1;
+}
+
+static int __init psmouse_smartscroll_setup(char *str)
+{
+ get_option(&str, &psmouse_smartscroll);
+ return 1;
+}
+
+__setup("psmouse_noext", psmouse_noext_setup);
+__setup("psmouse_resolution=", psmouse_resolution_setup);
+__setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
+
#endif
int __init psmouse_init(void)
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index f2e9baa53d3f..05a24de18d7d 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -46,4 +46,6 @@ struct psmouse {
int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
+extern int psmouse_smartscroll;
+
#endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 73ced749126a..5fa695eb774e 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -171,9 +171,9 @@ static void print_ident(struct synaptics_data *priv)
static int query_hardware(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
- int retries = 3;
+ int retries = 0;
- while ((retries++ <= 3) && synaptics_reset(psmouse))
+ while ((retries++ < 3) && synaptics_reset(psmouse))
printk(KERN_ERR "synaptics reset failed\n");
if (synaptics_identify(psmouse, &priv->identity))
@@ -266,8 +266,7 @@ void synaptics_disconnect(struct psmouse *psmouse)
* Functions to interpret the absolute mode packets
****************************************************************************/
-static void synaptics_parse_hw_state(struct synaptics_data *priv,
- struct synaptics_hw_state *hw)
+static void synaptics_parse_hw_state(struct synaptics_data *priv, struct synaptics_hw_state *hw)
{
unsigned char *buf = priv->proto_buf;
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 4acaff4ef070..6e3e029a3bdd 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -9,21 +9,11 @@
#ifndef _SYNAPTICS_H
#define _SYNAPTICS_H
-#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
extern int synaptics_init(struct psmouse *psmouse);
extern void synaptics_disconnect(struct psmouse *psmouse);
-#else
-
-static inline void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) {}
-static inline int synaptics_init(struct psmouse *psmouse) { return -1; }
-static inline void synaptics_disconnect(struct psmouse *psmouse) {}
-
-#endif
-
-
/* synaptics queries */
#define SYN_QUE_IDENTIFY 0x00
#define SYN_QUE_MODES 0x01
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 4320ed345ca5..378ae8616dac 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -58,6 +58,7 @@ struct serio_event {
struct list_head node;
};
+static DECLARE_MUTEX(serio_sem);
static LIST_HEAD(serio_list);
static LIST_HEAD(serio_dev_list);
static LIST_HEAD(serio_event_list);
@@ -90,9 +91,11 @@ void serio_handle_events(void)
switch (event->type) {
case SERIO_RESCAN :
+ down(&serio_sem);
if (event->serio->dev && event->serio->dev->disconnect)
event->serio->dev->disconnect(event->serio);
serio_find_dev(event->serio);
+ up(&serio_sem);
break;
default:
break;
@@ -153,30 +156,37 @@ irqreturn_t serio_interrupt(struct serio *serio,
void serio_register_port(struct serio *serio)
{
+ down(&serio_sem);
list_add_tail(&serio->node, &serio_list);
serio_find_dev(serio);
+ up(&serio_sem);
}
void serio_unregister_port(struct serio *serio)
{
+ down(&serio_sem);
list_del_init(&serio->node);
if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio);
+ up(&serio_sem);
}
void serio_register_device(struct serio_dev *dev)
{
struct serio *serio;
+ down(&serio_sem);
list_add_tail(&dev->node, &serio_dev_list);
list_for_each_entry(serio, &serio_list, node)
if (!serio->dev && dev->connect)
dev->connect(serio, dev);
+ up(&serio_sem);
}
void serio_unregister_device(struct serio_dev *dev)
{
struct serio *serio;
+ down(&serio_sem);
list_del_init(&dev->node);
list_for_each_entry(serio, &serio_list, node) {
@@ -184,8 +194,10 @@ void serio_unregister_device(struct serio_dev *dev)
dev->disconnect(serio);
serio_find_dev(serio);
}
+ up(&serio_sem);
}
+/* called from serio_dev->connect/disconnect methods under serio_sem */
int serio_open(struct serio *serio, struct serio_dev *dev)
{
if (serio->open(serio))
@@ -194,6 +206,7 @@ int serio_open(struct serio *serio, struct serio_dev *dev)
return 0;
}
+/* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
serio->close(serio);
diff --git a/drivers/isdn/act2000/Makefile b/drivers/isdn/act2000/Makefile
index fd749f59ee4a..05e582fb5c00 100644
--- a/drivers/isdn/act2000/Makefile
+++ b/drivers/isdn/act2000/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000.o
# Multipart objects.
-act2000-objs := module.o capi.o act2000_isa.o
+act2000-y := module.o capi.o act2000_isa.o
diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile
index b8265712e7ec..57123e3e4978 100644
--- a/drivers/isdn/capi/Makefile
+++ b/drivers/isdn/capi/Makefile
@@ -13,4 +13,3 @@ obj-$(CONFIG_ISDN_CAPI_CAPIFS) += capifs.o
kernelcapi-y := kcapi.o capiutil.o capilib.o
kernelcapi-$(CONFIG_PROC_FS) += kcapi_proc.o
-kernelcapi-objs := $(kernelcapi-y)
diff --git a/drivers/isdn/divert/Makefile b/drivers/isdn/divert/Makefile
index f45e5b51408f..dd4a202e0bc2 100644
--- a/drivers/isdn/divert/Makefile
+++ b/drivers/isdn/divert/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_ISDN_DIVERSION) += dss1_divert.o
# Multipart objects.
-dss1_divert-objs := isdn_divert.o divert_procfs.o divert_init.o
+dss1_divert-y := isdn_divert.o divert_procfs.o divert_init.o
diff --git a/drivers/isdn/eicon/Makefile b/drivers/isdn/eicon/Makefile
index fcde8d013922..fd96828ae34b 100644
--- a/drivers/isdn/eicon/Makefile
+++ b/drivers/isdn/eicon/Makefile
@@ -7,15 +7,13 @@ obj-$(CONFIG_ISDN_DRV_EICON_DIVAS) += divas.o
# Multipart objects.
-eicon-objs := eicon_mod.o eicon_isa.o eicon_pci.o eicon_idi.o \
- eicon_io.o
-divas-objs := common.o idi.o bri.o pri.o log.o xlog.o kprintf.o fpga.o \
- fourbri.o lincfg.o linchr.o linsys.o linio.o Divas_mod.o
+eicon-y := eicon_mod.o eicon_isa.o eicon_pci.o \
+ eicon_idi.o eicon_io.o
+eicon-$(CONFIG_ISDN_DRV_EICON_PCI) += common.o idi.o bri.o pri.o log.o \
+ xlog.o kprintf.o fpga.o fourbri.o lincfg.o \
+ linchr.o linsys.o linio.o
-# Optional parts of multipart objects.
+divas-y := common.o idi.o bri.o pri.o log.o xlog.o \
+ kprintf.o fpga.o fourbri.o lincfg.o \
+ linchr.o linsys.o linio.o Divas_mod.o
-eicon-objs-$(CONFIG_ISDN_DRV_EICON_PCI) += common.o idi.o bri.o pri.o log.o \
- xlog.o kprintf.o fpga.o fourbri.o lincfg.o linchr.o \
- linsys.o linio.o
-
-eicon-objs += $(eicon-objs-y)
diff --git a/drivers/isdn/eicon/eicon_isa.c b/drivers/isdn/eicon/eicon_isa.c
index 1b0ff98d150b..b11a085a60f3 100644
--- a/drivers/isdn/eicon/eicon_isa.c
+++ b/drivers/isdn/eicon/eicon_isa.c
@@ -123,7 +123,7 @@ eicon_isa_find_card(int Mem, int Irq, char * Id)
int
eicon_isa_bootload(eicon_isa_card *card, eicon_isa_codebuf *cb) {
int tmp;
- int timeout;
+ unsigned long timeout;
eicon_isa_codebuf cbuf;
unsigned char *code;
eicon_isa_boot *boot;
@@ -300,7 +300,7 @@ int
eicon_isa_load(eicon_isa_card *card, eicon_isa_codebuf *cb) {
eicon_isa_boot *boot;
int tmp;
- int timeout;
+ unsigned long timeout;
int j;
eicon_isa_codebuf cbuf;
unsigned char *code;
diff --git a/drivers/isdn/hardware/avm/b1pci.c b/drivers/isdn/hardware/avm/b1pci.c
index 14e5658234de..bd9a741467fd 100644
--- a/drivers/isdn/hardware/avm/b1pci.c
+++ b/drivers/isdn/hardware/avm/b1pci.c
@@ -111,7 +111,7 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
cinfo->capi_ctrl.procinfo = b1pci_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
strcpy(cinfo->capi_ctrl.name, card->name);
- cinfo->capi_ctrl.owner = THIS_MODULE;
+ cinfo->capi_ctrl.owner = THIS_MODULE;
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
@@ -239,6 +239,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
goto err_unmap;
}
+ cinfo->capi_ctrl.owner = THIS_MODULE;
cinfo->capi_ctrl.driver_name = "b1pciv4";
cinfo->capi_ctrl.driverdata = cinfo;
cinfo->capi_ctrl.register_appl = b1dma_register_appl;
@@ -249,7 +250,6 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
cinfo->capi_ctrl.procinfo = b1pciv4_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
strcpy(cinfo->capi_ctrl.name, card->name);
- cinfo->capi_ctrl.owner = THIS_MODULE;
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c
index 8120237ef685..c304230735d2 100644
--- a/drivers/isdn/hardware/avm/b1pcmcia.c
+++ b/drivers/isdn/hardware/avm/b1pcmcia.c
@@ -95,6 +95,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
b1_reset(card->port);
b1_getrevision(card);
+ cinfo->capi_ctrl.owner = THIS_MODULE;
cinfo->capi_ctrl.driver_name = "b1pcmcia";
cinfo->capi_ctrl.driverdata = cinfo;
cinfo->capi_ctrl.register_appl = b1_register_appl;
@@ -105,7 +106,6 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
strcpy(cinfo->capi_ctrl.name, card->name);
- cinfo->capi_ctrl.owner = THIS_MODULE;
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c
index 0cb3091e5774..f459f1278440 100644
--- a/drivers/isdn/hardware/avm/t1pci.c
+++ b/drivers/isdn/hardware/avm/t1pci.c
@@ -109,6 +109,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
goto err_unmap;
}
+ cinfo->capi_ctrl.owner = THIS_MODULE;
cinfo->capi_ctrl.driver_name = "t1pci";
cinfo->capi_ctrl.driverdata = cinfo;
cinfo->capi_ctrl.register_appl = b1dma_register_appl;
@@ -119,7 +120,6 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
cinfo->capi_ctrl.procinfo = t1pci_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
strcpy(cinfo->capi_ctrl.name, card->name);
- cinfo->capi_ctrl.owner = THIS_MODULE;
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
diff --git a/drivers/isdn/hardware/eicon/Makefile b/drivers/isdn/hardware/eicon/Makefile
index 99fe876163fe..ce1f5cf4b5a1 100644
--- a/drivers/isdn/hardware/eicon/Makefile
+++ b/drivers/isdn/hardware/eicon/Makefile
@@ -1,24 +1,24 @@
# Makefile for the Eicon DIVA ISDN drivers.
-# Multipart objects.
+# Each configuration option enables a list of files.
-divas-objs := divasmain.o divasfunc.o di.o io.o istream.o diva.o dlist.o divasproc.o diva_dma.o
-divacapi-objs := capimain.o capifunc.o message.o capidtmf.o
-divadidd-objs := diva_didd.o diddfunc.o dadapter.o
-diva_mnt-objs := divamnt.o mntfunc.o debug.o maintidi.o
-diva_idi-objs := divasi.o idifunc.o um_idi.o dqueue.o dlist.o
+obj-$(CONFIG_ISDN_DIVAS) += divadidd.o divas.o
+obj-$(CONFIG_ISDN_DIVAS_MAINT) += diva_mnt.o
+obj-$(CONFIG_ISDN_DIVAS_USERIDI) += diva_idi.o
+obj-$(CONFIG_ISDN_DIVAS_DIVACAPI) += divacapi.o
-# Optional parts of multipart objects.
+# Multipart objects.
-divas-objs-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o
-divas-objs-$(CONFIG_ISDN_DIVAS_4BRIPCI) += os_4bri.o s_4bri.o
-divas-objs-$(CONFIG_ISDN_DIVAS_PRIPCI) += os_pri.o s_pri.o
+divas-y := divasmain.o divasfunc.o di.o io.o istream.o \
+ diva.o dlist.o divasproc.o diva_dma.o
+divas-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o
+divas-$(CONFIG_ISDN_DIVAS_4BRIPCI) += os_4bri.o s_4bri.o
+divas-$(CONFIG_ISDN_DIVAS_PRIPCI) += os_pri.o s_pri.o
-divas-objs += $(sort $(divas-objs-y))
+divacapi-y := capimain.o capifunc.o message.o capidtmf.o
-# Each configuration option enables a list of files.
+divadidd-y := diva_didd.o diddfunc.o dadapter.o
+
+diva_mnt-y := divamnt.o mntfunc.o debug.o maintidi.o
-obj-$(CONFIG_ISDN_DIVAS) += divadidd.o divas.o
-obj-$(CONFIG_ISDN_DIVAS_MAINT) += diva_mnt.o
-obj-$(CONFIG_ISDN_DIVAS_USERIDI) += diva_idi.o
-obj-$(CONFIG_ISDN_DIVAS_DIVACAPI) += divacapi.o
+diva_idi-y := divasi.o idifunc.o um_idi.o dqueue.o dlist.o
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
index 8f5f1409d449..8c384dffc5e6 100644
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -17,47 +17,45 @@ obj-$(CONFIG_HISAX_FRITZ_PCIPNP) += hisax_hfcpci.o
# Multipart objects.
-hisax_st5481-objs := st5481_init.o st5481_usb.o st5481_d.o st5481_b.o \
- st5481_hdlc.o
-hisax-objs := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
- lmgr.o q931.o callc.o fsm.o cert.o
-
-# Optional parts of multipart objects.
-hisax-objs-$(CONFIG_HISAX_EURO) += l3dss1.o
-hisax-objs-$(CONFIG_HISAX_NI1) += l3ni1.o
-hisax-objs-$(CONFIG_HISAX_1TR6) += l3_1tr6.o
-
-hisax-objs-$(CONFIG_HISAX_16_0) += teles0.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_16_3) += teles3.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_TELESPCI) += telespci.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o
-hisax-objs-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipac.o ipacx.o
-hisax-objs-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o
-hisax-objs-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o ipac.o isar.o
-hisax-objs-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o
-hisax-objs-$(CONFIG_HISAX_NETJET_U) += nj_u.o netjet.o icc.o
-hisax-objs-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o
-hisax-objs-$(CONFIG_HISAX_HFC_PCI) += hfc_pci.o
-hisax-objs-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o
-hisax-objs-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o
-hisax-objs-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o
-hisax-objs-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_W6692) += w6692.o
-hisax-objs-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
-#hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o
-
-hisax-objs += $(hisax-objs-y)
+hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \
+ st5481_b.o st5481_hdlc.o
+
+hisax-y := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
+ lmgr.o q931.o callc.o fsm.o cert.o
+hisax-$(CONFIG_HISAX_EURO) += l3dss1.o
+hisax-$(CONFIG_HISAX_NI1) += l3ni1.o
+hisax-$(CONFIG_HISAX_1TR6) += l3_1tr6.o
+
+hisax-$(CONFIG_HISAX_16_0) += teles0.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_16_3) += teles3.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_TELESPCI) += telespci.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o
+hisax-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipac.o ipacx.o
+hisax-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o
+hisax-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o ipac.o \
+ isar.o
+hisax-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o
+hisax-$(CONFIG_HISAX_NETJET_U) += nj_u.o netjet.o icc.o
+hisax-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o
+hisax-$(CONFIG_HISAX_HFC_PCI) += hfc_pci.o
+hisax-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o
+hisax-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o
+hisax-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o
+hisax-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_W6692) += w6692.o
+hisax-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
+#hisax-$(CONFIG_HISAX_TESTEMU) += testemu.o
CERT := $(shell cd $(src); md5sum -c md5sums.asc > /dev/null 2> /dev/null ;echo $$?)
CFLAGS_cert.o := -DCERTIFICATION=$(CERT)
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index dc983c107b83..77e1a43a0771 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -153,6 +153,8 @@ static dev_link_t *avma1cs_attach(void)
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ if (!link)
+ return NULL;
memset(link, 0, sizeof(struct dev_link_t));
link->release.function = &avma1cs_release;
link->release.data = (u_long)link;
@@ -186,6 +188,10 @@ static dev_link_t *avma1cs_attach(void)
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+ if (!local) {
+ kfree(link);
+ return NULL;
+ }
memset(local, 0, sizeof(local_info_t));
link->priv = local;
diff --git a/drivers/isdn/hysdn/Makefile b/drivers/isdn/hysdn/Makefile
index 2db847e67285..da63b636267d 100644
--- a/drivers/isdn/hysdn/Makefile
+++ b/drivers/isdn/hysdn/Makefile
@@ -2,15 +2,10 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_HYSDN) += hysdn.o
+obj-$(CONFIG_HYSDN) += hysdn.o
# Multipart objects.
-hysdn-objs := hysdn_procconf.o hysdn_proclog.o boardergo.o hysdn_boot.o \
- hysdn_sched.o hysdn_net.o hysdn_init.o
-
-# Optional parts of multipart objects.
-
-hysdn-objs-$(CONFIG_HYSDN_CAPI) += hycapi.o
-
-hysdn-objs += $(hysdn-objs-y)
+hysdn-y := hysdn_procconf.o hysdn_proclog.o boardergo.o \
+ hysdn_boot.o hysdn_sched.o hysdn_net.o hysdn_init.o
+hysdn-$(CONFIG_HYSDN_CAPI) += hycapi.o
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index c9a8b1920833..e9e5ec845d1a 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -98,7 +98,8 @@ put_log_buffer(hysdn_card * card, char *cp)
{
struct log_data *ib;
struct procdata *pd = card->proclog;
- int i, flags;
+ int i;
+ unsigned long flags;
if (!pd)
return;
@@ -300,7 +301,8 @@ hysdn_log_close(struct inode *ino, struct file *filep)
struct log_data *inf;
struct procdata *pd;
hysdn_card *card;
- int flags, retval = 0;
+ int retval = 0;
+ unsigned long flags;
lock_kernel();
diff --git a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile
index a76150977dcc..431662a3a4c8 100644
--- a/drivers/isdn/i4l/Makefile
+++ b/drivers/isdn/i4l/Makefile
@@ -2,25 +2,18 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_ISDN) += isdn.o
-obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
+obj-$(CONFIG_ISDN) += isdn.o
+obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
# Multipart objects.
-isdn-objs := isdn_net_lib.o \
- isdn_fsm.o \
- isdn_tty.o isdn_v110.o \
- isdn_common.o \
-
-# Optional parts of multipart objects.
-
-isdn-objs-$(CONFIG_ISDN_NET_SIMPLE) += isdn_net.o
-isdn-objs-$(CONFIG_ISDN_NET_CISCO) += isdn_ciscohdlck.o
-isdn-objs-$(CONFIG_ISDN_PPP) += isdn_ppp.o isdn_ppp_ccp.o
-isdn-objs-$(CONFIG_ISDN_PPP_VJ) += isdn_ppp_vj.o
-isdn-objs-$(CONFIG_ISDN_MPP) += isdn_ppp_mp.o
-isdn-objs-$(CONFIG_ISDN_X25) += isdn_concap.o isdn_x25iface.o
-isdn-objs-$(CONFIG_ISDN_AUDIO) += isdn_audio.o
-isdn-objs-$(CONFIG_ISDN_TTY_FAX) += isdn_ttyfax.o
-
-isdn-objs += $(isdn-objs-y)
+isdn-y := isdn_net_lib.o isdn_fsm.o isdn_tty.o \
+ isdn_v110.o isdn_common.o
+isdn-$(CONFIG_ISDN_NET_SIMPLE) += isdn_net.o
+isdn-$(CONFIG_ISDN_NET_CISCO) += isdn_ciscohdlck.o
+isdn-$(CONFIG_ISDN_PPP) += isdn_ppp.o isdn_ppp_ccp.o
+isdn-$(CONFIG_ISDN_PPP_VJ) += isdn_ppp_vj.o
+isdn-$(CONFIG_ISDN_MPP) += isdn_ppp_mp.o
+isdn-$(CONFIG_ISDN_X25) += isdn_concap.o isdn_x25iface.o
+isdn-$(CONFIG_ISDN_AUDIO) += isdn_audio.o
+isdn-$(CONFIG_ISDN_TTY_FAX) += isdn_ttyfax.o
diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c
index c48275b76141..16fda695fd42 100644
--- a/drivers/isdn/i4l/isdn_bsdcomp.c
+++ b/drivers/isdn/i4l/isdn_bsdcomp.c
@@ -300,7 +300,6 @@ static void bsd_free (void *state)
* Finally release the structure itself.
*/
kfree (db);
- MOD_DEC_USE_COUNT;
}
}
@@ -355,8 +354,6 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data)
return NULL;
}
- MOD_INC_USE_COUNT;
-
/*
* If this is the compression buffer then there is no length data.
* For decompression, the length information is needed as well.
@@ -907,6 +904,7 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
*************************************************************/
static struct isdn_ppp_compressor ippp_bsd_compress = {
+ .owner = THIS_MODULE,
.num = CI_BSD_COMPRESS,
.alloc = bsd_alloc,
.free = bsd_free,
diff --git a/drivers/isdn/i4l/isdn_ppp_ccp.c b/drivers/isdn/i4l/isdn_ppp_ccp.c
index 155e76b1b3d0..6e559e89d01e 100644
--- a/drivers/isdn/i4l/isdn_ppp_ccp.c
+++ b/drivers/isdn/i4l/isdn_ppp_ccp.c
@@ -259,11 +259,14 @@ ippp_ccp_free(struct ippp_ccp *ccp)
{
int id;
- if (ccp->comp_stat)
+ if (ccp->comp_stat) {
ccp->compressor->free(ccp->comp_stat);
- if (ccp->decomp_stat)
+ module_put(ccp->compressor->owner);
+ }
+ if (ccp->decomp_stat) {
ccp->decompressor->free(ccp->decomp_stat);
-
+ module_put(ccp->decompressor->owner);
+ }
for (id = 0; id < 256; id++) {
if (ccp->reset->rs[id])
ippp_ccp_reset_free_state(ccp, id);
@@ -553,13 +556,14 @@ ippp_ccp_send_ccp(struct ippp_ccp *ccp, struct sk_buff *skb)
}
}
-static struct isdn_ppp_compressor *ipc_head = NULL;
+static LIST_HEAD(ipc_head);
+static spinlock_t ipc_head_lock;
int
ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
struct isdn_ppp_comp_data *data)
{
- struct isdn_ppp_compressor *ipc = ipc_head;
+ struct isdn_ppp_compressor *ipc;
int ret;
void *stat;
int num = data->num;
@@ -568,34 +572,48 @@ ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
printk(KERN_DEBUG "[%d] Set %scompressor type %d\n", unit,
data->flags & IPPP_COMP_FLAG_XMIT ? "" : "de", num);
- for (ipc = ipc_head; ipc; ipc = ipc->next) {
- if (ipc->num != num)
- continue;
-
- stat = ipc->alloc(data);
- if (!stat) {
- printk(KERN_ERR "Can't alloc (de)compression!\n");
- break;
- }
- ret = ipc->init(stat, data, unit, 0);
- if(!ret) {
- printk(KERN_ERR "Can't init (de)compression!\n");
- ipc->free(stat);
- break;
+ spin_lock(&ipc_head_lock);
+ list_for_each_entry(ipc, &ipc_head, list) {
+ if (ipc->num == num &&
+ try_module_get(ipc->owner))
+ goto found;
+ }
+ spin_unlock(&ipc_head_lock);
+ return -EINVAL;
+
+ found:
+ spin_unlock(&ipc_head_lock);
+
+ stat = ipc->alloc(data);
+ if (!stat) {
+ printk(KERN_ERR "Can't alloc (de)compression!\n");
+ goto err;
+ }
+ ret = ipc->init(stat, data, unit, 0);
+ if(!ret) {
+ printk(KERN_ERR "Can't init (de)compression!\n");
+ ipc->free(stat);
+ goto err;
+ }
+ if (data->flags & IPPP_COMP_FLAG_XMIT) {
+ if (ccp->comp_stat) {
+ ccp->compressor->free(ccp->comp_stat);
+ module_put(ccp->compressor->owner);
}
- if (data->flags & IPPP_COMP_FLAG_XMIT) {
- if (ccp->comp_stat)
- ccp->compressor->free(ccp->comp_stat);
ccp->comp_stat = stat;
ccp->compressor = ipc;
- } else {
- if (ccp->decomp_stat)
- ccp->decompressor->free(ccp->decomp_stat);
- ccp->decomp_stat = stat;
- ccp->decompressor = ipc;
+ } else {
+ if (ccp->decomp_stat) {
+ ccp->decompressor->free(ccp->decomp_stat);
+ module_put(ccp->decompressor->owner);
}
- return 0;
+ ccp->decomp_stat = stat;
+ ccp->decompressor = ipc;
}
+ return 0;
+
+ err:
+ module_put(ipc->owner);
return -EINVAL;
}
@@ -606,36 +624,34 @@ ippp_ccp_get_compressors(unsigned long protos[8])
int i, j;
memset(protos, 0, sizeof(unsigned long) * 8);
- for (ipc = ipc_head; ipc; ipc = ipc->next) {
+
+ spin_lock(&ipc_head_lock);
+ list_for_each_entry(ipc, &ipc_head, list) {
j = ipc->num / (sizeof(long)*8);
i = ipc->num % (sizeof(long)*8);
if (j < 8)
protos[j] |= 1 << i;
}
+ spin_unlock(&ipc_head_lock);
}
int
isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
{
- ipc->next = ipc_head;
- ipc->prev = NULL;
- if (ipc_head) {
- ipc_head->prev = ipc;
- }
- ipc_head = ipc;
+ spin_lock(&ipc_head_lock);
+ list_add_tail(&ipc->list, &ipc_head);
+ spin_unlock(&ipc_head_lock);
+
return 0;
}
int
isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
{
- if (ipc->prev)
- ipc->prev->next = ipc->next;
- else
- ipc_head = ipc->next;
- if (ipc->next)
- ipc->next->prev = ipc->prev;
- ipc->prev = ipc->next = NULL;
+ spin_lock(&ipc_head_lock);
+ list_del(&ipc->list);
+ spin_unlock(&ipc_head_lock);
+
return 0;
}
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index dafefea45941..0bd61b05421c 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1983,7 +1983,7 @@ modem_write_profile(atemu * m)
memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
if (dev->profd)
- group_send_sig_info(SIGIO, SEND_SIG_PRIV, dev->profd);
+ kill_pg_info(SIGIO, SEND_SIG_PRIV, dev->profd->pgrp);
}
static struct tty_operations modem_ops = {
@@ -2095,11 +2095,10 @@ isdn_tty_init(void)
#endif
kfree(info->xmit_buf - 4);
}
- err_unregister_tty:
- tty_unregister_driver(&isdn_mdm->tty_modem);
+ tty_unregister_driver(m->tty_modem);
err:
- put_tty_driver(&isdn_mdm->tty_modem);
- isdn_mdm->tty_modem = NULL;
+ put_tty_driver(m->tty_modem);
+ m->tty_modem = NULL;
return retval;
}
@@ -2118,9 +2117,9 @@ isdn_tty_exit(void)
#endif
kfree(info->xmit_buf - 4);
}
- tty_unregister_driver(&isdn_mdm->tty_modem);
- put_tty_driver(&isdn_mdm->tty_modem);
- isdn_mdm->tty_modem = NULL;
+ tty_unregister_driver(isdn_mdm.tty_modem);
+ put_tty_driver(isdn_mdm.tty_modem);
+ isdn_mdm.tty_modem = NULL;
}
/*
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index c216f92aaece..dbccc7d31133 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -303,7 +303,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
isdn_ctrl c;
int par;
struct isdn_slot *slot;
- long flags;
+ unsigned long flags;
for (c.parm.aux.cmd = 0; c.parm.aux.cmd < 7; c.parm.aux.cmd++)
if (!strncmp(p[0], cmd[c.parm.aux.cmd], 2))
diff --git a/drivers/isdn/isdnloop/Makefile b/drivers/isdn/isdnloop/Makefile
index 7e60c21b9e69..317cd3c5b8ee 100644
--- a/drivers/isdn/isdnloop/Makefile
+++ b/drivers/isdn/isdnloop/Makefile
@@ -1,6 +1,4 @@
-#
# Makefile for the isdnloop ISDN device driver
-#
# Each configuration option enables a list of files.
diff --git a/drivers/isdn/pcbit/Makefile b/drivers/isdn/pcbit/Makefile
index 4646c1491ff3..2d026c3242e8 100644
--- a/drivers/isdn/pcbit/Makefile
+++ b/drivers/isdn/pcbit/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit.o
# Multipart objects.
-pcbit-objs := module.o edss1.o drv.o layer2.o capi.o callbacks.o
+pcbit-y := module.o edss1.o drv.o layer2.o capi.o callbacks.o
diff --git a/drivers/isdn/sc/Makefile b/drivers/isdn/sc/Makefile
index 5d819a743724..9cc474cd0c44 100644
--- a/drivers/isdn/sc/Makefile
+++ b/drivers/isdn/sc/Makefile
@@ -6,5 +6,5 @@ obj-$(CONFIG_ISDN_DRV_SC) += sc.o
# Multipart objects.
-sc-objs := shmem.o init.o debug.o packet.o command.o event.o \
- ioctl.o interrupt.o message.o timer.o
+sc-y := shmem.o init.o debug.o packet.o command.o event.o \
+ ioctl.o interrupt.o message.o timer.o
diff --git a/drivers/isdn/tpam/Makefile b/drivers/isdn/tpam/Makefile
index 1ae6c5093141..5860692b14b4 100644
--- a/drivers/isdn/tpam/Makefile
+++ b/drivers/isdn/tpam/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_ISDN_DRV_TPAM) += tpam.o
# Multipart objects.
-tpam-objs := tpam_main.o tpam_nco.o tpam_memory.o tpam_commands.o \
- tpam_queues.o tpam_hdlc.o tpam_crcpc.o
+tpam-y := tpam_main.o tpam_nco.o tpam_memory.o \
+ tpam_commands.o tpam_queues.o tpam_hdlc.o \
+ tpam_crcpc.o
diff --git a/drivers/isdn/tpam/tpam_queues.c b/drivers/isdn/tpam/tpam_queues.c
index c9841b0ad72f..9b55684dde0c 100644
--- a/drivers/isdn/tpam/tpam_queues.c
+++ b/drivers/isdn/tpam/tpam_queues.c
@@ -145,6 +145,7 @@ irqreturn_t tpam_irq(int irq, void *dev_id, struct pt_regs *regs)
do {
hpic = readl(card->bar0 + TPAM_HPIC_REGISTER);
if (waiting_too_long++ > 0xfffffff) {
+ kfree_skb(skb);
spin_unlock(&card->lock);
printk(KERN_ERR "TurboPAM(tpam_irq): "
"waiting too long...\n");
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
index 6640ebc8e994..527975d27176 100644
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -21,7 +21,7 @@
This is access code for flashes using ARM's flash partitioning
standards.
- $Id: afs.c,v 1.11 2003/05/16 17:08:24 dwmw2 Exp $
+ $Id: afs.c,v 1.12 2003/06/13 15:31:06 rmk Exp $
======================================================================*/
@@ -76,17 +76,19 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
return ret;
}
+ ret = 1;
+
/*
* Does it contain the magic number?
*/
if (fs.signature != 0xa0ffff9f)
- ret = 1;
+ ret = 0;
/*
* Don't touch the SIB.
*/
if (fs.type == 2)
- ret = 1;
+ ret = 0;
*iis_start = fs.image_info_base & mask;
*img_start = fs.image_start & mask;
@@ -96,14 +98,14 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
* be located after the footer structure.
*/
if (*iis_start >= ptr)
- ret = 1;
+ ret = 0;
/*
* Check the start of this image. The image
* data can not be located after this block.
*/
if (*img_start > off)
- ret = 1;
+ ret = 0;
return ret;
}
@@ -152,7 +154,7 @@ static int parse_afs_partitions(struct mtd_info *mtd,
ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
if (ret < 0)
break;
- if (ret == 1)
+ if (ret == 0)
continue;
ret = afs_read_iis(mtd, &iis, iis_ptr);
@@ -185,7 +187,7 @@ static int parse_afs_partitions(struct mtd_info *mtd,
ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
if (ret < 0)
break;
- if (ret == 1)
+ if (ret == 0)
continue;
/* Read the image info block */
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 78cdbfa561b1..6021b8b3c1fb 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
*
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
*
- * $Id: amd_flash.c,v 1.22 2003/05/28 13:47:19 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.23 2003/06/12 09:24:13 dwmw2 Exp $
*
* Copyright (c) 2001 Axis Communications AB
*
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/flashchip.h>
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index e395f642b50a..82fb2a60808f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0001.c,v 1.123 2003/05/28 12:51:48 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.126 2003/06/23 07:45:48 dwmw2 Exp $
*
*
* 10/10/2000 Nicolas Pitre <nico@cam.org>
@@ -936,7 +936,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
struct cfi_private *cfi = map->fldrv_priv;
cfi_word status, status_OK;
unsigned long cmd_adr, timeo;
- int wbufsize, z, ret=0;
+ int wbufsize, z, ret=0, bytes, words;
wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
adr += chip->start;
@@ -995,10 +995,13 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
}
/* Write length of data to come */
- cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr );
+ bytes = len & (CFIDEV_BUSWIDTH-1);
+ words = len / CFIDEV_BUSWIDTH;
+ cfi_write(map, CMD(words - !bytes), cmd_adr );
/* Write data */
- for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {
+ z = 0;
+ while(z < words * CFIDEV_BUSWIDTH) {
if (cfi_buswidth_is_1()) {
map_write8 (map, *((__u8*)buf)++, adr+z);
} else if (cfi_buswidth_is_2()) {
@@ -1011,6 +1014,26 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
ret = -EINVAL;
goto out;
}
+ z += CFIDEV_BUSWIDTH;
+ }
+ if (bytes) {
+ int i = 0, n = 0;
+ u_char tmp_buf[8], *tmp_p = tmp_buf;
+
+ while (bytes--)
+ tmp_buf[i++] = buf[n++];
+ while (i < CFIDEV_BUSWIDTH)
+ tmp_buf[i++] = 0xff;
+ if (cfi_buswidth_is_2()) {
+ map_write16 (map, *((__u16*)tmp_p)++, adr+z);
+ } else if (cfi_buswidth_is_4()) {
+ map_write32 (map, *((__u32*)tmp_p)++, adr+z);
+ } else if (cfi_buswidth_is_8()) {
+ map_write64 (map, *((__u64*)tmp_p)++, adr+z);
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
}
/* GO GO GO */
cfi_write(map, CMD(0xd0), cmd_adr);
@@ -1119,12 +1142,12 @@ static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
}
/* Write buffer is worth it only if more than one word to write... */
- while(len > CFIDEV_BUSWIDTH) {
+ while(len) {
/* We must not cross write block boundaries */
int size = wbufsize - (ofs & (wbufsize-1));
if (size > len)
- size = len & ~(CFIDEV_BUSWIDTH-1);
+ size = len;
ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size);
if (ret)
@@ -1142,17 +1165,6 @@ static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
return 0;
}
}
-
- /* ... and write the remaining bytes */
- if (len > 0) {
- size_t local_retlen;
- ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift),
- len, &local_retlen, buf);
- if (ret)
- return ret;
- (*retlen) += local_retlen;
- }
-
return 0;
}
@@ -1423,6 +1435,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
* with the chip now anyway.
*/
}
+ spin_unlock(chip->mutex);
}
/* Unlock the chips again */
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 7365633bbb89..5cb921d2197a 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2000.c,v 1.52 2003/05/20 21:03:07 dwmw2 Exp $
+ * $Id: doc2000.c,v 1.53 2003/06/11 09:45:19 dwmw2 Exp $
*/
#include <linux/kernel.h>
@@ -553,6 +553,7 @@ static void DoC2k_init(struct mtd_info *mtd)
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0;
mtd->erasesize = 0;
mtd->oobblock = 512;
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 6cd56efbaf5f..25eea68ad774 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001.c,v 1.40 2003/05/20 21:03:07 dwmw2 Exp $
+ * $Id: doc2001.c,v 1.41 2003/06/11 09:45:19 dwmw2 Exp $
*/
#include <linux/kernel.h>
@@ -359,9 +359,10 @@ static void DoCMil_init(struct mtd_info *mtd)
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0;
- /* FIXME: erase size is not always 8kB */
+ /* FIXME: erase size is not always 8KiB */
mtd->erasesize = 0x2000;
mtd->oobblock = 512;
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index dca160a5842e..e5e5fdaeb32d 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -6,7 +6,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001plus.c,v 1.4 2003/05/23 11:28:46 dwmw2 Exp $
+ * $Id: doc2001plus.c,v 1.5 2003/06/11 09:45:19 dwmw2 Exp $
*/
#include <linux/kernel.h>
@@ -458,6 +458,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0;
mtd->erasesize = 0;
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index a2ef3efb88f6..67649391125c 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
/* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.50 2003/05/21 10:49:47 dwmw2 Exp $
+ * $Id: ftl.c,v 1.51 2003/06/23 12:00:08 dwmw2 Exp $
*
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -984,37 +984,20 @@ static int ftl_write(partition_t *part, caddr_t buffer,
return 0;
} /* ftl_write */
-/*======================================================================
-
- IOCTL calls for getting device parameters.
-
-======================================================================*/
-
-static int ftl_ioctl(struct mtd_blktrans_dev *dev, struct inode *inode,
- struct file *file, u_int cmd, u_long arg)
+static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
{
- struct hd_geometry *geo = (struct hd_geometry *)arg;
- partition_t *part = (void *)dev;
- u_long sect;
+ partition_t *part = (void *)dev;
+ u_long sect;
- switch (cmd) {
- case HDIO_GETGEO:
- /* Sort of arbitrary: round size down to 4K boundary */
+ /* Sort of arbitrary: round size down to 4KiB boundary */
sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
- if (put_user(1, (char *)&geo->heads) ||
- put_user(8, (char *)&geo->sectors) ||
- put_user((sect>>3), (short *)&geo->cylinders) ||
- put_user(0, (u_long *)&geo->start))
- return -EFAULT;
-
- case BLKFLSBUF:
- return 0;
- }
- return -ENOTTY;
-} /* ftl_ioctl */
+ geo->heads = 1;
+ geo->sectors = 8;
+ geo->cylinders = sect >> 3;
-/*======================================================================*/
+ return 0;
+}
static int ftl_readsect(struct mtd_blktrans_dev *dev,
unsigned long block, char *buf)
@@ -1102,7 +1085,7 @@ struct mtd_blktrans_ops ftl_tr = {
.part_bits = PART_BITS,
.readsect = ftl_readsect,
.writesect = ftl_writesect,
- .ioctl = ftl_ioctl,
+ .getgeo = ftl_getgeo,
.add_mtd = ftl_add_mtd,
.remove_dev = ftl_remove_dev,
.owner = THIS_MODULE,
@@ -1110,7 +1093,7 @@ struct mtd_blktrans_ops ftl_tr = {
int init_ftl(void)
{
- DEBUG(0, "$Id: ftl.c,v 1.50 2003/05/21 10:49:47 dwmw2 Exp $\n");
+ DEBUG(0, "$Id: ftl.c,v 1.51 2003/06/23 12:00:08 dwmw2 Exp $\n");
return register_mtd_blktrans(&ftl_tr);
}
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index f9e4eca258d8..f12d676f67e1 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -7,7 +7,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* Author: David Woodhouse <dwmw2@infradead.org>
*
- * $Id: inftlcore.c,v 1.9 2003/05/23 11:41:47 dwmw2 Exp $
+ * $Id: inftlcore.c,v 1.11 2003/06/23 12:00:08 dwmw2 Exp $
*
* 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
@@ -113,7 +113,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
(long)inftl->sectors );
}
- if (add_mtd_blktrans_dev) {
+ if (add_mtd_blktrans_dev(&inftl->mbd)) {
if (inftl->PUtable)
kfree(inftl->PUtable);
if (inftl->VUtable)
@@ -835,35 +835,22 @@ foundit:
return 0;
}
-
-static int inftl_ioctl(struct mtd_blktrans_dev *dev,
- struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int inftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
{
struct NFTLrecord *nftl = (void *)dev;
- switch (cmd) {
- case HDIO_GETGEO: {
- struct hd_geometry g;
-
- g.heads = nftl->heads;
- g.sectors = nftl->sectors;
- g.cylinders = nftl->cylinders;
- g.start = 0;
- return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
- }
+ geo->heads = nftl->heads;
+ geo->sectors = nftl->sectors;
+ geo->cylinders = nftl->cylinders;
- default:
- return -ENOTTY;
- }
+ return 0;
}
-
struct mtd_blktrans_ops inftl_tr = {
.name = "inftl",
.major = INFTL_MAJOR,
.part_bits = INFTL_PARTN_BITS,
- .ioctl = inftl_ioctl,
+ .getgeo = inftl_getgeo,
.readsect = inftl_readblock,
.writesect = inftl_writeblock,
.add_mtd = inftl_add_mtd,
@@ -875,7 +862,7 @@ extern char inftlmountrev[];
int __init init_inftl(void)
{
- printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.9 $, "
+ printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.11 $, "
"inftlmount.c %s\n", inftlmountrev);
return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index abe3957c2f9d..042c4eeadf8e 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -8,7 +8,7 @@
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
*
- * $Id: inftlmount.c,v 1.9 2003/05/23 11:35:07 dwmw2 Exp $
+ * $Id: inftlmount.c,v 1.11 2003/06/23 07:39:21 dwmw2 Exp $
*
* 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
@@ -25,7 +25,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define __NO_VERSION__
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/errno.h>
@@ -42,7 +41,7 @@
#include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h>
-char inftlmountrev[]="$Revision: 1.9 $";
+char inftlmountrev[]="$Revision: 1.11 $";
/*
* find_boot_record: Find the INFTL Media Header and its Spare copy which
@@ -242,7 +241,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
}
if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
printk(KERN_WARNING "INFTL: Media Header "
- "Parition %d sanity check failed\n"
+ "Partition %d sanity check failed\n"
" firstUnit %d : lastUnit %d > "
"virtualUnits %d\n", i, ip->lastUnit,
ip->firstUnit, ip->Reserved0);
@@ -250,7 +249,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
}
if (ip->Reserved1 != 0) {
printk(KERN_WARNING "INFTL: Media Header "
- "Parition %d sanity check failed: "
+ "Partition %d sanity check failed: "
"Reserved1 %d != 0\n",
i, ip->Reserved1);
return -1;
@@ -261,7 +260,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
}
if (i >= 4) {
- printk(KERN_WARNING "INFTL: Media Header Parition "
+ printk(KERN_WARNING "INFTL: Media Header Partition "
"sanity check failed:\n No partition "
"marked as Disk Partition\n");
return -1;
@@ -630,7 +629,7 @@ int INFTL_mount(struct INFTLrecord *s)
if (prev_block < s->nb_blocks)
prev_block += s->firstEUN;
- /* Already explored paritial chain? */
+ /* Already explored partial chain? */
if (s->PUtable[block] != BLOCK_NOTEXPLORED) {
/* Check if chain for this logical */
if (logical_block == first_logical_block) {
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index a0fc12a90d92..d73559084fb9 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.11 2003/05/28 15:16:56 dwmw2 Exp $
+# $Id: Kconfig,v 1.12 2003/06/23 07:38:11 dwmw2 Exp $
menu "Mapping drivers for chip access"
depends on MTD!=n
@@ -476,7 +476,7 @@ config MTD_PCMCIA
config MTD_UCLINUX
tristate "Generic uClinux RAM/ROM filesystem support"
- depends on MTD_PARTITIONS
+ depends on MTD_PARTITIONS && !MMU
help
Map driver to support image based filesystems for uClinux.
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 974e7ceb94f8..c111b2d1f4c1 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -1,5 +1,5 @@
/*
- * $Id: arctic-mtd.c,v 1.8 2003/05/21 12:45:17 dwmw2 Exp $
+ * $Id: arctic-mtd.c,v 1.10 2003/06/02 16:37:59 trini Exp $
*
* drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
* IBM 405LP Arctic boards.
@@ -45,18 +45,23 @@
#include <asm/ibm4xx.h>
/*
- * fe000000 -- ff9fffff Arctic FFS (26MB)
- * ffa00000 -- fff5ffff kernel (5.504MB)
- * fff60000 -- ffffffff firmware (640KB)
+ * 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB)
+ * 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB)
+ * 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP)
+ * 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB)
*/
-#define ARCTIC_FFS_SIZE 0x01a00000 /* 26 M */
-#define ARCTIC_FIRMWARE_SIZE 0x000a0000 /* 640K */
+#define FFS1_SIZE 0x01000000 /* 16MiB */
+#define KERNEL_SIZE 0x00500000 /* 5.12MiB */
+#define FFS2_SIZE 0x00a60000 /* 10.624MiB */
+#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */
-#define NAME "Arctic Linux Flash"
-#define PADDR SUBZERO_BOOTFLASH_PADDR
-#define SIZE SUBZERO_BOOTFLASH_SIZE
-#define BUSWIDTH 2
+
+#define NAME "Arctic Linux Flash"
+#define PADDR SUBZERO_BOOTFLASH_PADDR
+#define BUSWIDTH 2
+#define SIZE SUBZERO_BOOTFLASH_SIZE
+#define PARTITIONS 4
/* Flash memories on these boards are memory resources, accessed big-endian. */
@@ -73,17 +78,19 @@ static struct map_info arctic_mtd_map = {
static struct mtd_info *arctic_mtd;
-static struct mtd_partition arctic_partitions[3] = {
- { .name = "Arctic FFS",
- .size = ARCTIC_FFS_SIZE,
+static struct mtd_partition arctic_partitions[PARTITIONS] = {
+ { .name = "Filesystem",
+ .size = FFS1_SIZE,
.offset = 0,},
- { .name = "Kernel",
- .size = SUBZERO_BOOTFLASH_SIZE - ARCTIC_FFS_SIZE -
- ARCTIC_FIRMWARE_SIZE,
- .offset = ARCTIC_FFS_SIZE,},
+ { .name = "Kernel",
+ .size = KERNEL_SIZE,
+ .offset = FFS1_SIZE,},
+ { .name = "Filesystem",
+ .size = FFS2_SIZE,
+ .offset = FFS1_SIZE + KERNEL_SIZE,},
{ .name = "Firmware",
- .size = ARCTIC_FIRMWARE_SIZE,
- .offset = SUBZERO_BOOTFLASH_SIZE - ARCTIC_FIRMWARE_SIZE,},
+ .size = FIRMWARE_SIZE,
+ .offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,},
};
static int __init
@@ -107,7 +114,7 @@ init_arctic_mtd(void)
arctic_mtd->owner = THIS_MODULE;
- return add_mtd_partitions(arctic_mtd, arctic_partitions, 3);
+ return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
}
static void __exit
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index cb28518159b0..00e87e21138a 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -1,5 +1,5 @@
/*
- * $Id: ebony.c,v 1.7 2003/05/21 12:45:18 dwmw2 Exp $
+ * $Id: ebony.c,v 1.8 2003/06/23 11:48:18 dwmw2 Exp $
*
* Mapping for Ebony user flash
*
@@ -60,8 +60,6 @@ static struct mtd_partition ebony_large_partitions[] = {
}
};
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
int __init init_ebony(void)
{
u8 fpga0_reg;
@@ -109,7 +107,7 @@ int __init init_ebony(void)
if (flash) {
flash->owner = THIS_MODULE;
add_mtd_partitions(flash, ebony_small_partitions,
- NB_OF(ebony_small_partitions));
+ ARRAY_SIZE(ebony_small_partitions));
} else {
printk("map probe failed for flash\n");
return -ENXIO;
@@ -131,7 +129,7 @@ int __init init_ebony(void)
if (flash) {
flash->owner = THIS_MODULE;
add_mtd_partitions(flash, ebony_large_partitions,
- NB_OF(ebony_large_partitions));
+ ARRAY_SIZE(ebony_large_partitions));
} else {
printk("map probe failed for flash\n");
return -ENXIO;
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
index 346ae2e4dd95..0ecac2071062 100644
--- a/drivers/mtd/maps/edb7312.c
+++ b/drivers/mtd/maps/edb7312.c
@@ -1,5 +1,5 @@
/*
- * $Id: edb7312.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $
+ * $Id: edb7312.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
*
* Handle mapping of the NOR flash on Cogent EDB7312 boards
*
@@ -67,7 +67,6 @@ static struct mtd_partition static_partitions[3] =
},
};
-#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
#endif
@@ -109,7 +108,7 @@ int __init init_edb7312nor(void)
if (mtd_parts_nb == 0)
{
mtd_parts = static_partitions;
- mtd_parts_nb = NB_OF(static_partitions);
+ mtd_parts_nb = ARRAY_SIZE(static_partitions);
part_type = "static";
}
#endif
diff --git a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
index 6caf4f8f877a..fe0bfe0f18bc 100644
--- a/drivers/mtd/maps/elan-104nc.c
+++ b/drivers/mtd/maps/elan-104nc.c
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- $Id: elan-104nc.c,v 1.17 2003/05/21 15:15:07 dwmw2 Exp $
+ $Id: elan-104nc.c,v 1.18 2003/06/23 07:37:02 dwmw2 Exp $
The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
@@ -223,20 +223,13 @@ static void cleanup_elan_104nc(void)
}
iounmap((void *)iomapadr);
- release_region(PAGE_IO,PAGE_IO_SIZE);
}
int __init init_elan_104nc(void)
{
- /* Urg! We use I/O port 0x22 without request_region()ing it */
- /*
- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
- elan_104nc_map.name,
- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
- return -EAGAIN;
- }
- */
+ /* Urg! We use I/O port 0x22 without request_region()ing it,
+ because it's already allocated to the PIC. */
+
iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
if (!iomapadr) {
printk( KERN_ERR"%s: failed to ioremap memory region\n",
@@ -244,10 +237,6 @@ int __init init_elan_104nc(void)
return -EIO;
}
- /*
- request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" );
- */
-
printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
elan_104nc_map.name,
PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c
index 9c3785aa67c1..fdf0dca3fd16 100644
--- a/drivers/mtd/maps/impa7.c
+++ b/drivers/mtd/maps/impa7.c
@@ -1,5 +1,5 @@
/*
- * $Id: impa7.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $
+ * $Id: impa7.c,v 1.9 2003/06/23 11:47:43 dwmw2 Exp $
*
* Handle mapping of the NOR flash on implementa A7 boards
*
@@ -66,12 +66,11 @@ static struct mtd_partition static_partitions[] =
},
};
-#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
+static int mtd_parts_nb[NUM_FLASHBANKS];
+static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
#endif
-static int mtd_parts_nb = 0;
-static struct mtd_partition *mtd_parts = 0;
static const char *probes[] = { "cmdlinepart", NULL };
int __init init_impa7(void)
@@ -84,7 +83,6 @@ int __init init_impa7(void)
{ WINDOW_ADDR0, WINDOW_SIZE0 },
{ WINDOW_ADDR1, WINDOW_SIZE1 },
};
- char mtdid[10];
int devicesfound = 0;
for(i=0; i<NUM_FLASHBANKS; i++)
@@ -107,42 +105,34 @@ int __init init_impa7(void)
impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]);
}
- if (impa7_mtd[i])
- {
+ if (impa7_mtd[i]) {
impa7_mtd[i]->owner = THIS_MODULE;
- add_mtd_device(impa7_mtd[i]);
devicesfound++;
#ifdef CONFIG_MTD_PARTITIONS
- mtd_parts_nb = parse_mtd_partitions(impa7_mtd[i],
- probes,
- &mtd_parts,
- 0);
- if (mtd_parts_nb > 0)
- part_type = "command line";
-#endif
- if (mtd_parts_nb <= 0)
- {
- mtd_parts = static_partitions;
- mtd_parts_nb = NB_OF(static_partitions);
+ mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
+ probes,
+ &mtd_parts[i],
+ 0);
+ if (mtd_parts_nb[i] > 0) {
+ part_type = "command line";
+ } else {
+ mtd_parts[i] = static_partitions;
+ mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
part_type = "static";
}
- if (mtd_parts_nb <= 0)
- {
- printk(KERN_NOTICE MSG_PREFIX
- "no partition info available\n");
- }
- else
- {
- printk(KERN_NOTICE MSG_PREFIX
- "using %s partition definition\n",
- part_type);
- add_mtd_partitions(impa7_mtd[i],
- mtd_parts, mtd_parts_nb);
- }
+
+ printk(KERN_NOTICE MSG_PREFIX
+ "using %s partition definition\n",
+ part_type);
+ add_mtd_partitions(impa7_mtd[i],
+ mtd_parts[i], mtd_parts_nb[i]);
+#else
+ add_mtd_device(impa7_mtd[i]);
+
#endif
}
else
- iounmap((void *)impa7_map[i].virt);
+ iounmap((void *)impa7_map[i].virt);
}
return devicesfound == 0 ? -ENXIO : 0;
}
@@ -150,15 +140,14 @@ int __init init_impa7(void)
static void __exit cleanup_impa7(void)
{
int i;
- for (i=0; i<NUM_FLASHBANKS; i++)
- {
- if (impa7_mtd[i])
- {
+ for (i=0; i<NUM_FLASHBANKS; i++) {
+ if (impa7_mtd[i]) {
+#ifdef CONFIG_MTD_PARTITIONS
+ del_mtd_partitions(impa7_mtd[i]);
+#else
del_mtd_device(impa7_mtd[i]);
+#endif
map_destroy(impa7_mtd[i]);
- }
- if (impa7_map[i].virt)
- {
iounmap((void *)impa7_map[i].virt);
impa7_map[i].virt = 0;
}
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
index d4eddc54f10b..f0b7b4dabe45 100644
--- a/drivers/mtd/maps/iq80310.c
+++ b/drivers/mtd/maps/iq80310.c
@@ -1,5 +1,5 @@
/*
- * $Id: iq80310.c,v 1.16 2003/05/21 15:15:07 dwmw2 Exp $
+ * $Id: iq80310.c,v 1.17 2003/06/23 11:48:18 dwmw2 Exp $
*
* Mapping for the Intel XScale IQ80310 evaluation board
*
@@ -57,8 +57,6 @@ static struct mtd_partition iq80310_partitions[4] = {
}
};
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
static struct mtd_info *mymtd;
static struct mtd_partition *parsed_parts;
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
@@ -94,7 +92,7 @@ static int __init init_iq80310(void)
nb_parts = parsed_nr_parts;
} else {
parts = iq80310_partitions;
- nb_parts = NB_OF(iq80310_partitions);
+ nb_parts = ARRAY_SIZE(iq80310_partitions);
}
add_mtd_partitions(mymtd, parts, nb_parts);
return 0;
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index facc7e0252f6..602542c15efd 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -1,5 +1,5 @@
/*
- * $Id: lubbock-flash.c,v 1.8 2003/05/21 12:45:19 dwmw2 Exp $
+ * $Id: lubbock-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
*
* Map driver for the Lubbock developer platform.
*
@@ -52,8 +52,6 @@ static struct mtd_partition lubbock_partitions[] = {
}
};
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
static struct mtd_info *mymtds[2];
static struct mtd_partition *parsed_parts[2];
static int nr_parsed_parts[2];
@@ -116,7 +114,7 @@ static int __init init_lubbock(void)
add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]);
} else if (!i) {
printk("Using static partitions on %s\n", lubbock_maps[i].name);
- add_mtd_partitions(mymtds[i], lubbock_partitions, NB_OF(lubbock_partitions));
+ add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions));
} else {
printk("Registering %s as whole device\n", lubbock_maps[i].name);
add_mtd_device(mymtds[i]);
diff --git a/drivers/mtd/maps/pb1xxx-flash.c b/drivers/mtd/maps/pb1xxx-flash.c
index b53795a120dd..713c52b0e729 100644
--- a/drivers/mtd/maps/pb1xxx-flash.c
+++ b/drivers/mtd/maps/pb1xxx-flash.c
@@ -3,7 +3,7 @@
*
* (C) 2001 Pete Popov <ppopov@mvista.com>
*
- * $Id: pb1xxx-flash.c,v 1.8 2003/05/21 12:45:19 dwmw2 Exp $
+ * $Id: pb1xxx-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
*/
#include <linux/config.h>
@@ -131,9 +131,6 @@ static struct mtd_partition pb1xxx_partitions[] = {
#error Unsupported board
#endif
-
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
static struct mtd_partition *parsed_parts;
static struct mtd_info *mymtd;
@@ -151,7 +148,7 @@ int __init pb1xxx_mtd_init(void)
*/
part_type = "static";
parts = pb1xxx_partitions;
- nb_parts = NB_OF(pb1xxx_partitions);
+ nb_parts = ARRAY_SIZE(pb1xxx_partitions);
pb1xxx_map.size = flash_size;
/*
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 1112440fc992..5607a29543cc 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -2,7 +2,7 @@
* Handle mapping of the flash memory access routines
* on TQM8xxL based devices.
*
- * $Id: tqm8xxl.c,v 1.8 2003/05/21 12:45:20 dwmw2 Exp $
+ * $Id: tqm8xxl.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
*
* based on rpxlite.c
*
@@ -110,8 +110,6 @@ static struct mtd_partition tqm8xxl_fs_partitions[] = {
};
#endif
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
int __init init_tqm_mtd(void)
{
int idx = 0, ret = 0;
@@ -198,11 +196,11 @@ int __init init_tqm_mtd(void)
*/
part_banks[0].mtd_part = tqm8xxl_partitions;
part_banks[0].type = "Static image";
- part_banks[0].nums = NB_OF(tqm8xxl_partitions);
+ part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions);
part_banks[1].mtd_part = tqm8xxl_fs_partitions;
part_banks[1].type = "Static file system";
- part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions);
+ part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions);
for(idx = 0; idx < num_banks ; idx++) {
if (part_banks[idx].nums == 0) {
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 0cc4998ba441..3b0c9c469ea3 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtd_blkdevs.c,v 1.12 2003/05/21 01:00:59 dwmw2 Exp $
+ * $Id: mtd_blkdevs.c,v 1.16 2003/06/23 13:34:43 dwmw2 Exp $
*
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
*
@@ -18,8 +18,10 @@
#include <linux/blk.h>
#include <linux/blkpg.h>
#include <linux/spinlock.h>
+#include <linux/hdreg.h>
#include <linux/init.h>
#include <asm/semaphore.h>
+#include <asm/uaccess.h>
#include <linux/devfs_fs_kernel.h>
static LIST_HEAD(blktrans_majors);
@@ -46,7 +48,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
nsect = req->current_nr_sectors;
buf = req->buffer;
- if (!req->flags & REQ_CMD)
+ if (!(req->flags & REQ_CMD))
return 0;
if (block + nsect > get_capacity(req->rq_disk))
@@ -93,14 +95,14 @@ static int mtd_blktrans_thread(void *arg)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
+ spin_lock_irq(rq->queue_lock);
+
while (!tr->blkcore_priv->exiting) {
struct request *req;
struct mtd_blktrans_dev *dev;
int res = 0;
DECLARE_WAITQUEUE(wait, current);
- spin_lock_irq(rq->queue_lock);
-
req = elv_next_request(rq);
if (!req) {
@@ -112,6 +114,8 @@ static int mtd_blktrans_thread(void *arg)
schedule();
remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
+ spin_lock_irq(rq->queue_lock);
+
continue;
}
@@ -159,7 +163,7 @@ int blktrans_open(struct inode *i, struct file *f)
dev->mtd->usecount++;
ret = 0;
- if (tr->open && (ret = tr->open(dev, i, f))) {
+ if (tr->open && (ret = tr->open(dev))) {
dev->mtd->usecount--;
module_put(dev->mtd->owner);
out_tr:
@@ -179,7 +183,7 @@ int blktrans_release(struct inode *i, struct file *f)
tr = dev->tr;
if (tr->release)
- ret = tr->release(dev, i, f);
+ ret = tr->release(dev);
if (!ret) {
dev->mtd->usecount--;
@@ -194,21 +198,33 @@ int blktrans_release(struct inode *i, struct file *f)
static int blktrans_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct mtd_blktrans_dev *dev;
- struct mtd_blktrans_ops *tr;
- int ret = -ENOTTY;
+ struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
+ struct mtd_blktrans_ops *tr = dev->tr;
- dev = inode->i_bdev->bd_disk->private_data;
- tr = dev->tr;
+ switch (cmd) {
+ case BLKFLSBUF:
+ if (tr->flush)
+ return tr->flush(dev);
+ /* The core code did the work, we had nothing to do. */
+ return 0;
- if (tr->ioctl)
- ret = tr->ioctl(dev, inode, file, cmd, arg);
+ case HDIO_GETGEO:
+ if (tr->getgeo) {
+ struct hd_geometry g;
- if (ret == -ENOTTY && (cmd == BLKROSET || cmd == BLKFLSBUF)) {
- /* The core code did the work, we had nothing to do. */
- ret = 0;
+ memset(&g, 0, sizeof(g));
+ int ret = tr->getgeo(dev, &g);
+ if (ret)
+ return ret;
+
+ g.start = get_start_sect(inode->i_bdev);
+ if (copy_to_user((void *)arg, &g, sizeof(g)))
+ return -EFAULT;
+ return 0;
+ } /* else */
+ default:
+ return -ENOTTY;
}
- return ret;
}
struct block_device_operations mtd_blktrans_ops = {
@@ -328,8 +344,6 @@ void blktrans_notify_add(struct mtd_info *mtd)
if (mtd->type == MTD_ABSENT)
return;
- printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count));
-
list_for_each(this, &blktrans_majors) {
struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
@@ -392,8 +406,6 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
INIT_LIST_HEAD(&tr->devs);
list_add(&tr->list, &blktrans_majors);
- printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count));
-
for (i=0; i<MAX_MTD_DEVICES; i++) {
if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
tr->add_mtd(tr, mtd_table[i]);
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index d4dc3b67807a..965c5954d728 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,7 +1,7 @@
/*
* Direct MTD block device access
*
- * $Id: mtdblock.c,v 1.61 2003/05/21 10:49:38 dwmw2 Exp $
+ * $Id: mtdblock.c,v 1.63 2003/06/23 12:00:08 dwmw2 Exp $
*
* (C) 2000-2003 Nicolas Pitre <nico@cam.org>
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
@@ -248,11 +248,19 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
unsigned long block, char *buf)
{
struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
+ if (unlikely(!mtdblk->cache_data)) {
+ mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
+ if (!mtdblk->cache_data)
+ return -EINTR;
+ /* -EINTR is not really correct, but it is the best match
+ * documented in man 2 write for all cases. We could also
+ * return -EAGAIN sometimes, but why bother?
+ */
+ }
return do_cached_write(mtdblk, block<<9, 512, buf);
}
-static int mtdblock_open(struct mtd_blktrans_dev *mbd,
- struct inode *inode, struct file *file)
+static int mtdblock_open(struct mtd_blktrans_dev *mbd)
{
struct mtdblk_dev *mtdblk;
struct mtd_info *mtd = mbd->mtd;
@@ -279,11 +287,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd,
if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
mtdblk->mtd->erasesize) {
mtdblk->cache_size = mtdblk->mtd->erasesize;
- mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
- if (!mtdblk->cache_data) {
- kfree(mtdblk);
- return -ENOMEM;
- }
+ mtdblk->cache_data = NULL;
}
mtdblks[dev] = mtdblk;
@@ -293,17 +297,13 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd,
return 0;
}
-static int mtdblock_release(struct mtd_blktrans_dev *mbd,
- struct inode *inode, struct file *file)
+static int mtdblock_release(struct mtd_blktrans_dev *mbd)
{
- int dev;
- struct mtdblk_dev *mtdblk;
+ int dev = mbd->devnum;
+ struct mtdblk_dev *mtdblk = mtdblks[dev];
DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
- dev = minor(inode->i_rdev);
- mtdblk = mtdblks[dev];
-
down(&mtdblk->cache_sem);
write_cached_data(mtdblk);
up(&mtdblk->cache_sem);
@@ -321,27 +321,17 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd,
return 0;
}
-
-static int mtdblock_ioctl(struct mtd_blktrans_dev *dev,
- struct inode * inode, struct file * file,
- unsigned int cmd, unsigned long arg)
+static int mtdblock_flush(struct mtd_blktrans_dev *dev)
{
- struct mtdblk_dev *mtdblk;
-
- mtdblk = mtdblks[minor(inode->i_rdev)];
+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
- switch (cmd) {
- case BLKFLSBUF:
- down(&mtdblk->cache_sem);
- write_cached_data(mtdblk);
- up(&mtdblk->cache_sem);
- if (mtdblk->mtd->sync)
- mtdblk->mtd->sync(mtdblk->mtd);
- return 0;
+ down(&mtdblk->cache_sem);
+ write_cached_data(mtdblk);
+ up(&mtdblk->cache_sem);
- default:
- return -ENOTTY;
- }
+ if (mtdblk->mtd->sync)
+ mtdblk->mtd->sync(mtdblk->mtd);
+ return 0;
}
static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
@@ -376,7 +366,7 @@ struct mtd_blktrans_ops mtdblock_tr = {
.major = 31,
.part_bits = 0,
.open = mtdblock_open,
- .ioctl = mtdblock_ioctl,
+ .flush = mtdblock_flush,
.release = mtdblock_release,
.readsect = mtdblock_readsect,
.writesect = mtdblock_writesect,
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
index e9133d25f6f2..cdd4ce1df205 100644
--- a/drivers/mtd/mtdblock_ro.c
+++ b/drivers/mtd/mtdblock_ro.c
@@ -1,11 +1,12 @@
/*
- * $Id: mtdblock_ro.c,v 1.17 2003/05/18 19:27:27 dwmw2 Exp $
+ * $Id: mtdblock_ro.c,v 1.18 2003/06/23 12:00:08 dwmw2 Exp $
*
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
*
* Simple read-only (writable only for RAM) mtdblock driver
*/
+#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/blktrans.h>
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index c0095f99d679..460d56f70bec 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,7 +5,7 @@
*
* This code is GPL
*
- * $Id: mtdpart.c,v 1.39 2003/05/21 15:15:03 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.41 2003/06/18 14:53:02 dwmw2 Exp $
*
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob
@@ -120,7 +120,7 @@ static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t le
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
- return part->master->read_user_prot_reg (part->master, from,
+ return part->master->read_fact_prot_reg (part->master, from,
len, retlen, buf);
}
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 5d928bfee613..2c149e94852c 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -6,7 +6,7 @@
* Derived from drivers/mtd/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
*
- * $Id: autcpu12.c,v 1.10 2003/04/20 07:24:40 gleixner Exp $
+ * $Id: autcpu12.c,v 1.11 2003/06/04 17:04:09 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -28,6 +28,7 @@
*/
#include <linux/slab.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index dc11ca9a6f8a..85cee7b17c8c 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -124,9 +124,15 @@
+ a structure, which will be supplied by a filesystem driver
* If NULL is given, then the defaults (none or defaults
* supplied by ioctl (MEMSETOOBSEL) are used.
- * For partitions the partition defaults are used (mtdpart.c)
+ * For partitions the partition defaults are used (mtdpart.c)
+ *
+ * 06-04-2003 tglx: fix compile errors and fix write verify problem for
+ * some chips, which need either a delay between the readback
+ * and the next write command or have the CE removed. The
+ * CE disable/enable is much faster than a 20us delay and
+ * it should work on all available chips.
*
- * $Id: nand.c,v 1.45 2003/05/20 21:01:30 dwmw2 Exp $
+ * $Id: nand.c,v 1.46 2003/06/04 17:10:36 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -141,6 +147,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/compatmac.h>
#include <linux/interrupt.h>
#include <asm/io.h>
@@ -510,6 +517,13 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
}
}
}
+ /*
+ * Terminate the read command. This is faster than sending a reset command or
+ * applying a 20us delay before issuing the next programm sequence.
+ * This is not a problem for all chips, but I have found a bunch of them.
+ */
+ nand_deselect();
+ nand_select();
#endif
return 0;
}
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index 13cd52025caf..ea709d7cf463 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -1,7 +1,7 @@
/* Linux driver for NAND Flash Translation Layer */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@infradead.org> */
-/* $Id: nftlcore.c,v 1.92 2003/05/23 11:41:47 dwmw2 Exp $ */
+/* $Id: nftlcore.c,v 1.94 2003/06/23 12:00:08 dwmw2 Exp $ */
/*
The contents of this file are distributed under the GNU General
@@ -101,7 +101,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
(long)nftl->sectors );
}
- if (add_mtd_blktrans_dev) {
+ if (add_mtd_blktrans_dev(&nftl->mbd)) {
if (nftl->ReplUnitTable)
kfree(nftl->ReplUnitTable);
if (nftl->EUNtable)
@@ -699,29 +699,17 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
return 0;
}
-static int nftl_ioctl(struct mtd_blktrans_dev *dev,
- struct inode * inode, struct file * file,
- unsigned int cmd, unsigned long arg)
+static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
{
struct NFTLrecord *nftl = (void *)dev;
- switch (cmd) {
- case HDIO_GETGEO: {
- struct hd_geometry g;
+ geo->heads = nftl->heads;
+ geo->sectors = nftl->sectors;
+ geo->cylinders = nftl->cylinders;
- g.heads = nftl->heads;
- g.sectors = nftl->sectors;
- g.cylinders = nftl->cylinders;
- g.start = 0;
- return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
- }
-
- default:
- return -ENOTTY;
- }
+ return 0;
}
-
/****************************************************************************
*
* Module stuff
@@ -733,7 +721,7 @@ struct mtd_blktrans_ops nftl_tr = {
.name = "nftl",
.major = NFTL_MAJOR,
.part_bits = NFTL_PARTN_BITS,
- .ioctl = nftl_ioctl,
+ .getgeo = nftl_getgeo,
.readsect = nftl_readblock,
#ifdef CONFIG_NFTL_RW
.writesect = nftl_writeblock,
@@ -747,7 +735,7 @@ extern char nftlmountrev[];
int __init init_nftl(void)
{
- printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.92 $, nftlmount.c %s\n", nftlmountrev);
+ printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.94 $, nftlmount.c %s\n", nftlmountrev);
return register_mtd_blktrans(&nftl_tr);
}
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index dcfb7b403196..140448b42c23 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -53,6 +53,8 @@ Revision History:
2. Bug fix: Fixed VLAN support failure.
3. Bug fix: Fixed receive interrupt coalescing bug.
4. Dynamic IPG support is disabled by default.
+ 3.0.3 06/05/2003
+ 1. Bug fix: Fixed failure to close the interface if SMP is enabled.
*/
@@ -89,9 +91,9 @@ Revision History:
#include "amd8111e.h"
#define MODULE_NAME "amd8111e"
-#define MODULE_VERSION "3.0.2"
+#define MODULE_VERSION "3.0.3"
MODULE_AUTHOR("Advanced Micro Devices, Inc.");
-MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.2");
+MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.3");
MODULE_LICENSE("GPL");
MODULE_PARM(speed_duplex, "1-" __MODULE_STRING (MAX_UNITS) "i");
MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
@@ -1171,11 +1173,11 @@ static int amd8111e_close(struct net_device * dev)
if(lp->options & OPTION_DYN_IPG_ENABLE)
del_timer_sync(&lp->ipg_data.ipg_timer);
- /* Update the statistics before closing */
- amd8111e_get_stats(dev);
spin_unlock_irq(&lp->lock);
-
free_irq(dev->irq, dev);
+
+ /* Update the statistics before closing */
+ amd8111e_get_stats(dev);
lp->opened = 0;
return 0;
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 043d6c783712..9ef8dab49d2f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -390,6 +390,7 @@
#include <linux/timer.h>
#include <linux/socket.h>
#include <linux/ctype.h>
+#include <linux/inet.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
@@ -2792,84 +2793,6 @@ static void activebackup_arp_monitor(struct net_device *master)
mod_timer(&bond->arp_timer, next_timer);
}
-typedef uint32_t in_addr_t;
-
-int
-my_inet_aton(char *cp, unsigned long *the_addr) {
- static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
- in_addr_t val;
- char c;
- union iaddr {
- uint8_t bytes[4];
- uint32_t word;
- } res;
- uint8_t *pp = res.bytes;
- int digit,base;
-
- res.word = 0;
-
- c = *cp;
- for (;;) {
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, isdigit=decimal.
- */
- if (!isdigit(c)) goto ret_0;
- val = 0; base = 10; digit = 0;
- for (;;) {
- if (isdigit(c)) {
- val = (val * base) + (c - '0');
- c = *++cp;
- digit = 1;
- } else {
- break;
- }
- }
- if (c == '.') {
- /*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16 bits)
- * a.b (with b treated as 24 bits)
- */
- if (pp > res.bytes + 2 || val > 0xff) {
- goto ret_0;
- }
- *pp++ = val;
- c = *++cp;
- } else
- break;
- }
- /*
- * Check for trailing characters.
- */
- if (c != '\0' && (!isascii(c) || !isspace(c))) {
- goto ret_0;
- }
- /*
- * Did we get a valid digit?
- */
- if (!digit) {
- goto ret_0;
- }
-
- /* Check whether the last part is in its limits depending on
- the number of parts in total. */
- if (val > max[pp - res.bytes]) {
- goto ret_0;
- }
-
- if (the_addr != NULL) {
- *the_addr = res.word | htonl (val);
- }
-
- return (1);
-
-ret_0:
- return (0);
-}
-
static int bond_sethwaddr(struct net_device *master, struct net_device *slave)
{
#ifdef BONDING_DEBUG
@@ -3877,15 +3800,18 @@ static int __init bonding_init(void)
for (arp_ip_count=0 ;
(arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count];
arp_ip_count++ ) {
- /* TODO: check and log bad ip address */
- if (my_inet_aton(arp_ip_target[arp_ip_count],
- &arp_target[arp_ip_count]) == 0) {
+ /* not complete check, but should be good enough to
+ catch mistakes */
+ if (!isdigit(arp_ip_target[arp_ip_count][0])) {
printk(KERN_WARNING
"bonding_init(): bad arp_ip_target module "
"parameter (%s), ARP monitoring will not be "
"performed\n",
arp_ip_target[arp_ip_count]);
arp_interval = 0;
+ } else {
+ u32 ip = in_aton(arp_ip_target[arp_ip_count]);
+ *(u32 *)(arp_ip_target[arp_ip_count]) = ip;
}
}
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 0842e54df8bd..26ac864936e8 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -376,7 +376,6 @@ static int eppconfig(struct baycom_state *bc)
char portarg[16];
char *argv[] = { eppconfig_path, "-s", "-p", portarg, "-m", modearg,
NULL };
- int ret;
/* set up arguments */
sprintf(modearg, "%sclk,%smodem,fclk=%d,bps=%d,divider=%d%s,extstat",
@@ -1164,7 +1163,6 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr)
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct baycom_state *bc;
- struct baycom_ioctl bi;
struct hdlcdrv_ioctl hi;
baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index ce3bd5f5e30d..e4d961b00eda 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -721,7 +721,7 @@ static irqreturn_t yam_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned char iir;
int counter = 100;
int i;
-
+ int handled = 0;
for (i = 0; i < NR_PORTS; i++) {
yp = &yam_ports[i];
@@ -735,14 +735,17 @@ static irqreturn_t yam_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned char lsr = inb(LSR(dev->base_addr));
unsigned char rxb;
+ handled = 1;
+
if (lsr & LSR_OE)
++yp->stats.rx_fifo_errors;
yp->dcd = (msr & RX_DCD) ? 1 : 0;
if (--counter <= 0) {
- printk(KERN_ERR "%s: too many irq iir=%d\n", dev->name, iir);
- return;
+ printk(KERN_ERR "%s: too many irq iir=%d\n",
+ dev->name, iir);
+ goto out;
}
if (msr & TX_RDY) {
++yp->nb_mdint;
@@ -758,7 +761,8 @@ static irqreturn_t yam_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
}
}
- return IRQ_HANDLED;
+out:
+ return IRQ_RETVAL(handled);
}
static int yam_net_get_info(char *buffer, char **start, off_t offset, int length)
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 3c641e56a3f6..4e0c3d459046 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -50,7 +50,6 @@ ixgb_eeprom_size(struct ixgb_hw *hw)
return (IXGB_EEPROM_SIZE << 1);
}
-#define SUPPORTED_10000baseT_Full (1 << 11)
#define SPEED_10000 10000
static void
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 7f4e64360f15..fdcad85b7cc6 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -766,10 +766,14 @@ static int myri_rebuild_header(struct sk_buff *skb)
int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{
unsigned short type = hh->hh_type;
- unsigned char *pad = (unsigned char *) hh->hh_data;
- struct ethhdr *eth = (struct ethhdr *) (pad + MYRI_PAD_LEN);
+ unsigned char *pad;
+ struct ethhdr *eth;
struct net_device *dev = neigh->dev;
+ pad = ((unsigned char *) hh->hh_data) +
+ HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN);
+ eth = (struct ethhdr *) (pad + MYRI_PAD_LEN);
+
if (type == __constant_htons(ETH_P_802_3))
return -1;
@@ -788,7 +792,8 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
/* Called by Address Resolution module to notify changes in address. */
void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
{
- memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+ memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
+ haddr, dev->addr_len);
}
static int myri_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 81459c1e6fe3..9b8c823f5cc1 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -225,9 +225,7 @@ MODULE_PARM(pc_debug, "i");
#else
#define DEBUG(n, args...)
#endif
-static char *version =
-"xirc2ps_cs.c 1.31 1998/12/09 19:32:55 (dd9jn+kvh)";
- /* !--- CVS revision */
+
#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
#define KWRN_XIRC KERN_WARNING "xirc2ps_cs: "
@@ -358,7 +356,6 @@ static dev_link_t *dev_list;
typedef struct local_info_t {
dev_link_t link;
- struct net_device dev;
dev_node_t node;
struct net_device_stats stats;
int card_type;
@@ -432,22 +429,10 @@ get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
#define PutByte(reg,value) outb((value), ioaddr+(reg))
#define PutWord(reg,value) outw((value), ioaddr+(reg))
-static void
-busy_loop(u_long len)
-{
- if (in_interrupt()) {
- u_long timeout = jiffies + len;
- u_long flags;
- save_flags(flags);
- sti();
- while (time_before_eq(jiffies, timeout))
- ;
- restore_flags(flags);
- } else {
- __set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(len);
- }
-}
+#define Wait(n) do { \
+ set_current_state(TASK_UNINTERRUPTIBLE); \
+ schedule_timeout(n); \
+} while (0)
/*====== Functions used for debugging =================================*/
#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
@@ -619,11 +604,12 @@ xirc2ps_attach(void)
flush_stale_links();
/* Allocate the device structure */
- local = kmalloc(sizeof(*local), GFP_KERNEL);
- if (!local) return NULL;
- memset(local, 0, sizeof(*local));
- link = &local->link; dev = &local->dev;
- link->priv = dev->priv = local;
+ dev = alloc_etherdev(sizeof(local_info_t));
+ if (!dev)
+ return NULL;
+ local = dev->priv;
+ link = &local->link;
+ link->priv = dev;
init_timer(&link->release);
link->release.function = &xirc2ps_release;
@@ -645,7 +631,6 @@ xirc2ps_attach(void)
dev->get_stats = &do_get_stats;
dev->do_ioctl = &do_ioctl;
dev->set_multicast_list = &set_multicast_list;
- ether_setup(dev);
dev->open = &do_open;
dev->stop = &do_stop;
#ifdef HAVE_TX_TIMEOUT
@@ -684,7 +669,7 @@ xirc2ps_attach(void)
static void
xirc2ps_detach(dev_link_t * link)
{
- local_info_t *local = link->priv;
+ struct net_device *dev = link->priv;
dev_link_t **linkp;
DEBUG(0, "detach(0x%p)\n", link);
@@ -706,10 +691,11 @@ xirc2ps_detach(dev_link_t * link)
*/
del_timer(&link->release);
if (link->state & DEV_CONFIG) {
- DEBUG(0, "detach postponed, '%s' still locked\n",
- link->dev->dev_name);
- link->state |= DEV_STALE_LINK;
- return;
+ xirc2ps_release((unsigned long)link);
+ if (link->state & DEV_STALE_CONFIG) {
+ link->state |= DEV_STALE_LINK;
+ return;
+ }
}
/* Break the link with Card Services */
@@ -719,8 +705,8 @@ xirc2ps_detach(dev_link_t * link)
/* Unlink device structure, free it */
*linkp = link->next;
if (link->dev)
- unregister_netdev(&local->dev);
- kfree(local);
+ unregister_netdev(dev);
+ kfree(dev);
} /* xirc2ps_detach */
@@ -745,7 +731,8 @@ xirc2ps_detach(dev_link_t * link)
static int
set_card_type(dev_link_t *link, const void *s)
{
- local_info_t *local = link->priv;
+ struct net_device *dev = link->priv;
+ local_info_t *local = dev->priv;
#ifdef PCMCIA_DEBUG
unsigned cisrev = ((const unsigned char *)s)[2];
#endif
@@ -839,8 +826,8 @@ static void
xirc2ps_config(dev_link_t * link)
{
client_handle_t handle = link->handle;
- local_info_t *local = link->priv;
- struct net_device *dev = &local->dev;
+ struct net_device *dev = link->priv;
+ local_info_t *local = dev->priv;
tuple_t tuple;
cisparse_t parse;
ioaddr_t ioaddr;
@@ -1195,11 +1182,10 @@ static void
xirc2ps_release(u_long arg)
{
dev_link_t *link = (dev_link_t *) arg;
- local_info_t *local = link->priv;
- struct net_device *dev = &local->dev;
DEBUG(0, "release(0x%p)\n", link);
+#if 0
/*
* If the device is currently in use, we won't release until it
* is actually closed.
@@ -1210,8 +1196,10 @@ xirc2ps_release(u_long arg)
link->state |= DEV_STALE_CONFIG;
return;
}
+#endif
if (link->win) {
+ struct net_device *dev = link->priv;
local_info_t *local = dev->priv;
if (local->dingo)
iounmap(local->dingo_ccr - 0x0800);
@@ -1243,8 +1231,7 @@ xirc2ps_event(event_t event, int priority,
event_callback_args_t * args)
{
dev_link_t *link = args->client_data;
- local_info_t *lp = link->priv;
- struct net_device *dev = &lp->dev;
+ struct net_device *dev = link->priv;
DEBUG(0, "event(%d)\n", (int)event);
@@ -1779,12 +1766,12 @@ hardreset(struct net_device *dev)
SelectPage(4);
udelay(1);
PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */
- busy_loop(HZ/25); /* wait 40 msec */
+ Wait(HZ/25); /* wait 40 msec */
if (local->mohawk)
PutByte(XIRCREG4_GPR1, 1); /* set bit 0: power up */
else
PutByte(XIRCREG4_GPR1, 1 | 4); /* set bit 0: power up, bit 2: AIC */
- busy_loop(HZ/50); /* wait 20 msec */
+ Wait(HZ/50); /* wait 20 msec */
}
static void
@@ -1798,9 +1785,9 @@ do_reset(struct net_device *dev, int full)
hardreset(dev);
PutByte(XIRCREG_CR, SoftReset); /* set */
- busy_loop(HZ/50); /* wait 20 msec */
+ Wait(HZ/50); /* wait 20 msec */
PutByte(XIRCREG_CR, 0); /* clear */
- busy_loop(HZ/25); /* wait 40 msec */
+ Wait(HZ/25); /* wait 40 msec */
if (local->mohawk) {
SelectPage(4);
/* set pin GP1 and GP2 to output (0x0c)
@@ -1811,7 +1798,7 @@ do_reset(struct net_device *dev, int full)
}
/* give the circuits some time to power up */
- busy_loop(HZ/2); /* about 500ms */
+ Wait(HZ/2); /* about 500ms */
local->last_ptr_value = 0;
local->silicon = local->mohawk ? (GetByte(XIRCREG4_BOV) & 0x70) >> 4
@@ -1830,7 +1817,7 @@ do_reset(struct net_device *dev, int full)
SelectPage(0x42);
PutByte(XIRCREG42_SWC1, 0x80);
}
- busy_loop(HZ/25); /* wait 40 msec to let it complete */
+ Wait(HZ/25); /* wait 40 msec to let it complete */
#ifdef PCMCIA_DEBUG
if (pc_debug) {
@@ -1889,7 +1876,7 @@ do_reset(struct net_device *dev, int full)
printk(KERN_INFO "%s: MII selected\n", dev->name);
SelectPage(2);
PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08);
- busy_loop(HZ/50);
+ Wait(HZ/50);
} else {
printk(KERN_INFO "%s: MII detected; using 10mbs\n",
dev->name);
@@ -1898,7 +1885,7 @@ do_reset(struct net_device *dev, int full)
PutByte(XIRCREG42_SWC1, 0xC0);
else /* enable 10BaseT */
PutByte(XIRCREG42_SWC1, 0x80);
- busy_loop(HZ/25); /* wait 40 msec to let it complete */
+ Wait(HZ/25); /* wait 40 msec to let it complete */
}
if (full_duplex)
PutByte(XIRCREG1_ECR, GetByte(XIRCREG1_ECR | FullDuplex));
@@ -1991,7 +1978,7 @@ init_mii(struct net_device *dev)
* Fixme: Better to use a timer here!
*/
for (i=0; i < 35; i++) {
- busy_loop(HZ/10); /* wait 100 msec */
+ Wait(HZ/10); /* wait 100 msec */
status = mii_rd(ioaddr, 0, 1);
if ((status & 0x0020) && (status & 0x0004))
break;
@@ -2083,12 +2070,8 @@ exit_xirc2ps_cs(void)
{
pcmcia_unregister_driver(&xirc2ps_cs_driver);
- while (dev_list) {
- if (dev_list->state & DEV_CONFIG)
- xirc2ps_release((u_long)dev_list);
- if (dev_list) /* xirc2ps_release() might already have detached... */
- xirc2ps_detach(dev_list);
- }
+ while (dev_list)
+ xirc2ps_detach(dev_list);
}
module_init(init_xirc2ps_cs);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 6f2e082480fd..ae9491176cfc 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1003,7 +1003,7 @@ pcnet32_init_ring(struct net_device *dev)
skb_reserve (rx_skbuff, 2);
}
- if (lp->rx_dma_addr[i] == NULL)
+ if (lp->rx_dma_addr[i] == 0)
lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE);
lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ);
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index ae3c088214fd..620b5c4223e5 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -1078,7 +1078,10 @@ int plip_hard_header_cache(struct neighbour *neigh,
if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0)
{
- struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2);
+ struct ethhdr *eth;
+
+ eth = (struct ethhdr*)(((u8*)hh->hh_data) +
+ HH_DATA_OFF(sizeof(*eth)));
plip_rewrite_address (neigh->dev, eth);
}
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 3cf67051e965..5edde5924205 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -147,7 +147,6 @@ ppp_asynctty_open(struct tty_struct *tty)
struct asyncppp *ap;
int err;
- MOD_INC_USE_COUNT;
err = -ENOMEM;
ap = kmalloc(sizeof(*ap), GFP_KERNEL);
if (ap == 0)
@@ -183,7 +182,6 @@ ppp_asynctty_open(struct tty_struct *tty)
out_free:
kfree(ap);
out:
- MOD_DEC_USE_COUNT;
return err;
}
@@ -223,7 +221,6 @@ ppp_asynctty_close(struct tty_struct *tty)
if (ap->tpkt != 0)
kfree_skb(ap->tpkt);
kfree(ap);
- MOD_DEC_USE_COUNT;
}
/*
@@ -351,6 +348,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
static struct tty_ldisc ppp_ldisc = {
+ .owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "ppp",
.open = ppp_asynctty_open,
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index f0945464e76e..8b45fc142d6b 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1061,6 +1061,7 @@ static int pppoe_seq_open(struct inode *inode, struct file *file)
}
static struct file_operations pppoe_seq_fops = {
+ .owner = THIS_MODULE,
.open = pppoe_seq_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index f195d355c9fd..b93997955291 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -124,6 +124,7 @@ static struct mii_chip_info {
{ "ICS LAN PHY", 0x0015, 0xF440, LAN },
{ "NS 83851 PHY", 0x2000, 0x5C20, MIX },
{ "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN },
+ { "VIA 6103 PHY", 0x0101, 0x8f20, LAN },
{0,},
};
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 8be319033272..c8c314c6a192 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -980,8 +980,8 @@ static void tx_timeout(struct net_device *dev)
{
int i;
for (i=0; i<TX_RING_SIZE; i++) {
- printk(KERN_DEBUG "%02x %08x %08x %08x(%02x) %08x %08x\n", i,
- np->tx_ring_dma + i*sizeof(*np->tx_ring),
+ printk(KERN_DEBUG "%02x %08Zx %08x %08x(%02x) %08x %08x\n", i,
+ np->tx_ring_dma + i*sizeof(*np->tx_ring),
le32_to_cpu(np->tx_ring[i].next_desc),
le32_to_cpu(np->tx_ring[i].status),
(le32_to_cpu(np->tx_ring[i].status) >> 2) & 0xff,
@@ -1666,7 +1666,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
switch (cmd) {
case SIOCDEVPRIVATE:
for (i=0; i<TX_RING_SIZE; i++) {
- printk(KERN_DEBUG "%02x %08x %08x %08x(%02x) %08x %08x\n", i,
+ printk(KERN_DEBUG "%02x %08Zx %08x %08x(%02x) %08x %08x\n", i,
np->tx_ring_dma + i*sizeof(*np->tx_ring),
le32_to_cpu(np->tx_ring[i].next_desc),
le32_to_cpu(np->tx_ring[i].status),
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index 19b856438012..1c03dba692d8 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -37,7 +37,7 @@ config TULIP
---help---
This driver is developed for the SMC EtherPower series Ethernet
cards and also works with cards based on the DECchip
- 21040/21041/21140 (Tulip series) chips. Some LinkSys PCI cards are
+ 21140 (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
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 035dcbcb970b..ea4b43068b23 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -93,7 +93,11 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
continue;
device_add(&dev->dev);
+
+ spin_lock(&pci_bus_lock);
list_add_tail(&dev->global_list, &pci_devices);
+ spin_unlock(&pci_bus_lock);
+
pci_proc_attach_device(dev);
pci_create_sysfs_dev_files(dev);
@@ -108,7 +112,9 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
* it and then scan for unattached PCI devices.
*/
if (dev->subordinate && list_empty(&dev->subordinate->node)) {
+ spin_lock(&pci_bus_lock);
list_add_tail(&dev->subordinate->node, &dev->bus->children);
+ spin_unlock(&pci_bus_lock);
pci_bus_add_devices(dev->subordinate);
}
}
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index e943e451acb7..3b2ac2a8c080 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -173,6 +173,24 @@ int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
}
EXPORT_SYMBOL(pci_visit_dev);
+static void pci_destroy_dev(struct pci_dev *dev)
+{
+ pci_proc_detach_device(dev);
+ device_unregister(&dev->dev);
+
+ /* Remove the device from the device lists, and prevent any further
+ * list accesses from this device */
+ spin_lock(&pci_bus_lock);
+ list_del(&dev->bus_list);
+ list_del(&dev->global_list);
+ dev->bus_list.next = dev->bus_list.prev = NULL;
+ dev->global_list.next = dev->global_list.prev = NULL;
+ spin_unlock(&pci_bus_lock);
+
+ pci_free_resources(dev);
+ pci_dev_put(dev);
+}
+
/**
* pci_remove_device_safe - remove an unused hotplug device
* @dev: the device to remove
@@ -186,11 +204,7 @@ int pci_remove_device_safe(struct pci_dev *dev)
{
if (pci_dev_driver(dev))
return -EBUSY;
- device_unregister(&dev->dev);
- list_del(&dev->bus_list);
- list_del(&dev->global_list);
- pci_free_resources(dev);
- pci_proc_detach_device(dev);
+ pci_destroy_dev(dev);
return 0;
}
EXPORT_SYMBOL(pci_remove_device_safe);
@@ -237,17 +251,15 @@ void pci_remove_bus_device(struct pci_dev *dev)
pci_remove_behind_bridge(dev);
pci_proc_detach_bus(b);
+ spin_lock(&pci_bus_lock);
list_del(&b->node);
+ spin_unlock(&pci_bus_lock);
+
kfree(b);
dev->subordinate = NULL;
}
- device_unregister(&dev->dev);
- list_del(&dev->bus_list);
- list_del(&dev->global_list);
- pci_free_resources(dev);
- pci_proc_detach_device(dev);
- pci_put_dev(dev);
+ pci_destroy_dev(dev);
}
/**
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 3becefc4024c..247714b9f80e 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -5,8 +5,8 @@
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
+ * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+ * Copyright (c) 2002,2003 NEC Corporation
*
* All rights reserved.
*
@@ -26,8 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <gregkh@us.ibm.com>,
- * <h-aono@ap.jp.nec.com>,
- * <t-kouchi@cq.jp.nec.com>
+ * <t-kochi@bq.jp.nec.com>
*
*/
@@ -35,6 +34,7 @@
#define _ACPIPHP_H
#include <linux/acpi.h>
+#include <linux/kobject.h> /* for KOBJ_NAME_LEN */
#include "pci_hotplug.h"
#define dbg(format, arg...) \
@@ -49,7 +49,7 @@
#define SLOT_MAGIC 0x67267322
/* name size which is used for entries in pcihpfs */
-#define SLOT_NAME_SIZE 32 /* ACPI{_SUN}-{BUS}:{DEV} */
+#define SLOT_NAME_SIZE KOBJ_NAME_LEN /* {_SUN} */
struct acpiphp_bridge;
struct acpiphp_slot;
@@ -212,11 +212,7 @@ struct acpiphp_func {
#define FUNC_HAS_PS2 (0x00000040)
#define FUNC_HAS_PS3 (0x00000080)
-/* not yet */
-#define SLOT_SUPPORT_66MHZ (0x00010000)
-#define SLOT_SUPPORT_100MHZ (0x00020000)
-#define SLOT_SUPPORT_133MHZ (0x00040000)
-#define SLOT_SUPPORT_PCIX (0x00080000)
+#define FUNC_EXISTS (0x10000000) /* to make sure we call _EJ0 only for existing funcs */
/* function prototypes */
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index cffa85dba2c8..b839e6d5e407 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -5,8 +5,8 @@
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
+ * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+ * Copyright (c) 2002,2003 NEC Corporation
*
* All rights reserved.
*
@@ -26,8 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <gregkh@us.ibm.com>,
- * <h-aono@ap.jp.nec.com>,
- * <t-kouchi@cq.jp.nec.com>
+ * <t-kochi@bq.jp.nec.com>
*
*/
@@ -57,7 +56,7 @@ int acpiphp_debug;
static int num_slots;
#define DRIVER_VERSION "0.4"
-#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kouchi@cq.jp.nec.com>"
+#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -376,10 +375,8 @@ static int init_acpi (void)
*/
static void make_slot_name (struct slot *slot)
{
- snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "ACPI%d-%02x:%02x",
- slot->acpi_slot->sun,
- slot->acpi_slot->bridge->bus,
- slot->acpi_slot->device);
+ snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%u",
+ slot->acpi_slot->sun);
}
/**
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 9ab2cda79548..3af6ad4adbe7 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1,9 +1,9 @@
/*
* ACPI PCI HotPlug glue functions to ACPI CA subsystem
*
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
+ * Copyright (c) 2002,2003 NEC Corporation
*
* All rights reserved.
*
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Send feedback to <t-kouchi@cq.jp.nec.com>
+ * Send feedback to <t-kochi@bq.jp.nec.com>
*
*/
@@ -204,7 +204,6 @@ register_slot (acpi_handle handle, u32 lvl, void *context, void **rv)
if (ACPI_FAILURE(status)) {
err("failed to register interrupt notify handler\n");
- kfree(newfunc);
return status;
}
@@ -617,9 +616,8 @@ find_p2p_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
/* find hot-pluggable slots, and then find P2P bridge */
-static int add_bridges(struct acpi_device *device)
+static int add_bridge(acpi_handle handle)
{
- acpi_handle *handle = device->handle;
acpi_status status;
unsigned long tmp;
int seg, bus;
@@ -673,6 +671,12 @@ static int add_bridges(struct acpi_device *device)
}
+static void remove_bridge (acpi_handle handle)
+{
+ /* No-op for now .. */
+}
+
+
static int power_on_slot (struct acpiphp_slot *slot)
{
acpi_status status;
@@ -725,9 +729,7 @@ static int power_off_slot (struct acpiphp_slot *slot)
list_for_each (l, &slot->funcs) {
func = list_entry(l, struct acpiphp_func, sibling);
- if (func->flags & FUNC_HAS_PS3) {
- dbg("%s: executing _PS3 on %s\n", __FUNCTION__,
- func->pci_dev->slot_name);
+ if (func->flags & (FUNC_HAS_PS3 | FUNC_EXISTS)) {
status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
if (ACPI_FAILURE(status)) {
warn("%s: _PS3 failed\n", __FUNCTION__);
@@ -740,10 +742,8 @@ static int power_off_slot (struct acpiphp_slot *slot)
list_for_each (l, &slot->funcs) {
func = list_entry(l, struct acpiphp_func, sibling);
- if (func->flags & FUNC_HAS_EJ0) {
- dbg("%s: executing _EJ0 on %s\n", __FUNCTION__,
- func->pci_dev->slot_name);
-
+ /* We don't want to call _EJ0 on non-existing functions. */
+ if (func->flags & (FUNC_HAS_EJ0 | FUNC_EXISTS)) {
/* _EJ0 method take one argument */
arg_list.count = 1;
arg_list.pointer = &arg;
@@ -756,6 +756,7 @@ static int power_off_slot (struct acpiphp_slot *slot)
retval = -1;
goto err_exit;
}
+ func->flags &= (~FUNC_EXISTS);
}
}
@@ -835,6 +836,8 @@ static int enable_device (struct acpiphp_slot *slot)
retval = acpiphp_configure_function(func);
if (retval)
goto err_exit;
+
+ func->flags |= FUNC_EXISTS;
}
slot->flags |= SLOT_ENABLED;
@@ -1029,13 +1032,10 @@ static void handle_hotplug_event_func (acpi_handle handle, u32 type, void *conte
}
}
-static struct acpi_driver acpi_pci_hp_driver = {
- .name = "pci_hp",
- .class = "",
- .ids = ACPI_PCI_HOST_HID,
- .ops = {
- .add = add_bridges,
- }
+
+static struct acpi_pci_driver acpi_pci_hp_driver = {
+ .add = add_bridge,
+ .remove = remove_bridge,
};
/**
@@ -1044,17 +1044,15 @@ static struct acpi_driver acpi_pci_hp_driver = {
*/
int acpiphp_glue_init (void)
{
- acpi_status status;
+ int num;
if (list_empty(&pci_root_buses))
return -1;
- status = acpi_bus_register_driver(&acpi_pci_hp_driver);
+ num = acpi_pci_register_driver(&acpi_pci_hp_driver);
- if (ACPI_FAILURE(status)) {
- err("%s: acpi_walk_namespace() failed\n", __FUNCTION__);
+ if (num <= 0)
return -1;
- }
return 0;
}
@@ -1296,7 +1294,7 @@ u8 acpiphp_get_power_status (struct acpiphp_slot *slot)
/*
* attention LED ON: 1
- * OFF: 0
+ * OFF: 0
*
* TBD
* no direct attention led status information via ACPI
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
index 6ebbb975d6f7..529f170a235f 100644
--- a/drivers/pci/hotplug/acpiphp_pci.c
+++ b/drivers/pci/hotplug/acpiphp_pci.c
@@ -4,7 +4,7 @@
* Copyright (c) 1995,2001 Compaq Computer Corporation
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001,2002 IBM Corp.
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
*
@@ -25,7 +25,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Send feedback to <t-kouchi@cq.jp.nec.com>
+ * Send feedback to <t-kochi@bq.jp.nec.com>
*
*/
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
index ea79c3c32b18..5ed1036617c1 100644
--- a/drivers/pci/hotplug/acpiphp_res.c
+++ b/drivers/pci/hotplug/acpiphp_res.c
@@ -5,7 +5,7 @@
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
*
* All rights reserved.
@@ -25,7 +25,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Send feedback to <gregkh@us.ibm.com>,<h-aono@ap.jp.nec.com>
+ * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
*
*/
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index dde99a9f3e3d..d7f601cdde3f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -138,10 +138,10 @@ static int pci_device_probe(struct device * dev)
drv = to_pci_driver(dev->driver);
pci_dev = to_pci_dev(dev);
- pci_get_dev(pci_dev);
+ pci_dev_get(pci_dev);
error = __pci_device_probe(drv, pci_dev);
if (error)
- pci_put_dev(pci_dev);
+ pci_dev_put(pci_dev);
return error;
}
@@ -156,7 +156,7 @@ static int pci_device_remove(struct device * dev)
drv->remove(pci_dev);
pci_dev->driver = NULL;
}
- pci_put_dev(pci_dev);
+ pci_dev_put(pci_dev);
return 0;
}
@@ -448,18 +448,18 @@ static int pci_bus_match(struct device * dev, struct device_driver * drv)
}
/**
- * pci_get_dev - increments the reference count of the pci device structure
+ * pci_dev_get - increments the reference count of the pci device structure
* @dev: the device being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for PCI devices should normally record such references in
* their probe() methods, when they bind to a device, and release
- * them by calling pci_put_dev(), in their disconnect() methods.
+ * them by calling pci_dev_put(), in their disconnect() methods.
*
* A pointer to the device with the incremented reference counter is returned.
*/
-struct pci_dev *pci_get_dev (struct pci_dev *dev)
+struct pci_dev *pci_dev_get(struct pci_dev *dev)
{
struct device *tmp;
@@ -474,13 +474,13 @@ struct pci_dev *pci_get_dev (struct pci_dev *dev)
}
/**
- * pci_put_dev - release a use of the pci device structure
+ * pci_dev_put - release a use of the pci device structure
* @dev: device that's been disconnected
*
* Must be called when a user of a device is finished with it. When the last
* user of the device calls this function, the memory of the device is freed.
*/
-void pci_put_dev(struct pci_dev *dev)
+void pci_dev_put(struct pci_dev *dev)
{
if (dev)
put_device(&dev->dev);
@@ -504,5 +504,5 @@ EXPORT_SYMBOL(pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);
EXPORT_SYMBOL(pci_dev_driver);
EXPORT_SYMBOL(pci_bus_type);
-EXPORT_SYMBOL(pci_get_dev);
-EXPORT_SYMBOL(pci_put_dev);
+EXPORT_SYMBOL(pci_dev_get);
+EXPORT_SYMBOL(pci_dev_put);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 4d33ee733b5b..4e13d7141b78 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -18,12 +18,6 @@
#include "pci.h"
-#if BITS_PER_LONG == 32
-#define LONG_FORMAT "\t%08lx"
-#else
-#define LONG_FORMAT "\t%16lx"
-#endif
-
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
@@ -36,11 +30,11 @@ show_##field (struct device *dev, char *buf) \
} \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
-pci_config_attr(vendor, "%04x\n");
-pci_config_attr(device, "%04x\n");
-pci_config_attr(subsystem_vendor, "%04x\n");
-pci_config_attr(subsystem_device, "%04x\n");
-pci_config_attr(class, "%06x\n");
+pci_config_attr(vendor, "0x%04x\n");
+pci_config_attr(device, "0x%04x\n");
+pci_config_attr(subsystem_vendor, "0x%04x\n");
+pci_config_attr(subsystem_device, "0x%04x\n");
+pci_config_attr(class, "0x%06x\n");
pci_config_attr(irq, "%u\n");
/* show resources */
@@ -50,9 +44,13 @@ pci_show_resources(struct device * dev, char * buf)
struct pci_dev * pci_dev = to_pci_dev(dev);
char * str = buf;
int i;
+ int max = 7;
+
+ if (pci_dev->subordinate)
+ max = DEVICE_COUNT_RESOURCE;
- for (i = 0; i < DEVICE_COUNT_RESOURCE && pci_resource_start(pci_dev,i); i++) {
- str += sprintf(str,LONG_FORMAT LONG_FORMAT LONG_FORMAT "\n",
+ for (i = 0; i < max; i++) {
+ str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",
pci_resource_start(pci_dev,i),
pci_resource_end(pci_dev,i),
pci_resource_flags(pci_dev,i));
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 69b2fff6f655..3288e401d914 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -58,3 +58,6 @@ struct pci_visit {
extern int pci_visit_dev(struct pci_visit *fn,
struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent);
+
+/* Lock for read/write access to pci device and bus lists */
+extern spinlock_t pci_bus_lock;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 42f8a6d92228..ee71590f89ca 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -524,7 +524,7 @@ pci_scan_device(struct pci_bus *bus, int devfn)
}
device_initialize(&dev->dev);
dev->dev.release = pci_release_dev;
- pci_get_dev(dev);
+ pci_dev_get(dev);
pci_name_device(dev);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 0073b58e823a..e576e7a62a13 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -308,39 +308,45 @@ static struct file_operations proc_bus_pci_operations = {
/* iterator */
static void *pci_seq_start(struct seq_file *m, loff_t *pos)
{
- struct list_head *p = &pci_devices;
+ struct pci_dev *dev = NULL;
loff_t n = *pos;
- /* XXX: surely we need some locking for traversing the list? */
+ dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
while (n--) {
- p = p->next;
- if (p == &pci_devices)
- return NULL;
+ dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+ if (dev == NULL)
+ goto exit;
}
- return p;
+exit:
+ return dev;
}
+
static void *pci_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
- struct list_head *p = v;
+ struct pci_dev *dev = v;
+
(*pos)++;
- return p->next != &pci_devices ? (void *)p->next : NULL;
+ dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+ return dev;
}
+
static void pci_seq_stop(struct seq_file *m, void *v)
{
- /* release whatever locks we need */
+ if (v) {
+ struct pci_dev *dev = v;
+ pci_dev_put(dev);
+ }
}
static int show_device(struct seq_file *m, void *v)
{
- struct list_head *p = v;
- const struct pci_dev *dev;
+ const struct pci_dev *dev = v;
const struct pci_driver *drv;
int i;
- if (p == &pci_devices)
+ if (dev == NULL)
return 0;
- dev = pci_dev_g(p);
drv = pci_dev_driver(dev);
seq_printf(m, "%02x%02x\t%04x%04x\t%x",
dev->bus->number,
@@ -383,7 +389,8 @@ int pci_proc_attach_device(struct pci_dev *dev)
return -EACCES;
if (!(de = bus->procdir)) {
- sprintf(name, "%02x", bus->number);
+ if (pci_name_bus(name, bus))
+ return -EEXIST;
de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
if (!de)
return -ENOMEM;
@@ -451,19 +458,18 @@ int pci_proc_detach_bus(struct pci_bus* bus)
*/
static int show_dev_config(struct seq_file *m, void *v)
{
- struct list_head *p = v;
- struct pci_dev *dev;
+ struct pci_dev *dev = v;
+ struct pci_dev *first_dev;
struct pci_driver *drv;
u32 class_rev;
unsigned char latency, min_gnt, max_lat, *class;
int reg;
- if (p == &pci_devices) {
+ first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ if (dev == first_dev)
seq_puts(m, "PCI devices found:\n");
- return 0;
- }
+ pci_dev_put(first_dev);
- dev = pci_dev_g(p);
drv = pci_dev_driver(dev);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ce1b710e0884..7bfbb30f94dc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -690,6 +690,9 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
if ((dev->device == PCI_DEVICE_ID_INTEL_82850_HB) &&
(dev->subsystem_device == 0x8030)) /* P4T533 */
asus_hides_smbus = 1;
+ if ((dev->device == PCI_DEVICE_ID_INTEL_7205_0) &&
+ (dev->subsystem_device == 0x8070)) /* P4G8X Deluxe */
+ asus_hides_smbus = 1;
return;
}
@@ -838,6 +841,7 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc },
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index c7b30f9b8a52..85c74126ee6a 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -1,6 +1,17 @@
+/*
+ * PCI searching functions.
+ *
+ * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
+ * David Mosberger-Tang
+ * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz>
+ * Copyright 2003 -- Greg Kroah-Hartman <greg@kroah.com>
+ */
+
#include <linux/pci.h>
#include <linux/module.h>
+spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
+
static struct pci_bus *
pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
{
@@ -52,11 +63,15 @@ pci_find_bus(unsigned char busnr)
struct pci_bus *
pci_find_next_bus(const struct pci_bus *from)
{
- struct list_head *n = from ? from->node.next : pci_root_buses.next;
+ struct list_head *n;
struct pci_bus *b = NULL;
+ WARN_ON(irqs_disabled());
+ spin_lock(&pci_bus_lock);
+ n = from ? from->node.next : pci_root_buses.next;
if (n != &pci_root_buses)
b = pci_bus_b(n);
+ spin_unlock(&pci_bus_lock);
return b;
}
@@ -97,24 +112,36 @@ pci_find_slot(unsigned int bus, unsigned int devfn)
* device structure is returned. Otherwise, %NULL is returned.
* A new search is initiated by passing %NULL to the @from argument.
* Otherwise if @from is not %NULL, searches continue from next device on the global list.
+ *
+ * NOTE: Do not use this function anymore, use pci_get_subsys() instead, as
+ * the pci device returned by this function can disappear at any moment in
+ * time.
*/
struct pci_dev *
pci_find_subsys(unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device,
const struct pci_dev *from)
{
- struct list_head *n = from ? from->global_list.next : pci_devices.next;
+ struct list_head *n;
+ struct pci_dev *dev;
+
+ WARN_ON(irqs_disabled());
+ spin_lock(&pci_bus_lock);
+ n = from ? from->global_list.next : pci_devices.next;
- while (n != &pci_devices) {
- struct pci_dev *dev = pci_dev_g(n);
+ while (n && (n != &pci_devices)) {
+ dev = pci_dev_g(n);
if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
(device == PCI_ANY_ID || dev->device == device) &&
(ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
(ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
- return dev;
+ goto exit;
n = n->next;
}
- return NULL;
+ dev = NULL;
+exit:
+ spin_unlock(&pci_bus_lock);
+ return dev;
}
/**
@@ -128,6 +155,10 @@ pci_find_subsys(unsigned int vendor, unsigned int device,
* returned. Otherwise, %NULL is returned.
* A new search is initiated by passing %NULL to the @from argument.
* Otherwise if @from is not %NULL, searches continue from next device on the global list.
+ *
+ * NOTE: Do not use this function anymore, use pci_get_device() instead, as
+ * the pci device returned by this function can disappear at any moment in
+ * time.
*/
struct pci_dev *
pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
@@ -135,6 +166,77 @@ pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *
return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
}
+/**
+ * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
+ * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
+ * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
+ * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
+ * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
+ * @from: Previous PCI device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI devices. If a PCI device is
+ * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
+ * device structure is returned, and the reference count to the device is
+ * incremented. Otherwise, %NULL is returned. A new search is initiated by
+ * passing %NULL to the @from argument. Otherwise if @from is not %NULL,
+ * searches continue from next device on the global list.
+ * The reference count for @from is always decremented if it is not %NULL.
+ */
+struct pci_dev *
+pci_get_subsys(unsigned int vendor, unsigned int device,
+ unsigned int ss_vendor, unsigned int ss_device,
+ struct pci_dev *from)
+{
+ struct list_head *n;
+ struct pci_dev *dev;
+
+ WARN_ON(irqs_disabled());
+ spin_lock(&pci_bus_lock);
+ n = from ? from->global_list.next : pci_devices.next;
+
+ while (n && (n != &pci_devices)) {
+ dev = pci_dev_g(n);
+ if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
+ (device == PCI_ANY_ID || dev->device == device) &&
+ (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
+ (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
+ goto exit;
+ n = n->next;
+ }
+ dev = NULL;
+exit:
+ pci_dev_put(from);
+ dev = pci_dev_get(dev);
+ spin_unlock(&pci_bus_lock);
+ return dev;
+}
+
+/**
+ * pci_get_device - begin or continue searching for a PCI device by vendor/device id
+ * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
+ * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
+ * @from: Previous PCI device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI devices. If a PCI device is
+ * found with a matching @vendor and @device, a pointer to its device structure is
+ * returned. Otherwise, %NULL is returned.
+ * A new search is initiated by passing %NULL to the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device on the global list.
+ *
+ * Iterates through the list of known PCI devices. If a PCI device is
+ * found with a matching @vendor and @device, the reference count to the
+ * device is incremented and a pointer to its device structure is returned.
+ * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
+ * to the @from argument. Otherwise if @from is not %NULL, searches continue
+ * from next device on the global list. The reference count for @from is
+ * always decremented if it is not %NULL.
+ */
+struct pci_dev *
+pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
+{
+ return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
+}
+
/**
* pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id
@@ -151,16 +253,24 @@ pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *
struct pci_dev *
pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from)
{
- struct list_head *n = from ? from->global_list.prev : pci_devices.prev;
+ struct list_head *n;
+ struct pci_dev *dev;
- while (n != &pci_devices) {
- struct pci_dev *dev = pci_dev_g(n);
+ WARN_ON(irqs_disabled());
+ spin_lock(&pci_bus_lock);
+ n = from ? from->global_list.prev : pci_devices.prev;
+
+ while (n && (n != &pci_devices)) {
+ dev = pci_dev_g(n);
if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
(device == PCI_ANY_ID || dev->device == device))
- return dev;
+ goto exit;
n = n->prev;
}
- return NULL;
+ dev = NULL;
+exit:
+ spin_unlock(&pci_bus_lock);
+ return dev;
}
@@ -179,15 +289,22 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p
struct pci_dev *
pci_find_class(unsigned int class, const struct pci_dev *from)
{
- struct list_head *n = from ? from->global_list.next : pci_devices.next;
+ struct list_head *n;
+ struct pci_dev *dev;
- while (n != &pci_devices) {
- struct pci_dev *dev = pci_dev_g(n);
+ spin_lock(&pci_bus_lock);
+ n = from ? from->global_list.next : pci_devices.next;
+
+ while (n && (n != &pci_devices)) {
+ dev = pci_dev_g(n);
if (dev->class == class)
- return dev;
+ goto exit;
n = n->next;
}
- return NULL;
+ dev = NULL;
+exit:
+ spin_unlock(&pci_bus_lock);
+ return dev;
}
EXPORT_SYMBOL(pci_find_bus);
@@ -196,3 +313,5 @@ EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_device_reverse);
EXPORT_SYMBOL(pci_find_slot);
EXPORT_SYMBOL(pci_find_subsys);
+EXPORT_SYMBOL(pci_get_device);
+EXPORT_SYMBOL(pci_get_subsys);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 04e800fff4bb..4f3c73172287 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1471,6 +1471,10 @@ static int __init init_i82365(void)
pcmcia_unregister_socket(&socket[i].socket);
break;
}
+ class_device_create_file(&socket[i].socket.dev,
+ &class_device_attr_info);
+ class_device_create_file(&socket[i].socket.dev,
+ &class_device_attr_exca);
}
/* Finally, schedule a polling interrupt */
@@ -1481,9 +1485,6 @@ static int __init init_i82365(void)
poll_timer.expires = jiffies + poll_interval;
add_timer(&poll_timer);
}
-
- class_device_create_file(&socket[i].socket.dev, &class_device_attr_info);
- class_device_create_file(&socket[i].socket.dev, &class_device_attr_exca);
return 0;
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index e991aa70220e..d479e099b259 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -4,29 +4,11 @@ void *pnp_alloc(long size);
int pnp_interface_attach_device(struct pnp_dev *dev);
void pnp_name_device(struct pnp_dev *dev);
void pnp_fixup_device(struct pnp_dev *dev);
-void pnp_free_resources(struct pnp_resources *resources);
+void pnp_free_option(struct pnp_option *option);
int __pnp_add_device(struct pnp_dev *dev);
void __pnp_remove_device(struct pnp_dev *dev);
-/* resource conflict types */
-#define CONFLICT_TYPE_NONE 0x0000 /* there are no conflicts, other than those in the link */
-#define CONFLICT_TYPE_RESERVED 0x0001 /* the resource requested was reserved */
-#define CONFLICT_TYPE_IN_USE 0x0002 /* there is a conflict because the resource is in use */
-#define CONFLICT_TYPE_PCI 0x0004 /* there is a conflict with a pci device */
-#define CONFLICT_TYPE_INVALID 0x0008 /* the resource requested is invalid */
-#define CONFLICT_TYPE_INTERNAL 0x0010 /* resources within the device conflict with each ohter */
-#define CONFLICT_TYPE_PNP_WARM 0x0020 /* there is a conflict with a pnp device that is active */
-#define CONFLICT_TYPE_PNP_COLD 0x0040 /* there is a conflict with a pnp device that is disabled */
-
-/* conflict search modes */
-#define SEARCH_WARM 1 /* check for conflicts with active devices */
-#define SEARCH_COLD 0 /* check for conflicts with disabled devices */
-
-struct pnp_dev * pnp_check_port_conflicts(struct pnp_dev * dev, int idx, int mode);
int pnp_check_port(struct pnp_dev * dev, int idx);
-struct pnp_dev * pnp_check_mem_conflicts(struct pnp_dev * dev, int idx, int mode);
int pnp_check_mem(struct pnp_dev * dev, int idx);
-struct pnp_dev * pnp_check_irq_conflicts(struct pnp_dev * dev, int idx, int mode);
int pnp_check_irq(struct pnp_dev * dev, int idx);
-struct pnp_dev * pnp_check_dma_conflicts(struct pnp_dev * dev, int idx, int mode);
int pnp_check_dma(struct pnp_dev * dev, int idx);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 7ca8de1a140f..313604dba12a 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -104,8 +104,8 @@ static void pnp_free_ids(struct pnp_dev *dev)
static void pnp_release_device(struct device *dmdev)
{
struct pnp_dev * dev = to_pnp_dev(dmdev);
- if (dev->possible)
- pnp_free_resources(dev->possible);
+ pnp_free_option(dev->independent);
+ pnp_free_option(dev->dependent);
pnp_free_ids(dev);
kfree(dev);
}
@@ -122,7 +122,7 @@ int __pnp_add_device(struct pnp_dev *dev)
list_add_tail(&dev->global_list, &pnp_global);
list_add_tail(&dev->protocol_list, &dev->protocol->devices);
spin_unlock(&pnp_lock);
- pnp_auto_config_dev(dev);
+
ret = device_register(&dev->dev);
if (ret == 0)
pnp_interface_attach_device(dev);
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 00f4f9463e96..5ce57358df3b 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -168,7 +168,8 @@ static void pnp_print_mem(pnp_info_buffer_t *buffer, char *space, struct pnp_mem
pnp_printf(buffer, ", %s\n", s);
}
-static void pnp_print_resources(pnp_info_buffer_t *buffer, char *space, struct pnp_resources *res, int dep)
+static void pnp_print_option(pnp_info_buffer_t *buffer, char *space,
+ struct pnp_option *option, int dep)
{
char *s;
struct pnp_port *port;
@@ -176,49 +177,55 @@ static void pnp_print_resources(pnp_info_buffer_t *buffer, char *space, struct p
struct pnp_dma *dma;
struct pnp_mem *mem;
- switch (res->priority) {
- case PNP_RES_PRIORITY_PREFERRED:
- s = "preferred";
- break;
- case PNP_RES_PRIORITY_ACCEPTABLE:
- s = "acceptable";
- break;
- case PNP_RES_PRIORITY_FUNCTIONAL:
- s = "functional";
- break;
- default:
- s = "invalid";
- }
- if (dep > 0)
+ if (dep) {
+ switch (option->priority) {
+ case PNP_RES_PRIORITY_PREFERRED:
+ s = "preferred";
+ break;
+ case PNP_RES_PRIORITY_ACCEPTABLE:
+ s = "acceptable";
+ break;
+ case PNP_RES_PRIORITY_FUNCTIONAL:
+ s = "functional";
+ break;
+ default:
+ s = "invalid";
+ }
pnp_printf(buffer, "Dependent: %02i - Priority %s\n",dep, s);
- for (port = res->port; port; port = port->next)
+ }
+
+ for (port = option->port; port; port = port->next)
pnp_print_port(buffer, space, port);
- for (irq = res->irq; irq; irq = irq->next)
+ for (irq = option->irq; irq; irq = irq->next)
pnp_print_irq(buffer, space, irq);
- for (dma = res->dma; dma; dma = dma->next)
+ for (dma = option->dma; dma; dma = dma->next)
pnp_print_dma(buffer, space, dma);
- for (mem = res->mem; mem; mem = mem->next)
+ for (mem = option->mem; mem; mem = mem->next)
pnp_print_mem(buffer, space, mem);
}
-static ssize_t pnp_show_possible_resources(struct device *dmdev, char *buf)
+
+static ssize_t pnp_show_options(struct device *dmdev, char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
- struct pnp_resources * res = dev->possible;
- int ret, dep = 0;
+ struct pnp_option * independent = dev->independent;
+ struct pnp_option * dependent = dev->dependent;
+ int ret, dep = 1;
+
pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer)
return -ENOMEM;
+
buffer->len = PAGE_SIZE;
buffer->buffer = buf;
buffer->curr = buffer->buffer;
- while (res){
- if (dep == 0)
- pnp_print_resources(buffer, "", res, dep);
- else
- pnp_print_resources(buffer, " ", res, dep);
- res = res->dep;
+ if (independent)
+ pnp_print_option(buffer, "", independent, 0);
+
+ while (dependent){
+ pnp_print_option(buffer, " ", dependent, dep);
+ dependent = dependent->next;
dep++;
}
ret = (buffer->curr - buf);
@@ -226,97 +233,8 @@ static ssize_t pnp_show_possible_resources(struct device *dmdev, char *buf)
return ret;
}
-static DEVICE_ATTR(possible,S_IRUGO,pnp_show_possible_resources,NULL);
-
-static void pnp_print_conflict_node(pnp_info_buffer_t *buffer, struct pnp_dev * dev)
-{
- if (!dev)
- return;
- pnp_printf(buffer, "'%s'.\n", dev->dev.bus_id);
-}
-
-static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict)
-{
- if (!conflict)
- return;
- pnp_printf(buffer, " Conflict Detected: %2x - ", conflict);
- switch (conflict) {
- case CONFLICT_TYPE_RESERVED:
- pnp_printf(buffer, "manually reserved.\n");
- break;
-
- case CONFLICT_TYPE_IN_USE:
- pnp_printf(buffer, "currently in use.\n");
- break;
-
- case CONFLICT_TYPE_PCI:
- pnp_printf(buffer, "PCI device.\n");
- break;
-
- case CONFLICT_TYPE_INVALID:
- pnp_printf(buffer, "invalid.\n");
- break;
-
- case CONFLICT_TYPE_INTERNAL:
- pnp_printf(buffer, "another resource on this device.\n");
- break;
-
- case CONFLICT_TYPE_PNP_WARM:
- pnp_printf(buffer, "active PnP device ");
- break;
-
- case CONFLICT_TYPE_PNP_COLD:
- pnp_printf(buffer, "disabled PnP device ");
- break;
- default:
- pnp_printf(buffer, "Unknown conflict.\n");
- break;
- }
-}
-
-static void pnp_print_conflict(pnp_info_buffer_t *buffer, struct pnp_dev * dev, int idx, int type)
-{
- struct pnp_dev * cdev, * wdev = NULL;
- int conflict;
- switch (type) {
- case IORESOURCE_IO:
- conflict = pnp_check_port(dev, idx);
- if (conflict == CONFLICT_TYPE_PNP_WARM)
- wdev = pnp_check_port_conflicts(dev, idx, SEARCH_WARM);
- cdev = pnp_check_port_conflicts(dev, idx, SEARCH_COLD);
- break;
- case IORESOURCE_MEM:
- conflict = pnp_check_mem(dev, idx);
- if (conflict == CONFLICT_TYPE_PNP_WARM)
- wdev = pnp_check_mem_conflicts(dev, idx, SEARCH_WARM);
- cdev = pnp_check_mem_conflicts(dev, idx, SEARCH_COLD);
- break;
- case IORESOURCE_IRQ:
- conflict = pnp_check_irq(dev, idx);
- if (conflict == CONFLICT_TYPE_PNP_WARM)
- wdev = pnp_check_irq_conflicts(dev, idx, SEARCH_WARM);
- cdev = pnp_check_irq_conflicts(dev, idx, SEARCH_COLD);
- break;
- case IORESOURCE_DMA:
- conflict = pnp_check_dma(dev, idx);
- if (conflict == CONFLICT_TYPE_PNP_WARM)
- wdev = pnp_check_dma_conflicts(dev, idx, SEARCH_WARM);
- cdev = pnp_check_dma_conflicts(dev, idx, SEARCH_COLD);
- break;
- default:
- return;
- }
-
- pnp_print_conflict_desc(buffer, conflict);
+static DEVICE_ATTR(options,S_IRUGO,pnp_show_options,NULL);
- if (wdev)
- pnp_print_conflict_node(buffer, wdev);
-
- if (cdev) {
- pnp_print_conflict_desc(buffer, CONFLICT_TYPE_PNP_COLD);
- pnp_print_conflict_node(buffer, cdev);
- }
-}
static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
{
@@ -332,12 +250,6 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
buffer->buffer = buf;
buffer->curr = buffer->buffer;
- pnp_printf(buffer,"mode = ");
- if (dev->config_mode & PNP_CONFIG_MANUAL)
- pnp_printf(buffer,"manual\n");
- else
- pnp_printf(buffer,"auto\n");
-
pnp_printf(buffer,"state = ");
if (dev->active)
pnp_printf(buffer,"active\n");
@@ -350,7 +262,6 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
pnp_printf(buffer," 0x%lx-0x%lx \n",
pnp_port_start(dev, i),
pnp_port_end(dev, i));
- pnp_print_conflict(buffer, dev, i, IORESOURCE_IO);
}
}
for (i = 0; i < PNP_MAX_MEM; i++) {
@@ -359,21 +270,18 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
pnp_printf(buffer," 0x%lx-0x%lx \n",
pnp_mem_start(dev, i),
pnp_mem_end(dev, i));
- pnp_print_conflict(buffer, dev, i, IORESOURCE_MEM);
}
}
for (i = 0; i < PNP_MAX_IRQ; i++) {
if (pnp_irq_valid(dev, i)) {
pnp_printf(buffer,"irq");
pnp_printf(buffer," %ld \n", pnp_irq(dev, i));
- pnp_print_conflict(buffer, dev, i, IORESOURCE_IRQ);
}
}
for (i = 0; i < PNP_MAX_DMA; i++) {
if (pnp_dma_valid(dev, i)) {
pnp_printf(buffer,"dma");
pnp_printf(buffer," %ld \n", pnp_dma(dev, i));
- pnp_print_conflict(buffer, dev, i, IORESOURCE_DMA);
}
}
ret = (buffer->curr - buf);
@@ -381,7 +289,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
return ret;
}
-extern int pnp_resolve_conflicts(struct pnp_dev *dev);
+extern struct semaphore pnp_res_mutex;
static ssize_t
pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count)
@@ -390,6 +298,12 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
char *buf = (void *)ubuf;
int retval = 0;
+ if (dev->status & PNP_ATTACHED) {
+ retval = -EBUSY;
+ pnp_info("Device %s cannot be configured because it is in use.", dev->dev.bus_id);
+ goto done;
+ }
+
while (isspace(*buf))
++buf;
if (!strnicmp(buf,"disable",7)) {
@@ -400,41 +314,30 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
retval = pnp_activate_dev(dev);
goto done;
}
- if (!strnicmp(buf,"reset",5)) {
- if (!dev->active)
- goto done;
- retval = pnp_disable_dev(dev);
- if (retval)
+ if (!strnicmp(buf,"fill",4)) {
+ if (dev->active)
goto done;
- retval = pnp_activate_dev(dev);
+ retval = pnp_auto_config_dev(dev);
goto done;
}
if (!strnicmp(buf,"auto",4)) {
if (dev->active)
goto done;
+ pnp_init_resources(&dev->res);
retval = pnp_auto_config_dev(dev);
goto done;
}
if (!strnicmp(buf,"clear",5)) {
if (dev->active)
goto done;
- spin_lock(&pnp_lock);
- dev->config_mode = PNP_CONFIG_MANUAL;
- pnp_init_resource_table(&dev->res);
- if (dev->rule)
- dev->rule->depnum = 0;
- spin_unlock(&pnp_lock);
- goto done;
- }
- if (!strnicmp(buf,"resolve",7)) {
- retval = pnp_resolve_conflicts(dev);
+ pnp_init_resources(&dev->res);
goto done;
}
if (!strnicmp(buf,"get",3)) {
- spin_lock(&pnp_lock);
+ down(&pnp_res_mutex);
if (pnp_can_read(dev))
dev->protocol->get(dev, &dev->res);
- spin_unlock(&pnp_lock);
+ up(&pnp_res_mutex);
goto done;
}
if (!strnicmp(buf,"set",3)) {
@@ -442,9 +345,8 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
if (dev->active)
goto done;
buf += 3;
- spin_lock(&pnp_lock);
- dev->config_mode = PNP_CONFIG_MANUAL;
- pnp_init_resource_table(&dev->res);
+ pnp_init_resources(&dev->res);
+ down(&pnp_res_mutex);
while (1) {
while (isspace(*buf))
++buf;
@@ -514,7 +416,7 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
}
break;
}
- spin_unlock(&pnp_lock);
+ up(&pnp_res_mutex);
goto done;
}
done:
@@ -543,7 +445,7 @@ static DEVICE_ATTR(id,S_IRUGO,pnp_show_current_ids,NULL);
int pnp_interface_attach_device(struct pnp_dev *dev)
{
- device_create_file(&dev->dev,&dev_attr_possible);
+ device_create_file(&dev->dev,&dev_attr_options);
device_create_file(&dev->dev,&dev_attr_resources);
device_create_file(&dev->dev,&dev_attr_id);
return 0;
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 5f659c17cc34..df1c89a61773 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -31,6 +31,7 @@
* 2002-06-06 Made the use of dma channel 0 configurable
* Gerald Teschl <gerald.teschl@univie.ac.at>
* 2002-10-06 Ported to PnP Layer - Adam Belay <ambx1@neo.rr.com>
+ * 2003-08-11 Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
*/
#include <linux/config.h>
@@ -54,7 +55,6 @@
int isapnp_disable; /* Disable ISA PnP */
int isapnp_rdp; /* Read Data Port */
int isapnp_reset = 1; /* reset all PnP cards (deactivate) */
-int isapnp_skip_pci_scan; /* skip PCI resource scanning */
int isapnp_verbose = 1; /* verbose mode */
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -66,8 +66,6 @@ MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
MODULE_PARM(isapnp_reset, "i");
MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
MODULE_PARM(isapnp_allow_dma0, "i");
-MODULE_PARM(isapnp_skip_pci_scan, "i");
-MODULE_PARM_DESC(isapnp_skip_pci_scan, "ISA Plug & Play skip PCI resource scanning");
MODULE_PARM(isapnp_verbose, "i");
MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
MODULE_LICENSE("GPL");
@@ -460,6 +458,7 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
dev->capabilities |= PNP_READ;
dev->capabilities |= PNP_WRITE;
dev->capabilities |= PNP_DISABLE;
+ pnp_init_resources(&dev->res);
return dev;
}
@@ -468,8 +467,8 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
* Add IRQ resource to resources list.
*/
-static void __init isapnp_add_irq_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_irq_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[3];
struct pnp_irq *irq;
@@ -483,7 +482,7 @@ static void __init isapnp_add_irq_resource(struct pnp_dev *dev,
irq->flags = tmp[2];
else
irq->flags = IORESOURCE_IRQ_HIGHEDGE;
- pnp_add_irq_resource(dev, depnum, irq);
+ pnp_register_irq_resource(option, irq);
return;
}
@@ -491,8 +490,8 @@ static void __init isapnp_add_irq_resource(struct pnp_dev *dev,
* Add DMA resource to resources list.
*/
-static void __init isapnp_add_dma_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_dma_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[2];
struct pnp_dma *dma;
@@ -503,7 +502,7 @@ static void __init isapnp_add_dma_resource(struct pnp_dev *dev,
return;
dma->map = tmp[0];
dma->flags = tmp[1];
- pnp_add_dma_resource(dev, depnum, dma);
+ pnp_register_dma_resource(option, dma);
return;
}
@@ -511,8 +510,8 @@ static void __init isapnp_add_dma_resource(struct pnp_dev *dev,
* Add port resource to resources list.
*/
-static void __init isapnp_add_port_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_port_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[7];
struct pnp_port *port;
@@ -526,7 +525,7 @@ static void __init isapnp_add_port_resource(struct pnp_dev *dev,
port->align = tmp[5];
port->size = tmp[6];
port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
- pnp_add_port_resource(dev,depnum,port);
+ pnp_register_port_resource(option,port);
return;
}
@@ -534,8 +533,8 @@ static void __init isapnp_add_port_resource(struct pnp_dev *dev,
* Add fixed port resource to resources list.
*/
-static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[3];
struct pnp_port *port;
@@ -548,7 +547,7 @@ static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,
port->size = tmp[2];
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
- pnp_add_port_resource(dev,depnum,port);
+ pnp_register_port_resource(option,port);
return;
}
@@ -556,8 +555,8 @@ static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,
* Add memory resource to resources list.
*/
-static void __init isapnp_add_mem_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_mem_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[9];
struct pnp_mem *mem;
@@ -571,7 +570,7 @@ static void __init isapnp_add_mem_resource(struct pnp_dev *dev,
mem->align = (tmp[6] << 8) | tmp[5];
mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
mem->flags = tmp[0];
- pnp_add_mem_resource(dev,depnum,mem);
+ pnp_register_mem_resource(option,mem);
return;
}
@@ -579,8 +578,8 @@ static void __init isapnp_add_mem_resource(struct pnp_dev *dev,
* Add 32-bit memory resource to resources list.
*/
-static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[17];
struct pnp_mem *mem;
@@ -594,15 +593,15 @@ static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,
mem->align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
mem->size = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
mem->flags = tmp[0];
- pnp_add_mem_resource(dev,depnum,mem);
+ pnp_register_mem_resource(option,mem);
}
/*
* Add 32-bit fixed memory resource to resources list.
*/
-static void __init isapnp_add_fixed_mem32_resource(struct pnp_dev *dev,
- int depnum, int size)
+static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
+ int size)
{
unsigned char tmp[9];
struct pnp_mem *mem;
@@ -615,14 +614,14 @@ static void __init isapnp_add_fixed_mem32_resource(struct pnp_dev *dev,
mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
mem->align = 0;
mem->flags = tmp[0];
- pnp_add_mem_resource(dev,depnum,mem);
+ pnp_register_mem_resource(option,mem);
}
/*
* Parse card name for ISA PnP device.
*/
-
-static void __init
+
+static void __init
isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
{
if (name[0] == '\0') {
@@ -634,7 +633,7 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
/* clean whitespace from end of string */
while (size1 > 0 && name[--size1] == ' ')
name[size1] = '\0';
- }
+ }
}
/*
@@ -644,14 +643,17 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
static int __init isapnp_create_device(struct pnp_card *card,
unsigned short size)
{
- int number = 0, skip = 0, depnum = 0, dependent = 0, compat = 0;
+ int number = 0, skip = 0, priority = 0, compat = 0;
unsigned char type, tmp[17];
+ struct pnp_option *option;
struct pnp_dev *dev;
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
- if (pnp_build_resource(dev, 0) == NULL)
+ option = pnp_register_independent_option(dev);
+ if (!option)
return 1;
pnp_add_card_device(card,dev);
+
while (1) {
if (isapnp_read_tag(&type, &size)<0)
return 1;
@@ -662,15 +664,16 @@ static int __init isapnp_create_device(struct pnp_card *card,
if (size >= 5 && size <= 6) {
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
- pnp_build_resource(dev,0);
- pnp_add_card_device(card,dev);
size = 0;
skip = 0;
+ option = pnp_register_independent_option(dev);
+ if (!option)
+ return 1;
+ pnp_add_card_device(card,dev);
} else {
skip = 1;
}
- dependent = 0;
- depnum = 0;
+ priority = 0;
compat = 0;
break;
case _STAG_COMPATDEVID:
@@ -684,43 +687,43 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_IRQ:
if (size < 2 || size > 3)
goto __skip;
- isapnp_add_irq_resource(dev, depnum, size);
+ isapnp_parse_irq_resource(option, size);
size = 0;
break;
case _STAG_DMA:
if (size != 2)
goto __skip;
- isapnp_add_dma_resource(dev, depnum, size);
+ isapnp_parse_dma_resource(option, size);
size = 0;
break;
case _STAG_STARTDEP:
if (size > 1)
goto __skip;
- dependent = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+ priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
if (size > 0) {
isapnp_peek(tmp, size);
- dependent = 0x100 | tmp[0];
+ priority = 0x100 | tmp[0];
size = 0;
}
- pnp_build_resource(dev,dependent);
- depnum = pnp_get_max_depnum(dev);
+ option = pnp_register_dependent_option(dev,priority);
+ if (!option)
+ return 1;
break;
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
- dependent = 0;
- depnum = 0;
+ priority = 0;
break;
case _STAG_IOPORT:
if (size != 7)
goto __skip;
- isapnp_add_port_resource(dev, depnum, size);
+ isapnp_parse_port_resource(option, size);
size = 0;
break;
case _STAG_FIXEDIO:
if (size != 3)
goto __skip;
- isapnp_add_fixed_port_resource(dev, depnum, size);
+ isapnp_parse_fixed_port_resource(option, size);
size = 0;
break;
case _STAG_VENDOR:
@@ -728,7 +731,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEMRANGE:
if (size != 9)
goto __skip;
- isapnp_add_mem_resource(dev, depnum, size);
+ isapnp_parse_mem_resource(option, size);
size = 0;
break;
case _LTAG_ANSISTR:
@@ -743,13 +746,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEM32RANGE:
if (size != 17)
goto __skip;
- isapnp_add_mem32_resource(dev, depnum, size);
+ isapnp_parse_mem32_resource(option, size);
size = 0;
break;
case _LTAG_FIXEDMEM32RANGE:
if (size != 9)
goto __skip;
- isapnp_add_fixed_mem32_resource(dev, depnum, size);
+ isapnp_parse_fixed_mem32_resource(option, size);
size = 0;
break;
case _STAG_END:
@@ -859,63 +862,6 @@ static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor,
pnp_add_card_id(id,card);
}
-
-static int isapnp_parse_current_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
-{
- int tmp, ret;
- struct pnp_rule_table rule;
- if (dev->rule)
- rule = *dev->rule;
- else {
- if (!pnp_generate_rule(dev,1,&rule))
- return -EINVAL;
- }
-
- dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
- if (dev->active) {
- for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
- ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
- if (!ret)
- continue;
- res->port_resource[tmp].start = ret;
- if (rule.port[tmp])
- res->port_resource[tmp].end = ret + rule.port[tmp]->size - 1;
- else
- res->port_resource[tmp].end = ret + 1; /* all we can do is assume 1 :-( */
- res->port_resource[tmp].flags = IORESOURCE_IO;
- }
- for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
- ret = isapnp_read_dword(ISAPNP_CFG_MEM + (tmp << 3));
- if (!ret)
- continue;
- res->mem_resource[tmp].start = ret;
- if (rule.mem[tmp])
- res->mem_resource[tmp].end = ret + rule.mem[tmp]->size - 1;
- else
- res->mem_resource[tmp].end = ret + 1; /* all we can do is assume 1 :-( */
- res->mem_resource[tmp].flags = IORESOURCE_MEM;
- }
- for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
- ret = (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 8);
- if (!ret)
- continue;
- res->irq_resource[tmp].start = res->irq_resource[tmp].end = ret;
- res->irq_resource[tmp].flags = IORESOURCE_IRQ;
- }
- for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
- ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
- if (ret == 4)
- continue;
- if (rule.dma[tmp]) { /* some isapnp systems forget to set this to 4 so we have to check */
- res->dma_resource[tmp].start = res->dma_resource[tmp].end = ret;
- res->dma_resource[tmp].flags = IORESOURCE_DMA;
- }
- }
- }
- return 0;
-}
-
-
/*
* Build device list for all present ISA PnP devices.
*/
@@ -925,7 +871,6 @@ static int __init isapnp_build_device_list(void)
int csn;
unsigned char header[9], checksum;
struct pnp_card *card;
- struct pnp_dev *dev;
isapnp_wait();
isapnp_key();
@@ -959,13 +904,6 @@ static int __init isapnp_build_device_list(void)
card->checksum = isapnp_checksum_value;
card->protocol = &isapnp_protocol;
- /* read the current resource data */
- card_for_each_dev(card,dev) {
- isapnp_device(dev->number);
- pnp_init_resource_table(&dev->res);
- isapnp_parse_current_resources(dev, &dev->res);
- }
-
pnp_add_card(card);
}
isapnp_wait();
@@ -1041,12 +979,50 @@ EXPORT_SYMBOL(isapnp_write_dword);
EXPORT_SYMBOL(isapnp_wake);
EXPORT_SYMBOL(isapnp_device);
+static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res)
+{
+ int tmp, ret;
+
+ dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
+ if (dev->active) {
+ for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
+ ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
+ if (!ret)
+ continue;
+ res->port_resource[tmp].start = ret;
+ res->port_resource[tmp].flags = IORESOURCE_IO;
+ }
+ for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
+ ret = isapnp_read_dword(ISAPNP_CFG_MEM + (tmp << 3));
+ if (!ret)
+ continue;
+ res->mem_resource[tmp].start = ret;
+ res->mem_resource[tmp].flags = IORESOURCE_MEM;
+ }
+ for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
+ ret = (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 8);
+ if (!ret)
+ continue;
+ res->irq_resource[tmp].start = res->irq_resource[tmp].end = ret;
+ res->irq_resource[tmp].flags = IORESOURCE_IRQ;
+ }
+ for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
+ ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
+ if (ret == 4)
+ continue;
+ res->dma_resource[tmp].start = res->dma_resource[tmp].end = ret;
+ res->dma_resource[tmp].flags = IORESOURCE_DMA;
+ }
+ }
+ return 0;
+}
+
static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
{
int ret;
- pnp_init_resource_table(res);
+ pnp_init_resources(res);
isapnp_cfg_begin(dev->card->number, dev->number);
- ret = isapnp_parse_current_resources(dev, res);
+ ret = isapnp_read_resources(dev, res);
isapnp_cfg_end();
return ret;
}
@@ -1196,7 +1172,6 @@ static int __init isapnp_setup_isapnp(char *str)
{
(void)((get_option(&str,&isapnp_rdp) == 2) &&
(get_option(&str,&isapnp_reset) == 2) &&
- (get_option(&str,&isapnp_skip_pci_scan) == 2) &&
(get_option(&str,&isapnp_verbose) == 2));
return 1;
}
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 0b168a7b0c48..34d3620c8e3a 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -1,6 +1,7 @@
/*
* manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
*
+ * based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com>
*
*/
@@ -20,574 +21,363 @@
#include <linux/pnp.h>
#include "base.h"
+DECLARE_MUTEX(pnp_res_mutex);
-int pnp_max_moves = 4;
-
-
-static int pnp_next_port(struct pnp_dev * dev, int idx)
+static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
{
- struct pnp_port *port;
unsigned long *start, *end, *flags;
- if (!dev || idx < 0 || idx >= PNP_MAX_PORT)
- return 0;
- port = dev->rule->port[idx];
- if (!port)
+
+ if (!dev || !rule)
+ return -EINVAL;
+
+ if (idx >= PNP_MAX_PORT) {
+ pnp_err("More than 4 ports is incompatible with pnp specifications.");
+ /* pretend we were successful so at least the manager won't try again */
+ return 1;
+ }
+
+ /* check if this resource has been manually set, if so skip */
+ if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO))
return 1;
start = &dev->res.port_resource[idx].start;
end = &dev->res.port_resource[idx].end;
flags = &dev->res.port_resource[idx].flags;
- /* set the initial values if this is the first time */
- if (*start == 0) {
- *start = port->min;
- *end = *start + port->size - 1;
- *flags = port->flags | IORESOURCE_IO;
- if (!pnp_check_port(dev, idx))
- return 1;
- }
+ /* set the initial values */
+ *start = rule->min;
+ *end = *start + rule->size - 1;
+ *flags = *flags | rule->flags | IORESOURCE_IO;
/* run through until pnp_check_port is happy */
- do {
- *start += port->align;
- *end = *start + port->size - 1;
- if (*start > port->max || !port->align)
+ while (!pnp_check_port(dev, idx)) {
+ *start += rule->align;
+ *end = *start + rule->size - 1;
+ if (*start > rule->max || !rule->align)
return 0;
- } while (pnp_check_port(dev, idx));
+ }
return 1;
}
-static int pnp_next_mem(struct pnp_dev * dev, int idx)
+static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
{
- struct pnp_mem *mem;
unsigned long *start, *end, *flags;
- if (!dev || idx < 0 || idx >= PNP_MAX_MEM)
- return 0;
- mem = dev->rule->mem[idx];
- if (!mem)
+
+ if (!dev || !rule)
+ return -EINVAL;
+
+ if (idx >= PNP_MAX_MEM) {
+ pnp_err("More than 8 mems is incompatible with pnp specifications.");
+ /* pretend we were successful so at least the manager won't try again */
+ return 1;
+ }
+
+ /* check if this resource has been manually set, if so skip */
+ if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO))
return 1;
start = &dev->res.mem_resource[idx].start;
end = &dev->res.mem_resource[idx].end;
flags = &dev->res.mem_resource[idx].flags;
- /* set the initial values if this is the first time */
- if (*start == 0) {
- *start = mem->min;
- *end = *start + mem->size -1;
- *flags = mem->flags | IORESOURCE_MEM;
- if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
- *flags |= IORESOURCE_READONLY;
- if (mem->flags & IORESOURCE_MEM_CACHEABLE)
- *flags |= IORESOURCE_CACHEABLE;
- if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
- *flags |= IORESOURCE_RANGELENGTH;
- if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
- *flags |= IORESOURCE_SHADOWABLE;
- if (!pnp_check_mem(dev, idx))
- return 1;
- }
+ /* set the initial values */
+ *start = rule->min;
+ *end = *start + rule->size -1;
+ *flags = *flags | rule->flags | IORESOURCE_MEM;
+
+ /* convert pnp flags to standard Linux flags */
+ if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
+ *flags |= IORESOURCE_READONLY;
+ if (rule->flags & IORESOURCE_MEM_CACHEABLE)
+ *flags |= IORESOURCE_CACHEABLE;
+ if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
+ *flags |= IORESOURCE_RANGELENGTH;
+ if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
+ *flags |= IORESOURCE_SHADOWABLE;
/* run through until pnp_check_mem is happy */
- do {
- *start += mem->align;
- *end = *start + mem->size - 1;
- if (*start > mem->max || !mem->align)
+ while (!pnp_check_mem(dev, idx)) {
+ *start += rule->align;
+ *end = *start + rule->size - 1;
+ if (*start > rule->max || !rule->align)
return 0;
- } while (pnp_check_mem(dev, idx));
+ }
return 1;
}
-static int pnp_next_irq(struct pnp_dev * dev, int idx)
+static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx)
{
- struct pnp_irq *irq;
unsigned long *start, *end, *flags;
- int i, mask;
- if (!dev || idx < 0 || idx >= PNP_MAX_IRQ)
- return 0;
- irq = dev->rule->irq[idx];
- if (!irq)
- return 1;
+ int i;
- start = &dev->res.irq_resource[idx].start;
- end = &dev->res.irq_resource[idx].end;
- flags = &dev->res.irq_resource[idx].flags;
+ /* IRQ priority: this table is good for i386 */
+ static unsigned short xtab[16] = {
+ 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
+ };
- /* set the initial values if this is the first time */
- if (*start == -1) {
- *start = *end = 0;
- *flags = irq->flags | IORESOURCE_IRQ;
- if (!pnp_check_irq(dev, idx))
- return 1;
- }
+ if (!dev || !rule)
+ return -EINVAL;
- mask = irq->map;
- for (i = *start + 1; i < 16; i++)
- {
- if(mask>>i & 0x01) {
- *start = *end = i;
- if(!pnp_check_irq(dev, idx))
- return 1;
- }
+ if (idx >= PNP_MAX_IRQ) {
+ pnp_err("More than 2 irqs is incompatible with pnp specifications.");
+ /* pretend we were successful so at least the manager won't try again */
+ return 1;
}
- return 0;
-}
-static int pnp_next_dma(struct pnp_dev * dev, int idx)
-{
- struct pnp_dma *dma;
- unsigned long *start, *end, *flags;
- int i, mask;
- if (!dev || idx < 0 || idx >= PNP_MAX_DMA)
- return -EINVAL;
- dma = dev->rule->dma[idx];
- if (!dma)
+ /* check if this resource has been manually set, if so skip */
+ if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO))
return 1;
- start = &dev->res.dma_resource[idx].start;
- end = &dev->res.dma_resource[idx].end;
- flags = &dev->res.dma_resource[idx].flags;
+ start = &dev->res.irq_resource[idx].start;
+ end = &dev->res.irq_resource[idx].end;
+ flags = &dev->res.irq_resource[idx].flags;
- /* set the initial values if this is the first time */
- if (*start == -1) {
- *start = *end = 0;
- *flags = dma->flags | IORESOURCE_DMA;
- if (!pnp_check_dma(dev, idx))
- return 1;
- }
+ /* set the initial values */
+ *flags = *flags | rule->flags | IORESOURCE_IRQ;
- mask = dma->map;
- for (i = *start + 1; i < 8; i++)
- {
- if(mask>>i & 0x01) {
- *start = *end = i;
- if(!pnp_check_dma(dev, idx))
+ for (i = 0; i < 16; i++) {
+ if(rule->map & (1<<xtab[i])) {
+ *start = *end = xtab[i];
+ if(pnp_check_irq(dev, idx))
return 1;
}
}
return 0;
}
-static int pnp_next_rule(struct pnp_dev *dev)
-{
- int depnum = dev->rule->depnum;
- int max = pnp_get_max_depnum(dev);
- int priority = PNP_RES_PRIORITY_PREFERRED;
-
- if (depnum < 0)
- return 0;
-
- if (max == 0) {
- if (pnp_generate_rule(dev, 0, dev->rule)) {
- dev->rule->depnum = -1;
- return 1;
- }
- }
-
- if(depnum > 0) {
- struct pnp_resources * res = pnp_find_resources(dev, depnum);
- priority = res->priority;
- }
-
- for (; priority <= PNP_RES_PRIORITY_FUNCTIONAL; priority++, depnum = 0) {
- depnum += 1;
- for (; depnum <= max; depnum++) {
- struct pnp_resources * res = pnp_find_resources(dev, depnum);
- if (res->priority == priority) {
- if(pnp_generate_rule(dev, depnum, dev->rule)) {
- dev->rule->depnum = depnum;
- return 1;
- }
- }
- }
- }
- return 0;
-}
-
-struct pnp_change {
- struct list_head change_list;
- struct list_head changes;
- struct pnp_resource_table res_bak;
- struct pnp_rule_table rule_bak;
- struct pnp_dev * dev;
-};
-
-static void pnp_free_changes(struct pnp_change * parent)
-{
- struct list_head * pos, * temp;
- list_for_each_safe(pos, temp, &parent->changes) {
- struct pnp_change * change = list_entry(pos, struct pnp_change, change_list);
- list_del(&change->change_list);
- kfree(change);
- }
-}
-
-static void pnp_undo_changes(struct pnp_change * parent)
-{
- struct list_head * pos, * temp;
- list_for_each_safe(pos, temp, &parent->changes) {
- struct pnp_change * change = list_entry(pos, struct pnp_change, change_list);
- *change->dev->rule = change->rule_bak;
- change->dev->res = change->res_bak;
- list_del(&change->change_list);
- kfree(change);
- }
-}
-
-static struct pnp_change * pnp_add_change(struct pnp_change * parent, struct pnp_dev * dev)
-{
- struct pnp_change * change = pnp_alloc(sizeof(struct pnp_change));
- if (!change)
- return NULL;
- change->res_bak = dev->res;
- change->rule_bak = *dev->rule;
- change->dev = dev;
- INIT_LIST_HEAD(&change->changes);
- if (parent)
- list_add(&change->change_list, &parent->changes);
- return change;
-}
-
-static void pnp_commit_changes(struct pnp_change * parent, struct pnp_change * change)
-{
- /* check if it's the root change */
- if (!parent)
- return;
- if (!list_empty(&change->changes))
- list_splice_init(&change->changes, &parent->changes);
-}
-
-static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent);
-
-static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * parent, struct pnp_change * change)
+static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
{
+ unsigned long *start, *end, *flags;
int i;
- struct pnp_dev * cdev;
-
- for (i = 0; i < PNP_MAX_PORT; i++) {
- if (dev->res.port_resource[i].start == 0
- || pnp_check_port_conflicts(dev,i,SEARCH_WARM)) {
- if (!pnp_next_port(dev,i))
- return 0;
- }
- do {
- cdev = pnp_check_port_conflicts(dev,i,SEARCH_COLD);
- if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
- pnp_undo_changes(change);
- if (!pnp_next_port(dev,i))
- return 0;
- }
- } while (cdev);
- pnp_commit_changes(parent, change);
- }
- for (i = 0; i < PNP_MAX_MEM; i++) {
- if (dev->res.mem_resource[i].start == 0
- || pnp_check_mem_conflicts(dev,i,SEARCH_WARM)) {
- if (!pnp_next_mem(dev,i))
- return 0;
- }
- do {
- cdev = pnp_check_mem_conflicts(dev,i,SEARCH_COLD);
- if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
- pnp_undo_changes(change);
- if (!pnp_next_mem(dev,i))
- return 0;
- }
- } while (cdev);
- pnp_commit_changes(parent, change);
- }
- for (i = 0; i < PNP_MAX_IRQ; i++) {
- if (dev->res.irq_resource[i].start == -1
- || pnp_check_irq_conflicts(dev,i,SEARCH_WARM)) {
- if (!pnp_next_irq(dev,i))
- return 0;
- }
- do {
- cdev = pnp_check_irq_conflicts(dev,i,SEARCH_COLD);
- if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
- pnp_undo_changes(change);
- if (!pnp_next_irq(dev,i))
- return 0;
- }
- } while (cdev);
- pnp_commit_changes(parent, change);
- }
- for (i = 0; i < PNP_MAX_DMA; i++) {
- if (dev->res.dma_resource[i].start == -1
- || pnp_check_dma_conflicts(dev,i,SEARCH_WARM)) {
- if (!pnp_next_dma(dev,i))
- return 0;
- }
- do {
- cdev = pnp_check_dma_conflicts(dev,i,SEARCH_COLD);
- if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
- pnp_undo_changes(change);
- if (!pnp_next_dma(dev,i))
- return 0;
- }
- } while (cdev);
- pnp_commit_changes(parent, change);
- }
- return 1;
-}
-static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent)
-{
- struct pnp_change * change;
- move--;
- if (!dev->rule)
- return 0;
- change = pnp_add_change(parent,dev);
- if (!change)
- return 0;
- if (!pnp_can_configure(dev))
- goto fail;
- if (!dev->rule->depnum) {
- if (!pnp_next_rule(dev))
- goto fail;
- }
- while (!pnp_next_request(dev, move, parent, change)) {
- if(!pnp_next_rule(dev))
- goto fail;
- pnp_init_resource_table(&dev->res);
- }
- if (!parent) {
- pnp_free_changes(change);
- kfree(change);
- }
- return 1;
+ /* DMA priority: this table is good for i386 */
+ static unsigned short xtab[8] = {
+ 1, 3, 5, 6, 7, 0, 2, 4
+ };
-fail:
- if (!parent)
- kfree(change);
- return 0;
-}
+ if (!dev || !rule)
+ return -EINVAL;
-/* this advanced algorithm will shuffle other configs to make room and ensure that the most possible devices have configs */
-static int pnp_advanced_config(struct pnp_dev * dev)
-{
- int move;
- /* if the device cannot be configured skip it */
- if (!pnp_can_configure(dev))
+ if (idx >= PNP_MAX_DMA) {
+ pnp_err("More than 2 dmas is incompatible with pnp specifications.");
+ /* pretend we were successful so at least the manager won't try again */
return 1;
- if (!dev->rule) {
- dev->rule = pnp_alloc(sizeof(struct pnp_rule_table));
- if (!dev->rule)
- return -ENOMEM;
}
- spin_lock(&pnp_lock);
- for (move = 1; move <= pnp_max_moves; move++) {
- dev->rule->depnum = 0;
- pnp_init_resource_table(&dev->res);
- if (pnp_next_config(dev,move,NULL)) {
- spin_unlock(&pnp_lock);
- return 1;
- }
- }
+ /* check if this resource has been manually set, if so skip */
+ if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO))
+ return 1;
- pnp_init_resource_table(&dev->res);
- dev->rule->depnum = 0;
- spin_unlock(&pnp_lock);
- pnp_err("res: Unable to resolve resource conflicts for the device '%s', some devices may not be usable.", dev->dev.bus_id);
- return 0;
-}
+ start = &dev->res.dma_resource[idx].start;
+ end = &dev->res.dma_resource[idx].end;
+ flags = &dev->res.dma_resource[idx].flags;
-int pnp_resolve_conflicts(struct pnp_dev *dev)
-{
- int i;
- struct pnp_dev * cdev;
-
- for (i = 0; i < PNP_MAX_PORT; i++)
- {
- do {
- cdev = pnp_check_port_conflicts(dev,i,SEARCH_COLD);
- if (cdev)
- pnp_advanced_config(cdev);
- } while (cdev);
- }
- for (i = 0; i < PNP_MAX_MEM; i++)
- {
- do {
- cdev = pnp_check_mem_conflicts(dev,i,SEARCH_COLD);
- if (cdev)
- pnp_advanced_config(cdev);
- } while (cdev);
- }
- for (i = 0; i < PNP_MAX_IRQ; i++)
- {
- do {
- cdev = pnp_check_irq_conflicts(dev,i,SEARCH_COLD);
- if (cdev)
- pnp_advanced_config(cdev);
- } while (cdev);
- }
- for (i = 0; i < PNP_MAX_DMA; i++)
- {
- do {
- cdev = pnp_check_dma_conflicts(dev,i,SEARCH_COLD);
- if (cdev)
- pnp_advanced_config(cdev);
- } while (cdev);
- }
- return 1;
-}
+ /* set the initial values */
+ *flags = *flags | rule->flags | IORESOURCE_DMA;
-/* this is a much faster algorithm but it may not leave resources for other devices to use */
-static int pnp_simple_config(struct pnp_dev * dev)
-{
- int i;
- spin_lock(&pnp_lock);
- if (dev->active) {
- spin_unlock(&pnp_lock);
- return 1;
- }
- if (!dev->rule) {
- dev->rule = pnp_alloc(sizeof(struct pnp_rule_table));
- if (!dev->rule) {
- spin_unlock(&pnp_lock);
- return -ENOMEM;
- }
- }
- dev->rule->depnum = 0;
- pnp_init_resource_table(&dev->res);
- while (pnp_next_rule(dev)) {
- for (i = 0; i < PNP_MAX_PORT; i++) {
- if (!pnp_next_port(dev,i))
- continue;
- }
- for (i = 0; i < PNP_MAX_MEM; i++) {
- if (!pnp_next_mem(dev,i))
- continue;
- }
- for (i = 0; i < PNP_MAX_IRQ; i++) {
- if (!pnp_next_irq(dev,i))
- continue;
- }
- for (i = 0; i < PNP_MAX_DMA; i++) {
- if (!pnp_next_dma(dev,i))
- continue;
+ for (i = 0; i < 8; i++) {
+ if(rule->map & (1<<xtab[i])) {
+ *start = *end = xtab[i];
+ if(pnp_check_dma(dev, idx))
+ return 1;
}
- goto done;
}
- pnp_init_resource_table(&dev->res);
- dev->rule->depnum = 0;
- spin_unlock(&pnp_lock);
return 0;
-
-done:
- pnp_resolve_conflicts(dev); /* this is required or we will break the advanced configs */
- return 1;
}
-static int pnp_compare_resources(struct pnp_resource_table * resa, struct pnp_resource_table * resb)
+/**
+ * pnp_init_resources - Resets a resource table to default values.
+ * @table: pointer to the desired resource table
+ *
+ */
+void pnp_init_resources(struct pnp_resource_table *table)
{
int idx;
+ down(&pnp_res_mutex);
for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
- if (resa->irq_resource[idx].start != resb->irq_resource[idx].start)
- return 1;
+ table->irq_resource[idx].name = NULL;
+ table->irq_resource[idx].start = -1;
+ table->irq_resource[idx].end = -1;
+ table->irq_resource[idx].flags = IORESOURCE_AUTO;
}
for (idx = 0; idx < PNP_MAX_DMA; idx++) {
- if (resa->dma_resource[idx].start != resb->dma_resource[idx].start)
- return 1;
+ table->dma_resource[idx].name = NULL;
+ table->dma_resource[idx].start = -1;
+ table->dma_resource[idx].end = -1;
+ table->dma_resource[idx].flags = IORESOURCE_AUTO;
}
for (idx = 0; idx < PNP_MAX_PORT; idx++) {
- if (resa->port_resource[idx].start != resb->port_resource[idx].start)
- return 1;
- if (resa->port_resource[idx].end != resb->port_resource[idx].end)
- return 1;
+ table->port_resource[idx].name = NULL;
+ table->port_resource[idx].start = 0;
+ table->port_resource[idx].end = 0;
+ table->port_resource[idx].flags = IORESOURCE_AUTO;
}
for (idx = 0; idx < PNP_MAX_MEM; idx++) {
- if (resa->mem_resource[idx].start != resb->mem_resource[idx].start)
- return 1;
- if (resa->mem_resource[idx].end != resb->mem_resource[idx].end)
- return 1;
+ table->mem_resource[idx].name = NULL;
+ table->mem_resource[idx].start = 0;
+ table->mem_resource[idx].end = 0;
+ table->mem_resource[idx].flags = IORESOURCE_AUTO;
}
- return 0;
+ up(&pnp_res_mutex);
}
-
-/*
- * PnP Device Resource Management
- */
-
/**
- * pnp_auto_config_dev - determines the best possible resource configuration based on available information
- * @dev: pointer to the desired device
+ * pnp_clean_resources - clears resources that were not manually set
+ * @res - the resources to clean
*
*/
-
-int pnp_auto_config_dev(struct pnp_dev *dev)
-{
- int error;
- if(!dev)
- return -EINVAL;
-
- dev->config_mode = PNP_CONFIG_AUTO;
-
- if(dev->active)
- error = pnp_resolve_conflicts(dev);
- else
- error = pnp_advanced_config(dev);
- return error;
-}
-
-static void pnp_process_manual_resources(struct pnp_resource_table * ctab, struct pnp_resource_table * ntab)
+static void pnp_clean_resources(struct pnp_resource_table * res)
{
int idx;
for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
- if (ntab->irq_resource[idx].flags & IORESOURCE_AUTO)
+ if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO))
continue;
- ctab->irq_resource[idx].start = ntab->irq_resource[idx].start;
- ctab->irq_resource[idx].end = ntab->irq_resource[idx].end;
- ctab->irq_resource[idx].flags = ntab->irq_resource[idx].flags;
+ res->irq_resource[idx].start = -1;
+ res->irq_resource[idx].end = -1;
+ res->irq_resource[idx].flags = IORESOURCE_AUTO;
}
for (idx = 0; idx < PNP_MAX_DMA; idx++) {
- if (ntab->dma_resource[idx].flags & IORESOURCE_AUTO)
+ if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
continue;
- ctab->dma_resource[idx].start = ntab->dma_resource[idx].start;
- ctab->dma_resource[idx].end = ntab->dma_resource[idx].end;
- ctab->dma_resource[idx].flags = ntab->dma_resource[idx].flags;
+ res->dma_resource[idx].start = -1;
+ res->dma_resource[idx].end = -1;
+ res->dma_resource[idx].flags = IORESOURCE_AUTO;
}
for (idx = 0; idx < PNP_MAX_PORT; idx++) {
- if (ntab->port_resource[idx].flags & IORESOURCE_AUTO)
+ if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
continue;
- ctab->port_resource[idx].start = ntab->port_resource[idx].start;
- ctab->port_resource[idx].end = ntab->port_resource[idx].end;
- ctab->port_resource[idx].flags = ntab->port_resource[idx].flags;
+ res->port_resource[idx].start = 0;
+ res->port_resource[idx].end = 0;
+ res->port_resource[idx].flags = IORESOURCE_AUTO;
}
for (idx = 0; idx < PNP_MAX_MEM; idx++) {
- if (ntab->irq_resource[idx].flags & IORESOURCE_AUTO)
+ if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
continue;
- ctab->irq_resource[idx].start = ntab->mem_resource[idx].start;
- ctab->irq_resource[idx].end = ntab->mem_resource[idx].end;
- ctab->irq_resource[idx].flags = ntab->mem_resource[idx].flags;
+ res->mem_resource[idx].start = 0;
+ res->mem_resource[idx].end = 0;
+ res->mem_resource[idx].flags = IORESOURCE_AUTO;
}
}
/**
+ * pnp_assign_resources - assigns resources to the device based on the specified dependent number
+ * @dev: pointer to the desired device
+ * @depnum: the dependent function number
+ *
+ * Only set depnum to 0 if the device does not have dependent options.
+ */
+int pnp_assign_resources(struct pnp_dev *dev, int depnum)
+{
+ struct pnp_port *port;
+ struct pnp_mem *mem;
+ struct pnp_irq *irq;
+ struct pnp_dma *dma;
+ int nport = 0, nmem = 0, nirq = 0, ndma = 0;
+
+ if (!pnp_can_configure(dev))
+ return -ENODEV;
+
+ down(&pnp_res_mutex);
+ pnp_clean_resources(&dev->res); /* start with a fresh slate */
+ if (dev->independent) {
+ port = dev->independent->port;
+ mem = dev->independent->mem;
+ irq = dev->independent->irq;
+ dma = dev->independent->dma;
+ while (port) {
+ if (!pnp_assign_port(dev, port, nport))
+ goto fail;
+ nport++;
+ port = port->next;
+ }
+ while (mem) {
+ if (!pnp_assign_mem(dev, mem, nmem))
+ goto fail;
+ nmem++;
+ mem = mem->next;
+ }
+ while (irq) {
+ if (!pnp_assign_irq(dev, irq, nirq))
+ goto fail;
+ nirq++;
+ irq = irq->next;
+ }
+ while (dma) {
+ if (!pnp_assign_dma(dev, dma, ndma))
+ goto fail;
+ ndma++;
+ dma = dma->next;
+ }
+ }
+
+ if (depnum) {
+ struct pnp_option *dep;
+ int i;
+ for (i=1,dep=dev->dependent; i<depnum; i++, dep=dep->next)
+ if(!dep)
+ goto fail;
+ port =dep->port;
+ mem = dep->mem;
+ irq = dep->irq;
+ dma = dep->dma;
+ while (port) {
+ if (!pnp_assign_port(dev, port, nport))
+ goto fail;
+ nport++;
+ port = port->next;
+ }
+ while (mem) {
+ if (!pnp_assign_mem(dev, mem, nmem))
+ goto fail;
+ nmem++;
+ mem = mem->next;
+ }
+ while (irq) {
+ if (!pnp_assign_irq(dev, irq, nirq))
+ goto fail;
+ nirq++;
+ irq = irq->next;
+ }
+ while (dma) {
+ if (!pnp_assign_dma(dev, dma, ndma))
+ goto fail;
+ ndma++;
+ dma = dma->next;
+ }
+ } else if (dev->dependent)
+ goto fail;
+
+ up(&pnp_res_mutex);
+ return 1;
+
+fail:
+ pnp_clean_resources(&dev->res);
+ up(&pnp_res_mutex);
+ return 0;
+}
+
+/**
* pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
* @dev: pointer to the desired device
* @res: pointer to the new resource config
*
* This function can be used by drivers that want to manually set thier resources.
*/
-
int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, int mode)
{
int i;
struct pnp_resource_table * bak;
if (!dev || !res)
return -EINVAL;
- if (dev->active)
- return -EBUSY;
+ if (!pnp_can_configure(dev))
+ return -ENODEV;
bak = pnp_alloc(sizeof(struct pnp_resource_table));
if (!bak)
return -ENOMEM;
*bak = dev->res;
- spin_lock(&pnp_lock);
- pnp_process_manual_resources(&dev->res, res);
+ down(&pnp_res_mutex);
+ dev->res = *res;
if (!(mode & PNP_CONFIG_FORCE)) {
for (i = 0; i < PNP_MAX_PORT; i++) {
if(pnp_check_port(dev,i))
@@ -606,27 +396,64 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res,
goto fail;
}
}
- dev->config_mode = PNP_CONFIG_MANUAL;
- spin_unlock(&pnp_lock);
+ up(&pnp_res_mutex);
- pnp_resolve_conflicts(dev);
+ pnp_auto_config_dev(dev);
kfree(bak);
return 0;
fail:
dev->res = *bak;
- spin_unlock(&pnp_lock);
+ up(&pnp_res_mutex);
kfree(bak);
return -EINVAL;
}
/**
- * pnp_activate_dev - activates a PnP device for use
+ * pnp_auto_config_dev - automatically assigns resources to a device
* @dev: pointer to the desired device
*
- * finds the best resource configuration and then informs the correct pnp protocol
*/
+int pnp_auto_config_dev(struct pnp_dev *dev)
+{
+ struct pnp_option *dep;
+ int i = 1;
+ if(!dev)
+ return -EINVAL;
+
+ if(!pnp_can_configure(dev)) {
+ pnp_info("Device %s does not support resource configuration.", dev->dev.bus_id);
+ return -ENODEV;
+ }
+
+ if (!dev->dependent) {
+ if (pnp_assign_resources(dev, 0))
+ return 1;
+ else
+ return 0;
+ }
+
+ dep = dev->dependent;
+ do {
+ if (pnp_assign_resources(dev, i))
+ return 1;
+
+ /* if this dependent resource failed, try the next one */
+ dep = dep->next;
+ i++;
+ } while (dep);
+
+ pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id);
+ return 0;
+}
+
+/**
+ * pnp_activate_dev - activates a PnP device for use
+ * @dev: pointer to the desired device
+ *
+ * does not validate or set resources so be careful.
+ */
int pnp_activate_dev(struct pnp_dev *dev)
{
if (!dev)
@@ -634,55 +461,25 @@ int pnp_activate_dev(struct pnp_dev *dev)
if (dev->active) {
return 0; /* the device is already active */
}
- /* If this condition is true, advanced configuration failed, we need to get this device up and running
- * so we use the simple config engine which ignores cold conflicts, this of course may lead to new failures */
- if (!pnp_is_active(dev)) {
- if (!pnp_simple_config(dev)) {
- pnp_err("res: Unable to resolve resource conflicts for the device '%s'.", dev->dev.bus_id);
- goto fail;
- }
- }
- spin_lock(&pnp_lock); /* we lock just in case the device is being configured during this call */
- dev->active = 1;
- spin_unlock(&pnp_lock); /* once the device is claimed active we know it won't be configured so we can unlock */
+ /* ensure resources are allocated */
+ if (!pnp_auto_config_dev(dev))
+ return -EBUSY;
- if (dev->config_mode & PNP_CONFIG_INVALID) {
- pnp_info("res: Unable to activate the PnP device '%s' because its resource configuration is invalid.", dev->dev.bus_id);
- goto fail;
- }
- if (dev->status != PNP_READY && dev->status != PNP_ATTACHED){
- pnp_err("res: Activation failed because the PnP device '%s' is busy.", dev->dev.bus_id);
- goto fail;
- }
if (!pnp_can_write(dev)) {
- pnp_info("res: Unable to activate the PnP device '%s' because this feature is not supported.", dev->dev.bus_id);
- goto fail;
+ pnp_info("Device %s does not supported activation.", dev->dev.bus_id);
+ return -EINVAL;
}
+
if (dev->protocol->set(dev, &dev->res)<0) {
- pnp_err("res: The protocol '%s' reports that activating the PnP device '%s' has failed.", dev->protocol->name, dev->dev.bus_id);
- goto fail;
+ pnp_err("Failed to activate device %s.", dev->dev.bus_id);
+ return -EIO;
}
- if (pnp_can_read(dev)) {
- struct pnp_resource_table * res = pnp_alloc(sizeof(struct pnp_resource_table));
- if (!res)
- goto fail;
- dev->protocol->get(dev, res);
- if (pnp_compare_resources(&dev->res, res)) /* if this happens we may be in big trouble but it's best just to continue */
- pnp_err("res: The resources requested do not match those set for the PnP device '%s'.", dev->dev.bus_id);
- kfree(res);
- } else
- dev->active = pnp_is_active(dev);
- pnp_dbg("res: the device '%s' has been activated.", dev->dev.bus_id);
- if (dev->rule) {
- kfree(dev->rule);
- dev->rule = NULL;
- }
- return 0;
-fail:
- dev->active = 0; /* fixes incorrect active state */
- return -EINVAL;
+ dev->active = 1;
+ pnp_info("Device %s activated.", dev->dev.bus_id);
+
+ return 1;
}
/**
@@ -691,7 +488,6 @@ fail:
*
* inform the correct pnp protocol so that resources can be used by other devices
*/
-
int pnp_disable_dev(struct pnp_dev *dev)
{
if (!dev)
@@ -699,21 +495,25 @@ int pnp_disable_dev(struct pnp_dev *dev)
if (!dev->active) {
return 0; /* the device is already disabled */
}
- if (dev->status != PNP_READY){
- pnp_info("res: Disable failed becuase the PnP device '%s' is busy.", dev->dev.bus_id);
- return -EINVAL;
- }
+
if (!pnp_can_disable(dev)) {
- pnp_info("res: Unable to disable the PnP device '%s' because this feature is not supported.", dev->dev.bus_id);
+ pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
return -EINVAL;
}
if (dev->protocol->disable(dev)<0) {
- pnp_err("res: The protocol '%s' reports that disabling the PnP device '%s' has failed.", dev->protocol->name, dev->dev.bus_id);
- return -1;
+ pnp_err("Failed to disable device %s.", dev->dev.bus_id);
+ return -EIO;
}
- dev->active = 0; /* just in case the protocol doesn't do this */
- pnp_dbg("res: the device '%s' has been disabled.", dev->dev.bus_id);
- return 0;
+
+ dev->active = 0;
+ pnp_info("Device %s disabled.", dev->dev.bus_id);
+
+ /* release the resources so that other devices can use them */
+ down(&pnp_res_mutex);
+ pnp_clean_resources(&dev->res);
+ up(&pnp_res_mutex);
+
+ return 1;
}
/**
@@ -723,7 +523,6 @@ int pnp_disable_dev(struct pnp_dev *dev)
* @size: size of region
*
*/
-
void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size)
{
if (resource == NULL)
@@ -734,19 +533,10 @@ void pnp_resource_change(struct resource *resource, unsigned long start, unsigne
}
-EXPORT_SYMBOL(pnp_auto_config_dev);
+EXPORT_SYMBOL(pnp_assign_resources);
EXPORT_SYMBOL(pnp_manual_config_dev);
+EXPORT_SYMBOL(pnp_auto_config_dev);
EXPORT_SYMBOL(pnp_activate_dev);
EXPORT_SYMBOL(pnp_disable_dev);
EXPORT_SYMBOL(pnp_resource_change);
-
-
-/* format is: pnp_max_moves=num */
-
-static int __init pnp_setup_max_moves(char *str)
-{
- get_option(&str,&pnp_max_moves);
- return 1;
-}
-
-__setup("pnp_max_moves=", pnp_setup_max_moves);
+EXPORT_SYMBOL(pnp_init_resources);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 1c370c9f1abd..56a5f43716f7 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -935,6 +935,10 @@ static int insert_device(struct pnp_dev *dev, struct pnp_bios_node * node)
dev->capabilities |= PNP_REMOVABLE;
dev->protocol = &pnpbios_protocol;
+ /* clear out the damaged flags */
+ if (!dev->active)
+ pnp_init_resources(&dev->res);
+
pnp_add_device(dev);
pnpbios_interface_attach_device(node);
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index dcb4570cd657..883f845a8d11 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -30,7 +30,7 @@
static void quirk_awe32_resources(struct pnp_dev *dev)
{
struct pnp_port *port, *port2, *port3;
- struct pnp_resources *res = dev->possible->dep;
+ struct pnp_option *res = dev->dependent;
/*
* Unfortunately the isapnp_add_port_resource is too tightly bound
@@ -38,7 +38,7 @@ static void quirk_awe32_resources(struct pnp_dev *dev)
* two extra ports (at offset 0x400 and 0x800 from the one given) by
* hand.
*/
- for ( ; res ; res = res->dep ) {
+ for ( ; res ; res = res->next ) {
port2 = pnp_alloc(sizeof(struct pnp_port));
if (!port2)
return;
@@ -62,9 +62,9 @@ static void quirk_awe32_resources(struct pnp_dev *dev)
static void quirk_cmi8330_resources(struct pnp_dev *dev)
{
- struct pnp_resources *res = dev->possible->dep;
+ struct pnp_option *res = dev->dependent;
- for ( ; res ; res = res->dep ) {
+ for ( ; res ; res = res->next ) {
struct pnp_irq *irq;
struct pnp_dma *dma;
@@ -82,7 +82,7 @@ static void quirk_cmi8330_resources(struct pnp_dev *dev)
static void quirk_sb16audio_resources(struct pnp_dev *dev)
{
struct pnp_port *port;
- struct pnp_resources *res = dev->possible->dep;
+ struct pnp_option *res = dev->dependent;
int changed = 0;
/*
@@ -91,7 +91,7 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
* auto-configured.
*/
- for( ; res ; res = res->dep ) {
+ for( ; res ; res = res->next ) {
port = res->port;
if(!port)
continue;
@@ -118,11 +118,11 @@ static void quirk_opl3sax_resources(struct pnp_dev *dev)
* doesn't allow a DMA channel of 0, afflicted card is an
* OPL3Sax where x=4.
*/
- struct pnp_resources *res;
+ struct pnp_option *res;
int max;
- res = dev->possible;
+ res = dev->dependent;
max = 0;
- for (res = res->dep; res; res = res->dep) {
+ for (; res; res = res->next) {
if (res->dma->map > max)
max = res->dma->map;
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 7e738da9e6ee..3259ed7c3789 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -10,18 +10,19 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/pci.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/irq.h>
+#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pnp.h>
#include "base.h"
-int pnp_allow_dma0 = -1; /* allow dma 0 during auto activation: -1=off (:default), 0=off (set by user), 1=on */
+int pnp_allow_dma0 = -1; /* allow dma 0 during auto activation:
+ * -1=off (:default), 0=off (set by user), 1=on */
int pnp_skip_pci_scan; /* skip PCI resource scanning */
int pnp_reserve_irq[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
int pnp_reserve_dma[8] = { [0 ... 7] = -1 }; /* reserve (don't use) some DMA */
@@ -30,88 +31,75 @@ int pnp_reserve_mem[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some memor
/*
- * possible resource registration
+ * option registration
*/
-struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent)
+static struct pnp_option * pnp_build_option(int priority)
{
- struct pnp_resources *res, *ptr, *ptra;
+ struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
- res = pnp_alloc(sizeof(struct pnp_resources));
- if (!res)
+ /* check if pnp_alloc ran out of memory */
+ if (!option)
return NULL;
- ptr = dev->possible;
- if (ptr) { /* add to another list */
- ptra = ptr->dep;
- while (ptra && ptra->dep)
- ptra = ptra->dep;
- if (!ptra)
- ptr->dep = res;
- else
- ptra->dep = res;
- } else
- dev->possible = res;
- if (dependent) {
- res->priority = dependent & 0xff;
- if (res->priority > PNP_RES_PRIORITY_FUNCTIONAL)
- res->priority = PNP_RES_PRIORITY_INVALID;
- } else
- res->priority = PNP_RES_PRIORITY_PREFERRED;
- return res;
+
+ option->priority = priority & 0xff;
+ /* make sure the priority is valid */
+ if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
+ option->priority = PNP_RES_PRIORITY_INVALID;
+
+ return option;
}
-struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum)
+struct pnp_option * pnp_register_independent_option(struct pnp_dev *dev)
{
- int i;
- struct pnp_resources *res;
+ struct pnp_option *option;
if (!dev)
return NULL;
- res = dev->possible;
- if (!res)
- return NULL;
- for (i = 0; i < depnum; i++)
- {
- if (res->dep)
- res = res->dep;
- else
- return NULL;
- }
- return res;
+
+ option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
+
+ /* this should never happen but if it does we'll try to continue */
+ if (dev->independent)
+ pnp_err("independent resource already registered");
+ dev->independent = option;
+ return option;
}
-int pnp_get_max_depnum(struct pnp_dev *dev)
+struct pnp_option * pnp_register_dependent_option(struct pnp_dev *dev, int priority)
{
- int num = 0;
- struct pnp_resources *res;
+ struct pnp_option *option;
if (!dev)
- return -EINVAL;
- res = dev->possible;
- if (!res)
- return -EINVAL;
- while (res->dep){
- res = res->dep;
- num++;
- }
- return num;
+ return NULL;
+
+ option = pnp_build_option(priority);
+
+ if (dev->dependent) {
+ struct pnp_option *parent = dev->dependent;
+ while (parent->next)
+ parent = parent->next;
+ parent->next = option;
+ } else
+ dev->dependent = option;
+ return option;
}
-int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data)
+int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
{
int i;
- struct pnp_resources *res;
struct pnp_irq *ptr;
- res = pnp_find_resources(dev,depnum);
- if (!res)
+ if (!option)
return -EINVAL;
if (!data)
return -EINVAL;
- ptr = res->irq;
+
+ ptr = option->irq;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
- res->irq = data;
+ option->irq = data;
+
#ifdef CONFIG_PCI
for (i=0; i<16; i++)
if (data->map & (1<<i))
@@ -120,60 +108,59 @@ int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data)
return 0;
}
-int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data)
+int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
{
- struct pnp_resources *res;
struct pnp_dma *ptr;
- res = pnp_find_resources(dev,depnum);
- if (!res)
+ if (!option)
return -EINVAL;
if (!data)
return -EINVAL;
- ptr = res->dma;
+
+ ptr = option->dma;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
- res->dma = data;
+ option->dma = data;
+
return 0;
}
-int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data)
+int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
{
- struct pnp_resources *res;
struct pnp_port *ptr;
- res = pnp_find_resources(dev,depnum);
- if (!res)
+ if (!option)
return -EINVAL;
if (!data)
return -EINVAL;
- ptr = res->port;
+
+ ptr = option->port;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
- res->port = data;
+ option->port = data;
+
return 0;
}
-int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data)
+int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
{
- struct pnp_resources *res;
struct pnp_mem *ptr;
- res = pnp_find_resources(dev,depnum);
- if (!res)
+ if (!option)
return -EINVAL;
if (!data)
return -EINVAL;
- ptr = res->mem;
+
+ ptr = option->mem;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
- res->mem = data;
+ option->mem = data;
return 0;
}
@@ -221,18 +208,18 @@ static void pnp_free_mem(struct pnp_mem *mem)
}
}
-void pnp_free_resources(struct pnp_resources *resources)
+void pnp_free_option(struct pnp_option *option)
{
- struct pnp_resources *next;
-
- while (resources) {
- next = resources->dep;
- pnp_free_port(resources->port);
- pnp_free_irq(resources->irq);
- pnp_free_dma(resources->dma);
- pnp_free_mem(resources->mem);
- kfree(resources);
- resources = next;
+ struct pnp_option *next;
+
+ while (option) {
+ next = option->next;
+ pnp_free_port(option->port);
+ pnp_free_irq(option->irq);
+ pnp_free_dma(option->dma);
+ pnp_free_mem(option->mem);
+ kfree(option);
+ option = next;
}
}
@@ -253,50 +240,23 @@ void pnp_free_resources(struct pnp_resources *resources)
(*(enda) >= *(startb) && *(enda) <= *(endb)) || \
(*(starta) < *(startb) && *(enda) > *(endb)))
-struct pnp_dev * pnp_check_port_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
- int tmp;
- unsigned long *port, *end, *tport, *tend;
- struct pnp_dev *tdev;
- port = &dev->res.port_resource[idx].start;
- end = &dev->res.port_resource[idx].end;
-
- /* if the resource doesn't exist, don't complain about it */
- if (dev->res.port_resource[idx].start == 0)
- return NULL;
-
- /* check for cold conflicts */
- pnp_for_each_dev(tdev) {
- /* Is the device configurable? */
- if (tdev == dev || (mode ? !tdev->active : tdev->active))
- continue;
- for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
- if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
- tport = &tdev->res.port_resource[tmp].start;
- tend = &tdev->res.port_resource[tmp].end;
- if (ranged_conflict(port,end,tport,tend))
- return tdev;
- }
- }
- }
- return NULL;
-}
-
int pnp_check_port(struct pnp_dev * dev, int idx)
{
int tmp;
+ struct pnp_dev *tdev;
unsigned long *port, *end, *tport, *tend;
port = &dev->res.port_resource[idx].start;
end = &dev->res.port_resource[idx].end;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.port_resource[idx].start == 0)
- return 0;
+ return 1;
- /* check if the resource is already in use, skip if the device is active because it itself may be in use */
+ /* check if the resource is already in use, skip if the
+ * device is active because it itself may be in use */
if(!dev->active) {
- if (check_region(*port, length(port,end)))
- return CONFLICT_TYPE_IN_USE;
+ if (__check_region(&ioport_resource, *port, length(port,end)))
+ return 0;
}
/* check if the resource is reserved */
@@ -304,7 +264,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx)
int rport = pnp_reserve_io[tmp << 1];
int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1;
if (ranged_conflict(port,end,&rport,&rend))
- return CONFLICT_TYPE_RESERVED;
+ return 0;
}
/* check for internal conflicts */
@@ -313,61 +273,44 @@ int pnp_check_port(struct pnp_dev * dev, int idx)
tport = &dev->res.port_resource[tmp].start;
tend = &dev->res.port_resource[tmp].end;
if (ranged_conflict(port,end,tport,tend))
- return CONFLICT_TYPE_INTERNAL;
+ return 0;
}
}
- /* check for warm conflicts */
- if (pnp_check_port_conflicts(dev, idx, SEARCH_WARM))
- return CONFLICT_TYPE_PNP_WARM;
-
- return 0;
-}
-
-struct pnp_dev * pnp_check_mem_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
- int tmp;
- unsigned long *addr, *end, *taddr, *tend;
- struct pnp_dev *tdev;
- addr = &dev->res.mem_resource[idx].start;
- end = &dev->res.mem_resource[idx].end;
-
- /* if the resource doesn't exist, don't complain about it */
- if (dev->res.mem_resource[idx].start == 0)
- return NULL;
-
- /* check for cold conflicts */
+ /* check for conflicts with other pnp devices */
pnp_for_each_dev(tdev) {
- /* Is the device configurable? */
- if (tdev == dev || (mode ? !tdev->active : tdev->active))
+ if (tdev == dev)
continue;
- for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
- if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
- taddr = &tdev->res.mem_resource[tmp].start;
- tend = &tdev->res.mem_resource[tmp].end;
- if (ranged_conflict(addr,end,taddr,tend))
- return tdev;
+ for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
+ if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
+ tport = &tdev->res.port_resource[tmp].start;
+ tend = &tdev->res.port_resource[tmp].end;
+ if (ranged_conflict(port,end,tport,tend))
+ return 0;
}
}
}
- return NULL;
+
+ return 1;
}
int pnp_check_mem(struct pnp_dev * dev, int idx)
{
int tmp;
+ struct pnp_dev *tdev;
unsigned long *addr, *end, *taddr, *tend;
addr = &dev->res.mem_resource[idx].start;
end = &dev->res.mem_resource[idx].end;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.mem_resource[idx].start == 0)
- return 0;
+ return 1;
- /* check if the resource is already in use, skip if the device is active because it itself may be in use */
+ /* check if the resource is already in use, skip if the
+ * device is active because it itself may be in use */
if(!dev->active) {
- if (__check_region(&iomem_resource, *addr, length(addr,end)))
- return CONFLICT_TYPE_IN_USE;
+ if (check_mem_region(*addr, length(addr,end)))
+ return 0;
}
/* check if the resource is reserved */
@@ -375,7 +318,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
int raddr = pnp_reserve_mem[tmp << 1];
int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1;
if (ranged_conflict(addr,end,&raddr,&rend))
- return CONFLICT_TYPE_RESERVED;
+ return 0;
}
/* check for internal conflicts */
@@ -384,40 +327,25 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
taddr = &dev->res.mem_resource[tmp].start;
tend = &dev->res.mem_resource[tmp].end;
if (ranged_conflict(addr,end,taddr,tend))
- return CONFLICT_TYPE_INTERNAL;
+ return 0;
}
}
- /* check for warm conflicts */
- if (pnp_check_mem_conflicts(dev, idx, SEARCH_WARM))
- return CONFLICT_TYPE_PNP_WARM;
-
- return 0;
-}
-
-struct pnp_dev * pnp_check_irq_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
- int tmp;
- struct pnp_dev * tdev;
- unsigned long * irq = &dev->res.irq_resource[idx].start;
-
- /* if the resource doesn't exist, don't complain about it */
- if (dev->res.irq_resource[idx].start == -1)
- return NULL;
-
- /* check for cold conflicts */
+ /* check for conflicts with other pnp devices */
pnp_for_each_dev(tdev) {
- /* Is the device configurable? */
- if (tdev == dev || (mode ? !tdev->active : tdev->active))
+ if (tdev == dev)
continue;
- for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
- if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
- if ((tdev->res.irq_resource[tmp].start == *irq))
- return tdev;
+ for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
+ if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
+ taddr = &tdev->res.mem_resource[tmp].start;
+ tend = &tdev->res.mem_resource[tmp].end;
+ if (ranged_conflict(addr,end,taddr,tend))
+ return 0;
}
}
}
- return NULL;
+
+ return 1;
}
static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
@@ -428,27 +356,28 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
int pnp_check_irq(struct pnp_dev * dev, int idx)
{
int tmp;
+ struct pnp_dev *tdev;
unsigned long * irq = &dev->res.irq_resource[idx].start;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.irq_resource[idx].start == -1)
- return 0;
+ return 1;
/* check if the resource is valid */
if (*irq < 0 || *irq > 15)
- return CONFLICT_TYPE_INVALID;
+ return 0;
/* check if the resource is reserved */
for (tmp = 0; tmp < 16; tmp++) {
if (pnp_reserve_irq[tmp] == *irq)
- return CONFLICT_TYPE_RESERVED;
+ return 0;
}
/* check for internal conflicts */
for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) {
if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
if (dev->res.irq_resource[tmp].start == *irq)
- return CONFLICT_TYPE_INTERNAL;
+ return 0;
}
}
@@ -458,233 +387,94 @@ int pnp_check_irq(struct pnp_dev * dev, int idx)
struct pci_dev * pci = NULL;
while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) {
if (pci->irq == *irq)
- return CONFLICT_TYPE_PCI;
+ return 0;
}
}
#endif
- /* check if the resource is already in use, skip if the device is active because it itself may be in use */
+ /* check if the resource is already in use, skip if the
+ * device is active because it itself may be in use */
if(!dev->active) {
if (request_irq(*irq, pnp_test_handler, SA_INTERRUPT, "pnp", NULL))
- return CONFLICT_TYPE_IN_USE;
+ return 0;
free_irq(*irq, NULL);
}
- /* check for warm conflicts */
- if (pnp_check_irq_conflicts(dev, idx, SEARCH_WARM))
- return CONFLICT_TYPE_PNP_WARM;
-
- return 0;
-}
-
-
-struct pnp_dev * pnp_check_dma_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
- int tmp;
- struct pnp_dev * tdev;
- unsigned long * dma = &dev->res.dma_resource[idx].start;
-
- /* if the resource doesn't exist, don't complain about it */
- if (dev->res.dma_resource[idx].start == -1)
- return NULL;
-
- /* check for cold conflicts */
+ /* check for conflicts with other pnp devices */
pnp_for_each_dev(tdev) {
- /* Is the device configurable? */
- if (tdev == dev || (mode ? !tdev->active : tdev->active))
+ if (tdev == dev)
continue;
- for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
- if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
- if ((tdev->res.dma_resource[tmp].start == *dma))
- return tdev;
+ for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
+ if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
+ if ((tdev->res.irq_resource[tmp].start == *irq))
+ return 0;
}
}
}
- return NULL;
+
+ return 1;
}
int pnp_check_dma(struct pnp_dev * dev, int idx)
{
int tmp, mindma = 1;
+ struct pnp_dev *tdev;
unsigned long * dma = &dev->res.dma_resource[idx].start;
/* if the resource doesn't exist, don't complain about it */
if (dev->res.dma_resource[idx].start == -1)
- return 0;
+ return 1;
/* check if the resource is valid */
if (pnp_allow_dma0 == 1)
mindma = 0;
if (*dma < mindma || *dma == 4 || *dma > 7)
- return CONFLICT_TYPE_INVALID;
+ return 0;
/* check if the resource is reserved */
for (tmp = 0; tmp < 8; tmp++) {
if (pnp_reserve_dma[tmp] == *dma)
- return CONFLICT_TYPE_RESERVED;
+ return 0;
}
/* check for internal conflicts */
for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) {
if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
if (dev->res.dma_resource[tmp].start == *dma)
- return CONFLICT_TYPE_INTERNAL;
+ return 0;
}
}
- /* check if the resource is already in use, skip if the device is active because it itself may be in use */
+ /* check if the resource is already in use, skip if the
+ * device is active because it itself may be in use */
if(!dev->active) {
if (request_dma(*dma, "pnp"))
- return CONFLICT_TYPE_IN_USE;
+ return 0;
free_dma(*dma);
}
- /* check for warm conflicts */
- if (pnp_check_dma_conflicts(dev, idx, SEARCH_WARM))
- return CONFLICT_TYPE_PNP_WARM;
- return 0;
-}
-
-
-/**
- * pnp_init_resource_table - Resets a resource table to default values.
- * @table: pointer to the desired resource table
- *
- */
-
-void pnp_init_resource_table(struct pnp_resource_table *table)
-{
- int idx;
- for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
- table->irq_resource[idx].name = NULL;
- table->irq_resource[idx].start = -1;
- table->irq_resource[idx].end = -1;
- table->irq_resource[idx].flags = IORESOURCE_AUTO;
- }
- for (idx = 0; idx < PNP_MAX_DMA; idx++) {
- table->dma_resource[idx].name = NULL;
- table->dma_resource[idx].start = -1;
- table->dma_resource[idx].end = -1;
- table->dma_resource[idx].flags = IORESOURCE_AUTO;
- }
- for (idx = 0; idx < PNP_MAX_PORT; idx++) {
- table->port_resource[idx].name = NULL;
- table->port_resource[idx].start = 0;
- table->port_resource[idx].end = 0;
- table->port_resource[idx].flags = IORESOURCE_AUTO;
- }
- for (idx = 0; idx < PNP_MAX_MEM; idx++) {
- table->mem_resource[idx].name = NULL;
- table->mem_resource[idx].start = 0;
- table->mem_resource[idx].end = 0;
- table->mem_resource[idx].flags = IORESOURCE_AUTO;
- }
-}
-
-
-/**
- * pnp_generate_rule - Creates a rule table structure based on depnum and device.
- * @dev: pointer to the desired device
- * @depnum: dependent function, if not valid will return an error
- * @rule: pointer to a rule structure to record data to
- *
- */
-
-int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * rule)
-{
- int nport = 0, nirq = 0, ndma = 0, nmem = 0;
- struct pnp_resources * res;
- struct pnp_port * port;
- struct pnp_mem * mem;
- struct pnp_irq * irq;
- struct pnp_dma * dma;
-
- if (depnum < 0 || !rule)
- return -EINVAL;
-
- /* independent */
- res = pnp_find_resources(dev, 0);
- if (!res)
- return -ENODEV;
- port = res->port;
- mem = res->mem;
- irq = res->irq;
- dma = res->dma;
- while (port){
- rule->port[nport] = port;
- nport++;
- port = port->next;
- }
- while (mem){
- rule->mem[nmem] = mem;
- nmem++;
- mem = mem->next;
- }
- while (irq){
- rule->irq[nirq] = irq;
- nirq++;
- irq = irq->next;
- }
- while (dma){
- rule->dma[ndma] = dma;
- ndma++;
- dma = dma->next;
- }
-
- /* dependent */
- if (depnum == 0)
- return 1;
- res = pnp_find_resources(dev, depnum);
- if (!res)
- return -ENODEV;
- port = res->port;
- mem = res->mem;
- irq = res->irq;
- dma = res->dma;
- while (port){
- rule->port[nport] = port;
- nport++;
- port = port->next;
- }
- while (mem){
- rule->mem[nmem] = mem;
- nmem++;
- mem = mem->next;
- }
-
- while (irq){
- rule->irq[nirq] = irq;
- nirq++;
- irq = irq->next;
- }
- while (dma){
- rule->dma[ndma] = dma;
- ndma++;
- dma = dma->next;
+ /* check for conflicts with other pnp devices */
+ pnp_for_each_dev(tdev) {
+ if (tdev == dev)
+ continue;
+ for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
+ if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
+ if ((tdev->res.dma_resource[tmp].start == *dma))
+ return 0;
+ }
+ }
}
- /* clear the remaining values */
- for (; nport < PNP_MAX_PORT; nport++)
- rule->port[nport] = NULL;
- for (; nmem < PNP_MAX_MEM; nmem++)
- rule->mem[nmem] = NULL;
- for (; nirq < PNP_MAX_IRQ; nirq++)
- rule->irq[nirq] = NULL;
- for (; ndma < PNP_MAX_DMA; ndma++)
- rule->dma[ndma] = NULL;
return 1;
}
-EXPORT_SYMBOL(pnp_build_resource);
-EXPORT_SYMBOL(pnp_find_resources);
-EXPORT_SYMBOL(pnp_get_max_depnum);
-EXPORT_SYMBOL(pnp_add_irq_resource);
-EXPORT_SYMBOL(pnp_add_dma_resource);
-EXPORT_SYMBOL(pnp_add_port_resource);
-EXPORT_SYMBOL(pnp_add_mem_resource);
-EXPORT_SYMBOL(pnp_init_resource_table);
-EXPORT_SYMBOL(pnp_generate_rule);
+EXPORT_SYMBOL(pnp_register_dependent_option);
+EXPORT_SYMBOL(pnp_register_independent_option);
+EXPORT_SYMBOL(pnp_register_irq_resource);
+EXPORT_SYMBOL(pnp_register_dma_resource);
+EXPORT_SYMBOL(pnp_register_port_resource);
+EXPORT_SYMBOL(pnp_register_mem_resource);
/* format is: allowdma0 */
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index c54cf87fb8cc..f7a88a86c9c0 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -1,7 +1,7 @@
/*
* support.c - provides standard pnp functions for the use of pnp protocol drivers,
*
- * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
+ * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
*
* Resource parsing functions are based on those in the linux pnpbios driver.
* Copyright Christian Schmidt, Tom Lees, David Hinds, Alan Cox, Thomas Hood,
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/ctype.h>
#ifdef CONFIG_PNP_DEBUG
#define DEBUG
@@ -122,7 +123,7 @@ unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * e
return NULL;
/* Blank the resource table values */
- pnp_init_resource_table(res);
+ pnp_init_resources(res);
while ((char *)p < (char *)end) {
@@ -250,51 +251,51 @@ unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * e
* Possible resource reading functions *
*/
-static void possible_mem(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_mem(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_mem * mem;
mem = pnp_alloc(sizeof(struct pnp_mem));
if (!mem)
return;
- mem->min = ((p[3] << 8) | p[2]) << 8;
- mem->max = ((p[5] << 8) | p[4]) << 8;
- mem->align = (p[7] << 8) | p[6];
- mem->size = ((p[9] << 8) | p[8]) << 8;
- mem->flags = p[1];
- pnp_add_mem_resource(dev,depnum,mem);
+ mem->min = ((p[5] << 8) | p[4]) << 8;
+ mem->max = ((p[7] << 8) | p[6]) << 8;
+ mem->align = (p[9] << 8) | p[8];
+ mem->size = ((p[11] << 8) | p[10]) << 8;
+ mem->flags = p[3];
+ pnp_register_mem_resource(option,mem);
return;
}
-static void possible_mem32(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_mem32(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_mem * mem;
mem = pnp_alloc(sizeof(struct pnp_mem));
if (!mem)
return;
- mem->min = (p[5] << 24) | (p[4] << 16) | (p[3] << 8) | p[2];
- mem->max = (p[9] << 24) | (p[8] << 16) | (p[7] << 8) | p[6];
- mem->align = (p[13] << 24) | (p[12] << 16) | (p[11] << 8) | p[10];
- mem->size = (p[17] << 24) | (p[16] << 16) | (p[15] << 8) | p[14];
- mem->flags = p[1];
- pnp_add_mem_resource(dev,depnum,mem);
+ mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+ mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
+ mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
+ mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
+ mem->flags = p[3];
+ pnp_register_mem_resource(option,mem);
return;
}
-static void possible_fixed_mem32(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_fixed_mem32(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_mem * mem;
mem = pnp_alloc(sizeof(struct pnp_mem));
if (!mem)
return;
- mem->min = mem->max = (p[5] << 24) | (p[4] << 16) | (p[3] << 8) | p[2];
- mem->size = (p[9] << 24) | (p[8] << 16) | (p[7] << 8) | p[6];
+ mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+ mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
mem->align = 0;
- mem->flags = p[1];
- pnp_add_mem_resource(dev,depnum,mem);
+ mem->flags = p[3];
+ pnp_register_mem_resource(option,mem);
return;
}
-static void possible_irq(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_irq(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_irq * irq;
irq = pnp_alloc(sizeof(struct pnp_irq));
@@ -303,11 +304,13 @@ static void possible_irq(unsigned char *p, int size, int depnum, struct pnp_dev
irq->map = (p[2] << 8) | p[1];
if (size > 2)
irq->flags = p[3];
- pnp_add_irq_resource(dev,depnum,irq);
+ else
+ irq->flags = IORESOURCE_IRQ_HIGHEDGE;
+ pnp_register_irq_resource(option,irq);
return;
}
-static void possible_dma(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_dma(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_dma * dma;
dma = pnp_alloc(sizeof(struct pnp_dma));
@@ -315,11 +318,11 @@ static void possible_dma(unsigned char *p, int size, int depnum, struct pnp_dev
return;
dma->map = p[1];
dma->flags = p[2];
- pnp_add_dma_resource(dev,depnum,dma);
+ pnp_register_dma_resource(option,dma);
return;
}
-static void possible_port(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_port(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_port * port;
port = pnp_alloc(sizeof(struct pnp_port));
@@ -330,11 +333,11 @@ static void possible_port(unsigned char *p, int size, int depnum, struct pnp_dev
port->align = p[6];
port->size = p[7];
port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
- pnp_add_port_resource(dev,depnum,port);
+ pnp_register_port_resource(option,port);
return;
}
-static void possible_fixed_port(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_fixed_port(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_port * port;
port = pnp_alloc(sizeof(struct pnp_port));
@@ -344,7 +347,7 @@ static void possible_fixed_port(unsigned char *p, int size, int depnum, struct p
port->size = p[3];
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
- pnp_add_port_resource(dev,depnum,port);
+ pnp_register_port_resource(option,port);
return;
}
@@ -358,12 +361,14 @@ static void possible_fixed_port(unsigned char *p, int size, int depnum, struct p
unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char * end, struct pnp_dev *dev)
{
- int len, depnum = 0, dependent = 0;
+ int len, priority = 0;
+ struct pnp_option *option;
if (!p)
return NULL;
- if (pnp_build_resource(dev, 0) == NULL)
+ option = pnp_register_independent_option(dev);
+ if (!option)
return NULL;
while ((char *)p < (char *)end) {
@@ -375,21 +380,21 @@ unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char *
{
if (len != 9)
goto lrg_err;
- possible_mem(p,len,depnum,dev);
+ possible_mem(p,len,option);
break;
}
case LARGE_TAG_MEM32:
{
if (len != 17)
goto lrg_err;
- possible_mem32(p,len,depnum,dev);
+ possible_mem32(p,len,option);
break;
}
case LARGE_TAG_FIXEDMEM32:
{
if (len != 9)
goto lrg_err;
- possible_fixed_mem32(p,len,depnum,dev);
+ possible_fixed_mem32(p,len,option);
break;
}
default: /* an unkown tag */
@@ -410,46 +415,46 @@ unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char *
{
if (len < 2 || len > 3)
goto sm_err;
- possible_irq(p,len,depnum,dev);
+ possible_irq(p,len,option);
break;
}
case SMALL_TAG_DMA:
{
if (len != 2)
goto sm_err;
- possible_dma(p,len,depnum,dev);
+ possible_dma(p,len,option);
break;
}
case SMALL_TAG_STARTDEP:
{
if (len > 1)
goto sm_err;
- dependent = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+ priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
if (len > 0)
- dependent = 0x100 | p[1];
- pnp_build_resource(dev,dependent);
- depnum = pnp_get_max_depnum(dev);
+ priority = 0x100 | p[1];
+ option = pnp_register_dependent_option(dev, priority);
+ if (!option)
+ return NULL;
break;
}
case SMALL_TAG_ENDDEP:
{
if (len != 0)
goto sm_err;
- depnum = 0;
break;
}
case SMALL_TAG_PORT:
{
if (len != 7)
goto sm_err;
- possible_port(p,len,depnum,dev);
+ possible_port(p,len,option);
break;
}
case SMALL_TAG_FIXEDPORT:
{
if (len != 3)
goto sm_err;
- possible_fixed_port(p,len,depnum,dev);
+ possible_fixed_port(p,len,option);
break;
}
case SMALL_TAG_END:
@@ -481,12 +486,12 @@ static void write_mem(unsigned char *p, struct resource * res)
{
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
- p[2] = (base >> 8) & 0xff;
- p[3] = ((base >> 8) >> 8) & 0xff;
p[4] = (base >> 8) & 0xff;
p[5] = ((base >> 8) >> 8) & 0xff;
- p[8] = (len >> 8) & 0xff;
- p[9] = ((len >> 8) >> 8) & 0xff;
+ p[6] = (base >> 8) & 0xff;
+ p[7] = ((base >> 8) >> 8) & 0xff;
+ p[10] = (len >> 8) & 0xff;
+ p[11] = ((len >> 8) >> 8) & 0xff;
return;
}
@@ -494,32 +499,32 @@ static void write_mem32(unsigned char *p, struct resource * res)
{
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
- p[2] = base & 0xff;
- p[3] = (base >> 8) & 0xff;
- p[4] = (base >> 16) & 0xff;
- p[5] = (base >> 24) & 0xff;
- p[6] = base & 0xff;
- p[7] = (base >> 8) & 0xff;
- p[8] = (base >> 16) & 0xff;
- p[9] = (base >> 24) & 0xff;
- p[14] = len & 0xff;
- p[15] = (len >> 8) & 0xff;
- p[16] = (len >> 16) & 0xff;
- p[17] = (len >> 24) & 0xff;
+ p[4] = base & 0xff;
+ p[5] = (base >> 8) & 0xff;
+ p[6] = (base >> 16) & 0xff;
+ p[7] = (base >> 24) & 0xff;
+ p[8] = base & 0xff;
+ p[9] = (base >> 8) & 0xff;
+ p[10] = (base >> 16) & 0xff;
+ p[11] = (base >> 24) & 0xff;
+ p[16] = len & 0xff;
+ p[17] = (len >> 8) & 0xff;
+ p[18] = (len >> 16) & 0xff;
+ p[19] = (len >> 24) & 0xff;
return;
}
static void write_fixed_mem32(unsigned char *p, struct resource * res)
{ unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
- p[2] = base & 0xff;
- p[3] = (base >> 8) & 0xff;
- p[4] = (base >> 16) & 0xff;
- p[5] = (base >> 24) & 0xff;
- p[6] = len & 0xff;
- p[7] = (len >> 8) & 0xff;
- p[8] = (len >> 16) & 0xff;
- p[9] = (len >> 24) & 0xff;
+ p[4] = base & 0xff;
+ p[5] = (base >> 8) & 0xff;
+ p[6] = (base >> 16) & 0xff;
+ p[7] = (base >> 24) & 0xff;
+ p[8] = len & 0xff;
+ p[9] = (len >> 8) & 0xff;
+ p[10] = (len >> 16) & 0xff;
+ p[11] = (len >> 24) & 0xff;
return;
}
@@ -630,7 +635,7 @@ unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, stru
{
if (len != 2)
goto sm_err;
- write_dma(p, &res->dma_resource[irq]);
+ write_dma(p, &res->dma_resource[dma]);
dma++;
break;
}
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 2b011aa1627f..6d6f9333a8c4 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1518,7 +1518,7 @@ static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* psg)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
// Get rid of old data
psg->count = cpu_to_le32(0);
- psg->sg[0].addr = cpu_to_le32(NULL);
+ psg->sg[0].addr = cpu_to_le32(0);
psg->sg[0].count = cpu_to_le32(0);
if (scsicmd->use_sg) {
struct scatterlist *sg;
@@ -1558,7 +1558,7 @@ static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* psg)
psg->count = cpu_to_le32(1);
psg->sg[0].addr = cpu_to_le32(addr);
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
- scsicmd->SCp.ptr = (char *)addr;
+ scsicmd->SCp.ptr = (char *)(ulong)addr;
byte_count = scsicmd->request_bufflen;
}
return byte_count;
@@ -1574,8 +1574,8 @@ static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
// Get rid of old data
psg->count = cpu_to_le32(0);
- psg->sg[0].addr[0] = cpu_to_le32(NULL);
- psg->sg[0].addr[1] = cpu_to_le32(NULL);
+ psg->sg[0].addr[0] = cpu_to_le32(0);
+ psg->sg[0].addr[1] = cpu_to_le32(0);
psg->sg[0].count = cpu_to_le32(0);
if (scsicmd->use_sg) {
struct scatterlist *sg;
@@ -1619,7 +1619,7 @@ static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg)
psg->sg[0].addr[1] = (u32)(le_addr>>32);
psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
- scsicmd->SCp.ptr = (char *)addr;
+ scsicmd->SCp.ptr = (char *)(ulong)addr;
byte_count = scsicmd->request_bufflen;
}
return byte_count;
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 43e88edf464e..4071cbaab81d 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -52,9 +52,11 @@ static int ahd_linux_pci_dev_probe(struct pci_dev *pdev,
const struct pci_device_id *ent);
static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
u_long *base, u_long *base2);
+#ifdef MMAPIO
static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr,
uint8_t **maddr);
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
static void ahd_linux_pci_dev_remove(struct pci_dev *pdev);
@@ -271,6 +273,7 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
return (0);
}
+#ifdef MMAPIO
static int
ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr,
@@ -318,6 +321,7 @@ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
error = ENOMEM;
return (error);
}
+#endif
int
ahd_pci_map_registers(struct ahd_softc *ahd)
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index ee8ddf6f6866..31320862d25c 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -235,18 +235,17 @@ powertecscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length)
* of the required information.
* offset - offset into information that we have read upto.
* length - length of buffer
- * host_no - host number to return information for
* inout - 0 for reading, 1 for writing.
* Returns : length of data written to buffer.
*/
int powertecscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
- int length, int host_no, int inout)
+ int length, int inout)
{
struct powertec_info *info;
char *p = buffer;
int pos;
- If (inout == 1)
+ if (inout == 1)
return powertecscsi_set_proc_info(host, buffer, length);
info = (struct powertec_info *)host->hostdata;
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 4fd3f6f55141..a798bdf9c446 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -583,8 +583,6 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
sdev->host->host_no, sdev->channel,
sdev->id, sdev->lun);
- scsi_device_register(sdev);
-
/*
* End driverfs/devfs code.
*/
@@ -647,11 +645,18 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
sdev->use_10_for_rw = 1;
- sdev->use_10_for_ms = 0;
+ sdev->use_10_for_ms = 1;
if(sdev->host->hostt->slave_configure)
sdev->host->hostt->slave_configure(sdev);
+ /*
+ * Ok, the device is now all set up, we can
+ * register it and tell the rest of the kernel
+ * about it.
+ */
+ scsi_device_register(sdev);
+
return SCSI_SCAN_LUN_PRESENT;
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 31714438236b..a8010099008d 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -12,13 +12,12 @@
Copyright 1992 - 2003 Kai Makisara
email Kai.Makisara@kolumbus.fi
- Last modified: Sun Apr 13 10:17:18 2003 by makisara
Some small formal changes - aeb, 950809
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
-static char *verstr = "20030413";
+static char *verstr = "20030622";
#include <linux/module.h>
@@ -1555,6 +1554,7 @@ static ssize_t
}
} else {
filp->f_pos -= do_count;
+ count += do_count;
STps->drv_block = (-1); /* Too cautious? */
retval = (-EIO);
}
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index f44dba00d35b..d21396e514e6 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -315,19 +315,6 @@ static const struct pnp_device_id pnp_dev_table[] = {
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
-static inline void avoid_irq_share(struct pnp_dev *dev)
-{
- unsigned int map = 0x1FF8;
- struct pnp_irq *irq;
- struct pnp_resources *res = dev->possible;
-
- serial8250_get_irq_map(&map);
-
- for ( ; res; res = res->dep)
- for (irq = res->irq; irq; irq = irq->next)
- irq->map = map;
-}
-
static char *modem_names[] __devinitdata = {
"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
"56K", "56k", "K56", "33.6", "28.8", "14.4",
@@ -346,6 +333,29 @@ static int __devinit check_name(char *name)
return 0;
}
+static int __devinit check_resources(struct pnp_option *option)
+{
+ struct pnp_option *tmp;
+ if (!option)
+ return 0;
+
+ for (tmp = option; tmp; tmp = tmp->next) {
+ struct pnp_port *port;
+ for (port = tmp->port; port; port = port->next)
+ if ((port->size == 8) &&
+ ((port->min == 0x2f8) ||
+ (port->min == 0x3f8) ||
+ (port->min == 0x2e8) ||
+#ifdef CONFIG_X86_PC9800
+ (port->min == 0x8b0) ||
+#endif
+ (port->min == 0x3e8)))
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Given a complete unknown PnP device, try to use some heuristics to
* detect modems. Currently use such heuristic set:
@@ -357,30 +367,16 @@ static int __devinit check_name(char *name)
* PnP modems, alternatively we must hardcode all modems in pnp_devices[]
* table.
*/
-static int serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
+static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
{
- struct pnp_resources *res = dev->possible;
- struct pnp_resources *resa;
-
if (!(check_name(dev->dev.name) || (dev->card && check_name(dev->card->dev.name))))
return -ENODEV;
- if (!res)
- return -ENODEV;
+ if (check_resources(dev->independent))
+ return 0;
- for (resa = res->dep; resa; resa = resa->dep) {
- struct pnp_port *port;
- for (port = res->port; port; port = port->next)
- if ((port->size == 8) &&
- ((port->min == 0x2f8) ||
- (port->min == 0x3f8) ||
- (port->min == 0x2e8) ||
-#ifdef CONFIG_X86_PC9800
- (port->min == 0x8b0) ||
-#endif
- (port->min == 0x3e8)))
- return 0;
- }
+ if (check_resources(dev->dependent))
+ return 0;
return -ENODEV;
}
@@ -395,8 +391,6 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
if (ret < 0)
return ret;
}
- if (flags & SPCI_FL_NO_SHIRQ)
- avoid_irq_share(dev);
memset(&serial_req, 0, sizeof(serial_req));
serial_req.irq = pnp_irq(dev,0);
serial_req.port = pnp_port_start(dev, 0);
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index fe9c12cc0b38..74d68c51b957 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -7247,8 +7247,8 @@ static int ixj_get_status_proc(char *buf)
len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
- len += sprintf(buf + len, "\nsizeof IXJ struct %d bytes", sizeof(IXJ));
- len += sprintf(buf + len, "\nsizeof DAA struct %d bytes", sizeof(DAA_REGS));
+ len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ));
+ len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS));
len += sprintf(buf + len, "\nUsing old telephony API");
len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug);
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 44ebbce3443c..6d46a4e848d9 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -1213,7 +1213,7 @@ typedef struct {
#endif
char *read_buffer, *read_buffer_end;
char *read_convert_buffer;
- unsigned int read_buffer_size;
+ size_t read_buffer_size;
unsigned int read_buffer_ready;
#if LINUX_VERSION_CODE < 0x020400
struct wait_queue *write_q;
@@ -1222,7 +1222,7 @@ typedef struct {
#endif
char *write_buffer, *write_buffer_end;
char *write_convert_buffer;
- unsigned int write_buffer_size;
+ size_t write_buffer_size;
unsigned int write_buffers_empty;
unsigned long drybuffer;
char *write_buffer_rp, *write_buffer_wp;
@@ -1281,7 +1281,7 @@ typedef struct {
unsigned char fskcnt;
unsigned int cidsize;
unsigned int cidcnt;
- unsigned pstn_cid_received;
+ unsigned long pstn_cid_received;
PHONE_CID cid;
PHONE_CID cid_send;
unsigned long pstn_ring_int;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index dbfe5c8dcf2a..9526be598c14 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -974,7 +974,7 @@ static const struct hc_driver ehci_driver = {
/* EHCI spec says PCI is required. */
/* PCI driver selection metadata; PCI hotplugging uses this */
-static const struct pci_device_id __devinitdata pci_ids [] = { {
+static struct pci_device_id __devinitdata pci_ids [] = { {
/* handle any USB 2.0 EHCI controller */
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index fcf856645aaa..80822ed23a6c 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -215,7 +215,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
return -1;
}
- if (parser->global.logical_maximum <= parser->global.logical_minimum) {
+ if (parser->global.logical_maximum < parser->global.logical_minimum) {
dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
return -1;
}
@@ -674,7 +674,6 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
if (item.format != HID_ITEM_FORMAT_SHORT) {
dbg("unexpected long global item");
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -684,7 +683,6 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
if (dispatch_type[item.type](parser, &item)) {
dbg("item %u %u %u %u parsing failed\n",
item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -694,7 +692,6 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
if (start == end) {
if (parser->collection_stack_ptr) {
dbg("unbalanced collection at end of report description");
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -702,7 +699,6 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
}
if (parser->local.delimiter_depth) {
dbg("unbalanced delimiter at end of report description");
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -714,7 +710,6 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
}
dbg("item fetching failed at offset %d\n", (int)(end - start));
- kfree(device->rdesc);
kfree(device->collection);
hid_free_device(device);
kfree(parser);
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index d5b8294a2fa1..31591a9d6ea3 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -189,7 +189,7 @@ static int adfs_remount(struct super_block *sb, int *flags, char *data)
return parse_options(sb, data);
}
-static int adfs_statfs(struct super_block *sb, struct statfs *buf)
+static int adfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct adfs_sb_info *asb = ADFS_SB(sb);
@@ -200,7 +200,7 @@ static int adfs_statfs(struct super_block *sb, struct statfs *buf)
buf->f_files = asb->s_ids_per_zone * asb->s_map_size;
buf->f_bavail =
buf->f_bfree = adfs_map_free(sb);
- buf->f_ffree = buf->f_bfree * buf->f_files / buf->f_blocks;
+ buf->f_ffree = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks;
return 0;
}
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 61c71fe3f785..5a07bcd17f60 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -33,7 +33,7 @@
extern struct timezone sys_tz;
-static int affs_statfs(struct super_block *sb, struct statfs *buf);
+static int affs_statfs(struct super_block *sb, struct kstatfs *buf);
static int affs_remount (struct super_block *sb, int *flags, char *data);
static void
@@ -524,7 +524,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
}
static int
-affs_statfs(struct super_block *sb, struct statfs *buf)
+affs_statfs(struct super_block *sb, struct kstatfs *buf)
{
int free;
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 5295f9d97c84..4fb5a163e50d 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -47,7 +47,7 @@ static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
char **out, int *out_len);
static void befs_put_super(struct super_block *);
static int befs_remount(struct super_block *, int *, char *);
-static int befs_statfs(struct super_block *, struct statfs *);
+static int befs_statfs(struct super_block *, struct kstatfs *);
static int parse_options(char *, befs_mount_options *);
static const struct super_operations befs_sops = {
@@ -896,7 +896,7 @@ befs_remount(struct super_block *sb, int *flags, char *data)
}
static int
-befs_statfs(struct super_block *sb, struct statfs *buf)
+befs_statfs(struct super_block *sb, struct kstatfs *buf)
{
befs_debug(sb, "---> befs_statfs()");
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 7a28495b0a87..1cd9f94879a5 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -191,7 +191,7 @@ static void bfs_put_super(struct super_block *s)
s->s_fs_info = NULL;
}
-static int bfs_statfs(struct super_block *s, struct statfs *buf)
+static int bfs_statfs(struct super_block *s, struct kstatfs *buf)
{
struct bfs_sb_info *info = BFS_SB(s);
buf->f_type = BFS_MAGIC;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 929b9a9df594..20b21e9e0ea0 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -697,7 +697,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
load_bias += error -
ELF_PAGESTART(load_bias + vaddr);
load_addr += load_bias;
- reloc_func_desc = load_addr;
+ reloc_func_desc = load_bias;
}
}
k = elf_ppnt->p_vaddr;
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 0a02aa2bde50..03af9fb35147 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,17 @@
+Version 0.80
+-----------
+Fix oops on stopping oplock thread when removing cifs when
+built as module.
+
+Version 0.79
+------------
+Fix mount options for ro (readonly), uid, gid and file and directory mode.
+
+Version 0.78
+------------
+Fix errors displayed on failed mounts to be more understandable.
+Fixed various incorrect or misleading smb to posix error code mappings.
+
Version 0.77
------------
Fix display of NTFS DFS junctions to display as symlinks.
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index b6af49330e4c..a59742e0474b 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -432,7 +432,7 @@ static int
compare_oid(unsigned long *oid1, unsigned int oid1len,
unsigned long *oid2, unsigned int oid2len)
{
- int i;
+ unsigned int i;
if (oid1len != oid2len)
return 0;
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 8574b4d014af..8007c2e925f5 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -24,5 +24,9 @@ struct cifs_sb_info {
struct nls_table *local_nls;
unsigned int rsize;
unsigned int wsize;
+ uid_t mnt_uid;
+ gid_t mnt_gid;
+ mode_t mnt_file_mode;
+ mode_t mnt_dir_mode;
};
#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index ea19ac025e5b..1b3c43949f33 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -62,6 +62,9 @@ extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
void cifs_proc_init(void);
void cifs_proc_clean(void);
+static DECLARE_COMPLETION(cifs_oplock_exited);
+
+
static int
cifs_read_super(struct super_block *sb, void *data,
const char *devname, int silent)
@@ -143,7 +146,7 @@ cifs_put_super(struct super_block *sb)
}
int
-cifs_statfs(struct super_block *sb, struct statfs *buf)
+cifs_statfs(struct super_block *sb, struct kstatfs *buf)
{
int xid, rc;
struct cifs_sb_info *cifs_sb;
@@ -427,7 +430,8 @@ cifs_destroy_mids(void)
"cifs_destroy_mids: error not all structures were freed\n");
if (kmem_cache_destroy(cifs_oplock_cachep))
printk(KERN_WARNING
- "error not all oplock structures were freed\n");}
+ "error not all oplock structures were freed\n");
+}
static int cifs_oplock_thread(void * dummyarg)
{
@@ -439,14 +443,13 @@ static int cifs_oplock_thread(void * dummyarg)
int rc;
daemonize("cifsoplockd");
- allow_signal(SIGKILL);
+ allow_signal(SIGTERM);
oplockThread = current;
- while (1) {
+ do {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(100*HZ);
/* BB add missing code */
- cFYI(1,("oplock thread woken up - flush inode")); /* BB remove */
write_lock(&GlobalMid_Lock);
list_for_each_safe(tmp, tmp1, &GlobalOplock_Q) {
oplock_item = list_entry(tmp, struct oplock_q_entry,
@@ -466,11 +469,10 @@ static int cifs_oplock_thread(void * dummyarg)
write_lock(&GlobalMid_Lock);
} else
break;
- cFYI(1,("next time through list")); /* BB remove */
}
write_unlock(&GlobalMid_Lock);
- cFYI(1,("next time through while loop")); /* BB remove */
- }
+ } while(!signal_pending(current));
+ complete_and_exit (&cifs_oplock_exited, 0);
}
static int __init
@@ -532,8 +534,10 @@ exit_cifs(void)
cifs_destroy_inodecache();
cifs_destroy_mids();
cifs_destroy_request_bufs();
- if(oplockThread)
- send_sig(SIGKILL, oplockThread, 1);
+ if(oplockThread) {
+ send_sig(SIGTERM, oplockThread, 1);
+ wait_for_completion(&cifs_oplock_exited);
+ }
}
MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 0506717b6c54..e557442f61fd 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -49,7 +49,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
extern int is_valid_oplock_break(struct smb_hdr *smb);
-extern int smbCalcSize(struct smb_hdr *ptr);
+extern unsigned int smbCalcSize(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
enum securityEnum *secType);
extern int map_smb_to_linux_error(struct smb_hdr *smb);
@@ -137,7 +137,7 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path, const struct nls_table *nls_codepage,
unsigned int *pnum_referrals, unsigned char ** preferrals);
extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
- struct statfs *FSData,
+ struct kstatfs *FSData,
const struct nls_table *nls_codepage);
extern int CIFSSMBQFSAttributeInfo(const int xid,
struct cifsTconInfo *tcon,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 978f5cacd82a..1d2d347e3adb 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1782,7 +1782,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
int
CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
- struct statfs *FSData, const struct nls_table *nls_codepage)
+ struct kstatfs *FSData, const struct nls_table *nls_codepage)
{
/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -1846,8 +1846,9 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
FSData->f_bfree = FSData->f_bavail =
le64_to_cpu(response_data->FreeAllocationUnits);
cFYI(1,
- ("Blocks: %ld Free: %ld Block size %ld",
- FSData->f_blocks, FSData->f_bfree,
+ ("Blocks: %lld Free: %lld Block size %ld",
+ (unsigned long long)FSData->f_blocks,
+ (unsigned long long)FSData->f_bfree,
FSData->f_bsize));
}
}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index b38669111dde..add558cc01af 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -53,7 +53,7 @@ struct smb_vol {
char *UNC;
char *UNCip;
uid_t linux_uid;
- uid_t linux_gid;
+ gid_t linux_gid;
mode_t file_mode;
mode_t dir_mode;
int rw;
@@ -136,8 +136,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
int
cifs_demultiplex_thread(struct TCP_Server_Info *server)
{
- int length, total_read;
- unsigned int pdu_length;
+ int length;
+ unsigned int pdu_length, total_read;
struct smb_hdr *smb_buffer = NULL;
struct msghdr smb_msg;
mm_segment_t temp_fs;
@@ -351,6 +351,10 @@ parse_mount_options(char *options, const char *devname, struct smb_vol *vol)
memset(vol,0,sizeof(struct smb_vol));
vol->linux_uid = current->uid; /* current->euid instead? */
vol->linux_gid = current->gid;
+ vol->dir_mode = S_IRWXUGO;
+ /* 2767 perms indicate mandatory locking support */
+ vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
+
vol->rw = TRUE;
if (!options)
@@ -466,6 +470,8 @@ parse_mount_options(char *options, const char *devname, struct smb_vol *vol)
/* ignore */
} else if (strnicmp(data, "rw", 2) == 0) {
vol->rw = TRUE;
+ } else if (strnicmp(data, "ro", 2) == 0) {
+ vol->rw = FALSE;
} else
printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
}
@@ -929,8 +935,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->rsize = PAGE_CACHE_SIZE;
cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
}
-
-
+ cifs_sb->mnt_uid = volume_info.linux_uid;
+ cifs_sb->mnt_gid = volume_info.linux_gid;
+ cifs_sb->mnt_file_mode = volume_info.file_mode;
+ cifs_sb->mnt_dir_mode = volume_info.dir_mode;
+ cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
tcon =
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
volume_info.username);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index d4345e45c403..de7dd7908890 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -123,8 +123,8 @@ cifs_open(struct inode *inode, struct file *file)
to problems creating new read-only files */
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
- 0xFFFFFFFFFFFFFFFF,
- 0xFFFFFFFFFFFFFFFF,
+ (__u64)-1,
+ (__u64)-1,
cifs_sb->local_nls);
else {/* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
@@ -351,8 +351,8 @@ cifs_write(struct file * file, const char *write_data,
size_t write_size, loff_t * poffset)
{
int rc = 0;
- int bytes_written = 0;
- int total_written;
+ unsigned int bytes_written = 0;
+ unsigned int total_written;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int xid, long_op;
@@ -633,9 +633,9 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
loff_t * poffset)
{
int rc = -EACCES;
- int bytes_read = 0;
- int total_read;
- int current_read_size;
+ unsigned int bytes_read = 0;
+ unsigned int total_read;
+ unsigned int current_read_size;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int xid;
@@ -742,13 +742,13 @@ cifs_readpages(struct file *file, struct address_space *mapping,
struct list_head *page_list, unsigned num_pages)
{
int rc = -EACCES;
- int xid,i;
+ int xid;
loff_t offset;
struct page * page;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int bytes_read = 0;
- unsigned int read_size;
+ unsigned int read_size,i;
char * smb_read_data = 0;
struct smb_com_read_rsp * pSMBr;
struct pagevec lru_pvec;
@@ -877,6 +877,8 @@ fill_in_inode(struct inode *tmp_inode,
FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
{
struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
+
pfindData->ExtFileAttributes =
le32_to_cpu(pfindData->ExtFileAttributes);
pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
@@ -894,7 +896,13 @@ fill_in_inode(struct inode *tmp_inode,
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
/* treat dos attribute of read-only as read-only mode bit e.g. 555? */
/* 2767 perms - indicate mandatory locking */
- tmp_inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
+ /* BB fill in uid and gid here? with help from winbind?
+ or retrieve from NTFS stream extended attribute */
+ tmp_inode->i_uid = cifs_sb->mnt_uid;
+ tmp_inode->i_gid = cifs_sb->mnt_gid;
+ /* set default mode. will override for dirs below */
+ tmp_inode->i_mode = cifs_sb->mnt_file_mode;
+
cFYI(0,
("CIFS FFIRST: Attributes came in as 0x%x",
pfindData->ExtFileAttributes));
@@ -905,7 +913,7 @@ fill_in_inode(struct inode *tmp_inode,
} else if (pfindData->ExtFileAttributes & ATTR_DIRECTORY) {
*pobject_type = DT_DIR;
/* override default perms since we do not lock dirs */
- tmp_inode->i_mode = S_IRWXUGO;
+ tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
tmp_inode->i_mode |= S_IFDIR;
} else {
*pobject_type = DT_REG;
@@ -1091,10 +1099,10 @@ int
cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
{
int rc = 0;
- int xid, i;
+ int xid;
int Unicode = FALSE;
int UnixSearch = FALSE;
- unsigned int bufsize;
+ unsigned int bufsize, i;
__u16 searchHandle;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 7091afc6bd21..19b4bd43dcab 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -224,16 +224,19 @@ cifs_get_inode_info(struct inode **pinode,
cifs_NTtimeToUnix(le64_to_cpu(findData.LastWriteTime));
inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(findData.ChangeTime));
- inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); /* 2767 perms indicate mandatory locking - will override for dirs later */
cFYI(0,
(" Attributes came in as 0x%x ", findData.Attributes));
- if (findData.Attributes & ATTR_REPARSE) {
- /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */
+
+ /* set default mode. will override for dirs below */
+ inode->i_mode = cifs_sb->mnt_file_mode;
+
+ if (findData.Attributes & ATTR_REPARSE) {
+ /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */
inode->i_mode |= S_IFLNK;
} else if (findData.Attributes & ATTR_DIRECTORY) {
- /* override default perms since we do not do byte range locking on dirs */
- inode->i_mode = S_IRWXUGO;
- inode->i_mode |= S_IFDIR;
+ /* override default perms since we do not do byte range locking on dirs */
+ inode->i_mode = cifs_sb->mnt_dir_mode;
+ inode->i_mode |= S_IFDIR;
} else {
inode->i_mode |= S_IFREG;
/* treat the dos attribute of read-only as read-only mode e.g. 555 */
@@ -250,8 +253,11 @@ cifs_get_inode_info(struct inode **pinode,
(unsigned long) inode->i_size, inode->i_blocks));
inode->i_nlink = le32_to_cpu(findData.NumberOfLinks);
- /* BB fill in uid and gid here? with help from winbind? */
-
+ /* BB fill in uid and gid here? with help from winbind?
+ or retrieve from NTFS stream extended attribute */
+ inode->i_uid = cifs_sb->mnt_uid;
+ inode->i_gid = cifs_sb->mnt_gid;
+
if (S_ISREG(inode->i_mode)) {
cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops;
@@ -389,8 +395,8 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
direntry->d_inode->i_nlink = 2;
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
- 0xFFFFFFFFFFFFFFFF,
- 0xFFFFFFFFFFFFFFFF,
+ (__u64)-1,
+ (__u64)-1,
cifs_sb->local_nls);
else { /* BB to be implemented via Windows secrty descriptors*/
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 921ba32734d4..ee4e95a20b7c 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -274,12 +274,12 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
cFYI(0,
("Entering checkSMB with Length: %x, smb_buf_length: %x ",
length, ntohl(smb->smb_buf_length)));
- if ((length < 2 + sizeof (struct smb_hdr))
+ if (((unsigned int)length < 2 + sizeof (struct smb_hdr))
|| (4 + ntohl(smb->smb_buf_length) >
CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)) {
- if (length < 2 + sizeof (struct smb_hdr)) {
+ if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
cERROR(1, ("Length less than 2 + sizeof smb_hdr "));
- if ((length >= sizeof (struct smb_hdr) - 1)
+ if (((unsigned int)length >= sizeof (struct smb_hdr) - 1)
&& (smb->Status.CifsError != 0))
return 0; /* some error cases do not return wct and bcc */
@@ -298,7 +298,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
return 1;
if ((4 + ntohl(smb->smb_buf_length) != smbCalcSize(smb))
- || (4 + ntohl(smb->smb_buf_length) != length)) {
+ || (4 + ntohl(smb->smb_buf_length) != (unsigned int)length)) {
return 0;
} else {
cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb)));
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index f9801cdcfd48..77a23ab314d6 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -791,7 +791,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
int
map_smb_to_linux_error(struct smb_hdr *smb)
{
- int i;
+ unsigned int i;
int rc = -EIO; /* if transport error smb error may not be set */
__u8 smberrclass;
__u16 smberrcode;
@@ -859,10 +859,10 @@ map_smb_to_linux_error(struct smb_hdr *smb)
* calculate the size of the SMB message based on the fixed header
* portion, the number of word parameters and the data portion of the message
*/
-int
+unsigned int
smbCalcSize(struct smb_hdr *ptr)
{
- return (sizeof (struct smb_hdr) + (int) (2 * ptr->WordCount) +
+ return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
BCC(ptr));
}
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index ccfe283a6f37..4705a16d9ef5 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -186,7 +186,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
int *pbytes_returned, const int long_op)
{
int rc = 0;
- int receive_len;
+ unsigned int receive_len;
long timeout;
struct mid_q_entry *midQ;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index b7a836f30cf5..91087269e255 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -34,7 +34,7 @@
/* VFS super_block ops */
static void coda_clear_inode(struct inode *);
static void coda_put_super(struct super_block *);
-static int coda_statfs(struct super_block *sb, struct statfs *buf);
+static int coda_statfs(struct super_block *sb, struct kstatfs *buf);
static kmem_cache_t * coda_inode_cachep;
@@ -273,7 +273,7 @@ struct inode_operations coda_file_inode_operations = {
.setattr = coda_setattr,
};
-static int coda_statfs(struct super_block *sb, struct statfs *buf)
+static int coda_statfs(struct super_block *sb, struct kstatfs *buf)
{
int error;
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 9a15dedc8d8a..6ab4f181513e 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -585,7 +585,7 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
return error;
}
-int venus_statfs(struct super_block *sb, struct statfs *sfs)
+int venus_statfs(struct super_block *sb, struct kstatfs *sfs)
{
union inputArgs *inp;
union outputArgs *outp;
diff --git a/fs/compat.c b/fs/compat.c
index 832fc6042d81..21cc8f185df9 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -87,8 +87,15 @@ asmlinkage long compat_sys_newfstat(unsigned int fd,
return error;
}
-static int put_compat_statfs(struct compat_statfs *ubuf, struct statfs *kbuf)
+static int put_compat_statfs(struct compat_statfs *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) ||
@@ -99,7 +106,8 @@ static int put_compat_statfs(struct compat_statfs *ubuf, struct statfs *kbuf)
__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_fsid.val[1], &ubuf->f_fsid.val[1]) ||
+ __put_user(kbuf->f_frsize, &ubuf->f_frsize))
return -EFAULT;
return 0;
}
@@ -115,7 +123,7 @@ asmlinkage long compat_sys_statfs(const char *path, struct compat_statfs *buf)
error = user_path_walk(path, &nd);
if (!error) {
- struct statfs tmp;
+ struct kstatfs tmp;
error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
if (!error && put_compat_statfs(buf, &tmp))
error = -EFAULT;
@@ -127,7 +135,7 @@ asmlinkage long compat_sys_statfs(const char *path, struct compat_statfs *buf)
asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs *buf)
{
struct file * file;
- struct statfs tmp;
+ struct kstatfs tmp;
int error;
error = -EBADF;
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 7e7f162fc0e3..c6d6844796bb 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -266,7 +266,7 @@ out:
return -EINVAL;
}
-static int cramfs_statfs(struct super_block *sb, struct statfs *buf)
+static int cramfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
buf->f_type = CRAMFS_MAGIC;
buf->f_bsize = PAGE_CACHE_SIZE;
diff --git a/fs/efs/super.c b/fs/efs/super.c
index f7276de1f6b1..13ef5b5b7813 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -278,7 +278,7 @@ out_no_fs:
return -EINVAL;
}
-int efs_statfs(struct super_block *s, struct statfs *buf) {
+int efs_statfs(struct super_block *s, struct kstatfs *buf) {
struct efs_sb_info *sb = SUPER_INFO(s);
buf->f_type = EFS_SUPER_MAGIC; /* efs magic number */
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 48a3d099f9a0..c4604187f186 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -34,7 +34,7 @@
static void ext2_sync_super(struct super_block *sb,
struct ext2_super_block *es);
static int ext2_remount (struct super_block * sb, int * flags, char * data);
-static int ext2_statfs (struct super_block * sb, struct statfs * buf);
+static int ext2_statfs (struct super_block * sb, struct kstatfs * buf);
static char error_buf[1024];
@@ -939,7 +939,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
return 0;
}
-static int ext2_statfs (struct super_block * sb, struct statfs * buf)
+static int ext2_statfs (struct super_block * sb, struct kstatfs * buf)
{
struct ext2_sb_info *sbi = EXT2_SB(sb);
unsigned long overhead;
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 146dd832e23b..9313430093c5 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -361,7 +361,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
error = -ENOMEM;
if (!clone)
goto cleanup;
-
+
mode = inode->i_mode;
error = posix_acl_create_masq(clone, &mode);
if (error >= 0) {
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 8f2003b11d0e..9ce1003c13bd 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -54,7 +54,7 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
return NULL;
}
-
+
group_desc = block_group / EXT3_DESC_PER_BLOCK(sb);
desc = block_group % EXT3_DESC_PER_BLOCK(sb);
if (!EXT3_SB(sb)->s_group_desc[group_desc]) {
@@ -64,7 +64,7 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
block_group, group_desc, desc);
return NULL;
}
-
+
gdp = (struct ext3_group_desc *)
EXT3_SB(sb)->s_group_desc[group_desc]->b_data;
if (bh)
@@ -83,7 +83,7 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
{
struct ext3_group_desc * desc;
struct buffer_head * bh = NULL;
-
+
desc = ext3_get_group_desc (sb, block_group, NULL);
if (!desc)
goto error_out;
@@ -174,19 +174,19 @@ do_more:
err = ext3_journal_get_undo_access(handle, bitmap_bh, NULL);
if (err)
goto error_return;
-
+
/*
* We are about to modify some metadata. Call the journal APIs
* to unshare ->b_data if a currently-committing transaction is
* using it
*/
BUFFER_TRACE(gd_bh, "get_write_access");
- err = ext3_journal_get_write_access(handle, gd_bh);
+ err = ext3_journal_get_write_access(handle, gd_bh);
if (err)
goto error_return;
jbd_lock_bh_state(bitmap_bh);
-
+
for (i = 0; i < count; i++) {
/*
* An HJ special. This is expensive...
@@ -316,7 +316,7 @@ static int find_next_usable_block(int start, struct buffer_head *bh,
{
int here, next;
char *p, *r;
-
+
if (start > 0) {
/*
* The goal was occupied; search forward for a free
@@ -331,15 +331,14 @@ static int find_next_usable_block(int start, struct buffer_head *bh,
if (here < end_goal &&
ext3_test_allocatable(here, bh, have_access))
return here;
-
+
ext3_debug ("Bit not found near goal\n");
-
}
-
+
here = start;
if (here < 0)
here = 0;
-
+
/*
* There has been no free block found in the near vicinity of
* the goal: do a search forward through the block groups,
@@ -351,10 +350,10 @@ static int find_next_usable_block(int start, struct buffer_head *bh,
p = ((char *) bh->b_data) + (here >> 3);
r = memscan(p, 0, (maxblocks - here + 7) >> 3);
next = (r - ((char *) bh->b_data)) << 3;
-
+
if (next < maxblocks && ext3_test_allocatable(next, bh, have_access))
return next;
-
+
/* The bitmap search --- search forward alternately
* through the actual bitmap and the last-committed copy
* until we find a bit free in both. */
@@ -547,7 +546,7 @@ ext3_new_block(handle_t *handle, struct inode *inode, unsigned long goal,
EXT3_BLOCKS_PER_GROUP(sb));
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
- goto io_error;
+ goto io_error;
ret_block = ext3_try_to_allocate(sb, handle, group_no,
bitmap_bh, ret_block, &fatal);
if (fatal)
@@ -555,7 +554,7 @@ ext3_new_block(handle_t *handle, struct inode *inode, unsigned long goal,
if (ret_block >= 0)
goto allocated;
}
-
+
/*
* Now search the rest of the groups. We assume that
* i and gdp correctly point to the last group visited.
@@ -675,7 +674,7 @@ allocated:
*errp = 0;
brelse(bitmap_bh);
return ret_block;
-
+
io_error:
*errp = -EIO;
out:
@@ -690,7 +689,6 @@ out:
DQUOT_FREE_BLOCK(inode, 1);
brelse(bitmap_bh);
return 0;
-
}
unsigned long ext3_count_free_blocks(struct super_block *sb)
@@ -702,7 +700,7 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
struct ext3_super_block *es;
unsigned long bitmap_count, x;
struct buffer_head *bitmap_bh = NULL;
-
+
lock_super(sb);
es = EXT3_SB(sb)->s_es;
desc_count = 0;
@@ -717,7 +715,7 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
bitmap_bh = read_block_bitmap(sb, i);
if (bitmap_bh == NULL)
continue;
-
+
x = ext3_count_free(bitmap_bh, sb->s_blocksize);
printk("group %d: stored = %d, counted = %lu\n",
i, le16_to_cpu(gdp->bg_free_blocks_count), x);
diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
index 381559e65f01..6c419b9ab0e8 100644
--- a/fs/ext3/bitmap.c
+++ b/fs/ext3/bitmap.c
@@ -16,7 +16,7 @@ unsigned long ext3_count_free (struct buffer_head * map, unsigned int numchars)
{
unsigned int i;
unsigned long sum = 0;
-
+
if (!map)
return (0);
for (i = 0; i < numchars; i++)
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index b00bec6fe0ce..b9c64eb1d664 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -16,6 +16,9 @@
*
* Big-endian to little-endian byte-swapping/bitmaps by
* David S. Miller (davem@caip.rutgers.edu), 1995
+ *
+ * Hash Tree Directory indexing (c) 2001 Daniel Phillips
+ *
*/
#include <linux/fs.h>
@@ -154,7 +157,7 @@ static int ext3_readdir(struct file * filp,
brelse (bha[i]);
}
}
-
+
revalidate:
/* If the dir block has changed since the last call to
* readdir(2), then we might be pointing to an invalid
@@ -180,7 +183,7 @@ revalidate:
| offset;
filp->f_version = inode->i_version;
}
-
+
while (!error && filp->f_pos < inode->i_size
&& offset < sb->s_blocksize) {
de = (struct ext3_dir_entry_2 *) (bh->b_data + offset);
@@ -326,7 +329,7 @@ void ext3_htree_free_dir_info(struct dir_private_info *p)
free_rb_tree_fname(&p->root);
kfree(p);
}
-
+
/*
* Given a directory entry, enter it into the fname rb tree.
*/
@@ -355,7 +358,7 @@ int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
new_fn->file_type = dirent->file_type;
memcpy(new_fn->name, dirent->name, dirent->name_len);
new_fn->name[dirent->name_len] = 0;
-
+
while (*p) {
parent = *p;
fname = rb_entry(parent, struct fname, rb_hash);
@@ -370,7 +373,7 @@ int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
fname->next = new_fn;
return 0;
}
-
+
if (new_fn->hash < fname->hash)
p = &(*p)->rb_left;
else if (new_fn->hash > fname->hash)
@@ -403,7 +406,7 @@ static int call_filldir(struct file * filp, void * dirent,
int error;
sb = inode->i_sb;
-
+
if (!fname) {
printk("call_filldir: called with null fname?!?\n");
return 0;
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 7a329a70a6f2..94ac5cd28480 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -69,7 +69,7 @@ ext3_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos)
*/
if (ret <= 0)
return ret;
-
+
/*
* If the inode is IS_SYNC, or is O_SYNC and we are doing data
* journalling then we need to make sure that we force the transaction
@@ -97,14 +97,14 @@ ext3_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos)
*/
if (!IS_SYNC(inode))
return ret;
-
+
/*
* Open question #2 --- should we force data to disk here too? If we
* don't, the only impact is that data=writeback filesystems won't
* flush data to disk automatically on IS_SYNC, only metadata (but
* historically, that is what ext2 has done.)
*/
-
+
force_commit:
err = ext3_force_commit(inode->i_sb);
if (err)
diff --git a/fs/ext3/hash.c b/fs/ext3/hash.c
index d00d658b1cfb..f3780279f5c5 100644
--- a/fs/ext3/hash.c
+++ b/fs/ext3/hash.c
@@ -23,10 +23,10 @@ static void TEA_transform(__u32 buf[4], __u32 const in[])
__u32 a = in[0], b = in[1], c = in[2], d = in[3];
int n = 16;
- do {
- sum += DELTA;
- b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
- b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
+ do {
+ sum += DELTA;
+ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
+ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
} while(--n);
buf[0] += b0;
@@ -107,7 +107,7 @@ static __u32 dx_hack_hash (const char *name, int len)
__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
while (len--) {
__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-
+
if (hash & 0x80000000) hash -= 0x7fffffff;
hash1 = hash0;
hash0 = hash;
@@ -178,7 +178,7 @@ int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
if (i < 4)
memcpy(buf, hinfo->seed, sizeof(buf));
}
-
+
switch (hinfo->hash_version) {
case DX_HASH_LEGACY:
hash = dx_hack_hash(name, len);
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index fd83ce45b353..7f0c2bfb81f7 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -462,13 +462,13 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
for (i = 0; i < sbi->s_groups_count; i++) {
gdp = ext3_get_group_desc(sb, group, &bh2);
-
+
err = -EIO;
brelse(bitmap_bh);
bitmap_bh = read_inode_bitmap(sb, group);
if (!bitmap_bh)
goto fail;
-
+
ino = ext3_find_first_zero_bit((unsigned long *)
bitmap_bh->b_data, EXT3_INODES_PER_GROUP(sb));
if (ino < EXT3_INODES_PER_GROUP(sb)) {
@@ -532,7 +532,7 @@ got:
BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
err = ext3_journal_dirty_metadata(handle, bh2);
if (err) goto fail;
-
+
percpu_counter_dec(&sbi->s_freeinodes_counter);
if (S_ISDIR(mode))
percpu_counter_inc(&sbi->s_dirs_counter);
@@ -580,7 +580,7 @@ got:
ei->i_prealloc_count = 0;
#endif
ei->i_block_group = group;
-
+
ext3_set_inode_flags(inode);
if (IS_DIRSYNC(inode))
handle->h_sync = 1;
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 277f940cc002..190875df3a11 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -72,7 +72,7 @@ int ext3_forget(handle_t *handle, int is_metadata,
"data mode %lx\n",
bh, is_metadata, inode->i_mode,
test_opt(inode->i_sb, DATA_FLAGS));
-
+
/* Never use the revoke function if we are doing full data
* journaling: there is no need to, and a V1 superblock won't
* support it. Otherwise, only skip the revoke on un-journaled
@@ -107,7 +107,7 @@ int ext3_forget(handle_t *handle, int is_metadata,
static unsigned long blocks_for_truncate(struct inode *inode)
{
unsigned long needed;
-
+
needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
/* Give ourselves just enough room to cope with inodes in which
@@ -126,7 +126,7 @@ static unsigned long blocks_for_truncate(struct inode *inode)
return EXT3_DATA_TRANS_BLOCKS + needed;
}
-
+
/*
* Truncate transactions can be complex and absolutely huge. So we need to
* be able to restart the transaction at a conventient checkpoint to make
@@ -141,11 +141,11 @@ static unsigned long blocks_for_truncate(struct inode *inode)
static handle_t *start_transaction(struct inode *inode)
{
handle_t *result;
-
+
result = ext3_journal_start(inode, blocks_for_truncate(inode));
if (!IS_ERR(result))
return result;
-
+
ext3_std_error(inode->i_sb, PTR_ERR(result));
return result;
}
@@ -195,7 +195,7 @@ void ext3_put_inode(struct inode *inode)
void ext3_delete_inode (struct inode * inode)
{
handle_t *handle;
-
+
if (is_bad_inode(inode))
goto no_delete;
@@ -209,7 +209,7 @@ void ext3_delete_inode (struct inode * inode)
ext3_std_error(inode->i_sb, PTR_ERR(handle));
goto no_delete;
}
-
+
if (IS_SYNC(inode))
handle->h_sync = 1;
inode->i_size = 0;
@@ -593,7 +593,7 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
break;
branch[n].key = cpu_to_le32(nr);
keys = n+1;
-
+
/*
* Get buffer_head for parent block, zero it out
* and set the pointer to new one, then send
@@ -621,7 +621,7 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
err = ext3_journal_dirty_metadata(handle, bh);
if (err)
break;
-
+
parent = nr;
}
}
@@ -723,7 +723,7 @@ changed:
*/
jbd_debug(1, "the chain changed: try again\n");
err = -EAGAIN;
-
+
err_out:
for (i = 1; i < num; i++) {
BUFFER_TRACE(where[i].bh, "call journal_forget");
@@ -915,7 +915,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
{
struct buffer_head dummy;
int fatal = 0, err;
-
+
J_ASSERT(handle != NULL || create == 0);
dummy.b_state = 0;
@@ -1233,7 +1233,7 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)
struct inode *inode = mapping->host;
journal_t *journal;
int err;
-
+
if (EXT3_I(inode)->i_state & EXT3_STATE_JDATA) {
/*
* This is a REALLY heavyweight approach, but the use of
@@ -1252,17 +1252,17 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)
* hasn't yet been flushed to disk, they deserve
* everything they get.
*/
-
+
EXT3_I(inode)->i_state &= ~EXT3_STATE_JDATA;
journal = EXT3_JOURNAL(inode);
journal_lock_updates(journal);
err = journal_flush(journal);
journal_unlock_updates(journal);
-
+
if (err)
return 0;
}
-
+
return generic_block_bmap(mapping,block,ext3_get_block);
}
@@ -1347,7 +1347,7 @@ static int ext3_ordered_writepage(struct page *page,
int err;
J_ASSERT(PageLocked(page));
-
+
/*
* We give up here if we're reentered, because it might be for a
* different filesystem.
@@ -1356,7 +1356,7 @@ static int ext3_ordered_writepage(struct page *page,
goto out_fail;
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
-
+
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
goto out_fail;
@@ -2003,7 +2003,7 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode,
if (is_handle_aborted(handle))
return;
-
+
if (depth--) {
struct buffer_head *bh;
int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb);
@@ -2165,7 +2165,6 @@ void ext3_truncate(struct inode * inode)
>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
ext3_block_truncate_page(handle, inode->i_mapping, inode->i_size);
-
n = ext3_block_to_path(inode, last_block, offsets, NULL);
if (n == 0)
@@ -2296,7 +2295,7 @@ int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
unsigned long desc;
unsigned long offset;
struct ext3_group_desc * gdp;
-
+
if ((inode->i_ino != EXT3_ROOT_INO &&
inode->i_ino != EXT3_JOURNAL_INO &&
inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
@@ -2340,9 +2339,9 @@ int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
iloc->bh = bh;
iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
iloc->block_group = block_group;
-
+
return 0;
-
+
bad_inode:
return -EIO;
}
@@ -2372,7 +2371,7 @@ void ext3_read_inode(struct inode * inode)
struct ext3_inode_info *ei = EXT3_I(inode);
struct buffer_head *bh;
int block;
-
+
#ifdef CONFIG_EXT3_FS_POSIX_ACL
ei->i_acl = EXT3_ACL_NOT_CACHED;
ei->i_default_acl = EXT3_ACL_NOT_CACHED;
@@ -2472,7 +2471,7 @@ void ext3_read_inode(struct inode * inode)
}
ext3_set_inode_flags(inode);
return;
-
+
bad_inode:
make_bad_inode(inode);
return;
@@ -2634,7 +2633,7 @@ void ext3_write_inode(struct inode *inode, int wait)
if (!wait)
return;
- ext3_force_commit(inode->i_sb);
+ ext3_force_commit(inode->i_sb);
}
/*
@@ -2680,7 +2679,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
error = PTR_ERR(handle);
goto err_out;
}
-
+
error = ext3_orphan_add(handle, inode);
EXT3_I(inode)->i_disksize = attr->ia_size;
rc = ext3_mark_inode_dirty(handle, inode);
@@ -2688,7 +2687,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
error = rc;
ext3_journal_stop(handle);
}
-
+
rc = inode_setattr(inode, attr);
/* If inode_setattr's call to ext3_truncate failed to get a
@@ -2740,7 +2739,7 @@ int ext3_writepage_trans_blocks(struct inode *inode)
int bpp = ext3_journal_blocks_per_page(inode);
int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3;
int ret;
-
+
if (ext3_should_journal_data(inode))
ret = 3 * (bpp + indirects) + 2;
else
@@ -2877,7 +2876,7 @@ static inline int
ext3_pin_inode(handle_t *handle, struct inode *inode)
{
struct ext3_iloc iloc;
-
+
int err = 0;
if (handle) {
err = ext3_get_inode_loc(inode, &iloc);
@@ -2914,7 +2913,7 @@ int ext3_change_inode_journal_flag(struct inode *inode, int val)
journal = EXT3_JOURNAL(inode);
if (is_journal_aborted(journal) || IS_RDONLY(inode))
return -EROFS;
-
+
journal_lock_updates(journal);
journal_flush(journal);
@@ -2943,6 +2942,6 @@ int ext3_change_inode_journal_flag(struct inode *inode, int val)
handle->h_sync = 1;
ext3_journal_stop(handle);
ext3_std_error(inode->i_sb, err);
-
+
return err;
}
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index b250fbf55b29..3681474e57d9 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -61,7 +61,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
}
-
+
/*
* The JOURNAL_DATA flag can only be changed by
* the relevant capability.
@@ -80,7 +80,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
err = ext3_reserve_inode_write(handle, inode, &iloc);
if (err)
goto flags_err;
-
+
flags = flags & EXT3_FL_USER_MODIFIABLE;
flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
ei->i_flags = flags;
@@ -93,7 +93,7 @@ flags_err:
ext3_journal_stop(handle);
if (err)
return err;
-
+
if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
err = ext3_change_inode_journal_flag(inode, jflag);
return err;
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 7d03324974e2..1e71616f4d92 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -263,7 +263,7 @@ static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_ent
unsigned names = 0, space = 0;
char *base = (char *) de;
struct dx_hash_info h = *hinfo;
-
+
printk("names: ");
while ((char *) de < base + size)
{
@@ -546,7 +546,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
dxtrace(printk("In htree dirblock_to_tree: block %d\n", block));
if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
return err;
-
+
de = (struct ext3_dir_entry_2 *) bh->b_data;
top = (struct ext3_dir_entry_2 *) ((char *) de +
dir->i_sb->s_blocksize -
@@ -588,11 +588,11 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
int count = 0;
int ret;
__u32 hashval;
-
+
dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
start_minor_hash));
dir = dir_file->f_dentry->d_inode;
- if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) {
+ if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) {
hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed;
count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
@@ -663,7 +663,7 @@ static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
int count = 0;
char *base = (char *) de;
struct dx_hash_info h = *hinfo;
-
+
while ((char *) de < base + size)
{
if (de->name_len && de->inode) {
@@ -798,8 +798,6 @@ static inline int search_dirblock(struct buffer_head * bh,
* The returned buffer_head has ->b_count elevated. The caller is expected
* to brelse() it when appropriate.
*/
-
-
static struct buffer_head * ext3_find_entry (struct dentry *dentry,
struct ext3_dir_entry_2 ** res_dir)
{
@@ -903,7 +901,7 @@ restart:
start = 0;
goto restart;
}
-
+
cleanup_and_exit:
/* Clean up the read-ahead blocks */
for (; ra_ptr < ra_max; ra_ptr++)
@@ -926,7 +924,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
int namelen = dentry->d_name.len;
const u8 *name = dentry->d_name.name;
struct inode *dir = dentry->d_parent->d_inode;
-
+
sb = dir->i_sb;
if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
return NULL;
@@ -963,7 +961,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
goto errout;
}
} while (retval == 1);
-
+
*err = -ENOENT;
errout:
dxtrace(printk("%s not found\n", name));
@@ -1191,7 +1189,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
unsigned short reclen;
int nlen, rlen, err;
char *top;
-
+
reclen = EXT3_DIR_REC_LEN(namelen);
if (!de) {
de = (struct ext3_dir_entry_2 *)bh->b_data;
@@ -1223,7 +1221,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
brelse(bh);
return err;
}
-
+
/* By now the buffer is marked for journaling */
nlen = EXT3_DIR_REC_LEN(de->name_len);
rlen = le16_to_cpu(de->rec_len);
@@ -1286,7 +1284,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
unsigned blocksize;
struct dx_hash_info hinfo;
u32 block;
-
+
blocksize = dir->i_sb->s_blocksize;
dxtrace(printk("Creating index\n"));
retval = ext3_journal_get_write_access(handle, bh);
@@ -1296,7 +1294,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
return retval;
}
root = (struct dx_root *) bh->b_data;
-
+
EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
bh2 = ext3_append (handle, dir, &block, &retval);
if (!(bh2)) {
@@ -1479,13 +1477,13 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
unsigned icount1 = icount/2, icount2 = icount - icount1;
unsigned hash2 = dx_get_hash(entries + icount1);
dxtrace(printk("Split index %i/%i\n", icount1, icount2));
-
+
BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
err = ext3_journal_get_write_access(handle,
frames[0].bh);
if (err)
goto journal_error;
-
+
memcpy ((char *) entries2, (char *) (entries + icount1),
icount2 * sizeof(struct dx_entry));
dx_set_count (entries, icount1);
@@ -1535,7 +1533,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
err = add_dirent_to_buf(handle, dentry, inode, de, bh);
bh = 0;
goto cleanup;
-
+
journal_error:
ext3_std_error(dir->i_sb, err);
cleanup:
@@ -1831,7 +1829,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
struct super_block *sb = inode->i_sb;
struct ext3_iloc iloc;
int err = 0, rc;
-
+
lock_super(sb);
if (!list_empty(&EXT3_I(inode)->i_orphan))
goto out_unlock;
@@ -1852,7 +1850,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
if (err)
goto out_unlock;
-
+
err = ext3_reserve_inode_write(handle, inode, &iloc);
if (err)
goto out_unlock;
@@ -2045,7 +2043,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry)
retval = -EIO;
if (le32_to_cpu(de->inode) != inode->i_ino)
goto end_unlink;
-
+
if (!inode->i_nlink) {
ext3_warning (inode->i_sb, "ext3_unlink",
"Deleting nonexistent file (%lu), %d",
@@ -2251,7 +2249,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
*/
struct buffer_head *old_bh2;
struct ext3_dir_entry_2 *old_de2;
-
+
old_bh2 = ext3_find_entry(old_dentry, &old_de2);
if (old_bh2) {
retval = ext3_delete_entry(handle, old_dir,
@@ -2316,9 +2314,9 @@ struct inode_operations ext3_dir_inode_operations = {
.mknod = ext3_mknod,
.rename = ext3_rename,
.setattr = ext3_setattr,
- .setxattr = ext3_setxattr,
- .getxattr = ext3_getxattr,
- .listxattr = ext3_listxattr,
+ .setxattr = ext3_setxattr,
+ .getxattr = ext3_getxattr,
+ .listxattr = ext3_listxattr,
.removexattr = ext3_removexattr,
.permission = ext3_permission,
};
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 91dca2770189..b5c72519d5fd 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -119,7 +119,7 @@ static void clear_ro_after(struct super_block *sb)
handle_t *ext3_journal_start(struct inode *inode, int nblocks)
{
journal_t *journal;
-
+
if (inode->i_sb->s_flags & MS_RDONLY)
return ERR_PTR(-EROFS);
@@ -132,7 +132,7 @@ handle_t *ext3_journal_start(struct inode *inode, int nblocks)
"Detected aborted journal");
return ERR_PTR(-EROFS);
}
-
+
return journal_start(journal, nblocks);
}
@@ -164,7 +164,7 @@ void ext3_journal_abort_handle(const char *caller, const char *err_fn,
{
char nbuf[16];
const char *errstr = ext3_decode_error(NULL, err, nbuf);
-
+
printk(KERN_ERR "%s: aborting transaction: %s in %s",
caller, errstr, err_fn);
@@ -236,7 +236,7 @@ void ext3_error (struct super_block * sb, const char * function,
const char *ext3_decode_error(struct super_block * sb, int errno, char nbuf[16])
{
char *errstr = NULL;
-
+
switch (errno) {
case -EIO:
errstr = "IO failure";
@@ -259,7 +259,6 @@ const char *ext3_decode_error(struct super_block * sb, int errno, char nbuf[16])
if (snprintf(nbuf, 16, "error %d", -errno) >= 0)
errstr = nbuf;
}
-
break;
}
@@ -277,7 +276,7 @@ void __ext3_std_error (struct super_block * sb, const char * function,
printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
sb->s_id, function, errstr);
-
+
ext3_handle_error(sb);
}
@@ -311,7 +310,7 @@ void ext3_abort (struct super_block * sb, const char * function,
if (sb->s_flags & MS_RDONLY)
return;
-
+
printk (KERN_CRIT "Remounting filesystem read-only\n");
EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
sb->s_flags |= MS_RDONLY;
@@ -426,10 +425,10 @@ static inline struct inode *orphan_list_entry(struct list_head *l)
static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
{
struct list_head *l;
-
+
printk(KERN_ERR "sb orphan head is %d\n",
le32_to_cpu(sbi->s_es->s_last_orphan));
-
+
printk(KERN_ERR "sb_info orphan list:\n");
list_for_each(l, &sbi->s_orphan) {
struct inode *inode = orphan_list_entry(l);
@@ -1062,7 +1061,7 @@ static unsigned long descriptor_loc(struct super_block *sb,
struct ext3_sb_info *sbi = EXT3_SB(sb);
unsigned long bg, first_data_block, first_meta_bg;
int has_super = 0;
-
+
first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block);
first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
@@ -1138,7 +1137,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
sb->s_id);
goto failed_mount;
}
-
+
/* Set defaults before we parse the mount options */
def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
if (def_mount_opts & EXT3_DEFM_DEBUG)
@@ -1162,7 +1161,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_RO)
set_opt(sbi->s_mount_opt, ERRORS_RO);
-
+
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
@@ -1539,7 +1538,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
"EXT3-fs: blocksize too small for journal device.\n");
goto out_bdev;
}
-
+
sb_block = EXT3_MIN_BLOCK_SIZE / blocksize;
offset = EXT3_MIN_BLOCK_SIZE % blocksize;
set_blocksize(bdev, blocksize);
@@ -1753,7 +1752,7 @@ static void ext3_clear_journal_err(struct super_block * sb,
journal_t *journal;
int j_errno;
const char *errstr;
-
+
journal = EXT3_SB(sb)->s_journal;
/*
@@ -1764,13 +1763,13 @@ static void ext3_clear_journal_err(struct super_block * sb,
j_errno = journal_errno(journal);
if (j_errno) {
char nbuf[16];
-
+
errstr = ext3_decode_error(sb, j_errno, nbuf);
ext3_warning(sb, __FUNCTION__, "Filesystem error recorded "
"from previous mount: %s", errstr);
ext3_warning(sb, __FUNCTION__, "Marking fs in need of "
"filesystem check.");
-
+
EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
ext3_commit_super (sb, es, 1);
@@ -1886,7 +1885,7 @@ int ext3_remount (struct super_block * sb, int * flags, char * data)
es = sbi->s_es;
ext3_init_journal_params(sbi, sbi->s_journal);
-
+
if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
return -EROFS;
@@ -1934,7 +1933,7 @@ int ext3_remount (struct super_block * sb, int * flags, char * data)
return 0;
}
-int ext3_statfs (struct super_block * sb, struct statfs * buf)
+int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
{
struct ext3_super_block *es = EXT3_SB(sb)->s_es;
unsigned long overhead;
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 5ca5e3086e06..066316459d83 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -481,7 +481,7 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
unsigned int name_len;
int min_offs = sb->s_blocksize, not_found = 1, free, error;
char *end;
-
+
/*
* header -- Points either into bh, or to a temporarily
* allocated buffer.
@@ -493,7 +493,7 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
* towards the end of the block).
* end -- Points right after the block pointed to by header.
*/
-
+
ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
name_index, name, value, (long)value_len);
@@ -736,11 +736,11 @@ ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
ea_bdebug(new_bh, "%s block %ld",
(old_bh == new_bh) ? "keeping" : "reusing",
new_bh->b_blocknr);
-
+
error = -EDQUOT;
if (DQUOT_ALLOC_BLOCK(inode, 1))
goto cleanup;
-
+
error = ext3_journal_get_write_access(handle, new_bh);
if (error)
goto cleanup;
@@ -782,7 +782,7 @@ getblk_failed:
set_buffer_uptodate(new_bh);
unlock_buffer(new_bh);
ext3_xattr_cache_insert(new_bh);
-
+
ext3_xattr_update_super_block(handle, sb);
}
error = ext3_journal_dirty_metadata(handle, new_bh);
@@ -1108,7 +1108,7 @@ static void ext3_xattr_rehash(struct ext3_xattr_header *header,
{
struct ext3_xattr_entry *here;
__u32 hash = 0;
-
+
ext3_xattr_hash_entry(header, entry);
here = ENTRY(header+1);
while (!IS_LAST_ENTRY(here)) {
@@ -1131,7 +1131,7 @@ int __init
init_ext3_xattr(void)
{
int err;
-
+
err = ext3_xattr_register(EXT3_XATTR_INDEX_USER,
&ext3_xattr_user_handler);
if (err)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index d11c0fbd0a24..55df25851655 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1019,7 +1019,7 @@ out_fail:
return error;
}
-int fat_statfs(struct super_block *sb,struct statfs *buf)
+int fat_statfs(struct super_block *sb, struct kstatfs *buf)
{
int free,nr;
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index d3ebd64c780e..d49c04846e4f 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -55,7 +55,7 @@ MODULE_LICENSE("Dual BSD/GPL");
static void vxfs_put_super(struct super_block *);
-static int vxfs_statfs(struct super_block *, struct statfs *);
+static int vxfs_statfs(struct super_block *, struct kstatfs *);
static struct super_operations vxfs_super_ops = {
.read_inode = vxfs_read_inode,
@@ -105,7 +105,7 @@ vxfs_put_super(struct super_block *sbp)
* This is everything but complete...
*/
static int
-vxfs_statfs(struct super_block *sbp, struct statfs *bufp)
+vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp)
{
struct vxfs_sb_info *infp = VXFS_SBI(sbp);
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 8bbd871b03db..92682b02ff12 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -49,9 +49,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
{
struct super_block *sb = inode->i_sb;
- if (!sb)
- return; /* swapper_space */
-
/*
* Don't do this for I_DIRTY_PAGES - that doesn't actually
* dirty the inode itself
@@ -90,9 +87,12 @@ void __mark_inode_dirty(struct inode *inode, int flags)
* Only add valid (hashed) inodes to the superblock's
* dirty list. Add blockdev inodes as well.
*/
- if ((hlist_unhashed(&inode->i_hash) || (inode->i_state & (I_FREEING|I_CLEAR)))
- && !S_ISBLK(inode->i_mode))
- goto out;
+ if (!S_ISBLK(inode->i_mode)) {
+ if (hlist_unhashed(&inode->i_hash))
+ goto out;
+ if (inode->i_state & (I_FREEING|I_CLEAR))
+ goto out;
+ }
/*
* If the inode was already on s_dirty or s_io, don't
@@ -369,6 +369,9 @@ writeback_inodes(struct writeback_control *wbc)
*
* A finite limit is set on the number of pages which will be written.
* To prevent infinite livelock of sys_sync().
+ *
+ * We add in the number of potentially dirty inodes, because each inode write
+ * can dirty pagecache in the underlying blockdev.
*/
void sync_inodes_sb(struct super_block *sb, int wait)
{
@@ -382,7 +385,9 @@ void sync_inodes_sb(struct super_block *sb, int wait)
get_page_state(&ps);
wbc.nr_to_write = ps.nr_dirty + ps.nr_unstable +
- (ps.nr_dirty + ps.nr_unstable) / 4;
+ (inodes_stat.nr_inodes - inodes_stat.nr_unused) +
+ ps.nr_dirty + ps.nr_unstable;
+ wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */
spin_lock(&inode_lock);
sync_sb_inodes(sb, &wbc);
spin_unlock(&inode_lock);
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 48be69ce4108..408911021654 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -40,7 +40,7 @@ MODULE_LICENSE("GPL");
static void hfs_read_inode(struct inode *);
static void hfs_put_super(struct super_block *);
-static int hfs_statfs(struct super_block *, struct statfs *);
+static int hfs_statfs(struct super_block *, struct kstatfs *);
static void hfs_write_super(struct super_block *);
static kmem_cache_t * hfs_inode_cachep;
@@ -195,7 +195,7 @@ static void hfs_put_super(struct super_block *sb)
*
* changed f_files/f_ffree to reflect the fs_ablock/free_ablocks.
*/
-static int hfs_statfs(struct super_block *sb, struct statfs *buf)
+static int hfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 84d5023cac6c..91f880e88362 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -310,7 +310,7 @@ int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *);
int hpfs_remount_fs(struct super_block *, int *, char *);
void hpfs_put_super(struct super_block *);
unsigned hpfs_count_one_bitmap(struct super_block *, secno);
-int hpfs_statfs(struct super_block *, struct statfs *);
+int hpfs_statfs(struct super_block *, struct kstatfs *);
extern struct address_space_operations hpfs_aops;
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 36aa38cd829a..5827a006dd9b 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -136,7 +136,7 @@ static unsigned count_bitmaps(struct super_block *s)
return count;
}
-int hpfs_statfs(struct super_block *s, struct statfs *buf)
+int hpfs_statfs(struct super_block *s, struct kstatfs *buf)
{
struct hpfs_sb_info *sbi = hpfs_sb(s);
lock_kernel();
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 4c83c32a1905..f0d2a2c65170 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -22,7 +22,9 @@
#include <linux/hugetlb.h>
#include <linux/pagevec.h>
#include <linux/quotaops.h>
+#include <linux/slab.h>
#include <linux/dnotify.h>
+#include <linux/statfs.h>
#include <linux/security.h>
#include <asm/uaccess.h>
@@ -43,8 +45,9 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = {
static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct inode *inode =file->f_dentry->d_inode;
+ 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;
int ret;
@@ -57,6 +60,18 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
return -EINVAL;
+ 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);
+ spin_unlock(&sbinfo->stat_lock);
+ } else {
+ spin_unlock(&sbinfo->stat_lock);
+ return -ENOMEM;
+ }
+ }
+
down(&inode->i_sem);
update_atime(inode);
@@ -68,6 +83,16 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
if (ret == 0 && inode->i_size < len)
inode->i_size = len;
up(&inode->i_sem);
+
+ /*
+ * If the huge page allocation has failed then increment free_blocks.
+ */
+ if ((ret != 0) && (sbinfo->free_blocks >= 0)) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_blocks += (len >> HPAGE_SHIFT);
+ spin_unlock(&sbinfo->stat_lock);
+ }
+
return ret;
}
@@ -154,6 +179,7 @@ void truncate_huge_page(struct page *page)
void truncate_hugepages(struct address_space *mapping, loff_t lstart)
{
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
const pgoff_t start = lstart >> HPAGE_SHIFT;
struct pagevec pvec;
pgoff_t next;
@@ -178,6 +204,11 @@ void truncate_hugepages(struct address_space *mapping, loff_t lstart)
++next;
truncate_huge_page(page);
unlock_page(page);
+ if (sbinfo->free_blocks >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_blocks++;
+ spin_unlock(&sbinfo->stat_lock);
+ }
}
huge_pagevec_release(&pvec);
}
@@ -186,6 +217,8 @@ void truncate_hugepages(struct address_space *mapping, loff_t lstart)
static void hugetlbfs_delete_inode(struct inode *inode)
{
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
+
hlist_del_init(&inode->i_hash);
list_del_init(&inode->i_list);
inode->i_state |= I_FREEING;
@@ -197,6 +230,12 @@ static void hugetlbfs_delete_inode(struct inode *inode)
security_inode_delete(inode);
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_inodes++;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+
clear_inode(inode);
destroy_inode(inode);
}
@@ -204,6 +243,7 @@ static void hugetlbfs_delete_inode(struct inode *inode)
static void hugetlbfs_forget_inode(struct inode *inode)
{
struct super_block *super_block = inode->i_sb;
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
if (hlist_unhashed(&inode->i_hash))
goto out_truncate;
@@ -229,6 +269,12 @@ out_truncate:
if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_inodes++;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+
clear_inode(inode);
destroy_inode(inode);
}
@@ -341,13 +387,25 @@ out:
static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
gid_t gid, int mode, dev_t dev)
{
- struct inode * inode = new_inode(sb);
+ struct inode *inode;
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
+
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ if (!sbinfo->free_inodes) {
+ spin_unlock(&sbinfo->stat_lock);
+ return NULL;
+ }
+ sbinfo->free_inodes--;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+ inode = new_inode(sb);
if (inode) {
inode->i_mode = mode;
inode->i_uid = uid;
inode->i_gid = gid;
- inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blksize = HPAGE_SIZE;
inode->i_blocks = 0;
inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &hugetlbfs_aops;
@@ -379,17 +437,18 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
/*
* File creation. Allocate an inode, and we're done..
*/
-/* SMP-safe */
static int hugetlbfs_mknod(struct inode *dir,
struct dentry *dentry, int mode, dev_t dev)
{
- struct inode * inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
+ struct inode *inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
current->fsgid, mode, dev);
int error = -ENOSPC;
if (inode) {
+ dir->i_size += PSEUDO_DIRENT_SIZE;
+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
d_instantiate(dentry, inode);
- dget(dentry); /* Extra count - pin the dentry in core */
+ dget(dentry); /* Extra count - pin the dentry in core */
error = 0;
}
return error;
@@ -425,6 +484,9 @@ static int hugetlbfs_symlink(struct inode *dir,
} else
iput(inode);
}
+ dir->i_size += PSEUDO_DIRENT_SIZE;
+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+
return error;
}
@@ -436,6 +498,83 @@ int hugetlbfs_set_page_dirty(struct page *page)
return 0;
}
+static int hugetlbfs_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
+
+ buf->f_type = HUGETLBFS_MAGIC;
+ buf->f_bsize = HPAGE_SIZE;
+ if (sbinfo) {
+ spin_lock(&sbinfo->stat_lock);
+ buf->f_blocks = sbinfo->max_blocks;
+ buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
+ buf->f_files = sbinfo->max_inodes;
+ buf->f_ffree = sbinfo->free_inodes;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+ buf->f_namelen = NAME_MAX;
+ return 0;
+}
+
+static int hugetlbfs_link(struct dentry *old_dentry,
+ struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+
+ dir->i_size += PSEUDO_DIRENT_SIZE;
+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ inode->i_nlink++;
+ atomic_inc(&inode->i_count);
+ dget(dentry);
+ d_instantiate(dentry, inode);
+ return 0;
+}
+
+static int hugetlbfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+
+ dir->i_size -= PSEUDO_DIRENT_SIZE;
+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ inode->i_nlink--;
+ dput(dentry);
+ return 0;
+}
+
+static int hugetlbfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ if (!simple_empty(dentry))
+ return -ENOTEMPTY;
+
+ dir->i_nlink--;
+ return hugetlbfs_unlink(dir, dentry);
+}
+
+static int hugetlbfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+ int they_are_dirs = S_ISDIR(inode->i_mode);
+
+ if (!simple_empty(new_dentry))
+ return -ENOTEMPTY;
+
+ if (new_dentry->d_inode) {
+ hugetlbfs_unlink(new_dir, new_dentry);
+ if (they_are_dirs)
+ old_dir->i_nlink--;
+ } else if (they_are_dirs) {
+ old_dir->i_nlink--;
+ new_dir->i_nlink++;
+ }
+
+ old_dir->i_size -= PSEUDO_DIRENT_SIZE;
+ new_dir->i_size += PSEUDO_DIRENT_SIZE;
+ old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
+ new_dir->i_mtime = inode->i_ctime = CURRENT_TIME;
+ return 0;
+}
+
static struct address_space_operations hugetlbfs_aops = {
.readpage = hugetlbfs_readpage,
.prepare_write = hugetlbfs_prepare_write,
@@ -452,13 +591,13 @@ struct file_operations hugetlbfs_file_operations = {
static struct inode_operations hugetlbfs_dir_inode_operations = {
.create = hugetlbfs_create,
.lookup = simple_lookup,
- .link = simple_link,
- .unlink = simple_unlink,
+ .link = hugetlbfs_link,
+ .unlink = hugetlbfs_unlink,
.symlink = hugetlbfs_symlink,
.mkdir = hugetlbfs_mkdir,
- .rmdir = simple_rmdir,
+ .rmdir = hugetlbfs_rmdir,
.mknod = hugetlbfs_mknod,
- .rename = simple_rename,
+ .rename = hugetlbfs_rename,
.setattr = hugetlbfs_setattr,
};
@@ -467,29 +606,26 @@ static struct inode_operations hugetlbfs_inode_operations = {
};
static struct super_operations hugetlbfs_ops = {
- .statfs = simple_statfs,
+ .statfs = hugetlbfs_statfs,
.drop_inode = hugetlbfs_drop_inode,
};
static int
hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
{
- char *opt, *value;
- int ret = 0;
+ char *opt, *value, *rest;
if (!options)
- goto out;
+ return 0;
while ((opt = strsep(&options, ",")) != NULL) {
if (!*opt)
continue;
value = strchr(opt, '=');
- if (!value || !*value) {
- ret = -EINVAL;
- goto out;
- } else {
+ if (!value || !*value)
+ return -EINVAL;
+ else
*value++ = '\0';
- }
if (!strcmp(opt, "uid"))
pconfig->uid = simple_strtoul(value, &value, 0);
@@ -497,22 +633,27 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
pconfig->gid = simple_strtoul(value, &value, 0);
else if (!strcmp(opt, "mode"))
pconfig->mode = simple_strtoul(value,&value,0) & 0777U;
- else {
- ret = -EINVAL;
- goto out;
- }
+ else if (!strcmp(opt, "size")) {
+ unsigned long long size = memparse(value, &rest);
+ if (*rest == '%') {
+ size <<= HPAGE_SHIFT;
+ size *= htlbpage_max;
+ do_div(size, 100);
+ rest++;
+ }
+ size &= HPAGE_MASK;
+ pconfig->nr_blocks = (size >> HPAGE_SHIFT);
+ value = rest;
+ } else if (!strcmp(opt,"nr_inodes")) {
+ pconfig->nr_inodes = memparse(value, &rest);
+ value = rest;
+ } else
+ return -EINVAL;
- if (*value) {
- ret = -EINVAL;
- goto out;
- }
+ if (*value)
+ return -EINVAL;
}
return 0;
-out:
- pconfig->uid = current->fsuid;
- pconfig->gid = current->fsgid;
- pconfig->mode = 0755;
- return ret;
}
static int
@@ -522,13 +663,30 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
struct dentry * root;
int ret;
struct hugetlbfs_config config;
+ struct hugetlbfs_sb_info *sbinfo;
+
+ sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
+ if (!sbinfo)
+ return -ENOMEM;
+ sb->s_fs_info = sbinfo;
+ config.nr_blocks = -1; /* No limit on size by default */
+ config.nr_inodes = -1; /* No limit on number of inodes by default */
+ config.uid = current->fsuid;
+ config.gid = current->fsgid;
+ config.mode = 0755;
ret = hugetlbfs_parse_options(data, &config);
+
if (ret)
return ret;
- sb->s_blocksize = PAGE_CACHE_SIZE;
- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ spin_lock_init(&sbinfo->stat_lock);
+ sbinfo->max_blocks = config.nr_blocks;
+ sbinfo->free_blocks = config.nr_blocks;
+ sbinfo->max_inodes = config.nr_inodes;
+ sbinfo->free_inodes = config.nr_inodes;
+ sb->s_blocksize = HPAGE_SIZE;
+ sb->s_blocksize_bits = HPAGE_SHIFT;
sb->s_magic = HUGETLBFS_MAGIC;
sb->s_op = &hugetlbfs_ops;
inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
@@ -551,10 +709,19 @@ static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type,
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 = kill_litter_super,
+ .kill_sb = hugetlbfs_kill_super
};
static struct vfsmount *hugetlbfs_vfsmount;
diff --git a/fs/intermezzo/intermezzo_fs.h b/fs/intermezzo/intermezzo_fs.h
index 5a91c61188da..8d2d33fcee0e 100644
--- a/fs/intermezzo/intermezzo_fs.h
+++ b/fs/intermezzo/intermezzo_fs.h
@@ -530,7 +530,7 @@ int do_rename(struct presto_file_set *fset, struct dentry *old_dir,
struct dentry *old_dentry, struct dentry *new_dir,
struct dentry *new_dentry, struct lento_vfs_context *info);
int presto_do_statfs (struct presto_file_set *fset,
- struct statfs * buf);
+ struct kstatfs * buf);
int lento_setattr(const char *name, struct iattr *iattr,
struct lento_vfs_context *info);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 5e21abe15531..a28d5f174b9b 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -74,7 +74,7 @@ static void isofs_put_super(struct super_block *sb)
}
static void isofs_read_inode(struct inode *);
-static int isofs_statfs (struct super_block *, struct statfs *);
+static int isofs_statfs (struct super_block *, struct kstatfs *);
static kmem_cache_t *isofs_inode_cachep;
@@ -884,7 +884,7 @@ out_freesbi:
return -EINVAL;
}
-static int isofs_statfs (struct super_block *sb, struct statfs *buf)
+static int isofs_statfs (struct super_block *sb, struct kstatfs *buf)
{
buf->f_type = ISOFS_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 7b2fbb503ce5..2052795b8255 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -85,7 +85,7 @@ void __log_wait_for_space(journal_t *journal, int nblocks)
return;
spin_unlock(&journal->j_state_lock);
down(&journal->j_checkpoint_sem);
-
+
/*
* Test again, another process may have checkpointed while we
* were waiting for the checkpoint lock
@@ -232,7 +232,7 @@ static int __flush_buffer(journal_t *journal, struct journal_head *jh,
if (buffer_dirty(bh) && !buffer_locked(bh) && jh->b_jlist == BJ_None) {
J_ASSERT_JH(jh, jh->b_transaction == NULL);
-
+
/*
* Important: we are about to write the buffer, and
* possibly block, while still holding the journal lock.
@@ -267,7 +267,6 @@ static int __flush_buffer(journal_t *journal, struct journal_head *jh,
return ret;
}
-
/*
* Perform an actual checkpoint. We don't write out only enough to
* satisfy the current blocked requests: rather we submit a reasonably
@@ -373,7 +372,7 @@ int log_do_checkpoint(journal_t *journal, int nblocks)
result = cleanup_journal_tail(journal);
if (result < 0)
return result;
-
+
return 0;
}
@@ -524,7 +523,7 @@ void __journal_remove_checkpoint(struct journal_head *jh)
journal_t *journal;
JBUFFER_TRACE(jh, "entry");
-
+
if ((transaction = jh->b_cp_transaction) == NULL) {
JBUFFER_TRACE(jh, "not on transaction");
goto out;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index b009d38fd63a..b41b26d758b4 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -197,7 +197,7 @@ void journal_commit_transaction(journal_t *journal)
commit_transaction->t_log_start = journal->j_head;
wake_up(&journal->j_wait_transaction_locked);
spin_unlock(&journal->j_state_lock);
-
+
jbd_debug (3, "JBD: commit phase 2\n");
/*
@@ -368,7 +368,7 @@ sync_datalist_empty:
__journal_abort_hard(journal);
continue;
}
-
+
bh = jh2bh(descriptor);
jbd_debug(4, "JBD: got buffer %llu (%p)\n",
(unsigned long long)bh->b_blocknr, bh->b_data);
@@ -622,7 +622,7 @@ skip_commit: /* The journal should be unlocked by now. */
if (err)
__journal_abort_hard(journal);
-
+
/*
* Call any callbacks that had been registered for handles in this
* transaction. It is up to the callback to free any allocated
@@ -714,7 +714,7 @@ skip_commit: /* The journal should be unlocked by now. */
clear_buffer_freed(bh);
clear_buffer_jbddirty(bh);
}
-
+
if (buffer_jbddirty(bh)) {
JBUFFER_TRACE(jh, "add to new checkpointing trans");
__journal_insert_checkpoint(jh, commit_transaction);
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 27e3fef29a38..fe4bdf4a6f34 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -161,7 +161,7 @@ loop:
del_timer_sync(journal->j_commit_timer);
journal_commit_transaction(journal);
spin_lock(&journal->j_state_lock);
- goto loop;
+ goto end_loop;
}
wake_up(&journal->j_wait_done_commit);
@@ -175,7 +175,6 @@ loop:
spin_unlock(&journal->j_state_lock);
refrigerator(PF_IOTHREAD);
spin_lock(&journal->j_state_lock);
- jbd_debug(1, "Resuming kjournald\n");
} else {
/*
* We assume on resume that commits are already there,
@@ -185,7 +184,7 @@ loop:
int should_sleep = 1;
prepare_to_wait(&journal->j_wait_commit, &wait,
- TASK_INTERRUPTIBLE);
+ TASK_INTERRUPTIBLE);
if (journal->j_commit_sequence != journal->j_commit_request)
should_sleep = 0;
transaction = journal->j_running_transaction;
@@ -210,7 +209,7 @@ loop:
journal->j_commit_request = transaction->t_tid;
jbd_debug(1, "woke because of timeout\n");
}
-
+end_loop:
if (!(journal->j_flags & JFS_UNMOUNT))
goto loop;
@@ -230,12 +229,16 @@ static void journal_start_thread(journal_t *journal)
static void journal_kill_thread(journal_t *journal)
{
+ spin_lock(&journal->j_state_lock);
journal->j_flags |= JFS_UNMOUNT;
while (journal->j_task) {
wake_up(&journal->j_wait_commit);
+ spin_unlock(&journal->j_state_lock);
wait_event(journal->j_wait_done_commit, journal->j_task == 0);
+ spin_lock(&journal->j_state_lock);
}
+ spin_unlock(&journal->j_state_lock);
}
/*
@@ -729,7 +732,7 @@ journal_t * journal_init_inode (struct inode *inode)
kfree(journal);
return NULL;
}
-
+
bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
J_ASSERT(bh != NULL);
journal->j_sb_buffer = bh;
@@ -868,6 +871,22 @@ void journal_update_superblock(journal_t *journal, int wait)
journal_superblock_t *sb = journal->j_superblock;
struct buffer_head *bh = journal->j_sb_buffer;
+ /*
+ * As a special case, if the on-disk copy is already marked as needing
+ * no recovery (s_start == 0) and there are no outstanding transactions
+ * in the filesystem, then we can safely defer the superblock update
+ * until the next commit by setting JFS_FLUSHED. This avoids
+ * attempting a write to a potential-readonly device.
+ */
+ if (sb->s_start == 0 && journal->j_tail_sequence ==
+ journal->j_transaction_sequence) {
+ jbd_debug(1,"JBD: Skipping superblock update on recovered sb "
+ "(start %ld, seq %d, errno %d)\n",
+ journal->j_tail, journal->j_tail_sequence,
+ journal->j_errno);
+ goto out;
+ }
+
spin_lock(&journal->j_state_lock);
jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
journal->j_tail, journal->j_tail_sequence, journal->j_errno);
@@ -884,6 +903,7 @@ void journal_update_superblock(journal_t *journal, int wait)
else
ll_rw_block(WRITE, 1, &bh);
+out:
/* If we have just flushed the log (by marking s_start==0), then
* any future commit will have to be careful to update the
* superblock again to re-record the true start of the log. */
@@ -906,7 +926,7 @@ static int journal_get_superblock(journal_t *journal)
struct buffer_head *bh;
journal_superblock_t *sb;
int err = -EIO;
-
+
bh = journal->j_sb_buffer;
J_ASSERT(bh != NULL);
@@ -923,7 +943,7 @@ static int journal_get_superblock(journal_t *journal)
sb = journal->j_superblock;
err = -EINVAL;
-
+
if (sb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
sb->s_blocksize != htonl(journal->j_blocksize)) {
printk(KERN_WARNING "JBD: no valid journal superblock found\n");
@@ -1242,7 +1262,7 @@ int journal_flush(journal_t *journal)
unsigned long old_tail;
spin_lock(&journal->j_state_lock);
-
+
/* Force everything buffered to the log... */
if (journal->j_running_transaction) {
transaction = journal->j_running_transaction;
@@ -1520,7 +1540,7 @@ int journal_blocks_per_page(struct inode *inode)
*/
void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry)
{
- return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
+ return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
}
/*
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index d9afa22f5de2..d6e080c8c5ec 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -29,9 +29,9 @@
*/
struct recovery_info
{
- tid_t start_transaction;
+ tid_t start_transaction;
tid_t end_transaction;
-
+
int nr_replays;
int nr_revokes;
int nr_revoke_hits;
@@ -72,9 +72,9 @@ static int do_readahead(journal_t *journal, unsigned int start)
unsigned int max, nbufs, next;
unsigned long blocknr;
struct buffer_head *bh;
-
+
struct buffer_head * bufs[MAXBUF];
-
+
/* Do up to 128K of readahead */
max = start + (128 * 1024 / journal->j_blocksize);
if (max > journal->j_maxlen)
@@ -82,9 +82,9 @@ static int do_readahead(journal_t *journal, unsigned int start)
/* Do the readahead itself. We'll submit MAXBUF buffer_heads at
* a time to the block device IO layer. */
-
+
nbufs = 0;
-
+
for (next = start; next < max; next++) {
err = journal_bmap(journal, next, &blocknr);
@@ -115,7 +115,7 @@ static int do_readahead(journal_t *journal, unsigned int start)
ll_rw_block(READ, nbufs, bufs);
err = 0;
-failed:
+failed:
if (nbufs)
journal_brelse_array(bufs, nbufs);
return err;
@@ -138,7 +138,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
*bhp = NULL;
J_ASSERT (offset < journal->j_maxlen);
-
+
err = journal_bmap(journal, offset, &blocknr);
if (err) {
@@ -224,10 +224,10 @@ int journal_recover(journal_t *journal)
journal_superblock_t * sb;
struct recovery_info info;
-
+
memset(&info, 0, sizeof(info));
sb = journal->j_superblock;
-
+
/*
* The journal superblock's s_start field (the current log head)
* is always zero if, and only if, the journal was cleanly
@@ -240,7 +240,6 @@ int journal_recover(journal_t *journal)
journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
return 0;
}
-
err = do_one_pass(journal, &info, PASS_SCAN);
if (!err)
@@ -257,7 +256,7 @@ int journal_recover(journal_t *journal)
/* Restart the log at the next transaction ID, thus invalidating
* any existing commit records in the log. */
journal->j_transaction_sequence = ++info.end_transaction;
-
+
journal_clear_revoke(journal);
sync_blockdev(journal->j_fs_dev);
return err;
@@ -282,10 +281,10 @@ int journal_skip_recovery(journal_t *journal)
journal_superblock_t * sb;
struct recovery_info info;
-
+
memset (&info, 0, sizeof(info));
sb = journal->j_superblock;
-
+
err = do_one_pass(journal, &info, PASS_SCAN);
if (err) {
@@ -295,7 +294,6 @@ int journal_skip_recovery(journal_t *journal)
#ifdef CONFIG_JBD_DEBUG
int dropped = info.end_transaction - ntohl(sb->s_sequence);
#endif
-
jbd_debug(0,
"JBD: ignoring %d transaction%s from the journal.\n",
dropped, (dropped == 1) ? "" : "s");
@@ -303,14 +301,12 @@ int journal_skip_recovery(journal_t *journal)
}
journal->j_tail = 0;
-
return err;
}
static int do_one_pass(journal_t *journal,
struct recovery_info *info, enum passtype pass)
{
-
unsigned int first_commit_ID, next_commit_ID;
unsigned long next_log_block;
int err, success = 0;
@@ -319,7 +315,7 @@ static int do_one_pass(journal_t *journal,
struct buffer_head * bh;
unsigned int sequence;
int blocktype;
-
+
/* Precompute the maximum metadata descriptors in a descriptor block */
int MAX_BLOCKS_PER_DESC;
MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
@@ -354,11 +350,11 @@ static int do_one_pass(journal_t *journal,
journal_block_tag_t * tag;
struct buffer_head * obh;
struct buffer_head * nbh;
-
+
/* If we already know where to stop the log traversal,
* check right now that we haven't gone past the end of
* the log. */
-
+
if (pass != PASS_SCAN)
if (tid_geq(next_commit_ID, info->end_transaction))
break;
@@ -369,7 +365,7 @@ static int do_one_pass(journal_t *journal,
/* Skip over each chunk of the transaction looking
* either the next descriptor block or the final commit
* record. */
-
+
jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
err = jread(&bh, journal, next_log_block);
if (err)
@@ -377,7 +373,7 @@ static int do_one_pass(journal_t *journal,
next_log_block++;
wrap(journal, next_log_block);
-
+
/* What kind of buffer is it?
*
* If it is a descriptor block, check that it has the
@@ -385,7 +381,7 @@ static int do_one_pass(journal_t *journal,
* here. */
tmp = (journal_header_t *)bh->b_data;
-
+
if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
brelse(bh);
break;
@@ -395,12 +391,12 @@ static int do_one_pass(journal_t *journal,
sequence = ntohl(tmp->h_sequence);
jbd_debug(3, "Found magic %d, sequence %d\n",
blocktype, sequence);
-
+
if (sequence != next_commit_ID) {
brelse(bh);
break;
}
-
+
/* OK, we have a valid descriptor block which matches
* all of the sequence number checks. What are we going
* to do with it? That depends on the pass... */
@@ -429,7 +425,7 @@ static int do_one_pass(journal_t *journal,
tag = (journal_block_tag_t *) tagp;
flags = ntohl(tag->t_flags);
-
+
io_block = next_log_block++;
wrap(journal, next_log_block);
err = jread(&obh, journal, io_block);
@@ -443,7 +439,7 @@ static int do_one_pass(journal_t *journal,
err, io_block);
} else {
unsigned long blocknr;
-
+
J_ASSERT(obh != NULL);
blocknr = ntohl(tag->t_blocknr);
@@ -457,7 +453,7 @@ static int do_one_pass(journal_t *journal,
++info->nr_revoke_hits;
goto skip_write;
}
-
+
/* Find a buffer for the new
* data being restored */
nbh = __getblk(journal->j_fs_dev,
@@ -491,7 +487,7 @@ static int do_one_pass(journal_t *journal,
brelse(obh);
brelse(nbh);
}
-
+
skip_write:
tagp += sizeof(journal_block_tag_t);
if (!(flags & JFS_FLAG_SAME_UUID))
@@ -500,7 +496,7 @@ static int do_one_pass(journal_t *journal,
if (flags & JFS_FLAG_LAST_TAG)
break;
}
-
+
brelse(bh);
continue;
@@ -541,7 +537,7 @@ static int do_one_pass(journal_t *journal,
* log. If the latter happened, then we know that the "current"
* transaction marks the end of the valid log.
*/
-
+
if (pass == PASS_SCAN)
info->end_transaction = next_commit_ID;
else {
@@ -574,11 +570,11 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
header = (journal_revoke_header_t *) bh->b_data;
offset = sizeof(journal_revoke_header_t);
max = ntohl(header->r_count);
-
+
while (offset < max) {
unsigned long blocknr;
int err;
-
+
blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
offset += 4;
err = journal_set_revoke(journal, blocknr, sequence);
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index 933551effe14..0ab15014f950 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -81,7 +81,7 @@ struct jbd_revoke_record_s
{
struct list_head hash;
tid_t sequence; /* Used for recovery only */
- unsigned long blocknr;
+ unsigned long blocknr;
};
@@ -110,7 +110,7 @@ static inline int hash(journal_t *journal, unsigned long block)
{
struct jbd_revoke_table_s *table = journal->j_revoke;
int hash_shift = table->hash_shift;
-
+
return ((block << (hash_shift - 6)) ^
(block >> 13) ^
(block << (hash_shift - 12))) & (table->hash_size - 1);
@@ -149,7 +149,7 @@ static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
{
struct list_head *hash_list;
struct jbd_revoke_record_s *record;
-
+
hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
spin_lock(&journal->j_revoke_lock);
@@ -161,7 +161,7 @@ static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
}
record = (struct jbd_revoke_record_s *) record->hash.next;
}
- spin_unlock(&journal->j_revoke_lock);
+ spin_unlock(&journal->j_revoke_lock);
return NULL;
}
@@ -182,7 +182,7 @@ int __init journal_init_revoke_caches(void)
return -ENOMEM;
}
return 0;
-}
+}
void journal_destroy_revoke_caches(void)
{
@@ -197,9 +197,9 @@ void journal_destroy_revoke_caches(void)
int journal_init_revoke(journal_t *journal, int hash_size)
{
int shift, tmp;
-
+
J_ASSERT (journal->j_revoke_table[0] == NULL);
-
+
shift = 0;
tmp = hash_size;
while((tmp >>= 1UL) != 0UL)
@@ -209,7 +209,7 @@ int journal_init_revoke(journal_t *journal, int hash_size)
if (!journal->j_revoke_table[0])
return -ENOMEM;
journal->j_revoke = journal->j_revoke_table[0];
-
+
/* Check that the hash_size is a power of two */
J_ASSERT ((hash_size & (hash_size-1)) == 0);
@@ -224,19 +224,19 @@ int journal_init_revoke(journal_t *journal, int hash_size)
journal->j_revoke = NULL;
return -ENOMEM;
}
-
+
for (tmp = 0; tmp < hash_size; tmp++)
INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
-
+
journal->j_revoke_table[1] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
if (!journal->j_revoke_table[1]) {
kfree(journal->j_revoke_table[0]->hash_table);
kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
return -ENOMEM;
}
-
+
journal->j_revoke = journal->j_revoke_table[1];
-
+
/* Check that the hash_size is a power of two */
J_ASSERT ((hash_size & (hash_size-1)) == 0);
@@ -253,7 +253,7 @@ int journal_init_revoke(journal_t *journal, int hash_size)
journal->j_revoke = NULL;
return -ENOMEM;
}
-
+
for (tmp = 0; tmp < hash_size; tmp++)
INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
@@ -269,16 +269,16 @@ void journal_destroy_revoke(journal_t *journal)
struct jbd_revoke_table_s *table;
struct list_head *hash_list;
int i;
-
+
table = journal->j_revoke_table[0];
if (!table)
return;
-
+
for (i=0; i<table->hash_size; i++) {
hash_list = &table->hash_table[i];
J_ASSERT (list_empty(hash_list));
}
-
+
kfree(table->hash_table);
kmem_cache_free(revoke_table_cache, table);
journal->j_revoke = NULL;
@@ -286,12 +286,12 @@ void journal_destroy_revoke(journal_t *journal)
table = journal->j_revoke_table[1];
if (!table)
return;
-
+
for (i=0; i<table->hash_size; i++) {
hash_list = &table->hash_table[i];
J_ASSERT (list_empty(hash_list));
}
-
+
kfree(table->hash_table);
kmem_cache_free(revoke_table_cache, table);
journal->j_revoke = NULL;
@@ -420,7 +420,7 @@ int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
int need_cancel;
int did_revoke = 0; /* akpm: debug */
struct buffer_head *bh = jh2bh(jh);
-
+
jbd_debug(4, "journal_head %p, cancelling revoke\n", jh);
/* Is the existing Revoke bit valid? If so, we trust it, and
@@ -466,7 +466,6 @@ int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
__brelse(bh2);
}
}
-
return did_revoke;
}
@@ -482,7 +481,7 @@ void journal_switch_revoke_table(journal_t *journal)
journal->j_revoke = journal->j_revoke_table[1];
else
journal->j_revoke = journal->j_revoke_table[0];
-
+
for (i = 0; i < journal->j_revoke->hash_size; i++)
INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]);
}
@@ -506,11 +505,11 @@ void journal_write_revoke_records(journal_t *journal,
descriptor = NULL;
offset = 0;
count = 0;
-
+
/* select revoke table for committing transaction */
revoke = journal->j_revoke == journal->j_revoke_table[0] ?
journal->j_revoke_table[1] : journal->j_revoke_table[0];
-
+
for (i = 0; i < revoke->hash_size; i++) {
hash_list = &revoke->hash_table[i];
@@ -562,7 +561,7 @@ static void write_one_revoke_record(journal_t *journal,
descriptor = NULL;
}
}
-
+
if (!descriptor) {
descriptor = journal_get_descriptor_buffer(journal);
if (!descriptor)
@@ -579,7 +578,7 @@ static void write_one_revoke_record(journal_t *journal,
offset = sizeof(journal_revoke_header_t);
*descriptorp = descriptor;
}
-
+
* ((unsigned int *)(&jh2bh(descriptor)->b_data[offset])) =
htonl(record->blocknr);
offset += 4;
@@ -604,7 +603,7 @@ static void flush_descriptor(journal_t *journal,
__brelse(jh2bh(descriptor));
return;
}
-
+
header = (journal_revoke_header_t *) jh2bh(descriptor)->b_data;
header->r_count = htonl(offset);
set_bit(BH_JWrite, &jh2bh(descriptor)->b_state);
@@ -645,7 +644,7 @@ int journal_set_revoke(journal_t *journal,
tid_t sequence)
{
struct jbd_revoke_record_s *record;
-
+
record = find_revoke_record(journal, blocknr);
if (record) {
/* If we have multiple occurrences, only record the
@@ -669,7 +668,7 @@ int journal_test_revoke(journal_t *journal,
tid_t sequence)
{
struct jbd_revoke_record_s *record;
-
+
record = find_revoke_record(journal, blocknr);
if (!record)
return 0;
@@ -689,9 +688,9 @@ void journal_clear_revoke(journal_t *journal)
struct list_head *hash_list;
struct jbd_revoke_record_s *record;
struct jbd_revoke_table_s *revoke;
-
+
revoke = journal->j_revoke;
-
+
for (i = 0; i < revoke->hash_size; i++) {
hash_list = &revoke->hash_table[i];
while (!list_empty(hash_list)) {
@@ -701,4 +700,3 @@ void journal_clear_revoke(journal_t *journal)
}
}
}
-
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index b9a23b8c7a59..54e16b97fdaa 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -57,7 +57,7 @@ get_transaction(journal_t *journal, transaction_t *transaction)
/* Set up the commit timer for the new transaction. */
journal->j_commit_timer->expires = transaction->t_expires;
add_timer(journal->j_commit_timer);
-
+
J_ASSERT(journal->j_running_transaction == NULL);
journal->j_running_transaction = transaction;
@@ -130,7 +130,7 @@ repeat_locked:
journal->j_barrier_count == 0);
goto repeat;
}
-
+
if (!journal->j_running_transaction) {
if (!new_transaction) {
spin_unlock(&journal->j_state_lock);
@@ -153,7 +153,7 @@ repeat_locked:
transaction->t_state != T_LOCKED);
goto repeat;
}
-
+
/*
* If there is not enough space left in the log to write all potential
* buffers requested by this operation, we need to stall pending a log
@@ -210,7 +210,7 @@ repeat_locked:
if (journal->j_committing_transaction)
needed += journal->j_committing_transaction->
t_outstanding_credits;
-
+
if (__log_space_left(journal) < needed) {
jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
spin_unlock(&transaction->t_handle_lock);
@@ -268,7 +268,7 @@ handle_t *journal_start(journal_t *journal, int nblocks)
{
handle_t *handle = journal_current_handle();
int err;
-
+
if (!journal)
return ERR_PTR(-EROFS);
@@ -337,7 +337,7 @@ int journal_extend(handle_t *handle, int nblocks)
spin_lock(&transaction->t_handle_lock);
wanted = transaction->t_outstanding_credits + nblocks;
-
+
if (wanted > journal->j_max_transaction_buffers) {
jbd_debug(3, "denied handle %p %d blocks: "
"transaction too large\n", handle, nblocks);
@@ -349,7 +349,7 @@ int journal_extend(handle_t *handle, int nblocks)
"insufficient log space\n", handle, nblocks);
goto unlock;
}
-
+
handle->h_buffer_credits += nblocks;
transaction->t_outstanding_credits += nblocks;
result = 0;
@@ -388,7 +388,7 @@ int journal_restart(handle_t *handle, int nblocks)
* actually doing the restart! */
if (is_handle_aborted(handle))
return 0;
-
+
/*
* First unlink the handle from its current transaction, and start the
* commit on that.
@@ -496,7 +496,7 @@ static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
{
struct buffer_head *bh = jh2bh(jh);
int jlist;
-
+
if (buffer_dirty(bh)) {
/* If this buffer is one which might reasonably be dirty
* --- ie. data, or not part of this journal --- then
@@ -504,7 +504,7 @@ static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
* move the dirty bit to the journal's own internal
* JBDDirty bit. */
jlist = jh->b_jlist;
-
+
if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
jlist == BJ_Shadow || jlist == BJ_Forget) {
if (test_clear_buffer_dirty(jh2bh(jh))) {
@@ -609,7 +609,7 @@ repeat:
(*credits)++;
goto done_locked;
}
-
+
/* Is there data here we need to preserve? */
if (jh->b_transaction && jh->b_transaction != transaction) {
@@ -638,7 +638,7 @@ repeat:
wait_event(*wqh, (jh->b_jlist != BJ_Shadow));
goto repeat;
}
-
+
/* Only do the copy if the currently-owning transaction
* still needs it. If it is on the Forget list, the
* committing transaction is past that stage. The
@@ -697,7 +697,7 @@ repeat:
JBUFFER_TRACE(jh, "file as BJ_Reserved");
__journal_file_buffer(jh, transaction, BJ_Reserved);
}
-
+
done_locked:
spin_unlock(&journal->j_list_lock);
if (need_copy) {
@@ -778,13 +778,13 @@ int journal_get_create_access(handle_t *handle, struct buffer_head *bh)
journal_t *journal = transaction->t_journal;
struct journal_head *jh = journal_add_journal_head(bh);
int err;
-
+
jbd_debug(5, "journal_head %p\n", jh);
err = -EROFS;
if (is_handle_aborted(handle))
goto out;
err = 0;
-
+
JBUFFER_TRACE(jh, "entry");
/*
* The buffer may already belong to this transaction due to pre-zeroing
@@ -932,7 +932,7 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
if (is_handle_aborted(handle))
return 0;
-
+
jh = journal_add_journal_head(bh);
JBUFFER_TRACE(jh, "entry");
@@ -1098,7 +1098,7 @@ int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
JBUFFER_TRACE(jh, "entry");
if (is_handle_aborted(handle))
goto out;
-
+
jbd_lock_bh_state(bh);
/*
@@ -1130,7 +1130,7 @@ int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
set_buffer_jbddirty(bh);
J_ASSERT_JH(jh, jh->b_transaction != NULL);
-
+
/*
* Metadata already on the current transaction list doesn't
* need to be filed. Metadata on another transaction's list must
@@ -1272,7 +1272,6 @@ void journal_forget(handle_t *handle, struct buffer_head *bh)
return;
}
}
-
} else if (jh->b_transaction) {
J_ASSERT_JH(jh, (jh->b_transaction ==
journal->j_committing_transaction));
@@ -1346,18 +1345,18 @@ int journal_stop(handle_t *handle)
transaction_t *transaction = handle->h_transaction;
journal_t *journal = transaction->t_journal;
int old_handle_count, err;
-
+
if (!handle)
return 0;
J_ASSERT(transaction->t_updates > 0);
J_ASSERT(journal_current_handle() == handle);
-
+
if (is_handle_aborted(handle))
err = -EIO;
else
err = 0;
-
+
if (--handle->h_ref > 0) {
jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
handle->h_ref);
@@ -1413,7 +1412,7 @@ int journal_stop(handle_t *handle)
* completes the commit thread, it just doesn't write
* anything to disk. */
tid_t tid = transaction->t_tid;
-
+
spin_unlock(&transaction->t_handle_lock);
jbd_debug(2, "transaction too old, requesting commit for "
"handle %p\n", handle);
@@ -1563,7 +1562,7 @@ void __journal_unfile_buffer(struct journal_head *jh)
list = &transaction->t_reserved_list;
break;
}
-
+
__blist_del_buffer(list, jh);
jh->b_jlist = BJ_None;
if (test_clear_buffer_jbddirty(bh))
@@ -1811,7 +1810,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
JBUFFER_TRACE(jh, "not on any transaction: zap");
goto zap_buffer;
}
-
+
if (!buffer_dirty(bh)) {
/* bdflush has written it. We can drop it now */
goto zap_buffer;
@@ -1910,7 +1909,7 @@ int journal_invalidatepage(journal_t *journal,
struct buffer_head *head, *bh, *next;
unsigned int curr_off = 0;
int may_free = 1;
-
+
if (!PageLocked(page))
BUG();
if (!page_has_buffers(page))
@@ -1967,7 +1966,7 @@ void __journal_file_buffer(struct journal_head *jh,
if (jh->b_transaction && jh->b_jlist == jlist)
return;
-
+
/* The following list of buffer states needs to be consistent
* with __jbd_unexpected_dirty_buffer()'s handling of dirty
* state. */
@@ -2055,7 +2054,7 @@ void __journal_refile_buffer(struct journal_head *jh)
jh->b_transaction = NULL;
return;
}
-
+
/*
* It has been modified by a later transaction: add it to the new
* transaction's metadata list.
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index dceb9cbce3b9..61d1b71bc20c 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: dir.c,v 1.76 2003/05/26 09:50:38 dwmw2 Exp $
+ * $Id: dir.c,v 1.77 2003/06/05 14:42:24 dwmw2 Exp $
*
*/
@@ -356,7 +356,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
up(&f->sem);
/* Work out where to put the dirent node now. */
- writtenlen = (writtenlen+3)&~3;
+ writtenlen = PAD(writtenlen);
phys_ofs += writtenlen;
alloclen -= writtenlen;
@@ -653,7 +653,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk
up(&f->sem);
/* Work out where to put the dirent node now. */
- writtenlen = (writtenlen+3)&~3;
+ writtenlen = PAD(writtenlen);
phys_ofs += writtenlen;
alloclen -= writtenlen;
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index a027504cd82d..4c43d597d0aa 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -22,7 +22,7 @@
#include <linux/vfs.h>
#include "nodelist.h"
-int jffs2_statfs(struct super_block *sb, struct statfs *buf)
+int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
unsigned long avail;
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d08ca2e3a152..c4699f223ec2 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -123,7 +123,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf))
-struct statfs;
+struct kstatfs;
/* wbuf.c */
int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
@@ -169,7 +169,7 @@ void jffs2_read_inode (struct inode *);
void jffs2_clear_inode (struct inode *);
struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
struct jffs2_raw_inode *ri);
-int jffs2_statfs (struct super_block *, struct statfs *);
+int jffs2_statfs (struct super_block *, struct kstatfs *);
void jffs2_write_super (struct super_block *);
int jffs2_remount_fs (struct super_block *, int *, char *);
int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 8ed8212bb5eb..55c51478692c 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: scan.c,v 1.99 2003/04/28 10:17:17 dwmw2 Exp $
+ * $Id: scan.c,v 1.100 2003/06/05 14:42:24 dwmw2 Exp $
*
*/
#include <linux/kernel.h>
@@ -354,7 +354,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
if (ofs & 3) {
printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
- ofs = (ofs+3)&~3;
+ ofs = PAD(ofs);
continue;
}
if (ofs == prevofs) {
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 74036f743e31..32a123400a79 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -117,7 +117,7 @@ static void jfs_destroy_inode(struct inode *inode)
kmem_cache_free(jfs_inode_cachep, ji);
}
-static int jfs_statfs(struct super_block *sb, struct statfs *buf)
+static int jfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct jfs_sb_info *sbi = JFS_SBI(sb);
s64 maxinodes;
diff --git a/fs/libfs.c b/fs/libfs.c
index 2553f5463419..62fb3c0fbc24 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -16,7 +16,7 @@ int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
return 0;
}
-int simple_statfs(struct super_block *sb, struct statfs *buf)
+int simple_statfs(struct super_block *sb, struct kstatfs *buf)
{
buf->f_type = sb->s_magic;
buf->f_bsize = PAGE_CACHE_SIZE;
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 052e5518a7e3..7492f61754a4 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -34,6 +34,7 @@
#include <linux/sunrpc/svcsock.h>
#include <linux/lockd/lockd.h>
#include <linux/nfs.h>
+#include <linux/suspend.h>
#define NLMDBG_FACILITY NLMDBG_SVC
#define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
@@ -118,9 +119,11 @@ lockd(struct svc_rqst *rqstp)
* NFS mount or NFS daemon has gone away, and we've been sent a
* signal, or else another process has taken over our job.
*/
- while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid)
- {
+ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) {
long timeout = MAX_SCHEDULE_TIMEOUT;
+
+ if (current->flags & PF_FREEZE)
+ refrigerator(PF_IOTHREAD);
if (signalled()) {
flush_signals(current);
if (nlmsvc_ops) {
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 93005e83d319..710e46886609 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -19,7 +19,7 @@
static void minix_read_inode(struct inode * inode);
static void minix_write_inode(struct inode * inode, int wait);
-static int minix_statfs(struct super_block *sb, struct statfs *buf);
+static int minix_statfs(struct super_block *sb, struct kstatfs *buf);
static int minix_remount (struct super_block * sb, int * flags, char * data);
static void minix_delete_inode(struct inode *inode)
@@ -294,7 +294,7 @@ out_bad_sb:
return -EINVAL;
}
-static int minix_statfs(struct super_block *sb, struct statfs *buf)
+static int minix_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct minix_sb_info *sbi = minix_sb(sb);
buf->f_type = sb->s_magic;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index a982e1f14dc0..70eab7961377 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -39,7 +39,7 @@
static void ncp_delete_inode(struct inode *);
static void ncp_put_super(struct super_block *);
-static int ncp_statfs(struct super_block *, struct statfs *);
+static int ncp_statfs(struct super_block *, struct kstatfs *);
static kmem_cache_t * ncp_inode_cachep;
@@ -717,7 +717,7 @@ static void ncp_put_super(struct super_block *sb)
kfree(server);
}
-static int ncp_statfs(struct super_block *sb, struct statfs *buf)
+static int ncp_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct dentry* d;
struct inode* i;
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index 128d3188cd43..7767f1e66199 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -521,7 +521,7 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
return result;
}
if (result > len) {
- printk(KERN_ERR "ncpfs: tcp: bug in recvmsg (%u > %u)\n", result, len);
+ printk(KERN_ERR "ncpfs: tcp: bug in recvmsg (%u > %Zu)\n", result, len);
return -EIO;
}
return result;
@@ -614,7 +614,7 @@ skipdata:;
goto skipdata2;
}
if (datalen > req->datalen + 8) {
- printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d (expected at most %d)\n", datalen, req->datalen + 8);
+ printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d (expected at most %Zd)\n", datalen, req->datalen + 8);
server->rcv.state = 3;
goto skipdata;
}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b27662b85b3c..cdf78285b736 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -53,7 +53,7 @@ static void nfs_delete_inode(struct inode *);
static void nfs_put_super(struct super_block *);
static void nfs_clear_inode(struct inode *);
static void nfs_umount_begin(struct super_block *);
-static int nfs_statfs(struct super_block *, struct statfs *);
+static int nfs_statfs(struct super_block *, struct kstatfs *);
static int nfs_show_options(struct seq_file *, struct vfsmount *);
static struct super_operations nfs_sops = {
@@ -474,7 +474,7 @@ out_fail:
}
static int
-nfs_statfs(struct super_block *sb, struct statfs *buf)
+nfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct nfs_server *server = NFS_SB(sb);
unsigned char blockbits;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index ea64d649de3d..b3bcce53d605 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -866,7 +866,7 @@ int
nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p,
struct nfsd3_fsstatres *resp)
{
- struct statfs *s = &resp->stats;
+ struct kstatfs *s = &resp->stats;
u64 bs = s->f_bsize;
*p++ = xdr_zero; /* no post_op_attr */
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 2146b8eaa045..26cf94635f61 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1081,7 +1081,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct name_ent *owner = NULL;
struct name_ent *group = NULL;
struct svc_fh tempfh;
- struct statfs statfs;
+ struct kstatfs statfs;
int buflen = *countp << 2;
u32 *attrlenp;
u32 dummy;
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index f28c4c0d2508..f724778dc44c 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -441,7 +441,7 @@ int
nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
struct nfsd_statfsres *resp)
{
- struct statfs *stat = &resp->stats;
+ struct kstatfs *stat = &resp->stats;
*p++ = htonl(NFSSVC_MAXBLKSIZE); /* max transfer size */
*p++ = htonl(stat->f_bsize);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 294860aefa8b..8759cb1076ad 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1505,7 +1505,7 @@ out:
* N.B. After this call fhp needs an fh_put
*/
int
-nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct statfs *stat)
+nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
{
int err = fh_verify(rqstp, fhp, 0, MAY_NOP);
if (!err && vfs_statfs(fhp->fh_dentry->d_inode->i_sb,stat))
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 475799f476ac..aaa7ec00b633 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1251,7 +1251,7 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol)
*
* Return 0 on success or -errno on error.
*/
-static int ntfs_statfs(struct super_block *sb, struct statfs *sfs)
+static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
{
ntfs_volume *vol = NTFS_SB(sb);
s64 size;
diff --git a/fs/open.c b/fs/open.c
index fac3d44702d6..2e2e4e4dae97 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -23,23 +23,85 @@
#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-int vfs_statfs(struct super_block *sb, struct statfs *buf)
+int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
int retval = -ENODEV;
if (sb) {
retval = -ENOSYS;
if (sb->s_op->statfs) {
- memset(buf, 0, sizeof(struct statfs));
+ memset(buf, 0, sizeof(*buf));
retval = security_sb_statfs(sb);
if (retval)
return retval;
retval = sb->s_op->statfs(sb, buf);
+ if (retval == 0 && buf->f_frsize == 0)
+ buf->f_frsize = buf->f_bsize;
}
}
return retval;
}
+static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
+{
+ struct kstatfs st;
+ int retval;
+
+ retval = vfs_statfs(sb, &st);
+ if (retval)
+ return retval;
+
+ if (sizeof(*buf) == sizeof(st))
+ memcpy(buf, &st, sizeof(st));
+ else {
+ if (sizeof buf->f_blocks == 4) {
+ if ((st.f_blocks | st.f_bfree |
+ st.f_bavail | st.f_files | st.f_ffree) &
+ 0xffffffff00000000ULL)
+ return -EOVERFLOW;
+ }
+
+ buf->f_type = st.f_type;
+ buf->f_bsize = st.f_bsize;
+ buf->f_blocks = st.f_blocks;
+ buf->f_bfree = st.f_bfree;
+ buf->f_bavail = st.f_bavail;
+ buf->f_files = st.f_files;
+ buf->f_ffree = st.f_ffree;
+ buf->f_fsid = st.f_fsid;
+ buf->f_namelen = st.f_namelen;
+ buf->f_frsize = st.f_frsize;
+ memset(buf->f_spare, 0, sizeof(buf->f_spare));
+ }
+ return 0;
+}
+
+static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf)
+{
+ struct kstatfs st;
+ int retval;
+
+ retval = vfs_statfs(sb, &st);
+ if (retval)
+ return retval;
+
+ if (sizeof(*buf) == sizeof(st))
+ memcpy(buf, &st, sizeof(st));
+ else {
+ buf->f_type = st.f_type;
+ buf->f_bsize = st.f_bsize;
+ buf->f_blocks = st.f_blocks;
+ buf->f_bfree = st.f_bfree;
+ buf->f_bavail = st.f_bavail;
+ buf->f_files = st.f_files;
+ buf->f_ffree = st.f_ffree;
+ buf->f_fsid = st.f_fsid;
+ buf->f_namelen = st.f_namelen;
+ buf->f_frsize = st.f_frsize;
+ memset(buf->f_spare, 0, sizeof(buf->f_spare));
+ }
+ return 0;
+}
asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
{
@@ -49,14 +111,34 @@ asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
error = user_path_walk(path, &nd);
if (!error) {
struct statfs tmp;
- error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
- if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs)))
+ error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp);
+ if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT;
path_release(&nd);
}
return error;
}
+
+asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf)
+{
+ struct nameidata nd;
+ long error;
+
+ if (sz != sizeof(*buf))
+ return -EINVAL;
+ error = user_path_walk(path, &nd);
+ if (!error) {
+ struct statfs64 tmp;
+ error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp);
+ if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+ error = -EFAULT;
+ path_release(&nd);
+ }
+ return error;
+}
+
+
asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
{
struct file * file;
@@ -67,8 +149,29 @@ asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
file = fget(fd);
if (!file)
goto out;
- error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
- if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs)))
+ error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp);
+ if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+ error = -EFAULT;
+ fput(file);
+out:
+ return error;
+}
+
+asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user *buf)
+{
+ struct file * file;
+ struct statfs64 tmp;
+ int error;
+
+ if (sz != sizeof(*buf))
+ return -EINVAL;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+ error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp);
+ if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
error = -EFAULT;
fput(file);
out:
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index 5b51ac3c3a44..34e7225c303f 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -20,7 +20,17 @@ config ACORN_PARTITION
help
Support hard disks partitioned under Acorn operating systems.
-# bool ' Cumana partition support' CONFIG_ACORN_PARTITION_CUMANA
+config ACORN_PARTITION_CUMANA
+ bool "Cumana partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+ default y if !PARTITION_ADVANCED && ARCH_ACORN
+ help
+ Say Y here if you would like to use hard disks under Linux which
+ were partitioned using the Cumana interface on Acorn machines.
+
+config ACORN_PARTITION_EESOX
+ bool "EESOX partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+ default y if !PARTITION_ADVANCED && ARCH_ACORN
+
config ACORN_PARTITION_ICS
bool "ICS partition support" if PARTITION_ADVANCED && ACORN_PARTITION
default y if !PARTITION_ADVANCED && ARCH_ACORN
diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c
index 2516a2027b0e..5706a8893f31 100644
--- a/fs/partitions/acorn.c
+++ b/fs/partitions/acorn.c
@@ -7,14 +7,25 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Scan ADFS partitions on hard disk drives.
+ * Scan ADFS partitions on hard disk drives. Unfortunately, there
+ * isn't a standard for partitioning drives on Acorn machines, so
+ * every single manufacturer of SCSI and IDE cards created their own
+ * method.
*/
#include <linux/config.h>
#include <linux/buffer_head.h>
+#include <linux/adfs_fs.h>
#include "check.h"
#include "acorn.h"
+/*
+ * Partition types. (Oh for reusability)
+ */
+#define PARTITION_RISCIX_MFM 1
+#define PARTITION_RISCIX_SCSI 2
+#define PARTITION_LINUX 9
+
static struct adfs_discrecord *
adfs_partition(struct parsed_partitions *state, char *name, char *data,
unsigned long first_sector, int slot)
@@ -40,6 +51,21 @@ adfs_partition(struct parsed_partitions *state, char *name, char *data,
}
#ifdef CONFIG_ACORN_PARTITION_RISCIX
+
+struct riscix_part {
+ __u32 start;
+ __u32 length;
+ __u32 one;
+ char name[16];
+};
+
+struct riscix_record {
+ __u32 magic;
+#define RISCIX_MAGIC (0x4a657320)
+ __u32 date;
+ struct riscix_part part[8];
+};
+
static int
riscix_partition(struct parsed_partitions *state, struct block_device *bdev,
unsigned long first_sect, int slot, unsigned long nr_sects)
@@ -81,6 +107,15 @@ riscix_partition(struct parsed_partitions *state, struct block_device *bdev,
}
#endif
+#define LINUX_NATIVE_MAGIC 0xdeafa1de
+#define LINUX_SWAP_MAGIC 0xdeafab1e
+
+struct linux_part {
+ __u32 magic;
+ __u32 start_sect;
+ __u32 nr_sects;
+};
+
static int
linux_partition(struct parsed_partitions *state, struct block_device *bdev,
unsigned long first_sect, int slot, unsigned long nr_sects)
@@ -114,7 +149,7 @@ linux_partition(struct parsed_partitions *state, struct block_device *bdev,
}
#ifdef CONFIG_ACORN_PARTITION_CUMANA
-static int
+int
adfspart_check_CUMANA(struct parsed_partitions *state, struct block_device *bdev)
{
unsigned long first_sector = 0;
@@ -126,7 +161,7 @@ adfspart_check_CUMANA(struct parsed_partitions *state, struct block_device *bdev
int slot = 1;
/*
- * Try Cumana style partitions - sector 3 contains ADFS boot block
+ * Try Cumana style partitions - sector 6 contains ADFS boot block
* with pointer to next 'drive'.
*
* There are unknowns in this code - is the 'cylinder number' of the
@@ -206,7 +241,7 @@ adfspart_check_CUMANA(struct parsed_partitions *state, struct block_device *bdev
* hda1 = ADFS partition on first drive.
* hda2 = non-ADFS partition.
*/
-static int
+int
adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev)
{
unsigned long start_sect, nr_sects, sectscyl, heads;
@@ -263,11 +298,18 @@ adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev)
break;
}
}
+ printk("\n");
return 1;
}
#endif
#ifdef CONFIG_ACORN_PARTITION_ICS
+
+struct ics_part {
+ __u32 start;
+ __s32 size;
+};
+
static int adfspart_check_ICSLinux(struct block_device *bdev, unsigned long block)
{
Sector sect;
@@ -284,6 +326,22 @@ static int adfspart_check_ICSLinux(struct block_device *bdev, unsigned long bloc
}
/*
+ * Check for a valid ICS partition using the checksum.
+ */
+static inline int valid_ics_sector(const unsigned char *data)
+{
+ unsigned long sum;
+ int i;
+
+ for (i = 0, sum = 0x50617274; i < 508; i++)
+ sum += data[i];
+
+ sum -= le32_to_cpu(*(__u32 *)(&data[508]));
+
+ return sum == 0;
+}
+
+/*
* Purpose: allocate ICS partitions.
* Params : hd - pointer to gendisk structure to store partition info.
* dev - device number to access.
@@ -293,15 +351,13 @@ static int adfspart_check_ICSLinux(struct block_device *bdev, unsigned long bloc
* hda2 = ADFS partition 1 on first drive.
* ..etc..
*/
-static int
+int
adfspart_check_ICS(struct parsed_partitions *state, struct block_device *bdev)
{
- Sector sect;
- unsigned char *data;
- unsigned long sum;
- unsigned int i;
+ const unsigned char *data;
+ const struct ics_part *p;
int slot;
- struct ics_part *p;
+ Sector sect;
/*
* Try ICS style partitions - sector 0 contains partition info.
@@ -310,33 +366,33 @@ adfspart_check_ICS(struct parsed_partitions *state, struct block_device *bdev)
if (!data)
return -1;
- /*
- * check for a valid checksum
- */
- for (i = 0, sum = 0x50617274; i < 508; i++)
- sum += data[i];
-
- sum -= le32_to_cpu(*(__u32 *)(&data[508]));
- if (sum) {
+ if (!valid_ics_sector(data)) {
put_dev_sector(sect);
- return 0; /* not ICS partition table */
+ return 0;
}
printk(" [ICS]");
- for (slot = 1, p = (struct ics_part *)data; p->size; p++) {
+ for (slot = 1, p = (const struct ics_part *)data; p->size; p++) {
u32 start = le32_to_cpu(p->start);
- u32 size = le32_to_cpu(p->size);
+ s32 size = le32_to_cpu(p->size); /* yes, it's signed. */
if (slot == state->limit)
break;
+ /*
+ * Negative sizes tell the RISC OS ICS driver to ignore
+ * this partition - in effect it says that this does not
+ * contain an ADFS filesystem.
+ */
if (size < 0) {
size = -size;
/*
- * We use the first sector to identify what type
- * this partition is...
+ * Our own extension - We use the first sector
+ * of the partition to identify what type this
+ * partition is. We must not make this visible
+ * to the filesystem.
*/
if (size > 1 && adfspart_check_ICSLinux(bdev, start)) {
start += 1;
@@ -349,10 +405,39 @@ adfspart_check_ICS(struct parsed_partitions *state, struct block_device *bdev)
}
put_dev_sector(sect);
+ printk("\n");
return 1;
}
#endif
+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
+struct ptec_part {
+ __u32 unused1;
+ __u32 unused2;
+ __u32 start;
+ __u32 size;
+ __u32 unused5;
+ char type[8];
+};
+
+static inline int valid_ptec_sector(const unsigned char *data)
+{
+ unsigned char checksum = 0x2a;
+ int i;
+
+ /*
+ * If it looks like a PC/BIOS partition, then it
+ * probably isn't PowerTec.
+ */
+ if (data[510] == 0x55 && data[511] == 0xaa)
+ return 0;
+
+ for (i = 0; i < 511; i++)
+ checksum += data[i];
+
+ return checksum == data[511];
+}
+
/*
* Purpose: allocate ICS partitions.
* Params : hd - pointer to gendisk structure to store partition info.
@@ -363,14 +448,12 @@ adfspart_check_ICS(struct parsed_partitions *state, struct block_device *bdev)
* hda2 = ADFS partition 1 on first drive.
* ..etc..
*/
-#ifdef CONFIG_ACORN_PARTITION_POWERTEC
-static int
+int
adfspart_check_POWERTEC(struct parsed_partitions *state, struct block_device *bdev)
{
Sector sect;
- unsigned char *data;
- struct ptec_partition *p;
- unsigned char checksum;
+ const unsigned char *data;
+ const struct ptec_part *p;
int slot = 1;
int i;
@@ -378,17 +461,14 @@ adfspart_check_POWERTEC(struct parsed_partitions *state, struct block_device *bd
if (!data)
return -1;
- for (checksum = 0x2a, i = 0; i < 511; i++)
- checksum += data[i];
-
- if (checksum != data[511]) {
+ if (!valid_ptec_sector(data)) {
put_dev_sector(sect);
return 0;
}
printk(" [POWERTEC]");
- for (i = 0, p = (struct ptec_partition *)data; i < 12; i++, p++) {
+ for (i = 0, p = (const struct ptec_part *)data; i < 12; i++, p++) {
u32 start = le32_to_cpu(p->start);
u32 size = le32_to_cpu(p->size);
@@ -397,46 +477,81 @@ adfspart_check_POWERTEC(struct parsed_partitions *state, struct block_device *bd
}
put_dev_sector(sect);
+ printk("\n");
return 1;
}
#endif
-static int (*partfn[])(struct parsed_partitions *, struct block_device *) = {
-#ifdef CONFIG_ACORN_PARTITION_ICS
- adfspart_check_ICS,
-#endif
-#ifdef CONFIG_ACORN_PARTITION_POWERTEC
- adfspart_check_POWERTEC,
-#endif
-#ifdef CONFIG_ACORN_PARTITION_CUMANA
- adfspart_check_CUMANA,
-#endif
-#ifdef CONFIG_ACORN_PARTITION_ADFS
- adfspart_check_ADFS,
-#endif
- NULL
+#ifdef CONFIG_ACORN_PARTITION_EESOX
+struct eesox_part {
+ char magic[6];
+ char name[10];
+ u32 start;
+ u32 unused6;
+ u32 unused7;
+ u32 unused8;
+};
+
+/*
+ * Guess who created this format?
+ */
+static const char eesox_name[] = {
+ 'N', 'e', 'i', 'l', ' ',
+ 'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' '
};
+
/*
- * Purpose: initialise all the partitions on an ADFS drive.
- * These may be other ADFS partitions or a Linux/RiscBSD/RISCiX
- * partition.
+ * EESOX SCSI partition format.
*
- * Params : hd - pointer to gendisk structure
- * dev - device number to access
+ * This is a goddamned awful partition format. We don't seem to store
+ * the size of the partition in this table, only the start addresses.
*
- * Returns: -1 on error, 0 if not ADFS format, 1 if ok.
+ * There are two possibilities where the size comes from:
+ * 1. The individual ADFS boot block entries that are placed on the disk.
+ * 2. The start address of the next entry.
*/
-int acorn_partition(struct parsed_partitions *state, struct block_device *bdev)
+int
+adfspart_check_EESOX(struct parsed_partitions *state, struct block_device *bdev)
{
- int i;
+ Sector sect;
+ const unsigned char *data;
+ unsigned char buffer[256];
+ struct eesox_part *p;
+ u32 start = 0;
+ int i, slot = 1;
- for (i = 0; partfn[i]; i++) {
- int r = partfn[i](state, bdev);
- if (r) {
- if (r > 0)
- printk("\n");
- return r;
- }
+ data = read_dev_sector(bdev, 7, &sect);
+ if (!data)
+ return -1;
+
+ /*
+ * "Decrypt" the partition table. God knows why...
+ */
+ for (i = 0; i < 256; i++)
+ buffer[i] = data[i] ^ eesox_name[i & 15];
+
+ put_dev_sector(sect);
+
+ for (i = 0, p = (struct eesox_part *)buffer; i < 8; i++, p++) {
+ u32 next;
+
+ if (memcmp(p->magic, "Eesox", 6))
+ break;
+
+ next = le32_to_cpu(p->start) + first_sector;
+ if (i)
+ put_partition(state, slot++, start, next - start);
+ start = next;
}
- return 0;
+
+ if (i != 0) {
+ unsigned long size;
+
+ size = hd->part[minor(to_kdev_t(bdev->bd_dev))].nr_sects;
+ add_gd_partition(hd, minor++, start, size - start);
+ printk("\n");
+ }
+
+ return i ? 1 : 0;
}
+#endif
diff --git a/fs/partitions/acorn.h b/fs/partitions/acorn.h
index 7c984234ae81..81fd50ecc080 100644
--- a/fs/partitions/acorn.h
+++ b/fs/partitions/acorn.h
@@ -1,53 +1,14 @@
/*
- * fs/partitions/acorn.h
+ * linux/fs/partitions/acorn.h
*
- * Copyright (C) 1996-1998 Russell King
- */
-#include <linux/adfs_fs.h>
-
-/*
- * Partition types. (Oh for reusability)
+ * Copyright (C) 1996-2001 Russell King.
+ *
+ * I _hate_ this partitioning mess - why can't we have one defined
+ * format, and everyone stick to it?
*/
-#define PARTITION_RISCIX_MFM 1
-#define PARTITION_RISCIX_SCSI 2
-#define PARTITION_LINUX 9
-
-struct riscix_part {
- __u32 start;
- __u32 length;
- __u32 one;
- char name[16];
-};
-
-struct riscix_record {
- __u32 magic;
-#define RISCIX_MAGIC (0x4a657320)
- __u32 date;
- struct riscix_part part[8];
-};
-
-#define LINUX_NATIVE_MAGIC 0xdeafa1de
-#define LINUX_SWAP_MAGIC 0xdeafab1e
-
-struct linux_part {
- __u32 magic;
- __u32 start_sect;
- __u32 nr_sects;
-};
-
-struct ics_part {
- __u32 start;
- __s32 size;
-};
-
-struct ptec_partition {
- __u32 unused1;
- __u32 unused2;
- __u32 start;
- __u32 size;
- __u32 unused5;
- char type[8];
-};
-
-int acorn_partition(struct parsed_partitions *state, struct block_device *bdev);
+int adfspart_check_CUMANA(struct parsed_partitions *state, struct block_device *bdev);
+int adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev);
+int adfspart_check_ICS(struct parsed_partitions *state, struct block_device *bdev);
+int adfspart_check_POWERTEC(struct parsed_partitions *state, struct block_device *bdev);
+int adfspart_check_EESOX(struct parsed_partitions *state, struct block_device *bdev);
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 8f09ea0494f8..fa9d8eb03f98 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -45,9 +45,33 @@ extern void md_autodetect_dev(dev_t dev);
int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
static int (*check_part[])(struct parsed_partitions *, struct block_device *) = {
-#ifdef CONFIG_ACORN_PARTITION
- acorn_partition,
+ /*
+ * Probe partition formats with tables at disk address 0
+ * that also have an ADFS boot block at 0xdc0.
+ */
+#ifdef CONFIG_ACORN_PARTITION_ICS
+ adfspart_check_ICS,
#endif
+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
+ adfspart_check_POWERTEC,
+#endif
+#ifdef CONFIG_ACORN_PARTITION_EESOX
+ adfspart_check_EESOX,
+#endif
+
+ /*
+ * Now move on to formats that only have partition info at
+ * disk address 0xdc0. Since these may also have stale
+ * PC/BIOS partition tables, they need to come before
+ * the msdos entry.
+ */
+#ifdef CONFIG_ACORN_PARTITION_CUMANA
+ adfspart_check_CUMANA,
+#endif
+#ifdef CONFIG_ACORN_PARTITION_ADFS
+ adfspart_check_ADFS,
+#endif
+
#ifdef CONFIG_EFI_PARTITION
efi_partition, /* this must come before msdos */
#endif
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d6415745561a..e843c6584cc9 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1362,10 +1362,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
- put_task_struct(task);
- if (!inode)
+ if (!inode) {
+ put_task_struct(task);
goto out;
+ }
inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
inode->i_op = &proc_base_inode_operations;
inode->i_fop = &proc_base_operations;
@@ -1379,6 +1380,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
d_add(dentry, inode);
spin_unlock(&task->proc_lock);
+ put_task_struct(task);
return NULL;
out:
return ERR_PTR(-ENOENT);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index e70d8b03ddd2..fa9f9cc4d519 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -451,8 +451,20 @@ static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t
kfree(elf_buf);
} else {
if (kern_addr_valid(start)) {
- if (copy_to_user(buffer, (char *)start, tsz))
- return -EFAULT;
+ unsigned long n;
+
+ n = copy_to_user(buffer, (char *)start, tsz);
+ /*
+ * We cannot distingush between fault on source
+ * and fault on destination. When this happens
+ * we clear too and hope it will trigger the
+ * EFAULT again.
+ */
+ if (n) {
+ if (clear_user(buffer + tsz - n,
+ tsz - n))
+ return -EFAULT;
+ }
} else {
if (clear_user(buffer, tsz))
return -EFAULT;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index a9d6f99c1869..3d7d759c63da 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -91,13 +91,13 @@ static int show_map(struct seq_file *m, void *v)
}
seq_printf(m, "%0*lx-%0*lx %c%c%c%c %0*lx %02x:%02x %lu %n",
- 2*sizeof(void*), map->vm_start,
- 2*sizeof(void*), map->vm_end,
+ (int) (2*sizeof(void*)), map->vm_start,
+ (int) (2*sizeof(void*)), map->vm_end,
flags & VM_READ ? 'r' : '-',
flags & VM_WRITE ? 'w' : '-',
flags & VM_EXEC ? 'x' : '-',
flags & VM_MAYSHARE ? 's' : 'p',
- 2*sizeof(void*), map->vm_pgoff << PAGE_SHIFT,
+ (int) (2*sizeof(void*)), map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino, &len);
if (map->vm_file) {
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 90f7a0034e64..c894b7ecac00 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -126,7 +126,7 @@ static struct inode *qnx4_alloc_inode(struct super_block *sb);
static void qnx4_destroy_inode(struct inode *inode);
static void qnx4_read_inode(struct inode *);
static int qnx4_remount(struct super_block *sb, int *flags, char *data);
-static int qnx4_statfs(struct super_block *, struct statfs *);
+static int qnx4_statfs(struct super_block *, struct kstatfs *);
static struct super_operations qnx4_sops =
{
@@ -276,7 +276,7 @@ unsigned long qnx4_block_map( struct inode *inode, long iblock )
return block;
}
-static int qnx4_statfs(struct super_block *sb, struct statfs *buf)
+static int qnx4_statfs(struct super_block *sb, struct kstatfs *buf)
{
lock_kernel();
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 8ff47e47a2e1..9f37ffd92761 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -62,7 +62,7 @@ int is_reiserfs_super (struct super_block *s)
}
static int reiserfs_remount (struct super_block * s, int * flags, char * data);
-static int reiserfs_statfs (struct super_block * s, struct statfs * buf);
+static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
static void reiserfs_write_super (struct super_block * s)
{
@@ -1414,13 +1414,11 @@ static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
}
-static int reiserfs_statfs (struct super_block * s, struct statfs * buf)
+static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf)
{
struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
buf->f_namelen = (REISERFS_MAX_NAME (s->s_blocksize));
- buf->f_ffree = -1;
- buf->f_files = -1;
buf->f_bfree = sb_free_blocks(rs);
buf->f_bavail = buf->f_bfree;
buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index dd52de09689c..fb60389d42fc 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -176,7 +176,7 @@ outnobh:
/* That's simple too. */
static int
-romfs_statfs(struct super_block *sb, struct statfs *buf)
+romfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
buf->f_type = ROMFS_MAGIC;
buf->f_bsize = ROMBSIZE;
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index abe004b1e78f..b3dd504d88e6 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -47,7 +47,7 @@
static void smb_delete_inode(struct inode *);
static void smb_put_super(struct super_block *);
-static int smb_statfs(struct super_block *, struct statfs *);
+static int smb_statfs(struct super_block *, struct kstatfs *);
static int smb_show_options(struct seq_file *, struct vfsmount *);
static kmem_cache_t *smb_inode_cachep;
@@ -610,7 +610,7 @@ out_no_server:
}
static int
-smb_statfs(struct super_block *sb, struct statfs *buf)
+smb_statfs(struct super_block *sb, struct kstatfs *buf)
{
int result;
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index e3221e28b887..8c386131c9ea 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -3160,7 +3160,7 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
}
int
-smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
+smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr)
{
struct smb_sb_info *server = SMB_SB(sb);
int result;
diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h
index ec44bad0e84e..e42cf69c061c 100644
--- a/fs/smbfs/proto.h
+++ b/fs/smbfs/proto.h
@@ -29,7 +29,7 @@ extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor);
extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
-extern int smb_proc_dskattr(struct super_block *sb, struct statfs *attr);
+extern int smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr);
extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len);
extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
diff --git a/fs/super.c b/fs/super.c
index 2aae8ed4cdcc..8f1f26de1673 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -409,7 +409,7 @@ asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf)
{
struct super_block *s;
struct ustat tmp;
- struct statfs sbuf;
+ struct kstatfs sbuf;
int err = -EINVAL;
s = user_get_super(dev);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index d433042d358f..9a4564610aae 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -75,7 +75,7 @@ static void sysv_put_super(struct super_block *sb)
kfree(sbi);
}
-static int sysv_statfs(struct super_block *sb, struct statfs *buf)
+static int sysv_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 00bfdd3d6a1b..2b82a0451814 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -95,7 +95,7 @@ static void udf_load_partdesc(struct super_block *, struct buffer_head *);
static void udf_open_lvid(struct super_block *);
static void udf_close_lvid(struct super_block *);
static unsigned int udf_count_free(struct super_block *);
-static int udf_statfs(struct super_block *, struct statfs *);
+static int udf_statfs(struct super_block *, struct kstatfs *);
/* UDF filesystem type */
static struct super_block *udf_get_sb(struct file_system_type *fs_type,
@@ -1720,7 +1720,7 @@ udf_put_super(struct super_block *sb)
* Written, tested, and released.
*/
static int
-udf_statfs(struct super_block *sb, struct statfs *buf)
+udf_statfs(struct super_block *sb, struct kstatfs *buf)
{
buf->f_type = UDF_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index d9d96adb4672..802ca517153e 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -973,7 +973,7 @@ int ufs_remount (struct super_block * sb, int * mount_flags, char * data)
return 0;
}
-int ufs_statfs (struct super_block * sb, struct statfs * buf)
+int ufs_statfs (struct super_block * sb, struct kstatfs * buf)
{
struct ufs_sb_private_info * uspi;
struct ufs_super_block_first * usb1;
@@ -988,8 +988,8 @@ int ufs_statfs (struct super_block * sb, struct statfs * buf)
buf->f_blocks = uspi->s_dsize;
buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) +
fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
- buf->f_bavail = (buf->f_bfree > ((buf->f_blocks / 100) * uspi->s_minfree))
- ? (buf->f_bfree - ((buf->f_blocks / 100) * uspi->s_minfree)) : 0;
+ buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree))
+ ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;
buf->f_files = uspi->s_ncg * uspi->s_ipg;
buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
buf->f_namelen = UFS_MAXNAMLEN;
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index 7cf9629179d7..0df0d915865f 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -477,7 +477,7 @@ linvfs_write_super(
STATIC int
linvfs_statfs(
struct super_block *sb,
- struct statfs *statp)
+ struct kstatfs *statp)
{
vfs_t *vfsp = LINVFS_GET_VFS(sb);
int error;
@@ -673,7 +673,7 @@ linvfs_fill_super(
vnode_t *rootvp;
struct vfs *vfsp = vfs_allocate();
struct xfs_mount_args *args = args_allocate(sb);
- struct statfs statvfs;
+ struct kstatfs statvfs;
int error;
vfsp->vfs_super = sb;
diff --git a/fs/xfs/linux/xfs_vfs.c b/fs/xfs/linux/xfs_vfs.c
index 86329735784f..938a2a449475 100644
--- a/fs/xfs/linux/xfs_vfs.c
+++ b/fs/xfs/linux/xfs_vfs.c
@@ -134,7 +134,7 @@ vfs_root(
int
vfs_statvfs(
struct bhv_desc *bdp,
- struct statfs *sp,
+ struct kstatfs *sp,
struct vnode *vp)
{
struct bhv_desc *next = bdp;
diff --git a/fs/xfs/linux/xfs_vfs.h b/fs/xfs/linux/xfs_vfs.h
index 469da44bab75..d12501e7dac4 100644
--- a/fs/xfs/linux/xfs_vfs.h
+++ b/fs/xfs/linux/xfs_vfs.h
@@ -37,7 +37,7 @@
struct fid;
struct cred;
struct vnode;
-struct statfs;
+struct kstatfs;
struct seq_file;
struct super_block;
struct xfs_mount_args;
@@ -101,7 +101,7 @@ typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
struct xfs_mount_args *);
typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **);
-typedef int (*vfs_statvfs_t)(bhv_desc_t *, struct statfs *, struct vnode *);
+typedef int (*vfs_statvfs_t)(bhv_desc_t *, struct kstatfs *, struct vnode *);
typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *);
typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
@@ -168,7 +168,7 @@ extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
extern int vfs_root(bhv_desc_t *, struct vnode **);
-extern int vfs_statvfs(bhv_desc_t *, struct statfs *, struct vnode *);
+extern int vfs_statvfs(bhv_desc_t *, struct kstatfs *, struct vnode *);
extern int vfs_sync(bhv_desc_t *, int, struct cred *);
extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *);
extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index e575ffa1ba19..240a53e1ee49 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -754,7 +754,7 @@ xfs_root(
STATIC int
xfs_statvfs(
bhv_desc_t *bdp,
- struct statfs *statp,
+ struct kstatfs *statp,
vnode_t *vp)
{
__uint64_t fakeinos;
@@ -784,7 +784,7 @@ xfs_statvfs(
if (!mp->m_inoadd)
#endif
statp->f_files =
- MIN(statp->f_files, (long)mp->m_maxicount);
+ min_t(sector_t, statp->f_files, mp->m_maxicount);
statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
XFS_SB_UNLOCK(mp, s);
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 3fda218d6de3..329cdaafe22c 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -64,7 +64,7 @@
/* Version string */
-#define ACPI_CA_VERSION 0x20030522
+#define ACPI_CA_VERSION 0x20030619
/* Maximum objects in the various object caches */
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 254d11a7ac5e..8520f1372cca 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -105,6 +105,7 @@ ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS;
*/
ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
+ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 4be6958950e6..9fbb1b0e9c84 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -108,7 +108,7 @@ acpi_hw_low_level_write (
acpi_status
acpi_hw_clear_acpi_status (
- void);
+ u32 flags);
/* GPE support */
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 0d495da9ab1c..bb6df66442bc 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -287,15 +287,15 @@ acpi_os_derive_pci_id(
* Miscellaneous
*/
-BOOLEAN
+u8
acpi_os_readable (
void *pointer,
- u32 length);
+ acpi_size length);
-BOOLEAN
+u8
acpi_os_writable (
void *pointer,
- u32 length);
+ acpi_size length);
u32
acpi_os_get_timer (
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index d077d7419682..beec737952a3 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -50,11 +50,14 @@
/*
* Data type ranges
+ * Note: These macros are designed to be compiler independent as well as
+ * working around problems that some 32-bit compilers have with 64-bit
+ * constants.
*/
-#define ACPI_UINT8_MAX (~((UINT8) 0))
-#define ACPI_UINT16_MAX (~((UINT16) 0))
-#define ACPI_UINT32_MAX (~((UINT32) 0))
-#define ACPI_UINT64_MAX (~((UINT64) 0))
+#define ACPI_UINT8_MAX (UINT8) (~((UINT8) 0)) /* 0xFF */
+#define ACPI_UINT16_MAX (UINT16)(~((UINT16) 0)) /* 0xFFFF */
+#define ACPI_UINT32_MAX (UINT32)(~((UINT32) 0)) /* 0xFFFFFFFF */
+#define ACPI_UINT64_MAX (UINT64)(~((UINT64) 0)) /* 0xFFFFFFFFFFFFFFFF */
#define ACPI_ASCII_MAX 0x7F
@@ -299,8 +302,6 @@ struct uint32_struct
typedef u32 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT32_MAX
#define ACPI_INTEGER_BIT_SIZE 32
-#define ACPI_MAX_BCD_VALUE 99999999
-#define ACPI_MAX_BCD_DIGITS 8
#define ACPI_MAX_DECIMAL_DIGITS 10
#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */
@@ -313,12 +314,6 @@ typedef u32 acpi_integer;
typedef u64 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
#define ACPI_INTEGER_BIT_SIZE 64
-#if ACPI_MACHINE_WIDTH == 64
-#define ACPI_MAX_BCD_VALUE 9999999999999999UL
-#else
-#define ACPI_MAX_BCD_VALUE 9999999999999999ULL
-#endif
-#define ACPI_MAX_BCD_DIGITS 16
#define ACPI_MAX_DECIMAL_DIGITS 19
#if ACPI_MACHINE_WIDTH == 64
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
index d23b1f5db70c..34d0376dc322 100644
--- a/include/asm-alpha/pci.h
+++ b/include/asm-alpha/pci.h
@@ -194,6 +194,18 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+/* Bus number == domain number until we get above 256 busses */
+static inline int pci_name_bus(char *name, struct pci_bus *bus)
+{
+ int domain = pci_domain_nr(bus)
+ if (domain < 256) {
+ sprintf(name, "%02x", domain);
+ } else {
+ sprintf(name, "%04x:%02x", domain, bus->number);
+ }
+ return 0;
+}
+
#endif /* __KERNEL__ */
/* Values for the `which' argument to sys_pciconfig_iobase. */
diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h
index 1526b07d625b..29c697133046 100644
--- a/include/asm-alpha/smp.h
+++ b/include/asm-alpha/smp.h
@@ -57,6 +57,15 @@ 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;
+}
+
extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu);
#else /* CONFIG_SMP */
diff --git a/include/asm-alpha/statfs.h b/include/asm-alpha/statfs.h
index cc4ba1de0ede..ad15830baefe 100644
--- a/include/asm-alpha/statfs.h
+++ b/include/asm-alpha/statfs.h
@@ -1,25 +1,6 @@
#ifndef _ALPHA_STATFS_H
#define _ALPHA_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- int f_type;
- int f_bsize;
- int f_blocks;
- int f_bfree;
- int f_bavail;
- int f_files;
- int f_ffree;
- __kernel_fsid_t f_fsid;
- int f_namelen;
- int f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
index 7b500d3cfda2..38faced4d0a2 100644
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -593,13 +593,7 @@ static inline long read(int fd, char * buf, size_t nr)
return sys_read(fd, buf, nr);
}
-extern int __kernel_execve(char *, char **, char **, struct pt_regs *);
-static inline long execve(char * file, char ** argvp, char ** envp)
-{
- struct pt_regs regs;
- memset(&regs, 0, sizeof(regs));
- return __kernel_execve(file, argvp, envp, &regs);
-}
+extern long execve(char *, char **, char **);
extern long sys_setsid(void);
static inline long setsid(void)
diff --git a/include/asm-alpha/xor.h b/include/asm-alpha/xor.h
index a88d79d6e3ac..5ee1c2bc0499 100644
--- a/include/asm-alpha/xor.h
+++ b/include/asm-alpha/xor.h
@@ -822,19 +822,19 @@ xor_alpha_prefetch_5: \n\
");
static struct xor_block_template xor_block_alpha = {
- name: "alpha",
- do_2: xor_alpha_2,
- do_3: xor_alpha_3,
- do_4: xor_alpha_4,
- do_5: xor_alpha_5,
+ .name = "alpha",
+ .do_2 = xor_alpha_2,
+ .do_3 = xor_alpha_3,
+ .do_4 = xor_alpha_4,
+ .do_5 = xor_alpha_5,
};
static struct xor_block_template xor_block_alpha_prefetch = {
- name: "alpha prefetch",
- do_2: xor_alpha_prefetch_2,
- do_3: xor_alpha_prefetch_3,
- do_4: xor_alpha_prefetch_4,
- do_5: xor_alpha_prefetch_5,
+ .name = "alpha prefetch",
+ .do_2 = xor_alpha_prefetch_2,
+ .do_3 = xor_alpha_prefetch_3,
+ .do_4 = xor_alpha_prefetch_4,
+ .do_5 = xor_alpha_prefetch_5,
};
/* For grins, also test the generic routines. */
diff --git a/include/asm-arm/statfs.h b/include/asm-arm/statfs.h
index a1eba73ded99..e81f82783b87 100644
--- a/include/asm-arm/statfs.h
+++ b/include/asm-arm/statfs.h
@@ -1,25 +1,6 @@
#ifndef _ASMARM_STATFS_H
#define _ASMARM_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif
diff --git a/include/asm-cris/statfs.h b/include/asm-cris/statfs.h
index 9bfcc5ea2808..fdaf921844bc 100644
--- a/include/asm-cris/statfs.h
+++ b/include/asm-cris/statfs.h
@@ -1,25 +1,6 @@
#ifndef _CRIS_STATFS_H
#define _CRIS_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif
diff --git a/include/asm-generic/statfs.h b/include/asm-generic/statfs.h
new file mode 100644
index 000000000000..fecaf8fd5c10
--- /dev/null
+++ b/include/asm-generic/statfs.h
@@ -0,0 +1,37 @@
+#ifndef _GENERIC_STATFS_H
+#define _GENERIC_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+# include <linux/types.h>
+typedef __kernel_fsid_t fsid_t;
+#endif
+
+struct statfs {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u32 f_blocks;
+ __u32 f_bfree;
+ __u32 f_bavail;
+ __u32 f_files;
+ __u32 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_frsize;
+ __u32 f_spare[5];
+};
+
+struct 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
diff --git a/include/asm-h8300/statfs.h b/include/asm-h8300/statfs.h
index 9e3be68f0c07..b96efa712aac 100644
--- a/include/asm-h8300/statfs.h
+++ b/include/asm-h8300/statfs.h
@@ -1,25 +1,6 @@
#ifndef _H8300_STATFS_H
#define _H8300_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif /* _H8300_STATFS_H */
diff --git a/include/asm-h8300/uaccess.h b/include/asm-h8300/uaccess.h
index 24a0b92b13ee..6996b612f4a0 100644
--- a/include/asm-h8300/uaccess.h
+++ b/include/asm-h8300/uaccess.h
@@ -6,6 +6,8 @@
*/
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/string.h>
+
#include <asm/segment.h>
#define VERIFY_READ 0
@@ -159,7 +161,7 @@ static inline unsigned long
clear_user(void *to, unsigned long n)
{
memset(to, 0, n);
- return(0);
+ return 0;
}
#endif /* _H8300_UACCESS_H */
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index cdb2f1ecfc01..0f158dc1615e 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -106,6 +106,10 @@
:"0"(n_hi), "1"(n_lo))
+#ifdef CONFIG_ACPI_HT_ONLY
+extern int acpi_lapic;
+#define acpi_ioapic 0
+#else
#ifndef CONFIG_ACPI_BOOT
#define acpi_lapic 0
#define acpi_ioapic 0
@@ -120,6 +124,7 @@ extern int acpi_ioapic;
#else
#define acpi_ioapic 0
#endif
+#endif
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h
index 0fb2bd405e96..9b85a2259b4a 100644
--- a/include/asm-i386/genapic.h
+++ b/include/asm-i386/genapic.h
@@ -43,6 +43,7 @@ struct genapic {
struct mpc_config_translation *t);
void (*setup_portio_remap)(void);
int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
+ void (*enable_apic_mode)(void);
/* mpparse */
void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *,
@@ -101,6 +102,7 @@ struct genapic {
APICFUNC(send_IPI_mask), \
APICFUNC(send_IPI_allbutself), \
APICFUNC(send_IPI_all), \
+ APICFUNC(enable_apic_mode), \
}
extern struct genapic *genapic;
diff --git a/include/asm-i386/mach-default/mach_resources.h b/include/asm-i386/mach-default/mach_resources.h
index 2b0eadaaca20..b37858d0d0bd 100644
--- a/include/asm-i386/mach-default/mach_resources.h
+++ b/include/asm-i386/mach-default/mach_resources.h
@@ -9,18 +9,14 @@
struct resource standard_io_resources[] = {
{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
- { "pic1", 0x20, 0x3f, IORESOURCE_BUSY },
+ { "pic1", 0x20, 0x21, IORESOURCE_BUSY },
{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY },
{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
- { "pic2", 0xa0, 0xbf, IORESOURCE_BUSY },
+ { "pic2", 0xa0, 0xa1, IORESOURCE_BUSY },
{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
{ "fpu", 0xf0, 0xff, IORESOURCE_BUSY }
};
-#ifdef CONFIG_MELAN
-standard_io_resources[1] = { "pic1", 0x20, 0x21, IORESOURCE_BUSY };
-standard_io_resources[5] = { "pic2", 0xa0, 0xa1, IORESOURCE_BUSY };
-#endif
#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
diff --git a/include/asm-i386/mach-generic/mach_apic.h b/include/asm-i386/mach-generic/mach_apic.h
index 54fa2a48b234..71b4849614bc 100644
--- a/include/asm-i386/mach-generic/mach_apic.h
+++ b/include/asm-i386/mach-generic/mach_apic.h
@@ -25,5 +25,6 @@
#define check_phys_apicid_present (genapic->check_phys_apicid_present)
#define check_apicid_used (genapic->check_apicid_used)
#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
+#define enable_apic_mode (genapic->enable_apic_mode)
#endif /* __ASM_MACH_APIC_H */
diff --git a/include/asm-i386/mach-pc9800/setup_arch_pre.h b/include/asm-i386/mach-pc9800/setup_arch_pre.h
index 47d5f0c7c140..bd53bddd6956 100644
--- a/include/asm-i386/mach-pc9800/setup_arch_pre.h
+++ b/include/asm-i386/mach-pc9800/setup_arch_pre.h
@@ -25,8 +25,8 @@ static inline void arch_setup_pc9800(void)
{
CLOCK_TICK_RATE = PC9800_8MHz_P() ? 1996800 : 2457600;
printk(KERN_DEBUG "CLOCK_TICK_RATE = %d\n", CLOCK_TICK_RATE);
- tick_usec = TICK_USEC; /* ACTHZ period (usec) */
- tick_nsec = TICK_NSEC; /* USER_HZ period (nsec) */
+ tick_usec = TICK_USEC; /* USER_HZ period (usec) */
+ tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */
pc9800_misc_flags = PC9800_MISC_FLAGS;
#ifdef CONFIG_SMP
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 770938129032..ac14135d83ba 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -468,6 +468,7 @@ extern void prepare_to_copy(struct task_struct *tsk);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern unsigned long thread_saved_pc(struct task_struct *tsk);
+void show_trace(struct task_struct *task, unsigned long *stack);
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 71dd76aa0d83..ea83e1dc8660 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -78,12 +78,12 @@ static inline int num_booting_cpus(void)
extern void map_cpu_to_logical_apicid(void);
extern void unmap_cpu_to_logical_apicid(int cpu);
-extern inline int any_online_cpu(unsigned int mask)
+extern inline unsigned int any_online_cpu(unsigned int mask)
{
if (mask & cpu_online_map)
return __ffs(mask & cpu_online_map);
- return -1;
+ return NR_CPUS;
}
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/include/asm-i386/statfs.h b/include/asm-i386/statfs.h
index 113d5d428aa0..24972c175132 100644
--- a/include/asm-i386/statfs.h
+++ b/include/asm-i386/statfs.h
@@ -1,25 +1,6 @@
#ifndef _I386_STATFS_H
#define _I386_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
index 07caa21a978c..b7744806aed6 100644
--- a/include/asm-i386/uaccess.h
+++ b/include/asm-i386/uaccess.h
@@ -8,6 +8,7 @@
#include <linux/errno.h>
#include <linux/thread_info.h>
#include <linux/prefetch.h>
+#include <linux/string.h>
#include <asm/page.h>
#define VERIFY_READ 0
@@ -494,6 +495,8 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
+ else
+ memset(to, 0, n);
return n;
}
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 84d35a14522e..b1bdc016eed5 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -273,8 +273,10 @@
#define __NR_clock_gettime (__NR_timer_create+6)
#define __NR_clock_getres (__NR_timer_create+7)
#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_statfs64 268
+#define __NR_fstatfs64 269
-#define NR_syscalls 268
+#define NR_syscalls 270
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
diff --git a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
index 83e8115083f2..b8c101e54e47 100644
--- a/include/asm-ia64/compat.h
+++ b/include/asm-ia64/compat.h
@@ -99,7 +99,8 @@ struct compat_statfs {
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
- int f_spare[6];
+ int f_frsize;
+ int f_spare[5];
};
#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index 13e56cfe1e3c..129436b9e730 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -102,6 +102,16 @@ struct pci_controller {
#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
+static inline int pci_name_bus(char *name, struct pci_bus *bus)
+{
+ if (pci_domain_nr(bus) == 0) {
+ sprintf(name, "%02x", bus->number);
+ } else {
+ sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
+ }
+ return 0;
+}
+
/* generic pci stuff */
#include <asm-generic/pci.h>
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index df4b07cf7f46..0b9a1253845c 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -56,12 +56,12 @@ num_online_cpus (void)
return hweight64(cpu_online_map);
}
-static inline int
+static inline unsigned int
any_online_cpu (unsigned int mask)
{
if (mask & cpu_online_map)
return __ffs(mask & cpu_online_map);
- return -1;
+ return NR_CPUS;
}
/*
diff --git a/include/asm-ia64/statfs.h b/include/asm-ia64/statfs.h
index 4e684d5c8e14..56f545513f95 100644
--- a/include/asm-ia64/statfs.h
+++ b/include/asm-ia64/statfs.h
@@ -6,11 +6,9 @@
* Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
*/
-# ifndef __KERNEL_STRICT_NAMES
-# include <linux/types.h>
- typedef __kernel_fsid_t fsid_t;
-# endif
-
+/*
+ * This is ugly --- we're already 64-bit, so just duplicate the definitions
+ */
struct statfs {
long f_type;
long f_bsize;
@@ -21,7 +19,24 @@ struct statfs {
long f_ffree;
__kernel_fsid_t f_fsid;
long f_namelen;
- long f_spare[6];
+ long f_frsize;
+ long f_spare[5];
+};
+
+
+struct statfs64 {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
};
+
#endif /* _ASM_IA64_STATFS_H */
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 6bb7dff36ffe..8a254dbd5e1c 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -246,6 +246,8 @@
#define __NR_sys_clock_gettime 1254
#define __NR_sys_clock_getres 1255
#define __NR_sys_clock_nanosleep 1256
+#define __NR_sys_fstatfs64 1257
+#define __NR_sys_statfs64 1258
#ifdef __KERNEL__
diff --git a/include/asm-m68k/statfs.h b/include/asm-m68k/statfs.h
index 1ee08965d53b..08d93f14e061 100644
--- a/include/asm-m68k/statfs.h
+++ b/include/asm-m68k/statfs.h
@@ -1,25 +1,6 @@
#ifndef _M68K_STATFS_H
#define _M68K_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif /* _M68K_STATFS_H */
diff --git a/include/asm-m68knommu/uaccess.h b/include/asm-m68knommu/uaccess.h
index 48a4d74bc226..6ff1747b02e0 100644
--- a/include/asm-m68knommu/uaccess.h
+++ b/include/asm-m68knommu/uaccess.h
@@ -6,6 +6,8 @@
*/
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/string.h>
+
#include <asm/segment.h>
#define VERIFY_READ 0
@@ -178,7 +180,7 @@ static inline unsigned long
clear_user(void *to, unsigned long n)
{
memset(to, 0, n);
- return(0);
+ return 0;
}
#endif /* _M68KNOMMU_UACCESS_H */
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
index f888716df94f..cbb696307310 100644
--- a/include/asm-parisc/compat.h
+++ b/include/asm-parisc/compat.h
@@ -97,7 +97,8 @@ struct compat_statfs {
s32 f_ffree;
__kernel_fsid_t f_fsid;
s32 f_namelen;
- s32 f_spare[6];
+ s32 f_frsize;
+ s32 f_spare[5];
};
#define COMPAT_RLIM_INFINITY 0xffffffff
diff --git a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h
index cda89e45e05f..e03ccc7732c2 100644
--- a/include/asm-parisc/smp.h
+++ b/include/asm-parisc/smp.h
@@ -60,12 +60,12 @@ extern inline unsigned int num_online_cpus(void)
return hweight32(cpu_online_map);
}
-extern inline int any_online_cpu(unsigned int mask)
+extern inline unsigned int any_online_cpu(unsigned int mask)
{
if (mask & cpu_online_map)
return __ffs(mask & cpu_online_map);
- return -1;
+ return NR_CPUS;
}
#endif /* CONFIG_SMP */
diff --git a/include/asm-parisc/statfs.h b/include/asm-parisc/statfs.h
index db72e852efd8..e8c8169d5d7f 100644
--- a/include/asm-parisc/statfs.h
+++ b/include/asm-parisc/statfs.h
@@ -9,6 +9,10 @@ typedef __kernel_fsid_t fsid_t;
#endif
+/*
+ * It appears that PARISC could be 64 _or_ 32 bit.
+ * 64-bit fields must be explicitly 64-bit in statfs64.
+ */
struct statfs {
long f_type;
long f_bsize;
@@ -19,7 +23,22 @@ struct statfs {
long f_ffree;
__kernel_fsid_t f_fsid;
long f_namelen;
- long f_spare[6];
+ long f_frsize;
+ long f_spare[5];
+};
+
+struct statfs64 {
+ long f_type;
+ long f_bsize;
+ u64 f_blocks;
+ u64 f_bfree;
+ u64 f_bavail;
+ u64 f_files;
+ u64 f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
};
#endif
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index ae9f2d0d8a4f..0f535e374c97 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -269,6 +269,13 @@ pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len,
/* Return the index of the PCI controller for device PDEV. */
#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+/* Set the name of the bus as it appears in /proc/bus/pci */
+static inline int pci_name_bus(char *name, struct pci_bus *bus)
+{
+ sprintf(name, "%02x", bus->number);
+ return 0;
+}
+
/* Map a range of PCI memory or I/O space for a device into user space */
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index e8c8a89342dd..0f458a0f115e 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -53,12 +53,12 @@ extern inline unsigned int num_online_cpus(void)
return hweight32(cpu_online_map);
}
-extern inline int any_online_cpu(unsigned int mask)
+extern inline unsigned int any_online_cpu(unsigned int mask)
{
if (mask & cpu_online_map)
return __ffs(mask & cpu_online_map);
- return -1;
+ return NR_CPUS;
}
extern int __cpu_up(unsigned int cpu);
diff --git a/include/asm-ppc/statfs.h b/include/asm-ppc/statfs.h
index b2fd73564310..807c69954a1b 100644
--- a/include/asm-ppc/statfs.h
+++ b/include/asm-ppc/statfs.h
@@ -1,27 +1,7 @@
#ifndef _PPC_STATFS_H
#define _PPC_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
-
+#include <asm-generic/statfs.h>
#endif
diff --git a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
index 31e9ce210904..e4bacd3278ad 100644
--- a/include/asm-ppc64/compat.h
+++ b/include/asm-ppc64/compat.h
@@ -91,7 +91,8 @@ struct compat_statfs {
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
- int f_spare[6];
+ int f_frsize;
+ int f_spare[5];
};
#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index 12c74914bc5d..289683028031 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -88,6 +88,13 @@ static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
extern int pci_domain_nr(struct pci_bus *bus);
+/* Set the name of the bus as it appears in /proc/bus/pci */
+static inline int pci_name_bus(char *name, struct pci_bus *bus)
+{
+ sprintf(name, "%02x", bus->number);
+ return 0;
+}
+
struct vm_area_struct;
/* Map a range of PCI memory or I/O space for a device into user space */
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
diff --git a/include/asm-ppc64/statfs.h b/include/asm-ppc64/statfs.h
index dc3830d054c5..7cce64bf7ee0 100644
--- a/include/asm-ppc64/statfs.h
+++ b/include/asm-ppc64/statfs.h
@@ -13,6 +13,9 @@
typedef __kernel_fsid_t fsid_t;
#endif
+/*
+ * We're already 64-bit, so duplicate the definition
+ */
struct statfs {
long f_type;
long f_bsize;
@@ -23,7 +26,22 @@ struct statfs {
long f_ffree;
__kernel_fsid_t f_fsid;
long f_namelen;
- long f_spare[6];
+ long f_frsize;
+ long f_spare[5];
+};
+
+struct statfs64 {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
};
#endif /* _PPC64_STATFS_H */
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index 532ad996326e..5a5ca3f07e58 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -59,12 +59,12 @@ extern inline unsigned int num_online_cpus(void)
#endif /* __s390x__ */
}
-extern inline int any_online_cpu(unsigned int mask)
+extern inline unsigned int any_online_cpu(unsigned int mask)
{
if (mask & cpu_online_map)
return __ffs(mask & cpu_online_map);
- return -1;
+ return NR_CPUS;
}
extern __inline__ __u16 hard_smp_processor_id(void)
diff --git a/include/asm-sparc/statfs.h b/include/asm-sparc/statfs.h
index 91a19b92aa29..d623f144247d 100644
--- a/include/asm-sparc/statfs.h
+++ b/include/asm-sparc/statfs.h
@@ -2,25 +2,6 @@
#ifndef _SPARC_STATFS_H
#define _SPARC_STATFS_H
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t fsid_t;
-
-#endif
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- __kernel_fsid_t f_fsid;
- long f_namelen; /* SunOS ignores this field. */
- long f_spare[6];
-};
+#include <asm-generic/statfs.h>
#endif
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index b778e356823c..7924bcee54c2 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -250,6 +250,8 @@
#define __NR_time 231 /* Linux Specific */
/* #define __NR_oldstat 232 Linux Specific */
#define __NR_stime 233 /* Linux Specific */
+#define __NR_statfs64 234 /* Linux Specific */
+#define __NR_fstatfs64 235 /* Linux Specific */
#define __NR__llseek 236 /* Linux Specific */
#define __NR_mlock 237
#define __NR_munlock 238
@@ -270,6 +272,11 @@
#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 Sparc kernel are
+ * sized to have 256 entries (starting at zero). Therefore
+ * find a free slot in the 0-255 range.
+ */
#define _syscall0(type,name) \
type name(void) \
diff --git a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
index 19fe2635d188..02af9130ad1d 100644
--- a/include/asm-sparc64/compat.h
+++ b/include/asm-sparc64/compat.h
@@ -92,7 +92,8 @@ struct compat_statfs {
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
- int f_spare[6];
+ int f_frsize;
+ int f_spare[5];
};
#define COMPAT_RLIM_INFINITY 0x7fffffff
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index 440e7ac0c934..c276200453a3 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -191,6 +191,13 @@ pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len,
extern int pci_domain_nr(struct pci_bus *bus);
+/* Set the name of the bus as it appears in /proc/bus/pci */
+static inline int pci_name_bus(char *name, struct pci_bus *bus)
+{
+ sprintf(name, "%02x", bus->number);
+ return 0;
+}
+
/* Platform support for /proc/bus/pci/X/Y mmap()s. */
#define HAVE_PCI_MMAP
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index b57fd36a1193..fab5999a9a75 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -80,11 +80,11 @@ extern atomic_t sparc64_num_cpus_online;
extern atomic_t sparc64_num_cpus_possible;
#define num_possible_cpus() (atomic_read(&sparc64_num_cpus_possible))
-static inline int any_online_cpu(unsigned long mask)
+static inline unsigned int any_online_cpu(unsigned long mask)
{
if ((mask &= cpu_online_map) != 0UL)
return __ffs(mask);
- return -1;
+ return NR_CPUS;
}
/*
diff --git a/include/asm-sparc64/statfs.h b/include/asm-sparc64/statfs.h
index 3866255b84de..5985f1901cfc 100644
--- a/include/asm-sparc64/statfs.h
+++ b/include/asm-sparc64/statfs.h
@@ -20,7 +20,22 @@ struct statfs {
long f_ffree;
__kernel_fsid_t f_fsid;
long f_namelen;
- long f_spare[6];
+ long f_frsize;
+ long f_spare[5];
+};
+
+struct statfs64 {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
};
#endif
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 33808908dfa9..c16067e9b7c3 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -252,8 +252,8 @@
#endif
/* #define __NR_oldstat 232 Linux Specific */
#define __NR_stime 233 /* Linux Specific */
-/* #define __NR_UNUSED 234 */
-/* #define __NR_UNUSED 235 */
+#define __NR_statfs64 234 /* Linux Specific */
+#define __NR_fstatfs64 235 /* Linux Specific */
#define __NR__llseek 236 /* Linux Specific */
#define __NR_mlock 237
#define __NR_munlock 238
@@ -274,6 +274,11 @@
#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 _syscall0(type,name) \
type name(void) \
diff --git a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
index 63064e779369..60eb12d5cc0d 100644
--- a/include/asm-x86_64/compat.h
+++ b/include/asm-x86_64/compat.h
@@ -101,7 +101,8 @@ struct compat_statfs {
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
- int f_spare[6];
+ int f_frsize;
+ int f_spare[5];
};
#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index 281063a933fc..820ed467a366 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -66,12 +66,12 @@ extern volatile unsigned long cpu_callout_map;
cpu = __ffs(mask), mask != 0; \
mask &= ~(1UL<<cpu))
-extern inline int any_online_cpu(unsigned int mask)
+extern inline unsigned int any_online_cpu(unsigned int mask)
{
if (mask & cpu_online_map)
return __ffs(mask & cpu_online_map);
- return -1;
+ return NR_CPUS;
}
extern inline unsigned int num_online_cpus(void)
diff --git a/include/asm-x86_64/statfs.h b/include/asm-x86_64/statfs.h
index 2d6ea7a6b60f..bb11240c22b8 100644
--- a/include/asm-x86_64/statfs.h
+++ b/include/asm-x86_64/statfs.h
@@ -9,6 +9,10 @@ typedef __kernel_fsid_t fsid_t;
#endif
+/*
+ * This is ugly -- we're already 64-bit clean, so just duplicate the
+ * definitions.
+ */
struct statfs {
long f_type;
long f_bsize;
@@ -19,7 +23,22 @@ struct statfs {
long f_ffree;
__kernel_fsid_t f_fsid;
long f_namelen;
- long f_spare[6];
+ long f_frsize;
+ long f_spare[5];
+};
+
+struct statfs64 {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
};
#endif
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d2711ab6b024..8528f26c4a95 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -403,8 +403,8 @@ int acpi_pci_irq_init (void);
struct acpi_pci_driver {
struct acpi_pci_driver *next;
- int (*add)(acpi_handle *handle);
- void (*remove)(acpi_handle *handle);
+ int (*add)(acpi_handle handle);
+ void (*remove)(acpi_handle handle);
};
int acpi_pci_register_driver(struct acpi_pci_driver *driver);
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index b7487acd00cb..c23ac5fc0a53 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -108,7 +108,7 @@ static inline unsigned int generic_hweight8(unsigned int w)
return (res & 0x0F) + ((res >> 4) & 0x0F);
}
-static inline unsigned long generic_hweight64(u64 w)
+static inline unsigned long generic_hweight64(__u64 w)
{
#if BITS_PER_LONG < 64
return generic_hweight32((unsigned int)(w >> 32)) +
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
index 5c3fefddd4f7..e355bcacac17 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -73,7 +73,7 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
unsigned int cmd, struct PioctlData *data);
int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
int venus_fsync(struct super_block *sb, struct ViceFid *fid);
-int venus_statfs(struct super_block *sb, struct statfs *sfs);
+int venus_statfs(struct super_block *sb, struct kstatfs *sfs);
/* messages between coda filesystem in kernel and Venus */
diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h
index 808df8727891..c78e9c2a7b3a 100644
--- a/include/linux/efs_fs.h
+++ b/include/linux/efs_fs.h
@@ -41,7 +41,7 @@ extern struct file_operations efs_dir_operations;
extern struct address_space_operations efs_symlink_aops;
extern int efs_fill_super(struct super_block *, void *, int);
-extern int efs_statfs(struct super_block *, struct statfs *);
+extern int efs_statfs(struct super_block *, struct kstatfs *);
extern void efs_read_inode(struct inode *);
extern efs_block_t efs_map_block(struct inode *, efs_block_t);
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index a7f6c48a5ab9..62f37c1a17ba 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -764,7 +764,7 @@ extern void ext3_write_super (struct super_block *);
extern void ext3_write_super_lockfs (struct super_block *);
extern void ext3_unlockfs (struct super_block *);
extern int ext3_remount (struct super_block *, int *, char *);
-extern int ext3_statfs (struct super_block *, struct statfs *);
+extern int ext3_statfs (struct super_block *, struct kstatfs *);
#define ext3_std_error(sb, errno) \
do { \
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
index 02021676dd74..1a6a6c5922f7 100644
--- a/include/linux/ext3_fs_i.h
+++ b/include/linux/ext3_fs_i.h
@@ -66,7 +66,7 @@ struct ext3_inode_info {
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
-
+
struct list_head i_orphan; /* unlinked but open inodes */
/*
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
new file mode 100644
index 000000000000..93dd77eb7869
--- /dev/null
+++ b/include/linux/firmware.h
@@ -0,0 +1,19 @@
+#ifndef _LINUX_FIRMWARE_H
+#define _LINUX_FIRMWARE_H
+#include <linux/module.h>
+#include <linux/types.h>
+#define FIRMWARE_NAME_MAX 30
+struct firmware {
+ size_t size;
+ u8 *data;
+};
+int request_firmware(const struct firmware **fw, const char *name,
+ struct device *device);
+int request_firmware_nowait(
+ struct module *module,
+ const char *name, struct device *device, void *context,
+ void (*cont)(const struct firmware *fw, void *context));
+
+void release_firmware(const struct firmware *fw);
+void register_firmware(const char *name, const u8 *data, size_t size);
+#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0f79ec6c6949..c3bda88631bc 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -25,7 +25,7 @@ struct iovec;
struct nameidata;
struct pipe_inode_info;
struct poll_table_struct;
-struct statfs;
+struct kstatfs;
struct vm_area_struct;
struct vfsmount;
@@ -781,7 +781,7 @@ struct super_operations {
int (*sync_fs)(struct super_block *sb, int wait);
void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
- int (*statfs) (struct super_block *, struct statfs *);
+ int (*statfs) (struct super_block *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
@@ -960,7 +960,7 @@ extern struct vfsmount *kern_mount(struct file_system_type *);
extern int may_umount(struct vfsmount *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
-extern int vfs_statfs(struct super_block *, struct statfs *);
+extern int vfs_statfs(struct super_block *, struct kstatfs *);
/* Return value for VFS lock functions - tells locks.c to lock conventionally
* REALLY kosha for root NFS and nfs_lock
@@ -1278,7 +1278,7 @@ extern int dcache_dir_close(struct inode *, struct file *);
extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
extern int dcache_readdir(struct file *, void *, filldir_t);
extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int simple_statfs(struct super_block *, struct statfs *);
+extern int simple_statfs(struct super_block *, struct kstatfs *);
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
extern int simple_unlink(struct inode *, struct dentry *);
extern int simple_rmdir(struct inode *, struct dentry *);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index be82baa340fa..aa3705a9a21e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -7,7 +7,7 @@
/*
* GFP bitmasks..
*/
-/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low four bits) */
+/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
#define __GFP_DMA 0x01
#define __GFP_HIGHMEM 0x02
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 4cd2f596e705..2c9139a94f8f 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -3,6 +3,8 @@
#include <linux/config.h>
#include <linux/fs.h>
+#include <linux/mm.h>
+
#include <asm/cacheflush.h>
#ifdef CONFIG_HIGHMEM
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 266762203a70..edc512ee628f 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -73,11 +73,28 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
#ifdef CONFIG_HUGETLBFS
struct hugetlbfs_config {
- uid_t uid;
- gid_t gid;
- umode_t mode;
+ uid_t uid;
+ gid_t gid;
+ umode_t mode;
+ long nr_blocks;
+ long nr_inodes;
};
+struct hugetlbfs_sb_info {
+ long max_blocks; /* blocks allowed */
+ long free_blocks; /* blocks free */
+ long max_inodes; /* inodes allowed */
+ long free_inodes; /* inodes free */
+ spinlock_t stat_lock;
+};
+
+static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+#define PSEUDO_DIRENT_SIZE 20
+
extern struct file_operations hugetlbfs_file_operations;
extern struct vm_operations_struct hugetlb_vm_ops;
struct file *hugetlb_zero_setup(size_t);
diff --git a/include/linux/input.h b/include/linux/input.h
index 20dfaad9fe4f..da49f7ee0f18 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -358,6 +358,7 @@ struct input_absinfo {
#define BTN_EXTRA 0x114
#define BTN_FORWARD 0x115
#define BTN_BACK 0x116
+#define BTN_TASK 0x117
#define BTN_JOYSTICK 0x120
#define BTN_TRIGGER 0x120
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index fe4e4f154b1c..ecd0f5394e9e 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -283,7 +283,7 @@ typedef struct atemu {
#endif
int mdmcmdl; /* Length of Modem-Commandbuffer */
int pluscount; /* Counter for +++ sequence */
- int lastplus; /* Timestamp of last + */
+ unsigned long lastplus; /* Timestamp of last + */
char mdmcmd[255]; /* Modem-Commandbuffer */
unsigned int charge; /* Charge units of current connection */
} atemu;
diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h
index 669822e2868a..c32f338a5a28 100644
--- a/include/linux/isdn_ppp.h
+++ b/include/linux/isdn_ppp.h
@@ -95,7 +95,8 @@ struct isdn_ppp_resetparams {
* check the original include for more information
*/
struct isdn_ppp_compressor {
- struct isdn_ppp_compressor *next, *prev;
+ struct module *owner;
+ struct list_head list;
int num; /* CCP compression protocol number */
void *(*alloc) (struct isdn_ppp_comp_data *);
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 6f78f33cbac9..424ddff9b70a 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -14,6 +14,9 @@
#define LO_KEY_SIZE 32
#ifdef __KERNEL__
+#include <linux/bio.h>
+#include <linux/blk.h>
+#include <linux/spinlock.h>
/* Possible states of device */
enum {
@@ -22,18 +25,20 @@ enum {
Lo_rundown,
};
+struct loop_func_table;
+
struct loop_device {
int lo_number;
int lo_refcnt;
int lo_offset;
- int lo_encrypt_type;
- int lo_encrypt_key_size;
int lo_flags;
int (*transfer)(struct loop_device *, int cmd,
char *raw_buf, char *loop_buf, int size,
sector_t real_block);
char lo_name[LO_NAME_SIZE];
char lo_encrypt_key[LO_KEY_SIZE];
+ int lo_encrypt_key_size;
+ struct loop_func_table *lo_encryption;
__u32 lo_init[2];
uid_t lo_key_owner; /* Who set the key */
int (*ioctl)(struct loop_device *, int cmd,
@@ -129,9 +134,7 @@ struct loop_func_table {
/* release is called from loop_unregister_transfer or clr_fd */
int (*release)(struct loop_device *);
int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
- /* lock and unlock manage the module use counts */
- void (*lock)(struct loop_device *);
- void (*unlock)(struct loop_device *);
+ struct module *owner;
};
int loop_register_transfer(struct loop_func_table *funcs);
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 0555d7d08894..4268ed112436 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -270,7 +270,7 @@ extern void fat_clear_inode(struct inode *inode);
extern void fat_put_super(struct super_block *sb);
int fat_fill_super(struct super_block *sb, void *data, int silent,
struct inode_operations *fs_dir_inode_ops, int isvfat);
-extern int fat_statfs(struct super_block *sb, struct statfs *buf);
+extern int fat_statfs(struct super_block *sb, struct kstatfs *buf);
extern void fat_write_inode(struct inode *inode, int wait);
extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index ab9639b36e25..4ebc2e5a16e2 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -1,5 +1,5 @@
/*
- * $Id: blktrans.h,v 1.4 2003/05/21 01:01:32 dwmw2 Exp $
+ * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $
*
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
*
@@ -12,6 +12,7 @@
#include <asm/semaphore.h>
+struct hd_geometry;
struct mtd_info;
struct mtd_blktrans_ops;
struct file;
@@ -42,17 +43,13 @@ struct mtd_blktrans_ops {
int (*writesect)(struct mtd_blktrans_dev *dev,
unsigned long block, char *buffer);
- /* HDIO_GETGEO and HDIO_GETGEO_BIG are the only non-private
- ioctls which are expected to be passed through */
- int (*ioctl)(struct mtd_blktrans_dev *dev,
- struct inode * inode, struct file * file,
- unsigned int cmd, unsigned long arg);
+ /* Block layer ioctls */
+ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
+ int (*flush)(struct mtd_blktrans_dev *dev);
/* Called with mtd_table_mutex held; no race with add/remove */
- int (*open)(struct mtd_blktrans_dev *dev,
- struct inode *i, struct file *f);
- int (*release)(struct mtd_blktrans_dev *dev,
- struct inode *i, struct file *f);
+ int (*open)(struct mtd_blktrans_dev *dev);
+ int (*release)(struct mtd_blktrans_dev *dev);
/* Called on {de,}registration and on subsequent addition/removal
of devices, with mtd_table_mutex held. */
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index c224985990b9..64465a963442 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -2,7 +2,7 @@
/* Linux driver for Disk-On-Chip 2000 */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.h,v 1.16 2003/05/23 11:29:33 dwmw2 Exp $ */
+/* $Id: doc2000.h,v 1.17 2003/06/12 01:20:46 gerg Exp $ */
#ifndef __MTD_DOC2000_H__
#define __MTD_DOC2000_H__
@@ -44,7 +44,7 @@
#define DoC_Mplus_AccessStatus 0x1008
#define DoC_Mplus_DeviceSelect 0x1008
#define DoC_Mplus_Configuration 0x100a
-#define DoC_Mplus_OutputControl 0x1002
+#define DoC_Mplus_OutputControl 0x100c
#define DoC_Mplus_FlashControl 0x1020
#define DoC_Mplus_FlashSelect 0x1022
#define DoC_Mplus_FlashCmd 0x1024
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7bed3d24a2ea..fba9b5ddec1e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -195,8 +195,14 @@ struct hh_cache
int hh_len; /* length of header */
int (*hh_output)(struct sk_buff *skb);
rwlock_t hh_lock;
+
/* cached hardware header; allow for machine alignment needs. */
- unsigned long hh_data[16/sizeof(unsigned long)];
+#define HH_DATA_MOD 16
+#define HH_DATA_OFF(__len) \
+ (HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
+#define HH_DATA_ALIGN(__len) \
+ (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
+ unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER)];
};
/* These flag bits are private to the generic network queueing
diff --git a/include/linux/netfilter_arp.h b/include/linux/netfilter_arp.h
index 4f460b3b0cba..a3f8977f7f12 100644
--- a/include/linux/netfilter_arp.h
+++ b/include/linux/netfilter_arp.h
@@ -14,6 +14,7 @@
/* ARP Hooks */
#define NF_ARP_IN 0
#define NF_ARP_OUT 1
-#define NF_ARP_NUMHOOKS 2
+#define NF_ARP_FORWARD 2
+#define NF_ARP_NUMHOOKS 3
#endif /* __LINUX_ARP_NETFILTER_H */
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 6c936cc67ec1..667e7f223a10 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -113,7 +113,7 @@ int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
int nfsd_readdir(struct svc_rqst *, struct svc_fh *,
loff_t *, struct readdir_cd *, encode_dent_fn);
int nfsd_statfs(struct svc_rqst *, struct svc_fh *,
- struct statfs *);
+ struct kstatfs *);
int nfsd_notify_change(struct inode *, struct iattr *);
int nfsd_permission(struct svc_export *, struct dentry *, int);
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h
index 970474550bb9..0164bd1fc109 100644
--- a/include/linux/nfsd/xdr.h
+++ b/include/linux/nfsd/xdr.h
@@ -113,7 +113,7 @@ struct nfsd_readdirres {
};
struct nfsd_statfsres {
- struct statfs stats;
+ struct kstatfs stats;
};
/*
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
index df2de40faa23..1240afe79da9 100644
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -176,7 +176,7 @@ struct nfsd3_readdirres {
struct nfsd3_fsstatres {
__u32 status;
- struct statfs stats;
+ struct kstatfs stats;
__u32 invarsec;
};
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1983191d32c8..0a2ecb5fd9e7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -486,6 +486,13 @@ struct pci_ops {
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
};
+struct pci_raw_ops {
+ int (*read)(int dom, int bus, int dev, int func, int reg, int len, u32 *val);
+ int (*write)(int dom, int bus, int dev, int func, int reg, int len, u32 val);
+};
+
+extern struct pci_raw_ops *raw_pci_ops;
+
struct pci_bus_region {
unsigned long start;
unsigned long end;
@@ -549,8 +556,8 @@ char *pci_class_name(u32 class);
void pci_read_bridge_bases(struct pci_bus *child);
struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
-extern struct pci_dev *pci_get_dev(struct pci_dev *dev);
-extern void pci_put_dev(struct pci_dev *dev);
+extern struct pci_dev *pci_dev_get(struct pci_dev *dev);
+extern void pci_dev_put(struct pci_dev *dev);
extern void pci_remove_bus_device(struct pci_dev *dev);
@@ -566,6 +573,10 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
+struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
+struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
+ unsigned int ss_vendor, unsigned int ss_device,
+ struct pci_dev *from);
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val);
@@ -688,6 +699,13 @@ static inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int
unsigned int ss_vendor, unsigned int ss_device, const struct pci_dev *from)
{ return NULL; }
+static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
+{ return NULL; }
+
+static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
+unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from)
+{ return NULL; }
+
static inline void pci_set_master(struct pci_dev *dev) { }
static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
static inline void pci_disable_device(struct pci_dev *dev) { }
@@ -743,6 +761,20 @@ static inline int pci_module_init(struct pci_driver *drv)
return rc;
}
+/*
+ * PCI domain support. Sometimes called PCI segment (eg by ACPI),
+ * a PCI domain is defined to be a set of PCI busses which share
+ * configuration space.
+ */
+#ifndef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
+static inline int pci_name_bus(char *name, struct pci_bus *bus)
+{
+ sprintf(name, "%02x", bus->number);
+ return 0;
+}
+#endif
+
#endif /* !CONFIG_PCI */
/* these helpers provide future and backwards compatibility
@@ -800,15 +832,5 @@ extern int pci_pci_problems;
#define PCIPCI_VSFX 16
#define PCIPCI_ALIMAGIK 32
-/*
- * PCI domain support. Sometimes called PCI segment (eg by ACPI),
- * a PCI domain is defined to be a set of PCI busses which share
- * configuration space.
- */
-
-#ifndef CONFIG_PCI_DOMAINS
-static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
-#endif
-
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 9b51d57947f1..5a5d32aabc0c 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -549,6 +549,7 @@
#define PCI_DEVICE_ID_SI_601 0x0601
#define PCI_DEVICE_ID_SI_620 0x0620
#define PCI_DEVICE_ID_SI_630 0x0630
+#define PCI_DEVICE_ID_SI_633 0x0633
#define PCI_DEVICE_ID_SI_635 0x0635
#define PCI_DEVICE_ID_SI_640 0x0640
#define PCI_DEVICE_ID_SI_645 0x0645
@@ -559,6 +560,7 @@
#define PCI_DEVICE_ID_SI_652 0x0652
#define PCI_DEVICE_ID_SI_655 0x0655
#define PCI_DEVICE_ID_SI_730 0x0730
+#define PCI_DEVICE_ID_SI_733 0x0733
#define PCI_DEVICE_ID_SI_630_VGA 0x6300
#define PCI_DEVICE_ID_SI_730_VGA 0x7300
#define PCI_DEVICE_ID_SI_735 0x0735
@@ -579,7 +581,10 @@
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5518 0x5518
#define PCI_DEVICE_ID_SI_5571 0x5571
+#define PCI_DEVICE_ID_SI_5581 0x5581
+#define PCI_DEVICE_ID_SI_5582 0x5582
#define PCI_DEVICE_ID_SI_5591 0x5591
+#define PCI_DEVICE_ID_SI_5596 0x5596
#define PCI_DEVICE_ID_SI_5597 0x5597
#define PCI_DEVICE_ID_SI_5598 0x5598
#define PCI_DEVICE_ID_SI_5600 0x5600
@@ -602,6 +607,8 @@
#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049
#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A
#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B
+#define PCI_DEVICE_ID_HP_REO_SBA 0x10f0
+#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1
#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b
#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223
#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index d0249ab40676..348bb52a716e 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -102,22 +102,13 @@ struct pnp_mem {
#define PNP_RES_PRIORITY_FUNCTIONAL 2
#define PNP_RES_PRIORITY_INVALID 65535
-struct pnp_resources {
+struct pnp_option {
unsigned short priority; /* priority */
struct pnp_port *port; /* first port */
struct pnp_irq *irq; /* first IRQ */
struct pnp_dma *dma; /* first DMA */
struct pnp_mem *mem; /* first memory resource */
- struct pnp_dev *dev; /* parent */
- struct pnp_resources *dep; /* dependent resources */
-};
-
-struct pnp_rule_table {
- int depnum;
- struct pnp_port *port[PNP_MAX_PORT];
- struct pnp_irq *irq[PNP_MAX_IRQ];
- struct pnp_dma *dma[PNP_MAX_DMA];
- struct pnp_mem *mem[PNP_MAX_MEM];
+ struct pnp_option *next; /* used to chain dependent resources */
};
struct pnp_resource_table {
@@ -187,8 +178,6 @@ static inline void pnp_set_card_drvdata (struct pnp_card_link *pcard, void *data
struct pnp_dev {
struct device dev; /* Driver Model device interface */
unsigned char number; /* used as an index, must be unique */
- int active;
- int capabilities;
int status;
struct list_head global_list; /* node in global list of devices */
@@ -201,11 +190,13 @@ struct pnp_dev {
struct pnp_driver * driver;
struct pnp_card_link * card_link;
- struct pnp_id * id; /* supported EISA IDs*/
- struct pnp_resource_table res; /* contains the currently chosen resources */
- struct pnp_resources * possible; /* a list of possible resources */
- struct pnp_rule_table * rule; /* the current possible resource set */
- int config_mode; /* flags that determine how the device's resources should be configured */
+ struct pnp_id * id; /* supported EISA IDs*/
+
+ int active;
+ int capabilities;
+ struct pnp_option * independent;
+ struct pnp_option * dependent;
+ struct pnp_resource_table res;
void * protocol_data; /* Used to store protocol specific data */
unsigned short regs; /* ISAPnP: supported registers */
@@ -252,11 +243,9 @@ struct pnp_fixup {
void (*quirk_function)(struct pnp_dev *dev); /* fixup function */
};
-/* config modes */
-#define PNP_CONFIG_AUTO 0x0001 /* Use the Resource Configuration Engine to determine resource settings */
-#define PNP_CONFIG_MANUAL 0x0002 /* the config has been manually specified */
-#define PNP_CONFIG_FORCE 0x0004 /* disables validity checking */
-#define PNP_CONFIG_INVALID 0x0008 /* If this flag is set, the pnp layer will refuse to activate the device */
+/* config parameters */
+#define PNP_CONFIG_NORMAL 0x0001
+#define PNP_CONFIG_FORCE 0x0002 /* disables validity checking */
/* capabilities */
#define PNP_READ 0x0001
@@ -271,7 +260,7 @@ struct pnp_fixup {
((dev)->capabilities & PNP_WRITE))
#define pnp_can_disable(dev) (((dev)->protocol) && ((dev)->protocol->disable) && \
((dev)->capabilities & PNP_DISABLE))
-#define pnp_can_configure(dev) ((!(dev)->active) && ((dev)->config_mode & PNP_CONFIG_AUTO) && \
+#define pnp_can_configure(dev) ((!(dev)->active) && \
((dev)->capabilities & PNP_CONFIGURABLE))
#ifdef CONFIG_ISAPNP
@@ -383,7 +372,7 @@ struct pnp_protocol {
#if defined(CONFIG_PNP)
-/* core */
+/* device management */
int pnp_register_protocol(struct pnp_protocol *protocol);
void pnp_unregister_protocol(struct pnp_protocol *protocol);
int pnp_add_device(struct pnp_dev *dev);
@@ -392,7 +381,7 @@ int pnp_device_attach(struct pnp_dev *pnp_dev);
void pnp_device_detach(struct pnp_dev *pnp_dev);
extern struct list_head pnp_global;
-/* card */
+/* multidevice card support */
int pnp_add_card(struct pnp_card *card);
void pnp_remove_card(struct pnp_card *card);
int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
@@ -404,41 +393,35 @@ int pnp_register_card_driver(struct pnp_card_driver * drv);
void pnp_unregister_card_driver(struct pnp_card_driver * drv);
extern struct list_head pnp_cards;
-/* resource */
-struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent);
-struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum);
-int pnp_get_max_depnum(struct pnp_dev *dev);
-int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data);
-int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data);
-int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data);
-int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data);
-void pnp_init_resource_table(struct pnp_resource_table *table);
-int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * rule);
-
-/* manager */
+/* resource management */
+struct pnp_option * pnp_register_independent_option(struct pnp_dev *dev);
+struct pnp_option * pnp_register_dependent_option(struct pnp_dev *dev, int priority);
+int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data);
+int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data);
+int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data);
+int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data);
+void pnp_init_resources(struct pnp_resource_table *table);
+int pnp_assign_resources(struct pnp_dev *dev, int depnum);
+int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
+int pnp_auto_config_dev(struct pnp_dev *dev);
+int pnp_validate_config(struct pnp_dev *dev);
int pnp_activate_dev(struct pnp_dev *dev);
int pnp_disable_dev(struct pnp_dev *dev);
void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size);
-int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
-int pnp_auto_config_dev(struct pnp_dev *dev);
-
-/* driver */
-int compare_pnp_id(struct pnp_id * pos, const char * id);
-int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
-int pnp_register_driver(struct pnp_driver *drv);
-void pnp_unregister_driver(struct pnp_driver *drv);
-/* support */
+/* protocol helpers */
int pnp_is_active(struct pnp_dev * dev);
unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res);
unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char * end, struct pnp_dev * dev);
unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res);
+int compare_pnp_id(struct pnp_id * pos, const char * id);
+int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
+int pnp_register_driver(struct pnp_driver *drv);
+void pnp_unregister_driver(struct pnp_driver *drv);
#else
-/* just in case anyone decides to call these without PnP Support Enabled */
-
-/* core */
+/* device management */
static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; }
static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
@@ -447,7 +430,7 @@ static inline void pnp_remove_device(struct pnp_dev *dev) { }
static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
-/* card */
+/* multidevice card support */
static inline int pnp_add_card(struct pnp_card *card) { return -ENODEV; }
static inline void pnp_remove_card(struct pnp_card *card) { ; }
static inline int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; }
@@ -458,35 +441,31 @@ static inline void pnp_release_card_device(struct pnp_dev * dev) { ; }
static inline int pnp_register_card_driver(struct pnp_card_driver * drv) { return -ENODEV; }
static inline void pnp_unregister_card_driver(struct pnp_card_driver * drv) { ; }
-/* resource */
-static inline struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent) { return NULL; }
-static inline struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum) { return NULL; }
-static inline int pnp_get_max_depnum(struct pnp_dev *dev) { return -ENODEV; }
-static inline int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline void pnp_init_resource_table(struct pnp_resource_table *table) { ; }
-static inline int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * rule) { return -ENODEV; }
-
-/* manager */
-static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
-static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
-static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { ; }
+/* resource management */
+static inline struct pnp_option * pnp_register_independent_option(struct pnp_dev *dev) { return NULL; }
+static inline struct pnp_option * pnp_register_dependent_option(struct pnp_dev *dev, int priority) { return NULL; }
+static inline int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { return -ENODEV; }
+static inline int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { return -ENODEV; }
+static inline int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { return -ENODEV; }
+static inline int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { return -ENODEV; }
+static inline void pnp_init_resources(struct pnp_resource_table *table) { }
+static inline int pnp_assign_resources(struct pnp_dev *dev, int depnum) { return -ENODEV; }
static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_validate_config(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { }
-/* driver */
-static inline int compare_pnp_id(struct list_head * id_list, const char * id) { return -ENODEV; }
-static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
-static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
-static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
-
-/* support */
-static inline int pnp_is_active(struct pnp_dev * dev) { return -ENODEV; }
+/* protocol helpers */
+static inline int pnp_is_active(struct pnp_dev * dev) { return 0; }
static inline unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res) { return NULL; }
static inline unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char * end, struct pnp_dev * dev) { return NULL; }
static inline unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res) { return NULL; }
+static inline int compare_pnp_id(struct pnp_id * pos, const char * id) { return -ENODEV; }
+static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
+static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
#endif /* CONFIG_PNP */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index d313e2ccbf42..ca97376901b0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -148,10 +148,15 @@ extern void sched_init(void);
extern void init_idle(task_t *idle, int cpu);
extern void show_state(void);
-extern void show_trace(unsigned long *stack);
-extern void show_stack(unsigned long *stack);
extern void show_regs(struct pt_regs *);
+/*
+ * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
+ * task), SP is the stack pointer of the first frame that should be shown in the back
+ * trace (or NULL if the entire call-chain of the task should be shown).
+ */
+extern void show_stack(struct task_struct *task, unsigned long *sp);
+
void io_schedule(void);
long io_schedule_timeout(long timeout);
@@ -478,9 +483,12 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
#define PF_LESS_THROTTLE 0x01000000 /* Throttle me less: I clena memory */
#ifdef CONFIG_SMP
-extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
+extern int set_cpus_allowed(task_t *p, unsigned long new_mask);
#else
-# define set_cpus_allowed(p, new_mask) do { } while (0)
+static inline int set_cpus_allowed(task_t *p, unsigned long new_mask)
+{
+ return 0;
+}
#endif
#ifdef CONFIG_NUMA
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 38a64f8ea69b..2821bc07f647 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -128,13 +128,11 @@ struct sem_undo {
struct sem_undo_list {
atomic_t refcnt;
spinlock_t lock;
- volatile unsigned long add_count;
struct sem_undo *proc_list;
};
struct sysv_sem {
struct sem_undo_list *undo_list;
- struct sem_queue *sleep_list;
};
asmlinkage long sys_semget (key_t key, int nsems, int semflg);
@@ -143,6 +141,8 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg);
asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops,
unsigned nsops, const struct timespec __user *timeout);
+void exit_sem(struct task_struct *p);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SEM_H */
diff --git a/include/linux/serio.h b/include/linux/serio.h
index ae1a7f9bde2b..f1c67ff70f2a 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -26,7 +26,6 @@ struct serio {
void *driver;
char *name;
char *phys;
- int number;
unsigned short idbus;
unsigned short idvendor;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3398f0a283db..57af37850a4e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -803,12 +803,9 @@ static inline void skb_fill_page_desc(struct sk_buff *skb, int i, struct page *p
skb_shinfo(skb)->nr_frags = i+1;
}
-#define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) \
- BUG(); } while (0)
-#define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) \
- BUG(); } while (0)
-#define SKB_LINEAR_ASSERT(skb) do { if (skb_is_nonlinear(skb)) \
- BUG(); } while (0)
+#define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags)
+#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list)
+#define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb))
/*
* Add data to an sk_buff
@@ -837,7 +834,7 @@ static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
SKB_LINEAR_ASSERT(skb);
skb->tail += len;
skb->len += len;
- if (skb->tail>skb->end)
+ if (unlikely(skb->tail>skb->end))
skb_over_panic(skb, len, current_text_addr());
return tmp;
}
@@ -862,7 +859,7 @@ static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
{
skb->data -= len;
skb->len += len;
- if (skb->data<skb->head)
+ if (unlikely(skb->data<skb->head))
skb_under_panic(skb, len, current_text_addr());
return skb->data;
}
@@ -870,8 +867,7 @@ static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
static inline char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
skb->len -= len;
- if (skb->len < skb->data_len)
- BUG();
+ BUG_ON(skb->len < skb->data_len);
return skb->data += len;
}
@@ -1137,8 +1133,7 @@ static inline int __deprecated skb_linearize(struct sk_buff *skb, int gfp)
static inline void *kmap_skb_frag(const skb_frag_t *frag)
{
#ifdef CONFIG_HIGHMEM
- if (in_irq())
- BUG();
+ BUG_ON(in_irq());
local_bh_disable();
#endif
@@ -1154,9 +1149,9 @@ static inline void kunmap_skb_frag(void *vaddr)
}
#define skb_queue_walk(queue, skb) \
- for (skb = (queue)->next; \
+ for (skb = (queue)->next, prefetch(skb->next); \
(skb != (struct sk_buff *)(queue)); \
- skb = skb->next)
+ skb = skb->next, prefetch(skb->next))
extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
diff --git a/include/linux/smbno.h b/include/linux/smbno.h
index c202e2d6cb80..f99e02d9ffe2 100644
--- a/include/linux/smbno.h
+++ b/include/linux/smbno.h
@@ -347,8 +347,8 @@
#define SMB_MODE_NO_CHANGE 0xFFFFFFFF
#define SMB_UID_NO_CHANGE 0xFFFFFFFF
#define SMB_GID_NO_CHANGE 0xFFFFFFFF
-#define SMB_TIME_NO_CHANGE 0xFFFFFFFFFFFFFFFF
-#define SMB_SIZE_NO_CHANGE 0xFFFFFFFFFFFFFFFF
+#define SMB_TIME_NO_CHANGE 0xFFFFFFFFFFFFFFFFULL
+#define SMB_SIZE_NO_CHANGE 0xFFFFFFFFFFFFFFFFULL
/* UNIX filetype mappings. */
#define UNIX_TYPE_FILE 0
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 148ea9d43873..4e2c1973ae67 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -146,13 +146,8 @@ typedef struct {
/*
* gcc versions before ~2.95 have a nasty bug with empty initializers.
*/
-#if (__GNUC__ > 2)
- typedef struct { } spinlock_t;
- #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
-#else
- typedef struct { int gcc_is_buggy; } spinlock_t;
- #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-#endif
+typedef struct { } spinlock_t;
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { }
/*
* If CONFIG_SMP is unset, declare the _raw_* definitions as nops
diff --git a/include/linux/statfs.h b/include/linux/statfs.h
new file mode 100644
index 000000000000..ad83a2bdb821
--- /dev/null
+++ b/include/linux/statfs.h
@@ -0,0 +1,22 @@
+#ifndef _LINUX_STATFS_H
+#define _LINUX_STATFS_H
+
+#include <linux/types.h>
+
+#include <asm/statfs.h>
+
+struct kstatfs {
+ long f_type;
+ long f_bsize;
+ sector_t f_blocks;
+ sector_t f_bfree;
+ sector_t f_bavail;
+ sector_t f_files;
+ sector_t f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
+};
+
+#endif
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
index 614200d60389..4bc3e22b5104 100644
--- a/include/linux/sysdev.h
+++ b/include/linux/sysdev.h
@@ -72,7 +72,6 @@ struct sys_device {
u32 id;
struct sysdev_class * cls;
struct kobject kobj;
- struct list_head entry;
};
extern int sys_device_register(struct sys_device *);
diff --git a/include/linux/time.h b/include/linux/time.h
index 12d0a89a4ee9..e739d8128253 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -130,7 +130,8 @@ static __inline__ unsigned long
timeval_to_jiffies(struct timeval *value)
{
unsigned long sec = value->tv_sec;
- long usec = value->tv_usec + TICK_USEC - 1;
+ long usec = value->tv_usec
+ + ((TICK_NSEC + 1000UL/2) / 1000UL) - 1;
if (sec >= MAX_SEC_IN_JIFFIES){
sec = MAX_SEC_IN_JIFFIES;
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 593cdf411500..2b1665d57ad0 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -176,7 +176,7 @@
#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))
/* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
-#define TICK_USEC ((TICK_NSEC + 1000UL/2) / 1000UL)
+#define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
/* TICK_USEC_TO_NSEC is the time between ticks in nsec assuming real ACTHZ and */
/* a value TUSEC for TICK_USEC (can be set bij adjtimex) */
diff --git a/include/linux/vfs.h b/include/linux/vfs.h
index b3a58657d766..e701d0541405 100644
--- a/include/linux/vfs.h
+++ b/include/linux/vfs.h
@@ -1,6 +1,6 @@
#ifndef _LINUX_VFS_H
#define _LINUX_VFS_H
-#include <asm/statfs.h>
+#include <linux/statfs.h>
#endif
diff --git a/ipc/sem.c b/ipc/sem.c
index 991831da7f11..07d9a2e054b7 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -214,7 +214,7 @@ static int sem_revalidate(int semid, struct sem_array* sma, int nsems, short flg
return -EIDRM;
}
- if (ipcperms(&sma->sem_perm, flg)) {
+ if (flg && ipcperms(&sma->sem_perm, flg)) {
sem_unlock(smanew);
return -EACCES;
}
@@ -412,7 +412,7 @@ static void freeary (struct sem_array *sma, int id)
int size;
/* Invalidate the existing undo structures for this semaphore set.
- * (They will be freed without any further action in sem_exit()
+ * (They will be freed without any further action in exit_sem()
* or during the next semop.)
*/
for (un = sma->undo; un; un = un->id_next)
@@ -887,106 +887,87 @@ static inline int get_undo_list(struct sem_undo_list **undo_listp)
return 0;
}
-static struct sem_undo* freeundos(struct sem_undo* un)
+static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
{
- struct sem_undo* u;
- struct sem_undo** up;
-
- for(up = &current->sysvsem.undo_list->proc_list;(u=*up);up=&u->proc_next) {
- if(un==u) {
- un=u->proc_next;
- *up=un;
- kfree(u);
- return un;
- }
- }
- printk ("freeundos undo list error id=%d\n", un->semid);
- return un->proc_next;
-}
+ struct sem_undo **last, *un;
-static inline struct sem_undo *find_undo(int semid)
-{
- struct sem_undo *un;
-
- un = NULL;
- if (current->sysvsem.undo_list != NULL) {
- un = current->sysvsem.undo_list->proc_list;
- }
+ last = &ulp->proc_list;
+ un = *last;
while(un != NULL) {
if(un->semid==semid)
break;
- if(un->semid==-1)
- un=freeundos(un);
- else
- un=un->proc_next;
+ if(un->semid==-1) {
+ *last=un->proc_next;
+ kfree(un);
+ } else {
+ last=&un->proc_next;
+ }
+ un=*last;
}
return un;
}
-/* returns without sem_lock and semundo list locks on error! */
-static int alloc_undo(struct sem_array *sma, struct sem_undo** unp, int semid, int alter)
+static struct sem_undo *find_undo(int semid)
{
- int size, nsems, error;
- struct sem_undo *un, *new_un;
- struct sem_undo_list *undo_list;
- unsigned long saved_add_count;
+ struct sem_array *sma;
+ struct sem_undo_list *ulp;
+ struct sem_undo *un, *new;
+ int nsems;
+ int error;
+ error = get_undo_list(&ulp);
+ if (error)
+ return ERR_PTR(error);
- nsems = sma->sem_nsems;
- saved_add_count = 0;
- if (current->sysvsem.undo_list != NULL)
- saved_add_count = current->sysvsem.undo_list->add_count;
- sem_unlock(sma);
+ lock_semundo();
+ un = lookup_undo(ulp, semid);
unlock_semundo();
+ if (likely(un!=NULL))
+ goto out;
- error = get_undo_list(&undo_list);
- if (error)
- return error;
+ /* no undo structure around - allocate one. */
+ sma = sem_lock(semid);
+ un = ERR_PTR(-EINVAL);
+ if(sma==NULL)
+ goto out;
+ un = ERR_PTR(-EIDRM);
+ if (sem_checkid(sma,semid))
+ goto out_unlock;
+ nsems = sma->sem_nsems;
+ sem_unlock(sma);
- size = sizeof(struct sem_undo) + sizeof(short)*nsems;
- un = (struct sem_undo *) kmalloc(size, GFP_KERNEL);
- if (!un)
- return -ENOMEM;
+ new = (struct sem_undo *) kmalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL);
+ if (!new)
+ return ERR_PTR(-ENOMEM);
+ memset(new, 0, sizeof(struct sem_undo) + sizeof(short)*nsems);
+ new->semadj = (short *) &new[1];
+ new->semid = semid;
- memset(un, 0, size);
lock_semundo();
- error = sem_revalidate(semid, sma, nsems, alter ? S_IWUGO : S_IRUGO);
- if(error) {
+ un = lookup_undo(ulp, semid);
+ if (un) {
unlock_semundo();
- kfree(un);
- return error;
+ kfree(new);
+ goto out;
}
-
-
- /* alloc_undo has just
- * released all locks and reacquired them.
- * But, another thread may have
- * added the semundo we were looking for
- * during that time.
- * So, we check for it again.
- * only initialize and add the new one
- * if we don't discover one.
- */
- new_un = NULL;
- if (current->sysvsem.undo_list->add_count != saved_add_count)
- new_un = find_undo(semid);
-
- if (new_un != NULL) {
- if (sma->undo != new_un)
- BUG();
- kfree(un);
- un = new_un;
- } else {
- current->sysvsem.undo_list->add_count++;
- un->semadj = (short *) &un[1];
- un->semid = semid;
- un->proc_next = undo_list->proc_list;
- undo_list->proc_list = un;
- un->id_next = sma->undo;
- sma->undo = un;
+ error = sem_revalidate(semid, sma, nsems, 0);
+ if (error) {
+ sem_unlock(sma);
+ unlock_semundo();
+ kfree(new);
+ un = ERR_PTR(error);
+ goto out;
}
- *unp = un;
- return 0;
+ new->proc_next = ulp->proc_list;
+ ulp->proc_list = new;
+ new->id_next = sma->undo;
+ sma->undo = new;
+ sem_unlock(sma);
+ un = new;
+out_unlock:
+ unlock_semundo();
+out:
+ return un;
}
asmlinkage long sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
@@ -1002,7 +983,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops,
struct sembuf fast_sops[SEMOPM_FAST];
struct sembuf* sops = fast_sops, *sop;
struct sem_undo *un;
- int undos = 0, decrease = 0, alter = 0;
+ int undos = 0, decrease = 0, alter = 0, max;
struct sem_queue queue;
unsigned long jiffies_left = 0;
@@ -1032,18 +1013,10 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops,
}
jiffies_left = timespec_to_jiffies(&_timeout);
}
- lock_semundo();
- sma = sem_lock(semid);
- error=-EINVAL;
- if(sma==NULL)
- goto out_semundo_free;
- error = -EIDRM;
- if (sem_checkid(sma,semid))
- goto out_unlock_semundo_free;
- error = -EFBIG;
+ max = 0;
for (sop = sops; sop < sops + nsops; sop++) {
- if (sop->sem_num >= sma->sem_nsems)
- goto out_unlock_semundo_free;
+ if (sop->sem_num >= max)
+ max = sop->sem_num;
if (sop->sem_flg & SEM_UNDO)
undos++;
if (sop->sem_op < 0)
@@ -1053,30 +1026,42 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops,
}
alter |= decrease;
- error = -EACCES;
- if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO))
- goto out_unlock_semundo_free;
-
- error = security_sem_semop(sma, sops, nsops, alter);
- if (error)
- goto out_unlock_semundo_free;
-
- error = -EACCES;
+retry_undos:
if (undos) {
- /* Make sure we have an undo structure
- * for this process and this semaphore set.
- */
-
un = find_undo(semid);
- if (!un) {
- error = alloc_undo(sma,&un,semid,alter);
- if (error)
- goto out_free;
-
+ if (IS_ERR(un)) {
+ error = PTR_ERR(un);
+ goto out_free;
}
} else
un = NULL;
+ sma = sem_lock(semid);
+ error=-EINVAL;
+ if(sma==NULL)
+ goto out_free;
+ error = -EIDRM;
+ if (sem_checkid(sma,semid))
+ goto out_unlock_free;
+ /*
+ * semid identifies are not unique - find_undo may have
+ * allocated an undo structure, it was invalidated by an RMID
+ * and now a new array with received the same id. Check and retry.
+ */
+ if (un && un->semid == -1)
+ goto retry_undos;
+ error = -EFBIG;
+ if (max >= sma->sem_nsems)
+ goto out_unlock_free;
+
+ error = -EACCES;
+ if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO))
+ goto out_unlock_free;
+
+ error = security_sem_semop(sma, sops, nsops, alter);
+ if (error)
+ goto out_unlock_free;
+
error = try_atomic_semop (sma, sops, nsops, un, current->pid, 0);
if (error <= 0)
goto update;
@@ -1096,28 +1081,24 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops,
append_to_queue(sma ,&queue);
else
prepend_to_queue(sma ,&queue);
- current->sysvsem.sleep_list = &queue;
for (;;) {
queue.status = -EINTR;
queue.sleeper = current;
current->state = TASK_INTERRUPTIBLE;
sem_unlock(sma);
- unlock_semundo();
if (timeout)
jiffies_left = schedule_timeout(jiffies_left);
else
schedule();
- lock_semundo();
sma = sem_lock(semid);
if(sma==NULL) {
if(queue.prev != NULL)
BUG();
- current->sysvsem.sleep_list = NULL;
error = -EIDRM;
- goto out_semundo_free;
+ goto out_free;
}
/*
* If queue.status == 1 we where woken up and
@@ -1139,19 +1120,15 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops,
if (queue.prev) /* got Interrupt */
break;
/* Everything done by update_queue */
- current->sysvsem.sleep_list = NULL;
- goto out_unlock_semundo_free;
+ goto out_unlock_free;
}
}
- current->sysvsem.sleep_list = NULL;
remove_from_queue(sma,&queue);
update:
if (alter)
update_queue (sma);
-out_unlock_semundo_free:
+out_unlock_free:
sem_unlock(sma);
-out_semundo_free:
- unlock_semundo();
out_free:
if(sops != fast_sops)
kfree(sops);
@@ -1185,21 +1162,6 @@ int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
return 0;
}
-static inline void __exit_semundo(struct task_struct *tsk)
-{
- struct sem_undo_list *undo_list;
-
- undo_list = tsk->sysvsem.undo_list;
- if (!atomic_dec_and_test(&undo_list->refcnt))
- kfree(undo_list);
-}
-
-void exit_semundo(struct task_struct *tsk)
-{
- if (tsk->sysvsem.undo_list != NULL)
- __exit_semundo(tsk);
-}
-
/*
* add semadj values to semaphores, free undo structures.
* undo structures are not freed when semaphore arrays are destroyed
@@ -1212,44 +1174,29 @@ void exit_semundo(struct task_struct *tsk)
* The current implementation does not do so. The POSIX standard
* and SVID should be consulted to determine what behavior is mandated.
*/
-void sem_exit (void)
+void exit_sem(struct task_struct *tsk)
{
- struct sem_queue *q;
- struct sem_undo *u, *un = NULL, **up, **unp;
- struct sem_array *sma;
struct sem_undo_list *undo_list;
- int nsems, i;
-
- lock_kernel();
-
- /* If the current process was sleeping for a semaphore,
- * remove it from the queue.
- */
- if ((q = current->sysvsem.sleep_list)) {
- int semid = q->id;
- sma = sem_lock(semid);
- current->sysvsem.sleep_list = NULL;
+ struct sem_undo *u, **up;
- if (q->prev) {
- if(sma==NULL)
- BUG();
- remove_from_queue(q->sma,q);
- }
- if(sma!=NULL)
- sem_unlock(sma);
- }
+ undo_list = tsk->sysvsem.undo_list;
+ if (!undo_list)
+ return;
- undo_list = current->sysvsem.undo_list;
- if ((undo_list == NULL) || (atomic_read(&undo_list->refcnt) != 1)) {
- unlock_kernel();
+ if (!atomic_dec_and_test(&undo_list->refcnt))
return;
- }
/* There's no need to hold the semundo list lock, as current
* is the last task exiting for this undo list.
*/
for (up = &undo_list->proc_list; (u = *up); *up = u->proc_next, kfree(u)) {
- int semid = u->semid;
+ struct sem_array *sma;
+ int nsems, i;
+ struct sem_undo *un, **unp;
+ int semid;
+
+ semid = u->semid;
+
if(semid == -1)
continue;
sma = sem_lock(semid);
@@ -1259,15 +1206,14 @@ void sem_exit (void)
if (u->semid == -1)
goto next_entry;
- if (sem_checkid(sma,u->semid))
- goto next_entry;
+ BUG_ON(sem_checkid(sma,u->semid));
/* remove u from the sma->undo list */
for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
if (u == un)
goto found;
}
- printk ("sem_exit undo list error id=%d\n", u->semid);
+ printk ("exit_sem undo list error id=%d\n", u->semid);
goto next_entry;
found:
*unp = un->id_next;
@@ -1275,10 +1221,12 @@ found:
nsems = sma->sem_nsems;
for (i = 0; i < nsems; i++) {
struct sem * sem = &sma->sem_base[i];
- sem->semval += u->semadj[i];
- if (sem->semval < 0)
- sem->semval = 0; /* shouldn't happen */
- sem->sempid = current->pid;
+ if (u->semadj[i]) {
+ sem->semval += u->semadj[i];
+ if (sem->semval < 0)
+ sem->semval = 0; /* shouldn't happen */
+ sem->sempid = current->pid;
+ }
}
sma->sem_otime = get_seconds();
/* maybe some queued-up processes were waiting for this */
@@ -1286,9 +1234,7 @@ found:
next_entry:
sem_unlock(sma);
}
- __exit_semundo(current);
-
- unlock_kernel();
+ kfree(undo_list);
}
#ifdef CONFIG_PROC_FS
diff --git a/ipc/util.c b/ipc/util.c
index a2f4c3b1c680..b1e76464b850 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -541,17 +541,11 @@ int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
return 0;
}
-void exit_semundo(struct task_struct *tsk)
+void exit_sem(struct task_struct *tsk)
{
return;
}
-
-void sem_exit (void)
-{
- return;
-}
-
asmlinkage long sys_semget (key_t key, int nsems, int semflg)
{
return -ENOSYS;
diff --git a/kernel/acct.c b/kernel/acct.c
index 9f7cdf9a826b..e63095525ac2 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -54,6 +54,7 @@
#include <linux/jiffies.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
+#include <linux/blkdev.h> /* sector_div */
/*
* These constants control the amount of freespace that suspend and
@@ -100,9 +101,11 @@ static void acct_timeout(unsigned long unused)
*/
static int check_free_space(struct file *file)
{
- struct statfs sbuf;
+ struct kstatfs sbuf;
int res;
int act;
+ sector_t resume;
+ sector_t suspend;
spin_lock(&acct_globals.lock);
res = acct_globals.active;
@@ -113,10 +116,15 @@ static int check_free_space(struct file *file)
/* May block */
if (vfs_statfs(file->f_dentry->d_inode->i_sb, &sbuf))
return res;
+ suspend = sbuf.f_blocks * SUSPEND;
+ resume = sbuf.f_blocks * RESUME;
- if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100)
+ sector_div(suspend, 100);
+ sector_div(resume, 100);
+
+ if (sbuf.f_bavail <= suspend)
act = -1;
- else if (sbuf.f_bavail >= RESUME * sbuf.f_blocks / 100)
+ else if (sbuf.f_bavail >= resume)
act = 1;
else
act = 0;
diff --git a/kernel/exit.c b/kernel/exit.c
index c5b8ec241a83..7dee095b31bd 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -698,7 +698,7 @@ NORET_TYPE void do_exit(long code)
acct_process(code);
__exit_mm(tsk);
- sem_exit();
+ exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
exit_namespace(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index fba722be316e..5ef2dca02354 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -39,7 +39,7 @@
#include <asm/tlbflush.h>
extern int copy_semundo(unsigned long clone_flags, struct task_struct *tsk);
-extern void exit_semundo(struct task_struct *tsk);
+extern void exit_sem(struct task_struct *tsk);
/* The idle threads do not count..
* Protected by write_lock_irq(&tasklist_lock)
@@ -887,13 +887,11 @@ struct task_struct *copy_process(unsigned long clone_flags,
if (retval)
goto bad_fork_cleanup_namespace;
- if (clone_flags & CLONE_CHILD_SETTID)
- p->set_child_tid = child_tidptr;
+ p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
* Clear TID on mm_release()?
*/
- if (clone_flags & CLONE_CHILD_CLEARTID)
- p->clear_child_tid = child_tidptr;
+ p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
/*
* Syscall tracing should be turned off in the child regardless
@@ -1034,7 +1032,7 @@ bad_fork_cleanup_fs:
bad_fork_cleanup_files:
exit_files(p); /* blocking */
bad_fork_cleanup_semundo:
- exit_semundo(p);
+ exit_sem(p);
bad_fork_cleanup_security:
security_task_free(p);
bad_fork_cleanup:
diff --git a/kernel/kmod.c b/kernel/kmod.c
index d9e4299a8765..e011611afb7d 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -183,12 +183,15 @@ static int wait_for_helper(void *data)
struct subprocess_info *sub_info = data;
pid_t pid;
- pid = kernel_thread(____call_usermodehelper, sub_info,
- CLONE_VFORK | SIGCHLD);
+ sub_info->retval = 0;
+ pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
if (pid < 0)
sub_info->retval = pid;
else
- sys_wait4(pid, (unsigned int *)&sub_info->retval, 0, NULL);
+ /* We don't have a SIGCHLD signal handler, so this
+ * always returns -ECHILD, but the important thing is
+ * that it blocks. */
+ sys_wait4(pid, NULL, 0, NULL);
complete(sub_info->complete);
return 0;
@@ -231,8 +234,7 @@ static void __call_usermodehelper(void *data)
* (ie. it runs with full root capabilities).
*
* Must be called from process context. Returns a negative error code
- * if program was not execed successfully, or (exitcode << 8 + signal)
- * of the application (0 if wait is not set).
+ * if program was not execed successfully, or 0.
*/
int call_usermodehelper(char *path, char **argv, char **envp, int wait)
{
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index ab547345372e..cbb2313433ce 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -592,7 +592,6 @@ EXPORT_SYMBOL(__tasklet_hi_schedule);
/* init task, for moving kthread roots - ought to export a function ?? */
EXPORT_SYMBOL(init_task);
-EXPORT_SYMBOL(init_thread_union);
EXPORT_SYMBOL(tasklist_lock);
EXPORT_SYMBOL(find_task_by_pid);
diff --git a/kernel/sched.c b/kernel/sched.c
index c603aaa67790..9566cd11de18 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1880,10 +1880,6 @@ asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
return -EFAULT;
- new_mask &= cpu_online_map;
- if (!new_mask)
- return -EINVAL;
-
read_lock(&tasklist_lock);
p = find_process_by_pid(pid);
@@ -1905,8 +1901,7 @@ asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
!capable(CAP_SYS_NICE))
goto out_unlock;
- retval = 0;
- set_cpus_allowed(p, new_mask);
+ retval = set_cpus_allowed(p, new_mask);
out_unlock:
put_task_struct(p);
@@ -2182,10 +2177,7 @@ static void show_task(task_t * p)
else
printk(" (NOTLB)\n");
- {
- extern void show_trace_task(task_t *tsk);
- show_trace_task(p);
- }
+ show_stack(p, NULL);
}
void show_state(void)
@@ -2272,17 +2264,14 @@ typedef struct {
* task must not exit() & deallocate itself prematurely. The
* call is not atomic; no spinlocks may be held.
*/
-void set_cpus_allowed(task_t *p, unsigned long new_mask)
+int set_cpus_allowed(task_t *p, unsigned long new_mask)
{
unsigned long flags;
migration_req_t req;
runqueue_t *rq;
-#if 0 /* FIXME: Grab cpu_lock, return error on this case. --RR */
- new_mask &= cpu_online_map;
- if (!new_mask)
- BUG();
-#endif
+ if (any_online_cpu(new_mask) == NR_CPUS)
+ return -EINVAL;
rq = task_rq_lock(p, &flags);
p->cpus_allowed = new_mask;
@@ -2292,7 +2281,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
*/
if (new_mask & (1UL << task_cpu(p))) {
task_rq_unlock(rq, &flags);
- return;
+ return 0;
}
/*
* If the task is not on a runqueue (and not running), then
@@ -2301,7 +2290,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
if (!p->array && !task_running(rq, p)) {
set_task_cpu(p, any_online_cpu(p->cpus_allowed));
task_rq_unlock(rq, &flags);
- return;
+ return 0;
}
init_completion(&req.done);
req.task = p;
@@ -2311,6 +2300,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
wake_up_process(rq->migration_thread);
wait_for_completion(&req.done);
+ return 0;
}
/* Move (not current) task off this cpu, onto dest cpu. */
diff --git a/kernel/timer.c b/kernel/timer.c
index 5136630693b4..ad3758c663d4 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -439,8 +439,8 @@ repeat:
/*
* Timekeeping variables
*/
-unsigned long tick_usec = TICK_USEC; /* ACTHZ period (usec) */
-unsigned long tick_nsec = TICK_NSEC; /* USER_HZ period (nsec) */
+unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
+unsigned long tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */
/*
* The current time
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 968837218657..efeaaa4f0274 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -259,15 +259,41 @@ void flush_workqueue(struct workqueue_struct *wq)
}
}
-struct workqueue_struct *create_workqueue(const char *name)
+static int create_workqueue_thread(struct workqueue_struct *wq,
+ const char *name,
+ int cpu)
{
- int ret, cpu, destroy = 0;
- struct cpu_workqueue_struct *cwq;
startup_t startup;
+ struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+ int ret;
+
+ spin_lock_init(&cwq->lock);
+ cwq->wq = wq;
+ cwq->thread = NULL;
+ cwq->insert_sequence = 0;
+ cwq->remove_sequence = 0;
+ INIT_LIST_HEAD(&cwq->worklist);
+ init_waitqueue_head(&cwq->more_work);
+ init_waitqueue_head(&cwq->work_done);
+ init_completion(&cwq->exit);
+
+ init_completion(&startup.done);
+ startup.cwq = cwq;
+ startup.name = name;
+ ret = kernel_thread(worker_thread, &startup, CLONE_FS | CLONE_FILES);
+ if (ret >= 0) {
+ wait_for_completion(&startup.done);
+ BUG_ON(!cwq->thread);
+ }
+ return ret;
+}
+
+struct workqueue_struct *create_workqueue(const char *name)
+{
+ int cpu, destroy = 0;
struct workqueue_struct *wq;
BUG_ON(strlen(name) > 10);
- startup.name = name;
wq = kmalloc(sizeof(*wq), GFP_KERNEL);
if (!wq)
@@ -276,27 +302,8 @@ struct workqueue_struct *create_workqueue(const char *name)
for (cpu = 0; cpu < NR_CPUS; cpu++) {
if (!cpu_online(cpu))
continue;
- cwq = wq->cpu_wq + cpu;
-
- spin_lock_init(&cwq->lock);
- cwq->wq = wq;
- cwq->thread = NULL;
- cwq->insert_sequence = 0;
- cwq->remove_sequence = 0;
- INIT_LIST_HEAD(&cwq->worklist);
- init_waitqueue_head(&cwq->more_work);
- init_waitqueue_head(&cwq->work_done);
-
- init_completion(&startup.done);
- startup.cwq = cwq;
- ret = kernel_thread(worker_thread, &startup,
- CLONE_FS | CLONE_FILES);
- if (ret < 0)
+ if (create_workqueue_thread(wq, name, cpu) < 0)
destroy = 1;
- else {
- wait_for_completion(&startup.done);
- BUG_ON(!cwq->thread);
- }
}
/*
* Was there any error during startup? If yes then clean up:
@@ -308,28 +315,30 @@ struct workqueue_struct *create_workqueue(const char *name)
return wq;
}
-void destroy_workqueue(struct workqueue_struct *wq)
+static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu)
{
struct cpu_workqueue_struct *cwq;
- int cpu;
- flush_workqueue(wq);
-
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- if (!cpu_online(cpu))
- continue;
- cwq = wq->cpu_wq + cpu;
- if (!cwq->thread)
- continue;
- /*
- * Initiate an exit and wait for it:
- */
- init_completion(&cwq->exit);
+ cwq = wq->cpu_wq + cpu;
+ if (cwq->thread) {
+ /* Tell thread to exit and wait for it. */
cwq->thread = NULL;
wake_up(&cwq->more_work);
wait_for_completion(&cwq->exit);
}
+}
+
+void destroy_workqueue(struct workqueue_struct *wq)
+{
+ int cpu;
+
+ flush_workqueue(wq);
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (cpu_online(cpu))
+ cleanup_workqueue_thread(wq, cpu);
+ }
kfree(wq);
}
diff --git a/lib/kobject.c b/lib/kobject.c
index e2378597b989..fb49131f5ff9 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -100,6 +100,9 @@ static void fill_kobj_path(struct kset *kset, struct kobject *kobj, char *path,
#define BUFFER_SIZE 1024 /* should be enough memory for the env */
#define NUM_ENVP 32 /* number of env pointers */
+static unsigned long sequence_num;
+static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
+
static void kset_hotplug(const char *action, struct kset *kset,
struct kobject *kobj)
{
@@ -112,6 +115,7 @@ static void kset_hotplug(const char *action, struct kset *kset,
int kobj_path_length;
char *kobj_path = NULL;
char *name = NULL;
+ unsigned long seq;
/* If the kset has a filter operation, call it. If it returns
failure, no hotplug event is required. */
@@ -152,6 +156,13 @@ static void kset_hotplug(const char *action, struct kset *kset,
envp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action) + 1;
+ spin_lock(&sequence_lock);
+ seq = sequence_num++;
+ spin_unlock(&sequence_lock);
+
+ envp [i++] = scratch;
+ scratch += sprintf(scratch, "SEQNUM=%ld", seq) + 1;
+
kobj_path_length = get_kobj_path_length (kset, kobj);
kobj_path = kmalloc (kobj_path_length, GFP_KERNEL);
if (!kobj_path)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 9e54d17adaaa..db2e96ea0fdf 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -323,7 +323,8 @@ static void wb_kupdate(unsigned long arg)
oldest_jif = jiffies - (dirty_expire_centisecs * HZ) / 100;
start_jif = jiffies;
next_jif = start_jif + (dirty_writeback_centisecs * HZ) / 100;
- nr_to_write = ps.nr_dirty + ps.nr_unstable;
+ nr_to_write = ps.nr_dirty + ps.nr_unstable +
+ (inodes_stat.nr_inodes - inodes_stat.nr_unused);
while (nr_to_write > 0) {
wbc.encountered_congestion = 0;
wbc.nr_to_write = MAX_WRITEBACK_PAGES;
@@ -516,7 +517,9 @@ int __set_page_dirty_nobuffers(struct page *page)
list_add(&page->list, &mapping->dirty_pages);
}
spin_unlock(&mapping->page_lock);
- __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+ if (!PageSwapCache(page))
+ __mark_inode_dirty(mapping->host,
+ I_DIRTY_PAGES);
}
}
return ret;
diff --git a/mm/shmem.c b/mm/shmem.c
index 8df99f64eb9e..73301cee3f41 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1010,7 +1010,7 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
struct inode *inode = file->f_dentry->d_inode;
ops = &shmem_vm_ops;
- if (!inode->i_sb || !S_ISREG(inode->i_mode))
+ if (!S_ISREG(inode->i_mode))
return -EACCES;
update_atime(inode);
vma->vm_ops = ops;
@@ -1352,7 +1352,7 @@ static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos,
return desc.error;
}
-static int shmem_statfs(struct super_block *sb, struct statfs *buf)
+static int shmem_statfs(struct super_block *sb, struct kstatfs *buf)
{
struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
diff --git a/mm/slab.c b/mm/slab.c
index e236bbbfac21..b625155fd0e5 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -475,8 +475,6 @@ static void cache_estimate (unsigned long gfporder, size_t size,
*left_over = wastage;
}
-#if DEBUG
-
#define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg)
static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
@@ -486,8 +484,6 @@ static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
dump_stack();
}
-#endif
-
/*
* Start the reap timer running on the target CPU. We run at around 1 to 2Hz.
* Add the CPU number into the expiry time to minimize the possibility of the
@@ -1307,6 +1303,8 @@ int kmem_cache_shrink(kmem_cache_t *cachep)
*/
int kmem_cache_destroy (kmem_cache_t * cachep)
{
+ int i;
+
if (!cachep || in_interrupt())
BUG();
@@ -1319,21 +1317,19 @@ int kmem_cache_destroy (kmem_cache_t * cachep)
up(&cache_chain_sem);
if (__cache_shrink(cachep)) {
- printk(KERN_ERR "kmem_cache_destroy: Can't free all objects %p\n",
- cachep);
+ slab_error(cachep, "Can't free all objects");
down(&cache_chain_sem);
list_add(&cachep->next,&cache_chain);
up(&cache_chain_sem);
return 1;
}
- {
- int i;
- for (i = 0; i < NR_CPUS; i++)
- kfree(cachep->array[i]);
- /* NUMA: free the list3 structures */
- kfree(cachep->lists.shared);
- cachep->lists.shared = NULL;
- }
+
+ for (i = 0; i < NR_CPUS; i++)
+ kfree(cachep->array[i]);
+
+ /* NUMA: free the list3 structures */
+ kfree(cachep->lists.shared);
+ cachep->lists.shared = NULL;
kmem_cache_free(&cache_cache, cachep);
return 0;
@@ -1749,8 +1745,10 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep,
if (!objp)
return objp;
- if (cachep->flags & SLAB_POISON)
+ if (cachep->flags & SLAB_POISON) {
check_poison_obj(cachep, objp);
+ poison_obj(cachep, objp, POISON_BEFORE);
+ }
if (cachep->flags & SLAB_STORE_USER) {
objlen -= BYTES_PER_WORD;
*((void **)(objp+objlen)) = caller;
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 29198f06fcae..708141fb0215 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -16,14 +16,6 @@
#include <asm/pgtable.h>
-/*
- * swapper_inode doesn't do anything much. It is really only here to
- * avoid some special-casing in other parts of the kernel.
- */
-static struct inode swapper_inode = {
- .i_mapping = &swapper_space,
-};
-
static struct backing_dev_info swap_backing_dev_info = {
.ra_pages = 0, /* No readahead */
.memory_backed = 1, /* Does not contribute to dirty memory */
@@ -38,7 +30,6 @@ struct address_space swapper_space = {
.dirty_pages = LIST_HEAD_INIT(swapper_space.dirty_pages),
.io_pages = LIST_HEAD_INIT(swapper_space.io_pages),
.locked_pages = LIST_HEAD_INIT(swapper_space.locked_pages),
- .host = &swapper_inode,
.a_ops = &swap_aops,
.backing_dev_info = &swap_backing_dev_info,
.i_mmap = LIST_HEAD_INIT(swapper_space.i_mmap),
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 607a63581988..f2a9517511e1 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -22,6 +22,7 @@
#include <linux/if_ether.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_arp.h>
#include <linux/in_route.h>
#include <net/ip.h>
#include <asm/uaccess.h>
@@ -304,31 +305,36 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb,
return NF_ACCEPT;
}
-
/* PF_BRIDGE/FORWARD *************************************************/
static int br_nf_forward_finish(struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+ struct net_device *in;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug ^= (1 << NF_BR_FORWARD);
#endif
- if (nf_bridge->mask & BRNF_PKT_TYPE) {
- skb->pkt_type = PACKET_OTHERHOST;
- nf_bridge->mask ^= BRNF_PKT_TYPE;
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ in = nf_bridge->physindev;
+ if (nf_bridge->mask & BRNF_PKT_TYPE) {
+ skb->pkt_type = PACKET_OTHERHOST;
+ nf_bridge->mask ^= BRNF_PKT_TYPE;
+ }
+ } else {
+ in = *((struct net_device **)(skb->cb));
}
- NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, nf_bridge->physindev,
+ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
skb->dev, br_forward_finish, 1);
-
return 0;
}
-/* This is the 'purely bridged' case. We pass the packet to
+/* This is the 'purely bridged' case. For IP, we pass the packet to
* netfilter with indev and outdev set to the bridge device,
* but we are still able to filter on the 'real' indev/outdev
- * because of the ipt_physdev.c module.
+ * because of the ipt_physdev.c module. For ARP, indev and outdev are the
+ * bridge ports.
*/
static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
@@ -337,24 +343,33 @@ static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
- if (skb->protocol != __constant_htons(ETH_P_IP))
+ if (skb->protocol != __constant_htons(ETH_P_IP) &&
+ skb->protocol != __constant_htons(ETH_P_ARP))
return NF_ACCEPT;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug ^= (1 << NF_BR_FORWARD);
#endif
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ nf_bridge = skb->nf_bridge;
+ if (skb->pkt_type == PACKET_OTHERHOST) {
+ skb->pkt_type = PACKET_HOST;
+ nf_bridge->mask |= BRNF_PKT_TYPE;
+ }
- nf_bridge = skb->nf_bridge;
- if (skb->pkt_type == PACKET_OTHERHOST) {
- skb->pkt_type = PACKET_HOST;
- nf_bridge->mask |= BRNF_PKT_TYPE;
- }
+ /* The physdev module checks on this */
+ nf_bridge->mask |= BRNF_BRIDGED;
+ nf_bridge->physoutdev = skb->dev;
- nf_bridge->mask |= BRNF_BRIDGED; /* The physdev module checks on this */
- nf_bridge->physoutdev = skb->dev;
+ NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
+ bridge_parent(out), br_nf_forward_finish);
+ } else {
+ struct net_device **d = (struct net_device **)(skb->cb);
- NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(nf_bridge->physindev),
- bridge_parent(skb->dev), br_nf_forward_finish);
+ *d = (struct net_device *)in;
+ NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
+ (struct net_device *)out, br_nf_forward_finish);
+ }
return NF_STOLEN;
}
diff --git a/net/core/flow.c b/net/core/flow.c
index 35c6058d22f0..87a5b21694c9 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -12,7 +12,6 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/completion.h>
#include <linux/percpu.h>
@@ -301,7 +300,8 @@ void flow_cache_flush(void)
local_bh_disable();
smp_call_function(flow_cache_flush_per_cpu, &info, 1, 0);
- flow_cache_flush_tasklet((unsigned long)&info);
+ if (test_bit(smp_processor_id(), &info.cpumap))
+ flow_cache_flush_tasklet((unsigned long)&info);
local_bh_enable();
wait_for_completion(&info.completion);
@@ -309,13 +309,11 @@ void flow_cache_flush(void)
up(&flow_flush_sem);
}
-static void __devinit flow_cache_cpu_online(int cpu)
+static int __devinit flow_cache_cpu_prepare(int cpu)
{
struct tasklet_struct *tasklet;
unsigned long order;
- flow_hash_rnd_recalc(cpu) = 1;
-
for (order = 0;
(PAGE_SIZE << order) <
(sizeof(struct flow_cache_entry *)*flow_hash_size);
@@ -325,15 +323,28 @@ static void __devinit flow_cache_cpu_online(int cpu)
flow_table(cpu) = (struct flow_cache_entry **)
__get_free_pages(GFP_KERNEL, order);
+ if (!flow_table(cpu))
+ return NOTIFY_BAD;
+
memset(flow_table(cpu), 0, PAGE_SIZE << order);
+ flow_hash_rnd_recalc(cpu) = 1;
+ flow_count(cpu) = 0;
+
tasklet = flow_flush_tasklet(cpu);
tasklet_init(tasklet, flow_cache_flush_tasklet, 0);
+ return NOTIFY_OK;
+}
+
+static int __devinit flow_cache_cpu_online(int cpu)
+{
down(&flow_cache_cpu_sem);
set_bit(cpu, &flow_cache_cpu_map);
flow_cache_cpu_count++;
up(&flow_cache_cpu_sem);
+
+ return NOTIFY_OK;
}
static int __devinit flow_cache_cpu_notify(struct notifier_block *self,
@@ -342,7 +353,10 @@ static int __devinit flow_cache_cpu_notify(struct notifier_block *self,
unsigned long cpu = (unsigned long)cpu;
switch (action) {
case CPU_UP_PREPARE:
- flow_cache_cpu_online(cpu);
+ return flow_cache_cpu_prepare(cpu);
+ break;
+ case CPU_ONLINE:
+ return flow_cache_cpu_online(cpu);
break;
}
return NOTIFY_OK;
@@ -354,6 +368,8 @@ static struct notifier_block __devinitdata flow_cache_cpu_nb = {
static int __init flow_cache_init(void)
{
+ int i;
+
flow_cachep = kmem_cache_create("flow_cache",
sizeof(struct flow_cache_entry),
0, SLAB_HWCACHE_ALIGN,
@@ -371,8 +387,15 @@ static int __init flow_cache_init(void)
flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
add_timer(&flow_hash_rnd_timer);
- flow_cache_cpu_online(smp_processor_id());
register_cpu_notifier(&flow_cache_cpu_nb);
+ for (i = 0; i < NR_CPUS; i++) {
+ if (!cpu_online(i))
+ continue;
+ if (flow_cache_cpu_prepare(i) == NOTIFY_OK &&
+ flow_cache_cpu_online(i) == NOTIFY_OK)
+ continue;
+ panic("NET: failed to initialise flow cache hash table\n");
+ }
return 0;
}
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 80e2b0379858..bf49e394665f 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -216,9 +216,12 @@ int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{
unsigned short type = hh->hh_type;
- struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2);
+ struct ethhdr *eth;
struct net_device *dev = neigh->dev;
+ eth = (struct ethhdr*)
+ (((u8*)hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
+
if (type == __constant_htons(ETH_P_802_3))
return -1;
@@ -235,5 +238,6 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
{
- memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+ memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
+ haddr, dev->addr_len);
}
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index f9959c4e932f..1324b4e97d83 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -623,15 +623,20 @@ int arp_process(struct sk_buff *skb)
int addr_type;
struct neighbour *n;
- /* arp_rcv below verifies the ARP header, verifies the device
- * is ARP'able, and linearizes the SKB (if needed).
+ /* arp_rcv below verifies the ARP header and verifies the device
+ * is ARP'able.
*/
if (in_dev == NULL)
goto out;
+ /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
+ if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
+ (2 * dev->addr_len) +
+ (2 * sizeof(u32)))))
+ goto out;
+
arp = skb->nh.arph;
- arp_ptr= (unsigned char *)(arp+1);
switch (dev_type) {
default:
@@ -693,6 +698,7 @@ int arp_process(struct sk_buff *skb)
/*
* Extract fields
*/
+ arp_ptr= (unsigned char *)(arp+1);
sha = arp_ptr;
arp_ptr += dev->addr_len;
memcpy(&sip, arp_ptr, 4);
@@ -841,11 +847,6 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
goto out_of_mem;
- if (skb_is_nonlinear(skb)) {
- if (skb_linearize(skb, GFP_ATOMIC) != 0)
- goto freeskb;
- }
-
return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
freeskb:
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 765c13b96d64..7a736073666e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -193,8 +193,11 @@ static inline int ip_finish_output2(struct sk_buff *skb)
#endif /*CONFIG_NETFILTER_DEBUG*/
if (hh) {
+ int hh_alen;
+
read_lock_bh(&hh->hh_lock);
- memcpy(skb->data - 16, hh->hh_data, 16);
+ hh_alen = HH_DATA_ALIGN(hh->hh_len);
+ memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len);
return hh->hh_output(skb);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 751a5f550a28..aa9644848417 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -247,14 +247,16 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
{
static const char nulldevname[IFNAMSIZ] = { 0 };
unsigned int verdict = NF_DROP;
- struct arphdr *arp = (*pskb)->nh.arph;
+ struct arphdr *arp;
int hotdrop = 0;
struct arpt_entry *e, *back;
const char *indev, *outdev;
void *table_base;
- /* FIXME: Push down to extensions --RR */
- if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
+ /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
+ if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
+ (2 * (*pskb)->dev->addr_len) +
+ (2 * sizeof(u32)))))
return NF_DROP;
indev = in ? in->name : nulldevname;
@@ -267,6 +269,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
e = get_entry(table_base, table->private->hook_entry[hook]);
back = get_entry(table_base, table->private->underflow[hook]);
+ arp = (*pskb)->nh.arph;
do {
if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) {
struct arpt_entry_target *t;
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 3387279f6908..2404ad53a71f 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -8,7 +8,8 @@
#include <linux/module.h>
#include <linux/netfilter_arp/arp_tables.h>
-#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
+ (1 << NF_ARP_FORWARD))
/* Standard entry. */
struct arpt_standard
@@ -32,15 +33,17 @@ struct arpt_error
static struct
{
struct arpt_replace repl;
- struct arpt_standard entries[2];
+ struct arpt_standard entries[3];
struct arpt_error term;
} initial_table __initdata
-= { { "filter", FILTER_VALID_HOOKS, 3,
- sizeof(struct arpt_standard) * 2 + sizeof(struct arpt_error),
+= { { "filter", FILTER_VALID_HOOKS, 4,
+ sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error),
{ [NF_ARP_IN] = 0,
- [NF_ARP_OUT] = sizeof(struct arpt_standard) },
+ [NF_ARP_OUT] = sizeof(struct arpt_standard),
+ [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), },
{ [NF_ARP_IN] = 0,
- [NF_ARP_OUT] = sizeof(struct arpt_standard), },
+ [NF_ARP_OUT] = sizeof(struct arpt_standard),
+ [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), },
0, NULL, { } },
{
/* ARP_IN */
@@ -84,6 +87,27 @@ static struct
{ 0, 0 }, { } },
{ { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 }
+ },
+ /* ARP_FORWARD */
+ {
+ {
+ {
+ { 0 }, { 0 }, { 0 }, { 0 },
+ 0, 0,
+ { { 0, }, { 0, } },
+ { { 0, }, { 0, } },
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ "", "", { 0 }, { 0 },
+ 0, 0
+ },
+ sizeof(struct arpt_entry),
+ sizeof(struct arpt_standard),
+ 0,
+ { 0, 0 }, { } },
+ { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
+ -NF_ACCEPT - 1 }
}
},
/* ERROR */
@@ -142,35 +166,34 @@ static struct nf_hook_ops arpt_ops[] = {
.owner = THIS_MODULE,
.pf = NF_ARP,
.hooknum = NF_ARP_OUT,
- }
+ },
+ {
+ .hook = arpt_hook,
+ .owner = THIS_MODULE,
+ .pf = NF_ARP,
+ .hooknum = NF_ARP_FORWARD,
+ },
};
static int __init init(void)
{
- int ret;
+ int ret, i;
/* Register table */
ret = arpt_register_table(&packet_filter);
if (ret < 0)
return ret;
- /* Register hooks */
- ret = nf_register_hook(&arpt_ops[0]);
- if (ret < 0)
- goto cleanup_table;
-
- ret = nf_register_hook(&arpt_ops[1]);
- if (ret < 0)
- goto cleanup_hook0;
-
+ for (i = 0; i < ARRAY_SIZE(arpt_ops); i++)
+ if ((ret = nf_register_hook(&arpt_ops[i])) < 0)
+ goto cleanup_hooks;
return ret;
-cleanup_hook0:
- nf_unregister_hook(&arpt_ops[0]);
+cleanup_hooks:
+ while (--i >= 0)
+ nf_unregister_hook(&arpt_ops[i]);
-cleanup_table:
arpt_unregister_table(&packet_filter);
-
return ret;
}
@@ -178,7 +201,7 @@ static void __exit fini(void)
{
unsigned int i;
- for (i = 0; i < sizeof(arpt_ops)/sizeof(struct nf_hook_ops); i++)
+ for (i = 0; i < ARRAY_SIZE(arpt_ops); i++)
nf_unregister_hook(&arpt_ops[i]);
arpt_unregister_table(&packet_filter);
diff --git a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c
index fcd424bd73b8..3f8faff13dc4 100644
--- a/net/ipv4/netfilter/ipt_MIRROR.c
+++ b/net/ipv4/netfilter/ipt_MIRROR.c
@@ -90,8 +90,11 @@ static void ip_direct_send(struct sk_buff *skb)
struct hh_cache *hh = dst->hh;
if (hh) {
+ int hh_alen;
+
read_lock_bh(&hh->hh_lock);
- memcpy(skb->data - 16, hh->hh_data, 16);
+ hh_alen = HH_DATA_ALIGN(hh->hh_len);
+ memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len);
hh->hh_output(skb);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 9700faf3e8b3..5cfc70535e35 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -613,12 +613,6 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
case NDISC_NEIGHBOUR_SOLICITATION:
case NDISC_NEIGHBOUR_ADVERTISEMENT:
case NDISC_REDIRECT:
- if (skb_is_nonlinear(skb) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
- kfree_skb(skb);
- return 0;
- }
-
ndisc_rcv(skb);
break;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9b17cafeab36..0eb4d60f9dac 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -76,8 +76,11 @@ static inline int ip6_output_finish(struct sk_buff *skb)
struct hh_cache *hh = dst->hh;
if (hh) {
+ int hh_alen;
+
read_lock_bh(&hh->hh_lock);
- memcpy(skb->data - 16, hh->hh_data, 16);
+ hh_alen = HH_DATA_ALIGN(hh->hh_len);
+ memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len);
return hh->hh_output(skb);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index aab59050a6c5..1c582945bac7 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -714,12 +714,6 @@ void ndisc_recv_ns(struct sk_buff *skb)
struct inet6_ifaddr *ifp;
struct neighbour *neigh;
- if (skb->len < sizeof(struct nd_msg)) {
- if (net_ratelimit())
- printk(KERN_WARNING "ICMP NS: packet too short\n");
- return;
- }
-
if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
if (net_ratelimit())
printk(KERN_WARNING "ICMP NS: target address is multicast\n");
@@ -1410,7 +1404,12 @@ static void pndisc_redo(struct sk_buff *skb)
int ndisc_rcv(struct sk_buff *skb)
{
- struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
+ struct nd_msg *msg;
+
+ if (!pskb_may_pull(skb, skb->len))
+ return 0;
+
+ msg = (struct nd_msg *) skb->h.raw;
__skb_push(skb, skb->data-skb->h.raw);
diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c
index 743abb29c164..5092abb62d54 100644
--- a/net/irda/irda_device.c
+++ b/net/irda/irda_device.c
@@ -231,7 +231,7 @@ static void __irda_task_delete(struct irda_task *task)
void irda_task_delete(struct irda_task *task)
{
/* Unregister task */
- hashbin_remove(tasks, (int) task, NULL);
+ hashbin_remove(tasks, (long) task, NULL);
__irda_task_delete(task);
}
@@ -345,7 +345,7 @@ struct irda_task *irda_task_execute(void *instance,
init_timer(&task->timer);
/* Register task */
- hashbin_insert(tasks, (irda_queue_t *) task, (int) task, NULL);
+ hashbin_insert(tasks, (irda_queue_t *) task, (long) task, NULL);
/* No time to waste, so lets get going! */
ret = irda_task_kick(task);
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index 45dc5b03c168..05458c3d4a5a 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -33,8 +33,8 @@ irnet_post_event(irnet_socket * ap,
{
int index; /* In the log */
- DENTER(CTRL_TRACE, "(ap=0x%X, event=%d, daddr=%08x, name=``%s'')\n",
- (unsigned int) ap, event, daddr, name);
+ DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
+ ap, event, daddr, name);
/* Protect this section via spinlock.
* Note : as we are the only event producer, we only need to exclude
@@ -100,7 +100,7 @@ irnet_open_tsap(irnet_socket * self)
{
notify_t notify; /* Callback structure */
- DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");
@@ -125,8 +125,8 @@ irnet_open_tsap(irnet_socket * self)
/* Remember which TSAP selector we actually got */
self->stsap_sel = self->tsap->stsap_sel;
- DEXIT(IRDA_SR_TRACE, " - tsap=0x%X, sel=0x%X\n",
- (unsigned int) self->tsap, self->stsap_sel);
+ DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
+ self->tsap, self->stsap_sel);
return 0;
}
@@ -151,7 +151,7 @@ irnet_ias_to_tsap(irnet_socket * self,
{
__u8 dtsap_sel = 0; /* TSAP we are looking for */
- DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
/* By default, no error */
self->errno = 0;
@@ -231,7 +231,7 @@ irnet_ias_to_tsap(irnet_socket * self,
static inline int
irnet_find_lsap_sel(irnet_socket * self)
{
- DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
/* This should not happen */
DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");
@@ -268,7 +268,7 @@ irnet_connect_tsap(irnet_socket * self)
{
int err;
- DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
/* Open a local TSAP (an IrTTP instance) */
err = irnet_open_tsap(self);
@@ -369,7 +369,7 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
{
int ret;
- DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
/* Ask lmp for the current discovery log */
self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
@@ -382,8 +382,8 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
clear_bit(0, &self->ttp_connect);
DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
}
- DEBUG(IRDA_SR_INFO, "Got the log (0x%X), size is %d\n",
- (unsigned int) self->discoveries, self->disco_number);
+ DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
+ self->discoveries, self->disco_number);
/* Start with the first discovery */
self->disco_index = -1;
@@ -426,7 +426,7 @@ irnet_dname_to_daddr(irnet_socket * self)
int number; /* Number of nodes in the log */
int i;
- DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
/* Ask lmp for the current discovery log */
discoveries = irlmp_get_discoveries(&number, 0xffff,
@@ -474,7 +474,7 @@ irnet_dname_to_daddr(irnet_socket * self)
int
irda_irnet_create(irnet_socket * self)
{
- DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
self->magic = IRNET_MAGIC; /* Paranoia */
@@ -518,7 +518,7 @@ irda_irnet_connect(irnet_socket * self)
{
int err;
- DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
/* Check if we are already trying to connect.
* Because irda_irnet_connect() can be called directly by pppd plus
@@ -585,7 +585,7 @@ irda_irnet_connect(irnet_socket * self)
void
irda_irnet_destroy(irnet_socket * self)
{
- DENTER(IRDA_SOCK_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
if(self == NULL)
return;
@@ -676,7 +676,7 @@ irnet_daddr_to_dname(irnet_socket * self)
int number; /* Number of nodes in the log */
int i;
- DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
/* Ask lmp for the current discovery log */
discoveries = irlmp_get_discoveries(&number, 0xffff,
@@ -722,7 +722,7 @@ irnet_find_socket(irnet_socket * self)
irnet_socket * new = (irnet_socket *) NULL;
int err;
- DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
/* Get the addresses of the requester */
self->daddr = irttp_get_daddr(self->tsap);
@@ -741,8 +741,8 @@ irnet_find_socket(irnet_socket * self)
new = (irnet_socket *) hashbin_find(irnet_server.list,
0, self->rname);
if(new)
- DEBUG(IRDA_SERV_INFO, "Socket 0x%X matches rname ``%s''.\n",
- (unsigned int) new, new->rname);
+ DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches rname ``%s''.\n",
+ new, new->rname);
}
/* If no name matches, try to find an socket by the destination address */
@@ -758,8 +758,8 @@ irnet_find_socket(irnet_socket * self)
if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
{
/* Yes !!! Get it.. */
- DEBUG(IRDA_SERV_INFO, "Socket 0x%X matches daddr %#08x.\n",
- (unsigned int) new, self->daddr);
+ DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches daddr %#08x.\n",
+ new, self->daddr);
break;
}
new = (irnet_socket *) hashbin_get_next(irnet_server.list);
@@ -777,8 +777,8 @@ irnet_find_socket(irnet_socket * self)
(new->rname[0] == '\0') && (new->ppp_open))
{
/* Yes !!! Get it.. */
- DEBUG(IRDA_SERV_INFO, "Socket 0x%X is free.\n",
- (unsigned int) new);
+ DEBUG(IRDA_SERV_INFO, "Socket 0x%p is free.\n",
+ new);
break;
}
new = (irnet_socket *) hashbin_get_next(irnet_server.list);
@@ -788,7 +788,7 @@ irnet_find_socket(irnet_socket * self)
/* Spin lock end */
spin_unlock_bh(&irnet_server.spinlock);
- DEXIT(IRDA_SERV_TRACE, " - new = 0x%X\n", (unsigned int) new);
+ DEXIT(IRDA_SERV_TRACE, " - new = 0x%p\n", new);
return new;
}
@@ -806,8 +806,8 @@ irnet_connect_socket(irnet_socket * server,
__u32 max_sdu_size,
__u8 max_header_size)
{
- DENTER(IRDA_SERV_TRACE, "(server=0x%X, new=0x%X)\n",
- (unsigned int) server, (unsigned int) new);
+ DENTER(IRDA_SERV_TRACE, "(server=0x%p, new=0x%p)\n",
+ server, new);
/* Now attach up the new socket */
new->tsap = irttp_dup(server->tsap, new);
@@ -878,7 +878,7 @@ static inline void
irnet_disconnect_server(irnet_socket * self,
struct sk_buff *skb)
{
- DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
/* Put the received packet in the black hole */
kfree_skb(skb);
@@ -1010,8 +1010,8 @@ irnet_data_indication(void * instance,
unsigned char * p;
int code = 0;
- DENTER(IRDA_TCB_TRACE, "(self/ap=0x%X, skb=0x%X)\n",
- (unsigned int) ap,(unsigned int) skb);
+ DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
+ ap, skb);
DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");
/* Check is ppp is ready to receive our packet */
@@ -1081,7 +1081,7 @@ irnet_disconnect_indication(void * instance,
int test_open;
int test_connect;
- DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
/* Don't care about it, but let's not leak it */
@@ -1171,7 +1171,7 @@ irnet_connect_confirm(void * instance,
{
irnet_socket * self = (irnet_socket *) instance;
- DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
/* Check if socket is closing down (via irda_irnet_destroy()) */
if(! test_bit(0, &self->ttp_connect))
@@ -1237,7 +1237,7 @@ irnet_flow_indication(void * instance,
irnet_socket * self = (irnet_socket *) instance;
LOCAL_FLOW oldflow = self->tx_flow;
- DENTER(IRDA_TCB_TRACE, "(self=0x%X, flow=%d)\n", (unsigned int) self, flow);
+ DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);
/* Update our state */
self->tx_flow = flow;
@@ -1278,7 +1278,7 @@ irnet_status_indication(void * instance,
{
irnet_socket * self = (irnet_socket *) instance;
- DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
/* We can only get this event if we are connected */
@@ -1320,9 +1320,9 @@ irnet_connect_indication(void * instance,
irnet_socket * server = &irnet_server.s;
irnet_socket * new = (irnet_socket *) NULL;
- DENTER(IRDA_TCB_TRACE, "(server=0x%X)\n", (unsigned int) server);
+ DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
- "Invalid instance (0x%X) !!!\n", (unsigned int) instance);
+ "Invalid instance (0x%p) !!!\n", instance);
DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");
/* Try to find the most appropriate IrNET socket */
@@ -1466,7 +1466,7 @@ irnet_getvalue_confirm(int result,
{
irnet_socket * self = (irnet_socket *) priv;
- DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
/* Check if already connected (via irnet_connect_socket())
@@ -1530,7 +1530,7 @@ irnet_discovervalue_confirm(int result,
irnet_socket * self = (irnet_socket *) priv;
__u8 dtsap_sel; /* TSAP we are looking for */
- DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
/* Check if already connected (via irnet_connect_socket())
@@ -1583,8 +1583,8 @@ irnet_discovervalue_confirm(int result,
self->iriap = NULL;
/* No more items : remove the log and signal termination */
- DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%X)\n",
- (unsigned int) self->discoveries);
+ DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
+ self->discoveries);
if(self->discoveries != NULL)
{
/* Cleanup our copy of the discovery log */
@@ -1643,9 +1643,9 @@ irnet_discovery_indication(discinfo_t * discovery,
{
irnet_socket * self = &irnet_server.s;
- DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
- "Invalid instance (0x%X) !!!\n", (unsigned int) priv);
+ "Invalid instance (0x%p) !!!\n", priv);
DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
discovery->info);
@@ -1674,9 +1674,9 @@ irnet_expiry_indication(discinfo_t * expiry,
{
irnet_socket * self = &irnet_server.s;
- DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+ DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
- "Invalid instance (0x%X) !!!\n", (unsigned int) priv);
+ "Invalid instance (0x%p) !!!\n", priv);
DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
expiry->info);
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 187871a4208a..b724fb087220 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -43,7 +43,7 @@ irnet_ctrl_write(irnet_socket * ap,
char * next; /* Next command to process */
int length; /* Length of current command */
- DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)\n", (unsigned int) ap, count);
+ DENTER(CTRL_TRACE, "(ap=0x%p, count=%Zd)\n", ap, count);
/* Check for overflow... */
DABORT(count >= IRNET_MAX_COMMAND, -ENOMEM,
@@ -58,7 +58,7 @@ irnet_ctrl_write(irnet_socket * ap,
/* Safe terminate the string */
command[count] = '\0';
- DEBUG(CTRL_INFO, "Command line received is ``%s'' (%d).\n",
+ DEBUG(CTRL_INFO, "Command line received is ``%s'' (%Zd).\n",
command, count);
/* Check every commands in the command line */
@@ -184,8 +184,8 @@ irnet_read_discovery_log(irnet_socket * ap,
{
int done_event = 0;
- DENTER(CTRL_TRACE, "(ap=0x%X, event=0x%X)\n",
- (unsigned int) ap, (unsigned int) event);
+ DENTER(CTRL_TRACE, "(ap=0x%p, event=0x%p)\n",
+ ap, event);
/* Test if we have some work to do or we have already finished */
if(ap->disco_number == -1)
@@ -205,8 +205,8 @@ irnet_read_discovery_log(irnet_socket * ap,
/* Check if the we got some results */
if(ap->discoveries == NULL)
ap->disco_number = -1;
- DEBUG(CTRL_INFO, "Got the log (0x%X), size is %d\n",
- (unsigned int) ap->discoveries, ap->disco_number);
+ DEBUG(CTRL_INFO, "Got the log (0x%p), size is %d\n",
+ ap->discoveries, ap->disco_number);
}
/* Check if we have more item to dump */
@@ -232,8 +232,8 @@ irnet_read_discovery_log(irnet_socket * ap,
if(ap->disco_index >= ap->disco_number)
{
/* No more items : remove the log and signal termination */
- DEBUG(CTRL_INFO, "Cleaning up log (0x%X)\n",
- (unsigned int) ap->discoveries);
+ DEBUG(CTRL_INFO, "Cleaning up log (0x%p)\n",
+ ap->discoveries);
if(ap->discoveries != NULL)
{
/* Cleanup our copy of the discovery log */
@@ -261,7 +261,7 @@ irnet_ctrl_read(irnet_socket * ap,
char event[64]; /* Max event is 61 char */
ssize_t ret = 0;
- DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)\n", (unsigned int) ap, count);
+ DENTER(CTRL_TRACE, "(ap=0x%p, count=%Zd)\n", ap, count);
/* Check if we can write an event out in one go */
DABORT(count < sizeof(event), -EOVERFLOW, CTRL_ERROR, "Buffer to small.\n");
@@ -307,7 +307,7 @@ irnet_ctrl_read(irnet_socket * ap,
if(ret != 0)
{
/* No, return the error code */
- DEXIT(CTRL_TRACE, " - ret %d\n", ret);
+ DEXIT(CTRL_TRACE, " - ret %Zd\n", ret);
return ret;
}
@@ -402,7 +402,7 @@ irnet_ctrl_poll(irnet_socket * ap,
{
unsigned int mask;
- DENTER(CTRL_TRACE, "(ap=0x%X)\n", (unsigned int) ap);
+ DENTER(CTRL_TRACE, "(ap=0x%p)\n", ap);
poll_wait(file, &irnet_events.rwait, wait);
mask = POLLOUT | POLLWRNORM;
@@ -439,7 +439,7 @@ dev_irnet_open(struct inode * inode,
struct irnet_socket * ap;
int err;
- DENTER(FS_TRACE, "(file=0x%X)\n", (unsigned int) file);
+ DENTER(FS_TRACE, "(file=0x%p)\n", file);
#ifdef SECURE_DEVIRNET
/* This could (should?) be enforced by the permissions on /dev/irnet. */
@@ -482,7 +482,7 @@ dev_irnet_open(struct inode * inode,
/* Put our stuff where we will be able to find it later */
file->private_data = ap;
- DEXIT(FS_TRACE, " - ap=0x%X\n", (unsigned int) ap);
+ DEXIT(FS_TRACE, " - ap=0x%p\n", ap);
return 0;
}
@@ -498,8 +498,8 @@ dev_irnet_close(struct inode * inode,
{
irnet_socket * ap = (struct irnet_socket *) file->private_data;
- DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)\n",
- (unsigned int) file, (unsigned int) ap);
+ DENTER(FS_TRACE, "(file=0x%p, ap=0x%p)\n",
+ file, ap);
DABORT(ap == NULL, 0, FS_ERROR, "ap is NULL !!!\n");
/* Detach ourselves */
@@ -535,8 +535,8 @@ dev_irnet_write(struct file * file,
{
irnet_socket * ap = (struct irnet_socket *) file->private_data;
- DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)\n",
- (unsigned int) file, (unsigned int) ap, count);
+ DPASS(FS_TRACE, "(file=0x%p, ap=0x%p, count=%Zd)\n",
+ file, ap, count);
DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n");
/* If we are connected to ppp_generic, let it handle the job */
@@ -559,8 +559,8 @@ dev_irnet_read(struct file * file,
{
irnet_socket * ap = (struct irnet_socket *) file->private_data;
- DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)\n",
- (unsigned int) file, (unsigned int) ap, count);
+ DPASS(FS_TRACE, "(file=0x%p, ap=0x%p, count=%Zd)\n",
+ file, ap, count);
DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n");
/* If we are connected to ppp_generic, let it handle the job */
@@ -581,8 +581,8 @@ dev_irnet_poll(struct file * file,
irnet_socket * ap = (struct irnet_socket *) file->private_data;
unsigned int mask;
- DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)\n",
- (unsigned int) file, (unsigned int) ap);
+ DENTER(FS_TRACE, "(file=0x%p, ap=0x%p)\n",
+ file, ap);
mask = POLLOUT | POLLWRNORM;
DABORT(ap == NULL, mask, FS_ERROR, "ap is NULL !!!\n");
@@ -611,8 +611,8 @@ dev_irnet_ioctl(struct inode * inode,
int err;
int val;
- DENTER(FS_TRACE, "(file=0x%X, ap=0x%X, cmd=0x%X)\n",
- (unsigned int) file, (unsigned int) ap, cmd);
+ DENTER(FS_TRACE, "(file=0x%p, ap=0x%p, cmd=0x%X)\n",
+ file, ap, cmd);
/* Basic checks... */
DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n");
@@ -777,8 +777,8 @@ irnet_prepare_skb(irnet_socket * ap,
int islcp; /* Protocol == LCP */
int needaddr; /* Need PPP address */
- DENTER(PPP_TRACE, "(ap=0x%X, skb=0x%X)\n",
- (unsigned int) ap, (unsigned int) skb);
+ DENTER(PPP_TRACE, "(ap=0x%p, skb=0x%p)\n",
+ ap, skb);
/* Extract PPP protocol from the frame */
data = skb->data;
@@ -845,8 +845,8 @@ ppp_irnet_send(struct ppp_channel * chan,
irnet_socket * self = (struct irnet_socket *) chan->private;
int ret;
- DENTER(PPP_TRACE, "(channel=0x%X, ap/self=0x%X)\n",
- (unsigned int) chan, (unsigned int) self);
+ DENTER(PPP_TRACE, "(channel=0x%p, ap/self=0x%p)\n",
+ chan, self);
/* Check if things are somewhat valid... */
DASSERT(self != NULL, 0, PPP_ERROR, "Self is NULL !!!\n");
@@ -949,8 +949,8 @@ ppp_irnet_ioctl(struct ppp_channel * chan,
int val;
u32 accm[8];
- DENTER(PPP_TRACE, "(channel=0x%X, ap=0x%X, cmd=0x%X)\n",
- (unsigned int) chan, (unsigned int) ap, cmd);
+ DENTER(PPP_TRACE, "(channel=0x%p, ap=0x%p, cmd=0x%X)\n",
+ chan, ap, cmd);
/* Basic checks... */
DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n");
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index bb51edc7d99b..cc9069395d96 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -1408,7 +1408,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
spin_lock_irqsave(&irttp->tsaps->hb_spinlock, flags);
/* Find the old instance */
- if (!hashbin_find(irttp->tsaps, (int) orig, NULL)) {
+ if (!hashbin_find(irttp->tsaps, (long) orig, NULL)) {
IRDA_DEBUG(0, "%s(), unable to find TSAP\n", __FUNCTION__);
spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
return NULL;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 20bb98d47b76..ef4ea4452c5b 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -9,6 +9,8 @@
* Authors: Martin Devera, <devik@cdi.cz>
*
* Credits (in time order) for older HTB versions:
+ * Stef Coene <stef.coene@docum.org>
+ * HTB support at LARTC mailing list
* Ondrej Kraus, <krauso@barr.cz>
* found missing INIT_QDISC(htb)
* Vladimir Smelhaus, Aamer Akhter, Bert Hubert
@@ -19,7 +21,7 @@
* created test case so that I was able to fix nasty bug
* and many others. thanks.
*
- * $Id: sch_htb.c,v 1.17 2003/01/29 09:22:18 devik Exp devik $
+ * $Id: sch_htb.c,v 1.20 2003/06/18 19:55:49 devik Exp devik $
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -71,7 +73,7 @@
#define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
-#define HTB_VER 0x3000a /* major must be matched with number suplied by TC as version */
+#define HTB_VER 0x3000c /* major must be matched with number suplied by TC as version */
#if HTB_VER >> 16 != TC_HTB_PROTOVER
#error "Mismatched sch_htb.c and pkt_sch.h"
@@ -217,6 +219,9 @@ struct htb_sched
/* time of nearest event per level (row) */
unsigned long near_ev_cache[TC_HTB_MAXDEPTH];
+ /* cached value of jiffies in dequeue */
+ unsigned long jiffies;
+
/* whether we hit non-work conserving class during this dequeue; we use */
int nwc_hit; /* this to disable mindelay complaint in dequeue */
@@ -336,7 +341,7 @@ static void htb_next_rb_node(struct rb_node **n);
static void htb_debug_dump (struct htb_sched *q)
{
int i,p;
- printk(KERN_DEBUG "htb*g j=%lu\n",jiffies);
+ printk(KERN_DEBUG "htb*g j=%lu lj=%lu\n",jiffies,q->jiffies);
/* rows */
for (i=TC_HTB_MAXDEPTH-1;i>=0;i--) {
printk(KERN_DEBUG "htb*r%d m=%x",i,q->row_mask[i]);
@@ -419,8 +424,8 @@ static void htb_add_to_wait_tree (struct htb_sched *q,
if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit())
printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint);
#endif
- cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay);
- if (cl->pq_key == jiffies)
+ cl->pq_key = q->jiffies + PSCHED_US2JIFFIE(delay);
+ if (cl->pq_key == q->jiffies)
cl->pq_key++;
/* update the nearest event cache */
@@ -587,7 +592,7 @@ htb_class_mode(struct htb_class *cl,long *diff)
long toks;
if ((toks = (cl->ctokens + *diff)) < (
-#ifdef HTB_HYSTERESIS
+#if HTB_HYSTERESIS
cl->cmode != HTB_CANT_SEND ? -cl->cbuffer :
#endif
0)) {
@@ -595,7 +600,7 @@ htb_class_mode(struct htb_class *cl,long *diff)
return HTB_CANT_SEND;
}
if ((toks = (cl->tokens + *diff)) >= (
-#ifdef HTB_HYSTERESIS
+#if HTB_HYSTERESIS
cl->cmode == HTB_CAN_SEND ? -cl->buffer :
#endif
0))
@@ -798,7 +803,7 @@ static void htb_charge_class(struct htb_sched *q,struct htb_class *cl,
cl->classid, diff,
(unsigned long long) q->now,
(unsigned long long) cl->t_c,
- jiffies);
+ q->jiffies);
diff = 1000;
}
#endif
@@ -841,6 +846,7 @@ static void htb_charge_class(struct htb_sched *q,struct htb_class *cl,
*
* Scans event queue for pending events and applies them. Returns jiffies to
* next pending event (0 for no event in pq).
+ * Note: Aplied are events whose have cl->pq_key <= jiffies.
*/
static long htb_do_events(struct htb_sched *q,int level)
{
@@ -855,9 +861,9 @@ static long htb_do_events(struct htb_sched *q,int level)
while (p->rb_left) p = p->rb_left;
cl = rb_entry(p, struct htb_class, pq_node);
- if (cl->pq_key - (jiffies+1) < 0x80000000) {
- HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - jiffies);
- return cl->pq_key - jiffies;
+ if (cl->pq_key - (q->jiffies+1) < 0x80000000) {
+ HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - q->jiffies);
+ return cl->pq_key - q->jiffies;
}
htb_safe_rb_erase(p,q->wait_pq+level);
diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
@@ -868,7 +874,7 @@ static long htb_do_events(struct htb_sched *q,int level)
cl->classid, diff,
(unsigned long long) q->now,
(unsigned long long) cl->t_c,
- jiffies);
+ q->jiffies);
diff = 1000;
}
#endif
@@ -975,7 +981,8 @@ static void htb_delay_by(struct Qdisc *sch,long delay)
printk(KERN_INFO "HTB delay %ld > 5sec\n", delay);
delay = 5*HZ;
}
- mod_timer(&q->timer, jiffies + delay);
+ /* why don't use jiffies here ? because expires can be in past */
+ mod_timer(&q->timer, q->jiffies + delay);
sch->flags |= TCQ_F_THROTTLED;
sch->stats.overlimits++;
HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay);
@@ -991,6 +998,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
int evs_used = 0;
#endif
+ q->jiffies = jiffies;
HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue),
sch->q.qlen);
@@ -1010,14 +1018,14 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
/* common case optimization - skip event handler quickly */
int m;
long delay;
- if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
+ if (q->jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
delay = htb_do_events(q,level);
- q->near_ev_cache[level] += delay ? delay : HZ;
+ q->near_ev_cache[level] = q->jiffies + (delay ? delay : HZ);
#ifdef HTB_DEBUG
evs_used++;
#endif
} else
- delay = q->near_ev_cache[level] - jiffies;
+ delay = q->near_ev_cache[level] - q->jiffies;
if (delay && min_delay > delay)
min_delay = delay;
@@ -1036,8 +1044,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
#ifdef HTB_DEBUG
if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) {
if (min_delay == LONG_MAX) {
- printk(KERN_ERR "HTB: dequeue bug (%d), report it please !\n",
- evs_used);
+ printk(KERN_ERR "HTB: dequeue bug (%d,%lu,%lu), report it please !\n",
+ evs_used,q->jiffies,jiffies);
htb_debug_dump(q);
} else
printk(KERN_WARNING "HTB: mindelay=%ld, some class has "
@@ -1046,7 +1054,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
#endif
htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay);
fin:
- HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb);
+ HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,q->jiffies,skb);
return skb;
}
@@ -1409,7 +1417,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
parent = parentid == TC_H_ROOT ? NULL : htb_find (parentid,sch);
hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]);
- HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
+ HTB_DBG(0,1,"htb_chg cl=%p(%X), clid=%X, parid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,classid,parentid,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]);
ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]);
if (!rtab || !ctab) goto failure;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index d9ccb6d1db0e..79ebf10e03d9 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -20,6 +20,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
+#include <linux/suspend.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/xprt.h>
@@ -969,6 +970,8 @@ rpciod(void *ptr)
flush_signals(current);
}
__rpc_schedule();
+ if (current->flags & PF_FREEZE)
+ refrigerator(PF_IOTHREAD);
if (++rounds >= 64) { /* safeguard */
schedule();
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 8f8afaa113c9..122869868554 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -492,7 +492,7 @@ static void conf(struct menu *menu)
switch (type) {
case 'm':
if (single_menu_mode)
- submenu->data = (void *) !submenu->data;
+ submenu->data = (void *) (long) !submenu->data;
else
conf(submenu);
break;
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 10f782d8fd13..7540dc2a9bcb 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2070,7 +2070,7 @@ static void snd_korg1212_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *b
snd_iprintf(buffer, korg1212->card->longname);
snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1);
snd_iprintf(buffer, "\nGeneral settings\n");
- snd_iprintf(buffer, " period size: %d bytes\n", K1212_PERIOD_BYTES);
+ snd_iprintf(buffer, " period size: %Zd bytes\n", K1212_PERIOD_BYTES);
snd_iprintf(buffer, " clock mode: %s\n", clockSourceName[korg1212->clkSrcRate] );
snd_iprintf(buffer, " left ADC Sens: %d\n", korg1212->leftADCInSens );
snd_iprintf(buffer, " right ADC Sens: %d\n", korg1212->rightADCInSens );
@@ -2336,7 +2336,7 @@ static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci,
korg1212->sharedBufferPhy = (unsigned long)phys_addr;
if (korg1212->sharedBufferPtr == NULL) {
- snd_printk(KERN_ERR "can not allocate shared buffer memory (%d bytes)\n", sizeof(KorgSharedBuffer));
+ snd_printk(KERN_ERR "can not allocate shared buffer memory (%Zd bytes)\n", sizeof(KorgSharedBuffer));
return -ENOMEM;
}
@@ -2385,9 +2385,12 @@ static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci,
korg1212->dspCodeSize = sizeof (dspCode);
- korg1212->VolumeTablePhy = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->volumeData;
- korg1212->RoutingTablePhy = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->routeData;
- korg1212->AdatTimeCodePhy = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->AdatTimeCode;
+ korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
+ offsetof(KorgSharedBuffer, volumeData);
+ korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
+ offsetof(KorgSharedBuffer, routeData);
+ korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
+ offsetof(KorgSharedBuffer, AdatTimeCode);
korg1212->dspMemPtr = snd_malloc_pci_pages(korg1212->pci, korg1212->dspCodeSize, &phys_addr);
korg1212->dspMemPhy = (u32)phys_addr;
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 6f17ea0c1fd3..361dc0e79497 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -56,7 +56,7 @@ static void cpio_trailer(void)
const char *name = "TRAILER!!!";
sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
+ "%08X%08X%08X%08X%08X%08ZX%08X",
"070701", /* magic */
0, /* ino */
0, /* mode */
@@ -87,7 +87,7 @@ static void cpio_mkdir(const char *name, unsigned int mode,
time_t mtime = time(NULL);
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
+ "%08X%08X%08X%08X%08X%08ZX%08X",
"070701", /* magic */
ino++, /* ino */
S_IFDIR | mode, /* mode */
@@ -119,7 +119,7 @@ static void cpio_mknod(const char *name, unsigned int mode,
mode |= S_IFCHR;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
+ "%08X%08X%08X%08X%08X%08ZX%08X",
"070701", /* magic */
ino++, /* ino */
mode, /* mode */
@@ -176,7 +176,7 @@ void cpio_mkfile(const char *filename, const char *location,
}
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
- "%08X%08X%08X%08X%08X%08X%08X",
+ "%08X%08X%08X%08X%08X%08ZX%08X",
"070701", /* magic */
ino++, /* ino */
mode, /* mode */