summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-06-21 16:21:20 -0700
committerTony Luck <tony.luck@intel.com>2005-06-21 16:21:20 -0700
commit29516d75a0b09e0a0328dd55c98a342515c9615a (patch)
tree4b03326311958ad6de82653a1caf289ad8c38538
parent4ea78729b8dbfc400fe165a57b90a394a7275a54 (diff)
parent4a4f8fdba6f5a34ca90f426021e17491a30202da (diff)
downloadlinux-29516d75a0b09e0a0328dd55c98a342515c9615a.tar.gz
linux-29516d75a0b09e0a0328dd55c98a342515c9615a.tar.bz2
linux-29516d75a0b09e0a0328dd55c98a342515c9615a.zip
Auto merge with /home/aegl/GIT/linus
-rw-r--r--Documentation/DocBook/kernel-api.tmpl1
-rw-r--r--Documentation/driver-model/device.txt8
-rw-r--r--Documentation/driver-model/driver.txt51
-rw-r--r--Documentation/filesystems/sysfs.txt2
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/common/amba.c2
-rw-r--r--arch/arm/common/dmabounce.c18
-rw-r--r--arch/arm/common/sharpsl_param.c2
-rw-r--r--arch/arm/configs/enp2611_defconfig8
-rw-r--r--arch/arm/configs/ixdp2400_defconfig8
-rw-r--r--arch/arm/configs/ixdp2401_defconfig8
-rw-r--r--arch/arm/configs/ixdp2800_defconfig8
-rw-r--r--arch/arm/configs/ixdp2801_defconfig8
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/arch.c46
-rw-r--r--arch/arm/kernel/ecard.c12
-rw-r--r--arch/arm/kernel/smp.c3
-rw-r--r--arch/arm/lib/ashldi3.c47
-rw-r--r--arch/arm/lib/ashrdi3.c48
-rw-r--r--arch/arm/lib/gcclib.h27
-rw-r--r--arch/arm/lib/longlong.h68
-rw-r--r--arch/arm/lib/lshrdi3.c47
-rw-r--r--arch/arm/lib/muldi3.c31
-rw-r--r--arch/arm/lib/ucmpdi2.c30
-rw-r--r--arch/arm/lib/udivdi3.c372
-rw-r--r--arch/arm/mach-aaec2000/Kconfig11
-rw-r--r--arch/arm/mach-aaec2000/Makefile9
-rw-r--r--arch/arm/mach-aaec2000/aaed2000.c48
-rw-r--r--arch/arm/mach-aaec2000/core.c157
-rw-r--r--arch/arm/mach-aaec2000/core.h16
-rw-r--r--arch/arm/mach-integrator/core.c1
-rw-r--r--arch/arm/mach-ixp2000/core.c34
-rw-r--r--arch/arm/mach-versatile/Makefile1
-rw-r--r--arch/arm/mach-versatile/core.c14
-rw-r--r--arch/arm/mach-versatile/pci.c360
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/mm/copypage-v6.c6
-rw-r--r--arch/arm/mm/fault-armv.c31
-rw-r--r--arch/arm/mm/flush.c44
-rw-r--r--arch/arm/mm/ioremap.c47
-rw-r--r--arch/arm26/kernel/ecard.c10
-rw-r--r--arch/i386/kernel/cpuid.c22
-rw-r--r--arch/i386/kernel/msr.c22
-rw-r--r--arch/ia64/sn/kernel/tiocx.c25
-rw-r--r--arch/parisc/kernel/drivers.c2
-rw-r--r--arch/ppc/kernel/pci.c2
-rw-r--r--arch/ppc/syslib/ocp.c2
-rw-r--r--arch/ppc/syslib/of_device.c2
-rw-r--r--arch/ppc64/kernel/iommu.c3
-rw-r--r--arch/ppc64/kernel/of_device.c2
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c9
-rw-r--r--arch/ppc64/kernel/pci.c2
-rw-r--r--arch/ppc64/kernel/rtasd.c4
-rw-r--r--arch/ppc64/kernel/vio.c4
-rw-r--r--drivers/acpi/scan.c4
-rw-r--r--drivers/base/Makefile4
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/bus.c299
-rw-r--r--drivers/base/class.c194
-rw-r--r--drivers/base/class_simple.c199
-rw-r--r--drivers/base/core.c62
-rw-r--r--drivers/base/dd.c248
-rw-r--r--drivers/base/dmapool.c2
-rw-r--r--drivers/base/driver.c39
-rw-r--r--drivers/base/node.c20
-rw-r--r--drivers/base/power/resume.c8
-rw-r--r--drivers/base/power/suspend.c16
-rw-r--r--drivers/base/power/sysfs.c4
-rw-r--r--drivers/base/sys.c4
-rw-r--r--drivers/block/aoe/aoechr.c10
-rw-r--r--drivers/block/as-iosched.c4
-rw-r--r--drivers/block/cfq-iosched.c4
-rw-r--r--drivers/block/deadline-iosched.c4
-rw-r--r--drivers/block/genhd.c2
-rw-r--r--drivers/block/ll_rw_blk.c4
-rw-r--r--drivers/block/paride/pg.c14
-rw-r--r--drivers/block/paride/pt.c20
-rw-r--r--drivers/block/ub.c2
-rw-r--r--drivers/char/dsp56k.c14
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c30
-rw-r--r--drivers/char/hvcs.c14
-rw-r--r--drivers/char/ip2main.c24
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c14
-rw-r--r--drivers/char/istallion.c10
-rw-r--r--drivers/char/lp.c12
-rw-r--r--drivers/char/mbcs.c4
-rw-r--r--drivers/char/mem.c7
-rw-r--r--drivers/char/misc.c16
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/ppdev.c12
-rw-r--r--drivers/char/raw.c18
-rw-r--r--drivers/char/snsc.c7
-rw-r--r--drivers/char/stallion.c10
-rw-r--r--drivers/char/tipar.c14
-rw-r--r--drivers/char/tpm/tpm.c6
-rw-r--r--drivers/char/tty_io.c16
-rw-r--r--drivers/char/vc_screen.c16
-rw-r--r--drivers/char/viotape.c16
-rw-r--r--drivers/char/watchdog/ixp2000_wdt.c7
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/dio/dio-sysfs.c10
-rw-r--r--drivers/eisa/eisa-bus.c4
-rw-r--r--drivers/fc4/fc.c6
-rw-r--r--drivers/firmware/edd.c2
-rw-r--r--drivers/firmware/efivars.c4
-rw-r--r--drivers/i2c/chips/adm1021.c6
-rw-r--r--drivers/i2c/chips/adm1025.c28
-rw-r--r--drivers/i2c/chips/adm1026.c572
-rw-r--r--drivers/i2c/chips/adm1031.c44
-rw-r--r--drivers/i2c/chips/asb100.c46
-rw-r--r--drivers/i2c/chips/ds1621.c6
-rw-r--r--drivers/i2c/chips/fscher.c8
-rw-r--r--drivers/i2c/chips/fscpos.c16
-rw-r--r--drivers/i2c/chips/gl518sm.c12
-rw-r--r--drivers/i2c/chips/gl520sm.c8
-rw-r--r--drivers/i2c/chips/it87.c50
-rw-r--r--drivers/i2c/chips/lm63.c24
-rw-r--r--drivers/i2c/chips/lm75.c4
-rw-r--r--drivers/i2c/chips/lm77.c14
-rw-r--r--drivers/i2c/chips/lm78.c36
-rw-r--r--drivers/i2c/chips/lm80.c20
-rw-r--r--drivers/i2c/chips/lm83.c6
-rw-r--r--drivers/i2c/chips/lm85.c72
-rw-r--r--drivers/i2c/chips/lm87.c46
-rw-r--r--drivers/i2c/chips/lm90.c12
-rw-r--r--drivers/i2c/chips/lm92.c14
-rw-r--r--drivers/i2c/chips/max1619.c6
-rw-r--r--drivers/i2c/chips/pc87360.c68
-rw-r--r--drivers/i2c/chips/pcf8574.c6
-rw-r--r--drivers/i2c/chips/pcf8591.c10
-rw-r--r--drivers/i2c/chips/sis5595.c34
-rw-r--r--drivers/i2c/chips/smsc47b397.c4
-rw-r--r--drivers/i2c/chips/smsc47m1.c20
-rw-r--r--drivers/i2c/chips/via686a.c32
-rw-r--r--drivers/i2c/chips/w83627hf.c56
-rw-r--r--drivers/i2c/chips/w83781d.c52
-rw-r--r--drivers/i2c/chips/w83l785ts.c4
-rw-r--r--drivers/i2c/i2c-core.c4
-rw-r--r--drivers/ieee1394/dv1394.c6
-rw-r--r--drivers/ieee1394/ieee1394_core.c8
-rw-r--r--drivers/ieee1394/ieee1394_core.h3
-rw-r--r--drivers/ieee1394/nodemgr.c27
-rw-r--r--drivers/ieee1394/raw1394.c10
-rw-r--r--drivers/ieee1394/sbp2.c2
-rw-r--r--drivers/ieee1394/video1394.c4
-rw-r--r--drivers/infiniband/core/sysfs.c122
-rw-r--r--drivers/input/evdev.c9
-rw-r--r--drivers/input/gameport/gameport.c4
-rw-r--r--drivers/input/input.c10
-rw-r--r--drivers/input/joydev.c8
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/mouse/psmouse.h4
-rw-r--r--drivers/input/mousedev.c16
-rw-r--r--drivers/input/serio/serio.c16
-rw-r--r--drivers/input/tsdev.c9
-rw-r--r--drivers/isdn/capi/capi.c14
-rw-r--r--drivers/macintosh/adb.c9
-rw-r--r--drivers/macintosh/therm_adt746x.c11
-rw-r--r--drivers/macintosh/therm_pm72.c4
-rw-r--r--drivers/macintosh/therm_windtunnel.c4
-rw-r--r--drivers/mca/mca-bus.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c13
-rw-r--r--drivers/message/fusion/mptscsih.c2
-rw-r--r--drivers/message/fusion/mptscsih.h2
-rw-r--r--drivers/mmc/mmc_sysfs.c2
-rw-r--r--drivers/net/ppp_generic.c14
-rw-r--r--drivers/net/wan/cosa.c12
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c4
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c4
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c2
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c4
-rw-r--r--drivers/pci/pci-driver.c26
-rw-r--r--drivers/pci/pci-sysfs.c21
-rw-r--r--drivers/pci/pcie/portdrv_core.c139
-rw-r--r--drivers/pcmcia/ds.c4
-rw-r--r--drivers/pnp/card.c4
-rw-r--r--drivers/pnp/driver.c12
-rw-r--r--drivers/pnp/interface.c8
-rw-r--r--drivers/s390/block/dasd_devmap.c10
-rw-r--r--drivers/s390/block/dcssblk.c24
-rw-r--r--drivers/s390/char/raw3270.c6
-rw-r--r--drivers/s390/char/tape_class.c10
-rw-r--r--drivers/s390/char/tape_core.c10
-rw-r--r--drivers/s390/char/vmlogrdr.c22
-rw-r--r--drivers/s390/cio/ccwgroup.c6
-rw-r--r--drivers/s390/cio/chsc.c6
-rw-r--r--drivers/s390/cio/cmf.c12
-rw-r--r--drivers/s390/cio/device.c14
-rw-r--r--drivers/s390/net/claw.c40
-rw-r--r--drivers/s390/net/ctcmain.c18
-rw-r--r--drivers/s390/net/lcs.c10
-rw-r--r--drivers/s390/net/netiucv.c44
-rw-r--r--drivers/s390/net/qeth_sys.c126
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c2
-rw-r--r--drivers/s390/scsi/zfcp_sysfs_adapter.c10
-rw-r--r--drivers/s390/scsi/zfcp_sysfs_port.c10
-rw-r--r--drivers/s390/scsi/zfcp_sysfs_unit.c6
-rw-r--r--drivers/scsi/53c700.c2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c8
-rw-r--r--drivers/scsi/arm/eesox.c4
-rw-r--r--drivers/scsi/arm/powertec.c4
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c4
-rw-r--r--drivers/scsi/osst.c10
-rw-r--r--drivers/scsi/scsi_sysfs.c42
-rw-r--r--drivers/scsi/scsi_transport_spi.c16
-rw-r--r--drivers/scsi/sg.c14
-rw-r--r--drivers/scsi/st.c28
-rw-r--r--drivers/sh/superhyway/superhyway-sysfs.c2
-rw-r--r--drivers/usb/core/devices.c2
-rw-r--r--drivers/usb/core/file.c13
-rw-r--r--drivers/usb/core/hcd.c61
-rw-r--r--drivers/usb/core/sysfs.c26
-rw-r--r--drivers/usb/core/usb.c53
-rw-r--r--drivers/usb/gadget/dummy_hcd.c4
-rw-r--r--drivers/usb/gadget/file_storage.c8
-rw-r--r--drivers/usb/gadget/net2280.c6
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c2
-rw-r--r--drivers/usb/host/ehci-dbg.c10
-rw-r--r--drivers/usb/host/ohci-dbg.c10
-rw-r--r--drivers/usb/input/aiptek.c78
-rw-r--r--drivers/usb/misc/cytherm.c20
-rw-r--r--drivers/usb/misc/phidgetkit.c14
-rw-r--r--drivers/usb/misc/phidgetservo.c4
-rw-r--r--drivers/usb/misc/usbled.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c6
-rw-r--r--drivers/usb/storage/scsiglue.c4
-rw-r--r--drivers/video/fbmem.c10
-rw-r--r--drivers/video/gbefb.c4
-rw-r--r--drivers/video/w100fb.c12
-rw-r--r--drivers/w1/w1.c16
-rw-r--r--drivers/w1/w1_family.h4
-rw-r--r--drivers/w1/w1_smem.c8
-rw-r--r--drivers/w1/w1_therm.c8
-rw-r--r--drivers/zorro/zorro-sysfs.c4
-rw-r--r--fs/Kconfig50
-rw-r--r--fs/coda/psdev.c18
-rw-r--r--fs/debugfs/file.c67
-rw-r--r--fs/jfs/acl.c6
-rw-r--r--fs/jfs/file.c9
-rw-r--r--fs/jfs/inode.c11
-rw-r--r--fs/jfs/jfs_debug.c10
-rw-r--r--fs/jfs/jfs_debug.h15
-rw-r--r--fs/jfs/jfs_dmap.c9
-rw-r--r--fs/jfs/jfs_dtree.c3
-rw-r--r--fs/jfs/jfs_extent.c7
-rw-r--r--fs/jfs/jfs_imap.c6
-rw-r--r--fs/jfs/jfs_inode.c1
-rw-r--r--fs/jfs/jfs_inode.h19
-rw-r--r--fs/jfs/jfs_logmgr.c14
-rw-r--r--fs/jfs/jfs_logmgr.h2
-rw-r--r--fs/jfs/jfs_metapage.c6
-rw-r--r--fs/jfs/jfs_metapage.h6
-rw-r--r--fs/jfs/jfs_superblock.h11
-rw-r--r--fs/jfs/jfs_txnmgr.c40
-rw-r--r--fs/jfs/jfs_txnmgr.h52
-rw-r--r--fs/jfs/namei.c28
-rw-r--r--fs/jfs/super.c37
-rw-r--r--fs/jfs/symlink.c3
-rw-r--r--fs/jfs/xattr.c6
-rw-r--r--fs/libfs.c100
-rw-r--r--fs/sysfs/bin.c4
-rw-r--r--fs/sysfs/dir.c26
-rw-r--r--fs/sysfs/file.c6
-rw-r--r--fs/sysfs/inode.c102
-rw-r--r--fs/sysfs/mount.c4
-rw-r--r--fs/sysfs/symlink.c8
-rw-r--r--fs/sysfs/sysfs.h4
-rw-r--r--include/asm-arm/arch-aaec2000/aaec2000.h151
-rw-r--r--include/asm-arm/arch-aaec2000/debug-macro.S36
-rw-r--r--include/asm-arm/arch-aaec2000/dma.h17
-rw-r--r--include/asm-arm/arch-aaec2000/entry-macro.S33
-rw-r--r--include/asm-arm/arch-aaec2000/hardware.h49
-rw-r--r--include/asm-arm/arch-aaec2000/io.h19
-rw-r--r--include/asm-arm/arch-aaec2000/irqs.h46
-rw-r--r--include/asm-arm/arch-aaec2000/memory.h73
-rw-r--r--include/asm-arm/arch-aaec2000/param.h15
-rw-r--r--include/asm-arm/arch-aaec2000/system.h24
-rw-r--r--include/asm-arm/arch-aaec2000/timex.h18
-rw-r--r--include/asm-arm/arch-aaec2000/uncompress.h47
-rw-r--r--include/asm-arm/arch-aaec2000/vmalloc.h16
-rw-r--r--include/asm-arm/arch-ixp2000/ixp2000-regs.h1
-rw-r--r--include/asm-arm/arch-versatile/hardware.h27
-rw-r--r--include/asm-arm/arch-versatile/io.h2
-rw-r--r--include/asm-arm/arch-versatile/platform.h17
-rw-r--r--include/asm-arm/cacheflush.h3
-rw-r--r--include/asm-arm/io.h27
-rw-r--r--include/asm-ppc/ocp.h2
-rw-r--r--include/linux/atalk.h26
-rw-r--r--include/linux/device.h64
-rw-r--r--include/linux/fs.h46
-rw-r--r--include/linux/i2c-sysfs.h36
-rw-r--r--include/linux/input.h2
-rw-r--r--include/linux/klist.h55
-rw-r--r--include/linux/kobject.h8
-rw-r--r--include/linux/netfilter_ipv4.h6
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_core.h3
-rw-r--r--include/linux/netfilter_ipv4/ip_nat.h3
-rw-r--r--include/linux/netfilter_ipv4/listhelp.h1
-rw-r--r--include/linux/netfilter_ipv4/lockhelp.h129
-rw-r--r--include/linux/netlink.h3
-rw-r--r--include/linux/node.h1
-rw-r--r--include/linux/pfkeyv2.h1
-rw-r--r--include/linux/skbuff.h13
-rw-r--r--include/linux/sysfs.h15
-rw-r--r--include/linux/usb.h5
-rw-r--r--include/linux/xfrm.h1
-rw-r--r--include/net/ax25.h2
-rw-r--r--include/net/ip6_fib.h9
-rw-r--r--include/net/ip6_route.h9
-rw-r--r--include/net/ip_fib.h14
-rw-r--r--include/net/sctp/command.h8
-rw-r--r--include/net/sctp/constants.h7
-rw-r--r--include/net/sctp/sctp.h17
-rw-r--r--include/net/sctp/sm.h8
-rw-r--r--include/net/sctp/structs.h41
-rw-r--r--include/net/sctp/user.h3
-rw-r--r--include/net/xfrm.h4
-rw-r--r--kernel/params.c4
-rw-r--r--lib/Makefile7
-rw-r--r--lib/klist.c265
-rw-r--r--lib/kobject.c2
-rw-r--r--lib/kobject_uevent.c6
-rw-r--r--net/appletalk/aarp.c2
-rw-r--r--net/appletalk/ddp.c2
-rw-r--r--net/bridge/br_forward.c3
-rw-r--r--net/bridge/br_input.c4
-rw-r--r--net/bridge/br_netfilter.c38
-rw-r--r--net/core/netfilter.c138
-rw-r--r--net/core/skbuff.c6
-rw-r--r--net/ipv4/Kconfig26
-rw-r--r--net/ipv4/Makefile4
-rw-r--r--net/ipv4/af_inet.c12
-rw-r--r--net/ipv4/ah4.c2
-rw-r--r--net/ipv4/esp4.c2
-rw-r--r--net/ipv4/fib_frontend.c55
-rw-r--r--net/ipv4/fib_trie.c2454
-rw-r--r--net/ipv4/ip_input.c5
-rw-r--r--net/ipv4/ip_output.c11
-rw-r--r--net/ipv4/ipcomp.c11
-rw-r--r--net/ipv4/ipmr.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_xmit.c1
-rw-r--r--net/ipv4/netfilter/arp_tables.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c7
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c107
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c7
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c7
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_sctp.c23
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c27
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_udp.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c22
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c32
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c13
-rw-r--r--net/ipv4/netfilter/ip_nat_rule.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c5
-rw-r--r--net/ipv4/netfilter/ip_tables.c1
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c49
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c10
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c13
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c15
-rw-r--r--net/ipv4/netfilter/ipt_hashlimit.c17
-rw-r--r--net/ipv4/netfilter/ipt_helper.c4
-rw-r--r--net/ipv4/xfrm4_output.c8
-rw-r--r--net/ipv4/xfrm4_state.c9
-rw-r--r--net/ipv4/xfrm4_tunnel.c2
-rw-r--r--net/ipv6/addrconf.c14
-rw-r--r--net/ipv6/ah6.c2
-rw-r--r--net/ipv6/anycast.c4
-rw-r--r--net/ipv6/esp6.c2
-rw-r--r--net/ipv6/ip6_fib.c19
-rw-r--r--net/ipv6/ip6_output.c3
-rw-r--r--net/ipv6/ipcomp6.c9
-rw-r--r--net/ipv6/ipv6_sockglue.c5
-rw-r--r--net/ipv6/mcast.c68
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c1
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c54
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c6
-rw-r--r--net/ipv6/route.c78
-rw-r--r--net/ipv6/xfrm6_tunnel.c2
-rw-r--r--net/key/af_key.c16
-rw-r--r--net/sctp/associola.c151
-rw-r--r--net/sctp/endpointola.c1
-rw-r--r--net/sctp/input.c2
-rw-r--r--net/sctp/outqueue.c11
-rw-r--r--net/sctp/sm_make_chunk.c20
-rw-r--r--net/sctp/sm_sideeffect.c105
-rw-r--r--net/sctp/sm_statefuns.c148
-rw-r--r--net/sctp/sm_statetable.c6
-rw-r--r--net/sctp/socket.c405
-rw-r--r--net/sctp/transport.c4
-rw-r--r--net/xfrm/xfrm_policy.c1
-rw-r--r--net/xfrm/xfrm_state.c37
-rw-r--r--net/xfrm/xfrm_user.c9
-rw-r--r--security/seclvl.c4
-rw-r--r--sound/core/sound.c6
-rw-r--r--sound/oss/soundcard.c19
-rw-r--r--sound/sound_core.c10
399 files changed, 8472 insertions, 4117 deletions
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 757cef8f8491..bb6a0106be11 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -338,7 +338,6 @@ X!Earch/i386/kernel/mca.c
X!Iinclude/linux/device.h
-->
!Edrivers/base/driver.c
-!Edrivers/base/class_simple.c
!Edrivers/base/core.c
!Edrivers/base/firmware_class.c
!Edrivers/base/transport_class.c
diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.txt
index 58cc5dc8fd3e..a05ec50f8004 100644
--- a/Documentation/driver-model/device.txt
+++ b/Documentation/driver-model/device.txt
@@ -76,6 +76,14 @@ driver_data: Driver-specific data.
platform_data: Platform data specific to the device.
+ Example: for devices on custom boards, as typical of embedded
+ and SOC based hardware, Linux often uses platform_data to point
+ to board-specific structures describing devices and how they
+ are wired. That can include what ports are available, chip
+ variants, which GPIO pins act in what additional roles, and so
+ on. This shrinks the "Board Support Packages" (BSPs) and
+ minimizes board-specific #ifdefs in drivers.
+
current_state: Current power state of the device.
saved_state: Pointer to saved state of the device. This is usable by
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
index 6031a68dd3f5..fabaca1ab1b0 100644
--- a/Documentation/driver-model/driver.txt
+++ b/Documentation/driver-model/driver.txt
@@ -5,21 +5,17 @@ struct device_driver {
char * name;
struct bus_type * bus;
- rwlock_t lock;
- atomic_t refcount;
-
- list_t bus_list;
+ struct completion unloaded;
+ struct kobject kobj;
list_t devices;
- struct driver_dir_entry dir;
+ struct module *owner;
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state, u32 level);
int (*resume) (struct device * dev, u32 level);
-
- void (*release) (struct device_driver * drv);
};
@@ -51,7 +47,6 @@ being converted completely to the new model.
static struct device_driver eepro100_driver = {
.name = "eepro100",
.bus = &pci_bus_type,
- .devclass = &ethernet_devclass, /* when it's implemented */
.probe = eepro100_probe,
.remove = eepro100_remove,
@@ -85,7 +80,6 @@ static struct pci_driver eepro100_driver = {
.driver = {
.name = "eepro100",
.bus = &pci_bus_type,
- .devclass = &ethernet_devclass, /* when it's implemented */
.probe = eepro100_probe,
.remove = eepro100_remove,
.suspend = eepro100_suspend,
@@ -166,27 +160,32 @@ Callbacks
int (*probe) (struct device * dev);
-probe is called to verify the existence of a certain type of
-hardware. This is called during the driver binding process, after the
-bus has verified that the device ID of a device matches one of the
-device IDs supported by the driver.
-
-This callback only verifies that there actually is supported hardware
-present. It may allocate a driver-specific structure, but it should
-not do any initialization of the hardware itself. The device-specific
-structure may be stored in the device's driver_data field.
-
- int (*init) (struct device * dev);
-
-init is called during the binding stage. It is called after probe has
-successfully returned and the device has been registered with its
-class. It is responsible for initializing the hardware.
+The probe() entry is called in task context, with the bus's rwsem locked
+and the driver partially bound to the device. Drivers commonly use
+container_of() to convert "dev" to a bus-specific type, both in probe()
+and other routines. That type often provides device resource data, such
+as pci_dev.resource[] or platform_device.resources, which is used in
+addition to dev->platform_data to initialize the driver.
+
+This callback holds the driver-specific logic to bind the driver to a
+given device. That includes verifying that the device is present, that
+it's a version the driver can handle, that driver data structures can
+be allocated and initialized, and that any hardware can be initialized.
+Drivers often store a pointer to their state with dev_set_drvdata().
+When the driver has successfully bound itself to that device, then probe()
+returns zero and the driver model code will finish its part of binding
+the driver to that device.
+
+A driver's probe() may return a negative errno value to indicate that
+the driver did not bind to this device, in which case it should have
+released all reasources it allocated.
int (*remove) (struct device * dev);
-remove is called to dissociate a driver with a device. This may be
+remove is called to unbind a driver from a device. This may be
called if a device is physically removed from the system, if the
-driver module is being unloaded, or during a reboot sequence.
+driver module is being unloaded, during a reboot sequence, or
+in other cases.
It is up to the driver to determine if the device is present or
not. It should free any resources allocated specifically for the
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index 60f6c2c4d477..dc276598a65a 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -214,7 +214,7 @@ Other notes:
A very simple (and naive) implementation of a device attribute is:
-static ssize_t show_name(struct device * dev, char * buf)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%s\n",dev->name);
}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 475950c8a831..ee8a9ad7bbd9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -67,10 +67,6 @@ config GENERIC_BUST_SPINLOCK
config GENERIC_ISA_DMA
bool
-config GENERIC_IOMAP
- bool
- default y
-
config FIQ
bool
@@ -202,6 +198,11 @@ config ARCH_H720X
help
This enables support for systems based on the Hynix HMS720x
+config ARCH_AAEC2000
+ bool "Agilent AAEC-2000 based"
+ help
+ This enables support for systems based on the Agilent AAEC-2000
+
endchoice
source "arch/arm/mach-clps711x/Kconfig"
@@ -234,6 +235,8 @@ source "arch/arm/mach-h720x/Kconfig"
source "arch/arm/mach-versatile/Kconfig"
+source "arch/arm/mach-aaec2000/Kconfig"
+
# Definitions to make life easier
config ARCH_ACORN
bool
@@ -277,7 +280,7 @@ config ISA_DMA_API
default y
config PCI
- bool "PCI support" if ARCH_INTEGRATOR_AP
+ bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2277e3d179cc..8330495e2448 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -97,6 +97,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_IMX) := imx
machine-$(CONFIG_ARCH_H720X) := h720x
+ machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c
index a0507f8c33fe..c6beb751f2a9 100644
--- a/arch/arm/common/amba.c
+++ b/arch/arm/common/amba.c
@@ -169,7 +169,7 @@ static void amba_device_release(struct device *dev)
}
#define amba_attr(name,fmt,arg...) \
-static ssize_t show_##name(struct device *_dev, char *buf) \
+static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf) \
{ \
struct amba_device *dev = to_amba_device(_dev); \
return sprintf(buf, fmt, arg); \
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 5797b1b100a1..9d63a01214eb 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -30,6 +30,8 @@
#include <linux/dmapool.h>
#include <linux/list.h>
+#include <asm/cacheflush.h>
+
#undef DEBUG
#undef STATS
@@ -302,12 +304,24 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
DO_STATS ( device_info->bounce_count++ );
- if ((dir == DMA_FROM_DEVICE) ||
- (dir == DMA_BIDIRECTIONAL)) {
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+ unsigned long ptr;
+
dev_dbg(dev,
"%s: copy back safe %p to unsafe %p size %d\n",
__func__, buf->safe, buf->ptr, size);
memcpy(buf->ptr, buf->safe, size);
+
+ /*
+ * DMA buffers must have the same cache properties
+ * as if they were really used for DMA - which means
+ * data must be written back to RAM. Note that
+ * we don't use dmac_flush_range() here for the
+ * bidirectional case because we know the cache
+ * lines will be coherent with the data written.
+ */
+ ptr = (unsigned long)buf->ptr;
+ dmac_clean_range(ptr, ptr + size);
}
free_safe_buffer(device_info, buf);
}
diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
index c2c557a224c2..c94864c5b1af 100644
--- a/arch/arm/common/sharpsl_param.c
+++ b/arch/arm/common/sharpsl_param.c
@@ -22,7 +22,7 @@
* them early in the boot process, then pass them to the appropriate drivers.
* Not all devices use all paramaters but the format is common to all.
*/
-#ifdef ARCH_SA1100
+#ifdef CONFIG_ARCH_SA1100
#define PARAM_BASE 0xe8ffc000
#else
#define PARAM_BASE 0xa0000a00
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig
index e8f9fccffe84..06fae4b62774 100644
--- a/arch/arm/configs/enp2611_defconfig
+++ b/arch/arm/configs/enp2611_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
#
# System Type
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index 4fd663ecbe39..810a450a55d2 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
#
# System Type
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 6f51c98084a3..72e1b940e975 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
#
# System Type
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index 7be3521f91fc..1592e45f0278 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
#
# System Type
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index cd84a20f30f1..f1afe3d09ec6 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
#
# System Type
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 4a2af55e134b..3e1b0327e4d7 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -6,7 +6,7 @@ AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
# Object file lists.
-obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \
+obj-y := compat.o dma.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
deleted file mode 100644
index 4e02fbeb10a6..000000000000
--- a/arch/arm/kernel/arch.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * linux/arch/arm/kernel/arch.c
- *
- * Architecture specific fixups.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/elf.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-#include <asm/mach/arch.h>
-
-unsigned int vram_size;
-
-#ifdef CONFIG_ARCH_ACORN
-
-unsigned int memc_ctrl_reg;
-unsigned int number_mfm_drives;
-
-static int __init parse_tag_acorn(const struct tag *tag)
-{
- memc_ctrl_reg = tag->u.acorn.memc_control_reg;
- number_mfm_drives = tag->u.acorn.adfsdrives;
-
- switch (tag->u.acorn.vram_pages) {
- case 512:
- vram_size += PAGE_SIZE * 256;
- case 256:
- vram_size += PAGE_SIZE * 256;
- default:
- break;
- }
-#if 0
- if (vram_size) {
- desc->video_start = 0x02000000;
- desc->video_end = 0x02000000 + vram_size;
- }
-#endif
- return 0;
-}
-
-__tagtable(ATAG_ACORN, parse_tag_acorn);
-
-#endif
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 3dc15b131f53..6540db691338 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -866,19 +866,19 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
return ec;
}
-static ssize_t ecard_show_irq(struct device *dev, char *buf)
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->irq);
}
-static ssize_t ecard_show_dma(struct device *dev, char *buf)
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->dma);
}
-static ssize_t ecard_show_resources(struct device *dev, char *buf)
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
char *str = buf;
@@ -893,19 +893,19 @@ static ssize_t ecard_show_resources(struct device *dev, char *buf)
return str - buf;
}
-static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->cid.manufacturer);
}
-static ssize_t ecard_show_device(struct device *dev, char *buf)
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->cid.product);
}
-static ssize_t ecard_show_type(struct device *dev, char *buf)
+static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 45ed036336e0..34892758f098 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -145,7 +145,8 @@ int __init __cpu_up(unsigned int cpu)
pgd_free(pgd);
if (ret) {
- printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu);
+ printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
+
/*
* FIXME: We need to clean up the new idle thread. --rmk
*/
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
index 130f5a839669..b62875cfd8f8 100644
--- a/arch/arm/lib/ashldi3.c
+++ b/arch/arm/lib/ashldi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
#include "gcclib.h"
-DItype
-__ashldi3 (DItype u, word_type b)
+s64 __ashldi3(s64 u, int b)
{
- DIunion w;
- word_type bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
- if (bm <= 0)
- {
- w.s.low = 0;
- w.s.high = (USItype)uu.s.low << -bm;
- }
- else
- {
- USItype carries = (USItype)uu.s.low >> bm;
- w.s.low = (USItype)uu.s.low << b;
- w.s.high = ((USItype)uu.s.high << b) | carries;
- }
-
- return w.ll;
+ DIunion w;
+ int bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ w.s.low = 0;
+ w.s.high = (u32) uu.s.low << -bm;
+ } else {
+ u32 carries = (u32) uu.s.low >> bm;
+ w.s.low = (u32) uu.s.low << b;
+ w.s.high = ((u32) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
}
-
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
index 71625d218f8d..9a8600a7543f 100644
--- a/arch/arm/lib/ashrdi3.c
+++ b/arch/arm/lib/ashrdi3.c
@@ -31,31 +31,27 @@ Boston, MA 02111-1307, USA. */
#include "gcclib.h"
-DItype
-__ashrdi3 (DItype u, word_type b)
+s64 __ashrdi3(s64 u, int b)
{
- DIunion w;
- word_type bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
- if (bm <= 0)
- {
- /* w.s.high = 1..1 or 0..0 */
- w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
- w.s.low = uu.s.high >> -bm;
- }
- else
- {
- USItype carries = (USItype)uu.s.high << bm;
- w.s.high = uu.s.high >> b;
- w.s.low = ((USItype)uu.s.low >> b) | carries;
- }
-
- return w.ll;
+ DIunion w;
+ int bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ } else {
+ u32 carries = (u32) uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((u32) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
}
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
index 65314a3d9e27..8b6dcc656de7 100644
--- a/arch/arm/lib/gcclib.h
+++ b/arch/arm/lib/gcclib.h
@@ -1,25 +1,22 @@
/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
/* I Molton 29/07/01 */
-#define BITS_PER_UNIT 8
-#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#include <linux/types.h>
-typedef unsigned int UQItype __attribute__ ((mode (QI)));
-typedef int SItype __attribute__ ((mode (SI)));
-typedef unsigned int USItype __attribute__ ((mode (SI)));
-typedef int DItype __attribute__ ((mode (DI)));
-typedef int word_type __attribute__ ((mode (__word__)));
-typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#define BITS_PER_UNIT 8
+#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
#ifdef __ARMEB__
- struct DIstruct {SItype high, low;};
+struct DIstruct {
+ s32 high, low;
+};
#else
- struct DIstruct {SItype low, high;};
+struct DIstruct {
+ s32 low, high;
+};
#endif
-typedef union
-{
- struct DIstruct s;
- DItype ll;
+typedef union {
+ struct DIstruct s;
+ s64 ll;
} DIunion;
-
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
index 179eea4edc35..90ae647e4d76 100644
--- a/arch/arm/lib/longlong.h
+++ b/arch/arm/lib/longlong.h
@@ -26,18 +26,18 @@
#define __BITS4 (SI_TYPE_SIZE / 4)
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
-#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+#define __ll_lowpart(t) ((u32) (t) % __ll_B)
+#define __ll_highpart(t) ((u32) (t) / __ll_B)
/* Define auxiliary asm macros.
1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
- multiplies two USItype integers MULTIPLER and MULTIPLICAND,
- and generates a two-part USItype product in HIGH_PROD and
+ multiplies two u32 integers MULTIPLER and MULTIPLICAND,
+ and generates a two-part u32 product in HIGH_PROD and
LOW_PROD.
- 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
- and returns a UDItype product. This is just a variant of umul_ppmm.
+ 2) __umulsidi3(a,b) multiplies two u32 integers A and B,
+ and returns a u64 product. This is just a variant of umul_ppmm.
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
denominator) divides a two-word unsigned integer, composed by the
@@ -77,23 +77,23 @@
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds %1, %4, %5 \n\
adc %0, %2, %3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%r" ((USItype) (ah)), \
- "rI" ((USItype) (bh)), \
- "%r" ((USItype) (al)), \
- "rI" ((USItype) (bl)))
+ : "=r" ((u32) (sh)), \
+ "=&r" ((u32) (sl)) \
+ : "%r" ((u32) (ah)), \
+ "rI" ((u32) (bh)), \
+ "%r" ((u32) (al)), \
+ "rI" ((u32) (bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subs %1, %4, %5 \n\
sbc %0, %2, %3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "r" ((USItype) (ah)), \
- "rI" ((USItype) (bh)), \
- "r" ((USItype) (al)), \
- "rI" ((USItype) (bl)))
+ : "=r" ((u32) (sh)), \
+ "=&r" ((u32) (sl)) \
+ : "r" ((u32) (ah)), \
+ "rI" ((u32) (bh)), \
+ "r" ((u32) (al)), \
+ "rI" ((u32) (bl)))
#define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2; \
+{register u32 __t0, __t1, __t2; \
__asm__ ("%@ Inlined umul_ppmm \n\
mov %2, %5, lsr #16 \n\
mov %0, %6, lsr #16 \n\
@@ -107,14 +107,14 @@
addcs %0, %0, #65536 \n\
adds %1, %1, %3, lsl #16 \n\
adc %0, %0, %3, lsr #16" \
- : "=&r" ((USItype) (xh)), \
- "=r" ((USItype) (xl)), \
+ : "=&r" ((u32) (xh)), \
+ "=r" ((u32) (xl)), \
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
- : "r" ((USItype) (a)), \
- "r" ((USItype) (b)));}
+ : "r" ((u32) (a)), \
+ "r" ((u32) (b)));}
#define UMUL_TIME 20
#define UDIV_TIME 100
-#endif /* __arm__ */
+#endif /* __arm__ */
#define __umulsidi3(u, v) \
({DIunion __w; \
@@ -123,14 +123,14 @@
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
do { \
- USItype __d1, __d0, __q1, __q0; \
- USItype __r1, __r0, __m; \
+ u32 __d1, __d0, __q1, __q0; \
+ u32 __r1, __r0, __m; \
__d1 = __ll_highpart (d); \
__d0 = __ll_lowpart (d); \
\
__r1 = (n1) % __d1; \
__q1 = (n1) / __d1; \
- __m = (USItype) __q1 * __d0; \
+ __m = (u32) __q1 * __d0; \
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
if (__r1 < __m) \
{ \
@@ -143,7 +143,7 @@
\
__r0 = __r1 % __d1; \
__q0 = __r1 / __d1; \
- __m = (USItype) __q0 * __d0; \
+ __m = (u32) __q0 * __d0; \
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
if (__r0 < __m) \
{ \
@@ -154,7 +154,7 @@
} \
__r0 -= __m; \
\
- (q) = (USItype) __q1 * __ll_B | __q0; \
+ (q) = (u32) __q1 * __ll_B | __q0; \
(r) = __r0; \
} while (0)
@@ -163,14 +163,14 @@
#define count_leading_zeros(count, x) \
do { \
- USItype __xr = (x); \
- USItype __a; \
+ u32 __xr = (x); \
+ u32 __a; \
\
if (SI_TYPE_SIZE <= 32) \
{ \
- __a = __xr < ((USItype)1<<2*__BITS4) \
- ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
- : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
+ __a = __xr < ((u32)1<<2*__BITS4) \
+ ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \
+ : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
} \
else \
{ \
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
index b666f1bad451..3681f49d2b6e 100644
--- a/arch/arm/lib/lshrdi3.c
+++ b/arch/arm/lib/lshrdi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
#include "gcclib.h"
-DItype
-__lshrdi3 (DItype u, word_type b)
+s64 __lshrdi3(s64 u, int b)
{
- DIunion w;
- word_type bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
- if (bm <= 0)
- {
- w.s.high = 0;
- w.s.low = (USItype)uu.s.high >> -bm;
- }
- else
- {
- USItype carries = (USItype)uu.s.high << bm;
- w.s.high = (USItype)uu.s.high >> b;
- w.s.low = ((USItype)uu.s.low >> b) | carries;
- }
-
- return w.ll;
+ DIunion w;
+ int bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ w.s.high = 0;
+ w.s.low = (u32) uu.s.high >> -bm;
+ } else {
+ u32 carries = (u32) uu.s.high << bm;
+ w.s.high = (u32) uu.s.high >> b;
+ w.s.low = ((u32) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
}
-
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
index 44d611b1cfdb..0a3b93313f18 100644
--- a/arch/arm/lib/muldi3.c
+++ b/arch/arm/lib/muldi3.c
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
#include "gcclib.h"
#define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2; \
+{register u32 __t0, __t1, __t2; \
__asm__ ("%@ Inlined umul_ppmm \n\
mov %2, %5, lsr #16 \n\
mov %0, %6, lsr #16 \n\
@@ -46,32 +46,27 @@ Boston, MA 02111-1307, USA. */
addcs %0, %0, #65536 \n\
adds %1, %1, %3, lsl #16 \n\
adc %0, %0, %3, lsr #16" \
- : "=&r" ((USItype) (xh)), \
- "=r" ((USItype) (xl)), \
+ : "=&r" ((u32) (xh)), \
+ "=r" ((u32) (xl)), \
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
- : "r" ((USItype) (a)), \
- "r" ((USItype) (b)));}
-
+ : "r" ((u32) (a)), \
+ "r" ((u32) (b)));}
#define __umulsidi3(u, v) \
({DIunion __w; \
umul_ppmm (__w.s.high, __w.s.low, u, v); \
__w.ll; })
-
-DItype
-__muldi3 (DItype u, DItype v)
+s64 __muldi3(s64 u, s64 v)
{
- DIunion w;
- DIunion uu, vv;
+ DIunion w;
+ DIunion uu, vv;
- uu.ll = u,
- vv.ll = v;
+ uu.ll = u, vv.ll = v;
- w.ll = __umulsidi3 (uu.s.low, vv.s.low);
- w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
- + (USItype) uu.s.high * (USItype) vv.s.low);
+ w.ll = __umulsidi3(uu.s.low, vv.s.low);
+ w.s.high += ((u32) uu.s.low * (u32) vv.s.high
+ + (u32) uu.s.high * (u32) vv.s.low);
- return w.ll;
+ return w.ll;
}
-
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
index 6c6ae63efa02..57f3f2df3850 100644
--- a/arch/arm/lib/ucmpdi2.c
+++ b/arch/arm/lib/ucmpdi2.c
@@ -31,21 +31,19 @@ Boston, MA 02111-1307, USA. */
#include "gcclib.h"
-word_type
-__ucmpdi2 (DItype a, DItype b)
+int __ucmpdi2(s64 a, s64 b)
{
- DIunion au, bu;
-
- au.ll = a, bu.ll = b;
-
- if ((USItype) au.s.high < (USItype) bu.s.high)
- return 0;
- else if ((USItype) au.s.high > (USItype) bu.s.high)
- return 2;
- if ((USItype) au.s.low < (USItype) bu.s.low)
- return 0;
- else if ((USItype) au.s.low > (USItype) bu.s.low)
- return 2;
- return 1;
+ DIunion au, bu;
+
+ au.ll = a, bu.ll = b;
+
+ if ((u32) au.s.high < (u32) bu.s.high)
+ return 0;
+ else if ((u32) au.s.high > (u32) bu.s.high)
+ return 2;
+ if ((u32) au.s.low < (u32) bu.s.low)
+ return 0;
+ else if ((u32) au.s.low > (u32) bu.s.low)
+ return 2;
+ return 1;
}
-
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
index d25195f673f4..e343be4c6642 100644
--- a/arch/arm/lib/udivdi3.c
+++ b/arch/arm/lib/udivdi3.c
@@ -32,211 +32,191 @@ Boston, MA 02111-1307, USA. */
#include "gcclib.h"
#include "longlong.h"
-static const UQItype __clz_tab[] =
-{
- 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+static const u8 __clz_tab[] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
};
-UDItype
-__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
+u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
{
- DIunion ww;
- DIunion nn, dd;
- DIunion rr;
- USItype d0, d1, n0, n1, n2;
- USItype q0, q1;
- USItype b, bm;
-
- nn.ll = n;
- dd.ll = d;
-
- d0 = dd.s.low;
- d1 = dd.s.high;
- n0 = nn.s.low;
- n1 = nn.s.high;
-
- if (d1 == 0)
- {
- if (d0 > n1)
- {
- /* 0q = nn / 0D */
-
- count_leading_zeros (bm, d0);
-
- if (bm != 0)
- {
- /* Normalize, i.e. make the most significant bit of the
- denominator set. */
-
- d0 = d0 << bm;
- n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
- n0 = n0 << bm;
- }
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
- q1 = 0;
-
- /* Remainder in n0 >> bm. */
- }
- else
- {
- /* qq = NN / 0d */
-
- if (d0 == 0)
- d0 = 1 / d0; /* Divide intentionally by zero. */
-
- count_leading_zeros (bm, d0);
-
- if (bm == 0)
- {
- /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
- conclude (the most significant bit of n1 is set) /\ (the
- leading quotient digit q1 = 1).
-
- This special case is necessary, not an optimization.
- (Shifts counts of SI_TYPE_SIZE are undefined.) */
-
- n1 -= d0;
- q1 = 1;
- }
- else
- {
- /* Normalize. */
-
- b = SI_TYPE_SIZE - bm;
-
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd (q1, n1, n2, n1, d0);
- }
-
- /* n1 != d0... */
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
-
- /* Remainder in n0 >> bm. */
- }
-
- if (rp != 0)
- {
- rr.s.low = n0 >> bm;
- rr.s.high = 0;
- *rp = rr.ll;
- }
- }
- else
- {
- if (d1 > n1)
- {
- /* 00 = nn / DD */
-
- q0 = 0;
- q1 = 0;
-
- /* Remainder in n1n0. */
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- }
- else
- {
- /* 0q = NN / dd */
-
- count_leading_zeros (bm, d1);
- if (bm == 0)
- {
- /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
- conclude (the most significant bit of n1 is set) /\ (the
- quotient digit q0 = 0 or 1).
-
- This special case is necessary, not an optimization. */
-
- /* The condition on the next line takes advantage of that
- n1 >= d1 (true due to program flow). */
- if (n1 > d1 || n0 >= d0)
- {
- q0 = 1;
- sub_ddmmss (n1, n0, n1, n0, d1, d0);
- }
- else
- q0 = 0;
-
- q1 = 0;
-
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- }
- else
- {
- USItype m1, m0;
- /* Normalize. */
-
- b = SI_TYPE_SIZE - bm;
-
- d1 = (d1 << bm) | (d0 >> b);
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd (q0, n1, n2, n1, d1);
- umul_ppmm (m1, m0, q0, d0);
-
- if (m1 > n1 || (m1 == n1 && m0 > n0))
- {
- q0--;
- sub_ddmmss (m1, m0, m1, m0, d1, d0);
- }
-
- q1 = 0;
-
- /* Remainder in (n1n0 - m1m0) >> bm. */
- if (rp != 0)
- {
- sub_ddmmss (n1, n0, n1, n0, m1, m0);
- rr.s.low = (n1 << b) | (n0 >> bm);
- rr.s.high = n1 >> bm;
- *rp = rr.ll;
- }
- }
- }
- }
-
- ww.s.low = q0;
- ww.s.high = q1;
- return ww.ll;
+ DIunion ww;
+ DIunion nn, dd;
+ DIunion rr;
+ u32 d0, d1, n0, n1, n2;
+ u32 q0, q1;
+ u32 b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+ if (d1 == 0) {
+ if (d0 > n1) {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros(bm, d0);
+
+ if (bm != 0) {
+ /* Normalize, i.e. make the most significant bit of the
+ denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ } else {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros(bm, d0);
+
+ if (bm == 0) {
+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ leading quotient digit q1 = 1).
+
+ This special case is necessary, not an optimization.
+ (Shifts counts of SI_TYPE_SIZE are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ } else {
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd(q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0) {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ } else {
+ if (d1 > n1) {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ /* 0q = NN / dd */
+
+ count_leading_zeros(bm, d1);
+ if (bm == 0) {
+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ quotient digit q0 = 0 or 1).
+
+ This special case is necessary, not an optimization. */
+
+ /* The condition on the next line takes advantage of that
+ n1 >= d1 (true due to program flow). */
+ if (n1 > d1 || n0 >= d0) {
+ q0 = 1;
+ sub_ddmmss(n1, n0, n1, n0, d1, d0);
+ } else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ u32 m1, m0;
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd(q0, n1, n2, n1, d1);
+ umul_ppmm(m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0)) {
+ q0--;
+ sub_ddmmss(m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0) {
+ sub_ddmmss(n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);
+ rr.s.high = n1 >> bm;
+ *rp = rr.ll;
+ }
+ }
+ }
+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
}
-UDItype
-__udivdi3 (UDItype n, UDItype d)
+u64 __udivdi3(u64 n, u64 d)
{
- return __udivmoddi4 (n, d, (UDItype *) 0);
+ return __udivmoddi4(n, d, (u64 *) 0);
}
-UDItype
-__umoddi3 (UDItype u, UDItype v)
+u64 __umoddi3(u64 u, u64 v)
{
- UDItype w;
+ u64 w;
- (void) __udivmoddi4 (u ,v, &w);
+ (void)__udivmoddi4(u, v, &w);
- return w;
+ return w;
}
-
diff --git a/arch/arm/mach-aaec2000/Kconfig b/arch/arm/mach-aaec2000/Kconfig
new file mode 100644
index 000000000000..5e4bef93754c
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_AAEC2000
+
+menu "Agilent AAEC-2000 Implementations"
+
+config MACH_AAED2000
+ bool "Agilent AAED-2000 Development Platform"
+ select CPU_ARM920T
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
new file mode 100644
index 000000000000..20ec83896c37
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+obj-y += core.o
+
+# Specific board support
+obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
new file mode 100644
index 000000000000..5417ca3f4621
--- /dev/null
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/arm/mach-aaec2000/aaed2000.c
+ *
+ * Support for the Agilent AAED-2000 Development Platform.
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "core.h"
+
+static void __init aaed2000_init_irq(void)
+{
+ aaec2000_init_irq();
+}
+
+static void __init aaed2000_map_io(void)
+{
+ aaec2000_map_io();
+}
+
+MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
+ MAINTAINER("Nicolas Bellido Y Ortega")
+ BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE)
+ MAPIO(aaed2000_map_io)
+ INITIRQ(aaed2000_init_irq)
+ .timer = &aaec2000_timer,
+MACHINE_END
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
new file mode 100644
index 000000000000..fc145b3768fa
--- /dev/null
+++ b/arch/arm/mach-aaec2000/core.c
@@ -0,0 +1,157 @@
+/*
+ * linux/arch/arm/mach-aaec2000/core.c
+ *
+ * Code common to all AAEC-2000 machines
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/signal.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+/*
+ * Common I/O mapping:
+ *
+ * Static virtual address mappings are as follow:
+ *
+ * 0xf8000000-0xf8001ffff: Devices connected to APB bus
+ * 0xf8002000-0xf8003ffff: Devices connected to AHB bus
+ *
+ * Below 0xe8000000 is reserved for vm allocation.
+ *
+ * The machine specific code must provide the extra mapping beside the
+ * default mapping provided here.
+ */
+static struct map_desc standard_io_desc[] __initdata = {
+ /* virtual physical length type */
+ { VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE },
+ { VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE }
+};
+
+void __init aaec2000_map_io(void)
+{
+ iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+/*
+ * Interrupt handling routines
+ */
+static void aaec2000_int_ack(unsigned int irq)
+{
+ IRQ_INTSR = 1 << irq;
+}
+
+static void aaec2000_int_mask(unsigned int irq)
+{
+ IRQ_INTENC |= (1 << irq);
+}
+
+static void aaec2000_int_unmask(unsigned int irq)
+{
+ IRQ_INTENS |= (1 << irq);
+}
+
+static struct irqchip aaec2000_irq_chip = {
+ .ack = aaec2000_int_ack,
+ .mask = aaec2000_int_mask,
+ .unmask = aaec2000_int_unmask,
+};
+
+void __init aaec2000_init_irq(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ set_irq_handler(i, do_level_IRQ);
+ set_irq_chip(i, &aaec2000_irq_chip);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ /* Disable all interrupts */
+ IRQ_INTENC = 0xffffffff;
+
+ /* Clear any pending interrupts */
+ IRQ_INTSR = IRQ_INTSR;
+}
+
+/*
+ * Time keeping
+ */
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long aaec2000_gettimeoffset(void)
+{
+ unsigned long ticks_to_match, elapsed, usec;
+
+ /* Get ticks before next timer match */
+ ticks_to_match = TIMER1_LOAD - TIMER1_VAL;
+
+ /* We need elapsed ticks since last match */
+ elapsed = LATCH - ticks_to_match;
+
+ /* Now, convert them to usec */
+ usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
+
+ return usec;
+}
+
+/* We enter here with IRQs enabled */
+static irqreturn_t
+aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* TODO: Check timer accuracy */
+ write_seqlock(&xtime_lock);
+
+ timer_tick(regs);
+ TIMER1_CLEAR = 1;
+
+ write_sequnlock(&xtime_lock);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction aaec2000_timer_irq = {
+ .name = "AAEC-2000 Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = aaec2000_timer_interrupt
+};
+
+static void __init aaec2000_timer_init(void)
+{
+ /* Disable timer 1 */
+ TIMER1_CTRL = 0;
+
+ /* We have somehow to generate a 100Hz clock.
+ * We then use the 508KHz timer in periodic mode.
+ */
+ TIMER1_LOAD = LATCH;
+ TIMER1_CLEAR = 1; /* Clear interrupt */
+
+ setup_irq(INT_TMR1_OFL, &aaec2000_timer_irq);
+
+ TIMER1_CTRL = TIMER_CTRL_ENABLE |
+ TIMER_CTRL_PERIODIC |
+ TIMER_CTRL_CLKSEL_508K;
+}
+
+struct sys_timer aaec2000_timer = {
+ .init = aaec2000_timer_init,
+ .offset = aaec2000_gettimeoffset,
+};
+
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
new file mode 100644
index 000000000000..91893d848c16
--- /dev/null
+++ b/arch/arm/mach-aaec2000/core.h
@@ -0,0 +1,16 @@
+/*
+ * linux/arch/arm/mach-aaec2000/core.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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.
+ *
+ */
+
+struct sys_timer;
+
+extern struct sys_timer aaec2000_timer;
+extern void __init aaec2000_map_io(void);
+extern void __init aaec2000_init_irq(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index d302f0405fd2..bd1e5e3c9d34 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -227,7 +227,6 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* primary CPU
*/
if (hard_smp_processor_id() == 0) {
- nmi_tick();
timer_tick(regs);
#ifdef CONFIG_SMP
smp_send_timer();
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 4f3c3d5c781c..fc0555596d6d 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -162,12 +162,13 @@ void __init ixp2000_map_io(void)
static unsigned ticks_per_jiffy;
static unsigned ticks_per_usec;
static unsigned next_jiffy_time;
+static volatile unsigned long *missing_jiffy_timer_csr;
unsigned long ixp2000_gettimeoffset (void)
{
unsigned long offset;
- offset = next_jiffy_time - *IXP2000_T4_CSR;
+ offset = next_jiffy_time - *missing_jiffy_timer_csr;
return offset / ticks_per_usec;
}
@@ -179,7 +180,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* clear timer 1 */
ixp2000_reg_write(IXP2000_T1_CLR, 1);
- while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) {
+ while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
timer_tick(regs);
next_jiffy_time -= ticks_per_jiffy;
}
@@ -197,20 +198,37 @@ static struct irqaction ixp2000_timer_irq = {
void __init ixp2000_init_time(unsigned long tick_rate)
{
- ixp2000_reg_write(IXP2000_T1_CLR, 0);
- ixp2000_reg_write(IXP2000_T4_CLR, 0);
-
ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
ticks_per_usec = tick_rate / 1000000;
+ /*
+ * We use timer 1 as our timer interrupt.
+ */
+ ixp2000_reg_write(IXP2000_T1_CLR, 0);
ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
/*
- * We use T4 as a monotonic counter to track missed jiffies
+ * We use a second timer as a monotonic counter for tracking
+ * missed jiffies. The IXP2000 has four timers, but if we're
+ * on an A-step IXP2800, timer 2 and 3 don't work, so on those
+ * chips we use timer 4. Timer 4 is the only timer that can
+ * be used for the watchdog, so we use timer 2 if we're on a
+ * non-buggy chip.
*/
- ixp2000_reg_write(IXP2000_T4_CLD, -1);
- ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+ if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
+ printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
+
+ ixp2000_reg_write(IXP2000_T4_CLR, 0);
+ ixp2000_reg_write(IXP2000_T4_CLD, -1);
+ ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+ missing_jiffy_timer_csr = IXP2000_T4_CSR;
+ } else {
+ ixp2000_reg_write(IXP2000_T2_CLR, 0);
+ ixp2000_reg_write(IXP2000_T2_CLD, -1);
+ ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
+ missing_jiffy_timer_csr = IXP2000_T2_CSR;
+ }
next_jiffy_time = 0xffffffff;
/* register for interrupt */
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
index 5d608837757a..ba81e70ed813 100644
--- a/arch/arm/mach-versatile/Makefile
+++ b/arch/arm/mach-versatile/Makefile
@@ -5,3 +5,4 @@
obj-y := core.o clock.o
obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o
obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 302c2a7b9b63..6a7cbea5e098 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -196,11 +196,15 @@ static struct map_desc versatile_io_desc[] __initdata = {
#ifdef CONFIG_DEBUG_LL
{ IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE },
#endif
-#ifdef FIXME
- { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
- { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE },
- { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K, MT_DEVICE },
- { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE },
+#ifdef CONFIG_PCI
+ { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
+ { VERSATILE_PCI_VIRT_BASE, VERSATILE_PCI_BASE, VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
+ { VERSATILE_PCI_CFG_VIRT_BASE, VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
+#if 0
+ { VERSATILE_PCI_VIRT_MEM_BASE0, VERSATILE_PCI_MEM_BASE0, SZ_16M, MT_DEVICE },
+ { VERSATILE_PCI_VIRT_MEM_BASE1, VERSATILE_PCI_MEM_BASE1, SZ_16M, MT_DEVICE },
+ { VERSATILE_PCI_VIRT_MEM_BASE2, VERSATILE_PCI_MEM_BASE2, SZ_16M, MT_DEVICE },
+#endif
#endif
};
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
new file mode 100644
index 000000000000..d1565e851f0e
--- /dev/null
+++ b/arch/arm/mach-versatile/pci.c
@@ -0,0 +1,360 @@
+/*
+ * linux/arch/arm/mach-versatile/pci.c
+ *
+ * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
+ * You can redistribute and/or modify this software under the terms of version 2
+ * of the GNU General Public License as published by the Free Software Foundation.
+ * THIS SOFTWARE IS PROVIDED "AS IS" 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.
+ * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
+ *
+ * ARM Versatile PCI driver.
+ *
+ * 14/04/2005 Initial version, colin.king@philips.com
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * these spaces are mapped using the following base registers:
+ *
+ * Usage Local Bus Memory Base/Map registers used
+ *
+ * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0, non prefetch
+ * Mem 60000000 - 6FFFFFFF LB_BASE1/LB_MAP1, prefetch
+ * IO 44000000 - 4FFFFFFF LB_BASE2/LB_MAP2, IO
+ * Cfg 42000000 - 42FFFFFF PCI config
+ *
+ */
+#define SYS_PCICTL IO_ADDRESS(VERSATILE_SYS_PCICTL)
+#define PCI_IMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
+#define PCI_IMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
+#define PCI_IMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
+#define PCI_SMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
+#define PCI_SMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
+#define PCI_SMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
+#define PCI_SELFID IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
+
+#define DEVICE_ID_OFFSET 0x00
+#define CSR_OFFSET 0x04
+#define CLASS_ID_OFFSET 0x08
+
+#define VP_PCI_DEVICE_ID 0x030010ee
+#define VP_PCI_CLASS_ID 0x0b400000
+
+static unsigned long pci_slot_ignore = 0;
+
+static int __init versatile_pci_slot_ignore(char *str)
+{
+ int retval;
+ int slot;
+
+ while ((retval = get_option(&str,&slot))) {
+ if ((slot < 0) || (slot > 31)) {
+ printk("Illegal slot value: %d\n",slot);
+ } else {
+ pci_slot_ignore |= (1 << slot);
+ }
+ }
+ return 1;
+}
+
+__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
+
+
+static unsigned long __pci_addr(struct pci_bus *bus,
+ unsigned int devfn, int offset)
+{
+ unsigned int busnr = bus->number;
+
+ /*
+ * Trap out illegal values
+ */
+ if (offset > 255)
+ BUG();
+ if (busnr > 255)
+ BUG();
+ if (devfn > 255)
+ BUG();
+
+ return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) |
+ (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
+}
+
+static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ unsigned long addr = __pci_addr(bus, devfn, where);
+ u32 v;
+ int slot = PCI_SLOT(devfn);
+
+ if (pci_slot_ignore & (1 << slot)) {
+ /* Ignore this slot */
+ switch (size) {
+ case 1:
+ v = 0xff;
+ break;
+ case 2:
+ v = 0xffff;
+ break;
+ default:
+ v = 0xffffffff;
+ }
+ } else {
+ switch (size) {
+ case 1:
+ addr &= ~3;
+ v = __raw_readb(addr);
+ break;
+
+ case 2:
+ v = __raw_readl(addr & ~3);
+ if (addr & 2) v >>= 16;
+ v &= 0xffff;
+ break;
+
+ default:
+ addr &= ~3;
+ v = __raw_readl(addr);
+ break;
+ }
+ }
+
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ unsigned long addr = __pci_addr(bus, devfn, where);
+ int slot = PCI_SLOT(devfn);
+
+ if (pci_slot_ignore & (1 << slot)) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ switch (size) {
+ case 1:
+ __raw_writeb((u8)val, addr);
+ break;
+
+ case 2:
+ __raw_writew((u16)val, addr);
+ break;
+
+ case 4:
+ __raw_writel(val, addr);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_versatile_ops = {
+ .read = versatile_read_config,
+ .write = versatile_write_config,
+};
+
+static struct resource io_mem = {
+ .name = "PCI I/O space",
+ .start = VERSATILE_PCI_MEM_BASE0,
+ .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource non_mem = {
+ .name = "PCI non-prefetchable",
+ .start = VERSATILE_PCI_MEM_BASE1,
+ .end = VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+ .name = "PCI prefetchable",
+ .start = VERSATILE_PCI_MEM_BASE2,
+ .end = VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
+ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_versatile_setup_resources(struct resource **resource)
+{
+ int ret = 0;
+
+ ret = request_resource(&iomem_resource, &io_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate I/O "
+ "memory region (%d)\n", ret);
+ goto out;
+ }
+ ret = request_resource(&iomem_resource, &non_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
+ "memory region (%d)\n", ret);
+ goto release_io_mem;
+ }
+ ret = request_resource(&iomem_resource, &pre_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate prefetchable "
+ "memory region (%d)\n", ret);
+ goto release_non_mem;
+ }
+
+ /*
+ * bus->resource[0] is the IO resource for this bus
+ * bus->resource[1] is the mem resource for this bus
+ * bus->resource[2] is the prefetch mem resource for this bus
+ */
+ resource[0] = &io_mem;
+ resource[1] = &non_mem;
+ resource[2] = &pre_mem;
+
+ goto out;
+
+ release_non_mem:
+ release_resource(&non_mem);
+ release_io_mem:
+ release_resource(&io_mem);
+ out:
+ return ret;
+}
+
+int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+ int i;
+ int myslot = -1;
+ unsigned long val;
+
+ if (nr == 0) {
+ sys->mem_offset = 0;
+ ret = pci_versatile_setup_resources(sys->resource);
+ if (ret < 0) {
+ printk("pci_versatile_setup: resources... oops?\n");
+ goto out;
+ }
+ } else {
+ printk("pci_versatile_setup: resources... nr == 0??\n");
+ goto out;
+ }
+
+ __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28,PCI_IMAP0);
+ __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28,PCI_IMAP1);
+ __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28,PCI_IMAP2);
+
+ __raw_writel(1, SYS_PCICTL);
+
+ val = __raw_readl(SYS_PCICTL);
+ if (!(val & 1)) {
+ printk("Not plugged into PCI backplane!\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ /*
+ * We need to discover the PCI core first to configure itself
+ * before the main PCI probing is performed
+ */
+ for (i=0; i<32; i++) {
+ if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
+ (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
+ myslot = i;
+
+ __raw_writel(myslot, PCI_SELFID);
+ val = __raw_readl(VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
+ val |= (1<<2);
+ __raw_writel(val, VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
+ break;
+ }
+ }
+
+ if (myslot == -1) {
+ printk("Cannot find PCI core!\n");
+ ret = -EIO;
+ } else {
+ printk("PCI core found (slot %d)\n",myslot);
+ /* Do not to map Versatile FPGA PCI device
+ into memory space as we are short of
+ mappable memory */
+ pci_slot_ignore |= (1 << myslot);
+ ret = 1;
+ }
+
+ out:
+ return ret;
+}
+
+
+struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
+}
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP? - pci bus address
+ */
+void __init pci_versatile_preinit(void)
+{
+}
+
+void __init pci_versatile_postinit(void)
+{
+}
+
+
+/*
+ * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this.
+ */
+static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+ int devslot = PCI_SLOT(dev->devfn);
+
+ /* slot, pin, irq
+ 24 1 27
+ 25 1 28 untested
+ 26 1 29
+ 27 1 30 untested
+ */
+
+ irq = 27 + ((slot + pin + 2) % 3); /* Fudged */
+
+ printk("map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
+
+ return irq;
+}
+
+static struct hw_pci versatile_pci __initdata = {
+ .swizzle = NULL,
+ .map_irq = versatile_map_irq,
+ .nr_controllers = 1,
+ .setup = pci_versatile_setup,
+ .scan = pci_versatile_scan_bus,
+ .preinit = pci_versatile_preinit,
+ .postinit = pci_versatile_postinit,
+};
+
+static int __init versatile_pci_init(void)
+{
+ pci_common_init(&versatile_pci);
+ return 0;
+}
+
+subsys_initcall(versatile_pci_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 3fefb43c67f7..95606b4a3ba6 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -62,7 +62,7 @@ config CPU_ARM720T
# ARM920T
config CPU_ARM920T
bool "Support ARM920T processor" if !ARCH_S3C2410
- depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX
+ depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
default y if ARCH_S3C2410
select CPU_32v4
select CPU_ABRT_EV4T
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index a8c00236bd3d..27d041574ea7 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -30,8 +30,6 @@
static DEFINE_SPINLOCK(v6_lock);
-#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
-
/*
* Copy the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of these pages.
@@ -55,7 +53,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
*/
void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
- unsigned int offset = DCACHE_COLOUR(vaddr);
+ unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long from, to;
/*
@@ -95,7 +93,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
*/
void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
{
- unsigned int offset = DCACHE_COLOUR(vaddr);
+ unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long to = to_address + (offset << PAGE_SHIFT);
/*
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 01967ddeef53..be4ab3d73c91 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -77,9 +77,8 @@ no_pmd:
}
static void
-make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
+make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
{
- struct address_space *mapping = page_mapping(page);
struct mm_struct *mm = vma->vm_mm;
struct vm_area_struct *mpnt;
struct prio_tree_iter iter;
@@ -87,9 +86,6 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
pgoff_t pgoff;
int aliases = 0;
- if (!mapping)
- return;
-
pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
/*
@@ -115,9 +111,11 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
if (aliases)
adjust_pte(vma, addr);
else
- flush_cache_page(vma, addr, page_to_pfn(page));
+ flush_cache_page(vma, addr, pfn);
}
+void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
/*
* Take care of architecture specific things when placing a new PTE into
* a page table, or changing an existing PTE. Basically, there are two
@@ -134,29 +132,22 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
{
unsigned long pfn = pte_pfn(pte);
+ struct address_space *mapping;
struct page *page;
if (!pfn_valid(pfn))
return;
+
page = pfn_to_page(pfn);
- if (page_mapping(page)) {
+ mapping = page_mapping(page);
+ if (mapping) {
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
- if (dirty) {
- /*
- * This is our first userspace mapping of this page.
- * Ensure that the physical page is coherent with
- * the kernel mapping.
- *
- * FIXME: only need to do this on VIVT and aliasing
- * VIPT cache architectures. We can do that
- * by choosing whether to set this bit...
- */
- __cpuc_flush_dcache_page(page_address(page));
- }
+ if (dirty)
+ __flush_dcache_page(mapping, page);
if (cache_is_vivt())
- make_coherent(vma, addr, page, dirty);
+ make_coherent(mapping, vma, addr, pfn);
}
}
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 4085ed983e46..191788fb18d1 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -37,13 +37,8 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
#endif
-static void __flush_dcache_page(struct address_space *mapping, struct page *page)
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
{
- struct mm_struct *mm = current->active_mm;
- struct vm_area_struct *mpnt;
- struct prio_tree_iter iter;
- pgoff_t pgoff;
-
/*
* Writeback any data associated with the kernel mapping of this
* page. This ensures that data in the physical page is mutually
@@ -52,24 +47,21 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
__cpuc_flush_dcache_page(page_address(page));
/*
- * If there's no mapping pointer here, then this page isn't
- * visible to userspace yet, so there are no cache lines
- * associated with any other aliases.
- */
- if (!mapping)
- return;
-
- /*
- * This is a page cache page. If we have a VIPT cache, we
- * only need to do one flush - which would be at the relevant
+ * If this is a page cache page, and we have an aliasing VIPT cache,
+ * we only need to do one flush - which would be at the relevant
* userspace colour, which is congruent with page->index.
*/
- if (cache_is_vipt()) {
- if (cache_is_vipt_aliasing())
- flush_pfn_alias(page_to_pfn(page),
- page->index << PAGE_CACHE_SHIFT);
- return;
- }
+ if (mapping && cache_is_vipt_aliasing())
+ flush_pfn_alias(page_to_pfn(page),
+ page->index << PAGE_CACHE_SHIFT);
+}
+
+static void __flush_dcache_aliases(struct address_space *mapping, struct page *page)
+{
+ struct mm_struct *mm = current->active_mm;
+ struct vm_area_struct *mpnt;
+ struct prio_tree_iter iter;
+ pgoff_t pgoff;
/*
* There are possible user space mappings of this page:
@@ -116,12 +108,12 @@ void flush_dcache_page(struct page *page)
{
struct address_space *mapping = page_mapping(page);
- if (cache_is_vipt_nonaliasing())
- return;
-
if (mapping && !mapping_mapped(mapping))
set_bit(PG_dcache_dirty, &page->flags);
- else
+ else {
__flush_dcache_page(mapping, page);
+ if (mapping && cache_is_vivt())
+ __flush_dcache_aliases(mapping, page);
+ }
}
EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 00bb8fd37a59..7110e54182b1 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -170,3 +170,50 @@ void __iounmap(void __iomem *addr)
vfree((void *) (PAGE_MASK & (unsigned long) addr));
}
EXPORT_SYMBOL(__iounmap);
+
+#ifdef __io
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ return __io(port);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_unmap);
+#endif
+
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ unsigned long start = pci_resource_start(dev, bar);
+ unsigned long len = pci_resource_len(dev, bar);
+ unsigned long flags = pci_resource_flags(dev, bar);
+
+ if (!len || !start)
+ return NULL;
+ if (maxlen && len > maxlen)
+ len = maxlen;
+ if (flags & IORESOURCE_IO)
+ return ioport_map(start, len);
+ if (flags & IORESOURCE_MEM) {
+ if (flags & IORESOURCE_CACHEABLE)
+ return ioremap(start, len);
+ return ioremap_nocache(start, len);
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+ if ((unsigned long)addr >= VMALLOC_START &&
+ (unsigned long)addr < VMALLOC_END)
+ iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
+#endif
diff --git a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c
index 824c6b571ad9..f2278aadac8a 100644
--- a/arch/arm26/kernel/ecard.c
+++ b/arch/arm26/kernel/ecard.c
@@ -562,31 +562,31 @@ static void __init ecard_init_resources(struct expansion_card *ec)
}
}
-static ssize_t ecard_show_irq(struct device *dev, char *buf)
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->irq);
}
-static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->cid.manufacturer);
}
-static ssize_t ecard_show_device(struct device *dev, char *buf)
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->cid.product);
}
-static ssize_t ecard_show_dma(struct device *dev, char *buf)
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%u\n", ec->dma);
}
-static ssize_t ecard_show_resources(struct device *dev, char *buf)
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
char *str = buf;
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 2e2756345bb2..4647db4ad6de 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -45,7 +45,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-static struct class_simple *cpuid_class;
+static struct class *cpuid_class;
#ifdef CONFIG_SMP
@@ -158,12 +158,12 @@ static struct file_operations cpuid_fops = {
.open = cpuid_open,
};
-static int cpuid_class_simple_device_add(int i)
+static int cpuid_class_device_create(int i)
{
int err = 0;
struct class_device *class_err;
- class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+ class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
if (IS_ERR(class_err))
err = PTR_ERR(class_err);
return err;
@@ -175,10 +175,10 @@ static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsign
switch (action) {
case CPU_ONLINE:
- cpuid_class_simple_device_add(cpu);
+ cpuid_class_device_create(cpu);
break;
case CPU_DEAD:
- class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+ class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
break;
}
return NOTIFY_OK;
@@ -200,13 +200,13 @@ static int __init cpuid_init(void)
err = -EBUSY;
goto out;
}
- cpuid_class = class_simple_create(THIS_MODULE, "cpuid");
+ cpuid_class = class_create(THIS_MODULE, "cpuid");
if (IS_ERR(cpuid_class)) {
err = PTR_ERR(cpuid_class);
goto out_chrdev;
}
for_each_online_cpu(i) {
- err = cpuid_class_simple_device_add(i);
+ err = cpuid_class_device_create(i);
if (err != 0)
goto out_class;
}
@@ -218,9 +218,9 @@ static int __init cpuid_init(void)
out_class:
i = 0;
for_each_online_cpu(i) {
- class_simple_device_remove(MKDEV(CPUID_MAJOR, i));
+ class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
}
- class_simple_destroy(cpuid_class);
+ class_destroy(cpuid_class);
out_chrdev:
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
out:
@@ -232,8 +232,8 @@ static void __exit cpuid_exit(void)
int cpu = 0;
for_each_online_cpu(cpu)
- class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
- class_simple_destroy(cpuid_class);
+ class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+ class_destroy(cpuid_class);
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
unregister_cpu_notifier(&cpuid_class_cpu_notifier);
}
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 05d9f8f363a6..b2f03c39a6fe 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -44,7 +44,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-static struct class_simple *msr_class;
+static struct class *msr_class;
/* Note: "err" is handled in a funny way below. Otherwise one version
of gcc or another breaks. */
@@ -260,12 +260,12 @@ static struct file_operations msr_fops = {
.open = msr_open,
};
-static int msr_class_simple_device_add(int i)
+static int msr_class_device_create(int i)
{
int err = 0;
struct class_device *class_err;
- class_err = class_simple_device_add(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+ class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
if (IS_ERR(class_err))
err = PTR_ERR(class_err);
return err;
@@ -277,10 +277,10 @@ static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned
switch (action) {
case CPU_ONLINE:
- msr_class_simple_device_add(cpu);
+ msr_class_device_create(cpu);
break;
case CPU_DEAD:
- class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
+ class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
break;
}
return NOTIFY_OK;
@@ -302,13 +302,13 @@ static int __init msr_init(void)
err = -EBUSY;
goto out;
}
- msr_class = class_simple_create(THIS_MODULE, "msr");
+ msr_class = class_create(THIS_MODULE, "msr");
if (IS_ERR(msr_class)) {
err = PTR_ERR(msr_class);
goto out_chrdev;
}
for_each_online_cpu(i) {
- err = msr_class_simple_device_add(i);
+ err = msr_class_device_create(i);
if (err != 0)
goto out_class;
}
@@ -320,8 +320,8 @@ static int __init msr_init(void)
out_class:
i = 0;
for_each_online_cpu(i)
- class_simple_device_remove(MKDEV(MSR_MAJOR, i));
- class_simple_destroy(msr_class);
+ class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
+ class_destroy(msr_class);
out_chrdev:
unregister_chrdev(MSR_MAJOR, "cpu/msr");
out:
@@ -332,8 +332,8 @@ static void __exit msr_exit(void)
{
int cpu = 0;
for_each_online_cpu(cpu)
- class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
- class_simple_destroy(msr_class);
+ class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+ class_destroy(msr_class);
unregister_chrdev(MSR_MAJOR, "cpu/msr");
unregister_cpu_notifier(&msr_class_cpu_notifier);
}
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index ab9b5f35c2a7..a087b274847e 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -432,7 +432,7 @@ static int tiocx_reload(struct cx_dev *cx_dev)
return cx_device_reload(cx_dev);
}
-static ssize_t show_cxdev_control(struct device *dev, char *buf)
+static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *attr, char *buf)
{
struct cx_dev *cx_dev = to_cx_dev(dev);
@@ -442,7 +442,7 @@ static ssize_t show_cxdev_control(struct device *dev, char *buf)
tiocx_btchar_get(cx_dev->cx_id.nasid));
}
-static ssize_t store_cxdev_control(struct device *dev, const char *buf,
+static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
int n;
@@ -518,25 +518,22 @@ static int __init tiocx_init(void)
return 0;
}
-static void __exit tiocx_exit(void)
+static int cx_remove_device(struct device * dev, void * data)
{
- struct device *dev;
- struct device *tdev;
+ struct cx_dev *cx_dev = to_cx_dev(dev);
+ device_remove_file(dev, &dev_attr_cxdev_control);
+ cx_device_unregister(cx_dev);
+ return 0;
+}
+static void __exit tiocx_exit(void)
+{
DBG("tiocx_exit\n");
/*
* Unregister devices.
*/
- list_for_each_entry_safe(dev, tdev, &tiocx_bus_type.devices.list,
- bus_list) {
- if (dev) {
- struct cx_dev *cx_dev = to_cx_dev(dev);
- device_remove_file(dev, &dev_attr_cxdev_control);
- cx_device_unregister(cx_dev);
- }
- }
-
+ bus_for_each_dev(&tiocx_bus_type, NULL, NULL, cx_remove_device);
bus_unregister(&tiocx_bus_type);
}
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index ebf186656afb..d34bbe7ae0e3 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -466,7 +466,7 @@ static int parisc_generic_match(struct device *dev, struct device_driver *drv)
}
#define pa_dev_attr(name, field, format_string) \
-static ssize_t name##_show(struct device *dev, char *buf) \
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct parisc_device *padev = to_parisc_device(dev); \
return sprintf(buf, format_string, padev->field); \
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 47a15306823a..6d7b92d72458 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1003,7 +1003,7 @@ pci_create_OF_bus_map(void)
}
}
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev;
struct device_node *np;
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
index a5156c5179a6..e5fd2ae503ea 100644
--- a/arch/ppc/syslib/ocp.c
+++ b/arch/ppc/syslib/ocp.c
@@ -68,7 +68,7 @@ static int ocp_inited;
/* Sysfs support */
#define OCP_DEF_ATTR(field, format_string) \
static ssize_t \
-show_##field(struct device *dev, char *buf) \
+show_##field(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct ocp_device *odev = to_ocp_dev(dev); \
\
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
index 46269ed21aee..49c0e34e2d6b 100644
--- a/arch/ppc/syslib/of_device.c
+++ b/arch/ppc/syslib/of_device.c
@@ -161,7 +161,7 @@ void of_unregister_driver(struct of_platform_driver *drv)
}
-static ssize_t dev_show_devspec(struct device *dev, char *buf)
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
{
struct of_device *ofdev;
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
index 344164681d2c..8316426ccaf6 100644
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/ppc64/kernel/iommu.c
@@ -423,6 +423,9 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
tbl->it_largehint = tbl->it_halfpoint;
spin_lock_init(&tbl->it_lock);
+ /* Clear the hardware table in case firmware left allocations in it */
+ ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
+
if (!welcomed) {
printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
novmerge ? "disabled" : "enabled");
diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c
index f4c825a69fa0..66bd5ab7c25a 100644
--- a/arch/ppc64/kernel/of_device.c
+++ b/arch/ppc64/kernel/of_device.c
@@ -161,7 +161,7 @@ void of_unregister_driver(struct of_platform_driver *drv)
}
-static ssize_t dev_show_devspec(struct device *dev, char *buf)
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
{
struct of_device *ofdev;
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index fbad349ec58c..4203bd020c82 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -375,7 +375,7 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
* cpus are assumed to be secondary threads.
*/
if (system_state < SYSTEM_RUNNING &&
- cur_cpu_spec->cpu_features & CPU_FTR_SMT &&
+ cpu_has_feature(CPU_FTR_SMT) &&
!smt_enabled_at_boot && nr % 2 != 0)
return 0;
@@ -419,8 +419,8 @@ void __init smp_init_pSeries(void)
#endif
/* Mark threads which are still spinning in hold loops. */
- if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
- for_each_present_cpu(i) {
+ if (cpu_has_feature(CPU_FTR_SMT)) {
+ for_each_present_cpu(i) {
if (i % 2 == 0)
/*
* Even-numbered logical cpus correspond to
@@ -428,8 +428,9 @@ void __init smp_init_pSeries(void)
*/
cpu_set(i, of_spin_map);
}
- else
+ } else {
of_spin_map = cpu_present_map;
+ }
cpu_clear(boot_cpuid, of_spin_map);
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index d786d4b6af0b..2bf0513f3eca 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -507,7 +507,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
}
#ifdef CONFIG_PPC_MULTIPLATFORM
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev;
struct device_node *np;
diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
index ff65dc33320e..b0c3b829fe47 100644
--- a/arch/ppc64/kernel/rtasd.c
+++ b/arch/ppc64/kernel/rtasd.c
@@ -440,7 +440,7 @@ static int rtasd(void *unused)
goto error;
}
- printk(KERN_ERR "RTAS daemon started\n");
+ printk(KERN_INFO "RTAS daemon started\n");
DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
@@ -485,7 +485,7 @@ static int __init rtas_init(void)
/* No RTAS, only warn if we are on a pSeries box */
if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
if (systemcfg->platform & PLATFORM_PSERIES)
- printk(KERN_ERR "rtasd: no event-scan on system\n");
+ printk(KERN_INFO "rtasd: no event-scan on system\n");
return 1;
}
diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c
index cdd830cb2768..79f2dc7a9833 100644
--- a/arch/ppc64/kernel/vio.c
+++ b/arch/ppc64/kernel/vio.c
@@ -300,7 +300,7 @@ static void __devinit vio_dev_release(struct device *dev)
}
#ifdef CONFIG_PPC_PSERIES
-static ssize_t viodev_show_devspec(struct device *dev, char *buf)
+static ssize_t viodev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
{
struct device_node *of_node = dev->platform_data;
@@ -309,7 +309,7 @@ static ssize_t viodev_show_devspec(struct device *dev, char *buf)
DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
#endif
-static ssize_t viodev_show_name(struct device *dev, char *buf)
+static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 119c94093a13..e85885593280 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -65,14 +65,14 @@ static ssize_t acpi_device_attr_show(struct kobject *kobj,
{
struct acpi_device *device = to_acpi_device(kobj);
struct acpi_device_attribute *attribute = to_handle_attr(attr);
- return attribute->show ? attribute->show(device, buf) : 0;
+ return attribute->show ? attribute->show(device, buf) : -EIO;
}
static ssize_t acpi_device_attr_store(struct kobject *kobj,
struct attribute *attr, const char *buf, size_t len)
{
struct acpi_device *device = to_acpi_device(kobj);
struct acpi_device_attribute *attribute = to_handle_attr(attr);
- return attribute->store ? attribute->store(device, buf, len) : len;
+ return attribute->store ? attribute->store(device, buf, len) : -EIO;
}
static struct sysfs_ops acpi_device_sysfs_ops = {
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index a47928a2e575..66d9c4643fc1 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,7 +1,7 @@
# Makefile for the Linux device tree
-obj-y := core.o sys.o bus.o \
- driver.o class.o class_simple.o platform.o \
+obj-y := core.o sys.o bus.o dd.o \
+ driver.o class.o platform.o \
cpu.o firmware.o init.o map.o dmapool.o \
attribute_container.o transport_class.o
obj-y += power/
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 8d1e8bd48632..645f62692920 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -4,6 +4,8 @@ extern void bus_remove_device(struct device * dev);
extern int bus_add_driver(struct device_driver *);
extern void bus_remove_driver(struct device_driver *);
+extern void driver_detach(struct device_driver * drv);
+
static inline struct class_device *to_class_dev(struct kobject *obj)
{
return container_of(obj, struct class_device, kobj);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 3cb04bb04c2b..43722af90bdd 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -17,9 +17,6 @@
#include "base.h"
#include "power/power.h"
-#define to_dev(node) container_of(node, struct device, bus_list)
-#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
-
#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
@@ -36,7 +33,7 @@ drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
struct driver_attribute * drv_attr = to_drv_attr(attr);
struct device_driver * drv = to_driver(kobj);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (drv_attr->show)
ret = drv_attr->show(drv, buf);
@@ -49,7 +46,7 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
{
struct driver_attribute * drv_attr = to_drv_attr(attr);
struct device_driver * drv = to_driver(kobj);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (drv_attr->store)
ret = drv_attr->store(drv, buf, count);
@@ -135,50 +132,11 @@ static struct kobj_type ktype_bus = {
decl_subsys(bus, &ktype_bus, NULL);
-static int __bus_for_each_dev(struct bus_type *bus, struct device *start,
- void *data, int (*fn)(struct device *, void *))
-{
- struct list_head *head;
- struct device *dev;
- int error = 0;
-
- if (!(bus = get_bus(bus)))
- return -EINVAL;
-
- head = &bus->devices.list;
- dev = list_prepare_entry(start, head, bus_list);
- list_for_each_entry_continue(dev, head, bus_list) {
- get_device(dev);
- error = fn(dev, data);
- put_device(dev);
- if (error)
- break;
- }
- put_bus(bus);
- return error;
-}
-static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
- void * data, int (*fn)(struct device_driver *, void *))
+static struct device * next_device(struct klist_iter * i)
{
- struct list_head *head;
- struct device_driver *drv;
- int error = 0;
-
- if (!(bus = get_bus(bus)))
- return -EINVAL;
-
- head = &bus->drivers.list;
- drv = list_prepare_entry(start, head, kobj.entry);
- list_for_each_entry_continue(drv, head, kobj.entry) {
- get_driver(drv);
- error = fn(drv, data);
- put_driver(drv);
- if (error)
- break;
- }
- put_bus(bus);
- return error;
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device, knode_bus) : NULL;
}
/**
@@ -204,12 +162,27 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *))
{
- int ret;
+ struct klist_iter i;
+ struct device * dev;
+ int error = 0;
- down_read(&bus->subsys.rwsem);
- ret = __bus_for_each_dev(bus, start, data, fn);
- up_read(&bus->subsys.rwsem);
- return ret;
+ if (!bus)
+ return -EINVAL;
+
+ klist_iter_init_node(&bus->klist_devices, &i,
+ (start ? &start->knode_bus : NULL));
+ while ((dev = next_device(&i)) && !error)
+ error = fn(dev, data);
+ klist_iter_exit(&i);
+ return error;
+}
+
+
+
+static struct device_driver * next_driver(struct klist_iter * i)
+{
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device_driver, knode_bus) : NULL;
}
/**
@@ -235,179 +208,19 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *))
{
- int ret;
-
- down_read(&bus->subsys.rwsem);
- ret = __bus_for_each_drv(bus, start, data, fn);
- up_read(&bus->subsys.rwsem);
- return ret;
-}
-
-/**
- * device_bind_driver - bind a driver to one device.
- * @dev: device.
- *
- * Allow manual attachment of a driver to a device.
- * Caller must have already set @dev->driver.
- *
- * Note that this does not modify the bus reference count
- * nor take the bus's rwsem. Please verify those are accounted
- * for before calling this. (It is ok to call with no other effort
- * from a driver's probe() method.)
- */
-
-void device_bind_driver(struct device * dev)
-{
- pr_debug("bound device '%s' to driver '%s'\n",
- dev->bus_id, dev->driver->name);
- list_add_tail(&dev->driver_list, &dev->driver->devices);
- sysfs_create_link(&dev->driver->kobj, &dev->kobj,
- kobject_name(&dev->kobj));
- sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
-}
-
-
-/**
- * driver_probe_device - attempt to bind device & driver.
- * @drv: driver.
- * @dev: device.
- *
- * First, we call the bus's match function, if one present, which
- * should compare the device IDs the driver supports with the
- * device IDs of the device. Note we don't do this ourselves
- * because we don't know the format of the ID structures, nor what
- * is to be considered a match and what is not.
- *
- * If we find a match, we call @drv->probe(@dev) if it exists, and
- * call device_bind_driver() above.
- */
-int driver_probe_device(struct device_driver * drv, struct device * dev)
-{
- if (drv->bus->match && !drv->bus->match(dev, drv))
- return -ENODEV;
-
- dev->driver = drv;
- if (drv->probe) {
- int error = drv->probe(dev);
- if (error) {
- dev->driver = NULL;
- return error;
- }
- }
-
- device_bind_driver(dev);
- return 0;
-}
-
-
-/**
- * device_attach - try to attach device to a driver.
- * @dev: device.
- *
- * Walk the list of drivers that the bus has and call
- * driver_probe_device() for each pair. If a compatible
- * pair is found, break out and return.
- */
-int device_attach(struct device * dev)
-{
- struct bus_type * bus = dev->bus;
- struct list_head * entry;
- int error;
-
- if (dev->driver) {
- device_bind_driver(dev);
- return 1;
- }
-
- if (bus->match) {
- list_for_each(entry, &bus->drivers.list) {
- struct device_driver * drv = to_drv(entry);
- error = driver_probe_device(drv, dev);
- if (!error)
- /* success, driver matched */
- return 1;
- if (error != -ENODEV && error != -ENXIO)
- /* driver matched but the probe failed */
- printk(KERN_WARNING
- "%s: probe of %s failed with error %d\n",
- drv->name, dev->bus_id, error);
- }
- }
-
- return 0;
-}
-
-
-/**
- * driver_attach - try to bind driver to devices.
- * @drv: driver.
- *
- * Walk the list of devices that the bus has on it and try to
- * match the driver with each one. If driver_probe_device()
- * returns 0 and the @dev->driver is set, we've found a
- * compatible pair.
- *
- * Note that we ignore the -ENODEV error from driver_probe_device(),
- * since it's perfectly valid for a driver not to bind to any devices.
- */
-void driver_attach(struct device_driver * drv)
-{
- struct bus_type * bus = drv->bus;
- struct list_head * entry;
- int error;
-
- if (!bus->match)
- return;
-
- list_for_each(entry, &bus->devices.list) {
- struct device * dev = container_of(entry, struct device, bus_list);
- if (!dev->driver) {
- error = driver_probe_device(drv, dev);
- if (error && (error != -ENODEV))
- /* driver matched but the probe failed */
- printk(KERN_WARNING
- "%s: probe of %s failed with error %d\n",
- drv->name, dev->bus_id, error);
- }
- }
-}
-
-
-/**
- * device_release_driver - manually detach device from driver.
- * @dev: device.
- *
- * Manually detach device from driver.
- * Note that this is called without incrementing the bus
- * reference count nor taking the bus's rwsem. Be sure that
- * those are accounted for before calling this function.
- */
-
-void device_release_driver(struct device * dev)
-{
- struct device_driver * drv = dev->driver;
- if (drv) {
- sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
- sysfs_remove_link(&dev->kobj, "driver");
- list_del_init(&dev->driver_list);
- if (drv->remove)
- drv->remove(dev);
- dev->driver = NULL;
- }
-}
-
+ struct klist_iter i;
+ struct device_driver * drv;
+ int error = 0;
-/**
- * driver_detach - detach driver from all devices it controls.
- * @drv: driver.
- */
+ if (!bus)
+ return -EINVAL;
-static void driver_detach(struct device_driver * drv)
-{
- while (!list_empty(&drv->devices)) {
- struct device * dev = container_of(drv->devices.next, struct device, driver_list);
- device_release_driver(dev);
- }
+ klist_iter_init_node(&bus->klist_drivers, &i,
+ start ? &start->knode_bus : NULL);
+ while ((drv = next_driver(&i)) && !error)
+ error = fn(drv, data);
+ klist_iter_exit(&i);
+ return error;
}
static int device_add_attrs(struct bus_type * bus, struct device * dev)
@@ -456,14 +269,15 @@ int bus_add_device(struct device * dev)
int error = 0;
if (bus) {
- down_write(&dev->bus->subsys.rwsem);
pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
- list_add_tail(&dev->bus_list, &dev->bus->devices.list);
- device_attach(dev);
- up_write(&dev->bus->subsys.rwsem);
- device_add_attrs(bus, dev);
- sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
- sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
+ error = device_attach(dev);
+ klist_add_tail(&bus->klist_devices, &dev->knode_bus);
+ if (error >= 0)
+ error = device_add_attrs(bus, dev);
+ if (!error) {
+ sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
+ sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
+ }
}
return error;
}
@@ -483,11 +297,9 @@ void bus_remove_device(struct device * dev)
sysfs_remove_link(&dev->kobj, "bus");
sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
device_remove_attrs(dev->bus, dev);
- down_write(&dev->bus->subsys.rwsem);
+ klist_remove(&dev->knode_bus);
pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
device_release_driver(dev);
- list_del_init(&dev->bus_list);
- up_write(&dev->bus->subsys.rwsem);
put_bus(dev->bus);
}
}
@@ -547,9 +359,8 @@ int bus_add_driver(struct device_driver * drv)
return error;
}
- down_write(&bus->subsys.rwsem);
driver_attach(drv);
- up_write(&bus->subsys.rwsem);
+ klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
module_add_driver(drv->owner, drv);
driver_add_attrs(bus, drv);
@@ -571,10 +382,9 @@ void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
driver_remove_attrs(drv->bus, drv);
- down_write(&drv->bus->subsys.rwsem);
+ klist_remove(&drv->knode_bus);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
driver_detach(drv);
- up_write(&drv->bus->subsys.rwsem);
module_remove_driver(drv);
kobject_unregister(&drv->kobj);
put_bus(drv->bus);
@@ -587,7 +397,7 @@ static int bus_rescan_devices_helper(struct device *dev, void *data)
{
int *count = data;
- if (!dev->driver && device_attach(dev))
+ if (!dev->driver && (device_attach(dev) > 0))
(*count)++;
return 0;
@@ -607,9 +417,7 @@ int bus_rescan_devices(struct bus_type * bus)
{
int count = 0;
- down_write(&bus->subsys.rwsem);
- __bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
- up_write(&bus->subsys.rwsem);
+ bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
return count;
}
@@ -710,6 +518,9 @@ int bus_register(struct bus_type * bus)
retval = kset_register(&bus->drivers);
if (retval)
goto bus_drivers_fail;
+
+ klist_init(&bus->klist_devices);
+ klist_init(&bus->klist_drivers);
bus_add_attrs(bus);
pr_debug("bus type '%s' registered\n", bus->name);
@@ -749,12 +560,6 @@ int __init buses_init(void)
EXPORT_SYMBOL_GPL(bus_for_each_dev);
EXPORT_SYMBOL_GPL(bus_for_each_drv);
-EXPORT_SYMBOL_GPL(driver_probe_device);
-EXPORT_SYMBOL_GPL(device_bind_driver);
-EXPORT_SYMBOL_GPL(device_release_driver);
-EXPORT_SYMBOL_GPL(device_attach);
-EXPORT_SYMBOL_GPL(driver_attach);
-
EXPORT_SYMBOL_GPL(bus_add_device);
EXPORT_SYMBOL_GPL(bus_remove_device);
EXPORT_SYMBOL_GPL(bus_register);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index d2a2f8f2b4ed..479c12570881 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
+#include <linux/err.h>
#include "base.h"
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -26,7 +27,7 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
struct class_attribute * class_attr = to_class_attr(attr);
struct class * dc = to_class(kobj);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (class_attr->show)
ret = class_attr->show(dc, buf);
@@ -39,7 +40,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr,
{
struct class_attribute * class_attr = to_class_attr(attr);
struct class * dc = to_class(kobj);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (class_attr->store)
ret = class_attr->store(dc, buf, count);
@@ -162,6 +163,69 @@ void class_unregister(struct class * cls)
subsystem_unregister(&cls->subsys);
}
+static void class_create_release(struct class *cls)
+{
+ kfree(cls);
+}
+
+static void class_device_create_release(struct class_device *class_dev)
+{
+ kfree(class_dev);
+}
+
+/**
+ * class_create - create a struct class structure
+ * @owner: pointer to the module that is to "own" this struct class
+ * @name: pointer to a string for the name of this class.
+ *
+ * This is used to create a struct class pointer that can then be used
+ * in calls to class_device_create().
+ *
+ * Note, the pointer created here is to be destroyed when finished by
+ * making a call to class_destroy().
+ */
+struct class *class_create(struct module *owner, char *name)
+{
+ struct class *cls;
+ int retval;
+
+ cls = kmalloc(sizeof(struct class), GFP_KERNEL);
+ if (!cls) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ memset(cls, 0x00, sizeof(struct class));
+
+ cls->name = name;
+ cls->owner = owner;
+ cls->class_release = class_create_release;
+ cls->release = class_device_create_release;
+
+ retval = class_register(cls);
+ if (retval)
+ goto error;
+
+ return cls;
+
+error:
+ kfree(cls);
+ return ERR_PTR(retval);
+}
+
+/**
+ * class_destroy - destroys a struct class structure
+ * @cs: pointer to the struct class that is to be destroyed
+ *
+ * Note, the pointer to be destroyed must have been created with a call
+ * to class_create().
+ */
+void class_destroy(struct class *cls)
+{
+ if ((cls == NULL) || (IS_ERR(cls)))
+ return;
+
+ class_unregister(cls);
+}
/* Class Device Stuff */
@@ -262,7 +326,7 @@ static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
{
struct class_device *class_dev = to_class_dev(kobj);
@@ -375,7 +439,6 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
{
return print_dev_t(buf, class_dev->devt);
}
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
void class_device_initialize(struct class_device *class_dev)
{
@@ -412,7 +475,31 @@ int class_device_add(struct class_device *class_dev)
if ((error = kobject_add(&class_dev->kobj)))
goto register_done;
- /* now take care of our own registration */
+ /* add the needed attributes to this device */
+ if (MAJOR(class_dev->devt)) {
+ struct class_device_attribute *attr;
+ attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+ if (!attr) {
+ error = -ENOMEM;
+ kobject_del(&class_dev->kobj);
+ goto register_done;
+ }
+ memset(attr, sizeof(*attr), 0x00);
+ attr->attr.name = "dev";
+ attr->attr.mode = S_IRUGO;
+ attr->attr.owner = parent->owner;
+ attr->show = show_dev;
+ attr->store = NULL;
+ class_device_create_file(class_dev, attr);
+ class_dev->devt_attr = attr;
+ }
+
+ class_device_add_attrs(class_dev);
+ if (class_dev->dev)
+ sysfs_create_link(&class_dev->kobj,
+ &class_dev->dev->kobj, "device");
+
+ /* notify any interfaces this device is now here */
if (parent) {
down(&parent->sem);
list_add_tail(&class_dev->node, &parent->children);
@@ -421,16 +508,8 @@ int class_device_add(struct class_device *class_dev)
class_intf->add(class_dev);
up(&parent->sem);
}
-
- if (MAJOR(class_dev->devt))
- class_device_create_file(class_dev, &class_device_attr_dev);
-
- class_device_add_attrs(class_dev);
- if (class_dev->dev)
- sysfs_create_link(&class_dev->kobj,
- &class_dev->dev->kobj, "device");
-
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+
register_done:
if (error && parent)
class_put(parent);
@@ -444,6 +523,58 @@ int class_device_register(struct class_device *class_dev)
return class_device_add(class_dev);
}
+/**
+ * class_device_create - creates a class device and registers it with sysfs
+ * @cs: pointer to the struct class that this device should be registered to.
+ * @dev: the dev_t for the char device to be added.
+ * @device: a pointer to a struct device that is assiociated with this class device.
+ * @fmt: string for the class device's name
+ *
+ * This function can be used by char device classes. A struct
+ * class_device will be created in sysfs, registered to the specified
+ * class. A "dev" file will be created, showing the dev_t for the
+ * device. The pointer to the struct class_device will be returned from
+ * the call. Any further sysfs files that might be required can be
+ * created using this pointer.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct class_device *class_device_create(struct class *cls, dev_t devt,
+ struct device *device, char *fmt, ...)
+{
+ va_list args;
+ struct class_device *class_dev = NULL;
+ int retval = -ENODEV;
+
+ if (cls == NULL || IS_ERR(cls))
+ goto error;
+
+ class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+ if (!class_dev) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ memset(class_dev, 0x00, sizeof(struct class_device));
+
+ class_dev->devt = devt;
+ class_dev->dev = device;
+ class_dev->class = cls;
+
+ va_start(args, fmt);
+ vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
+ va_end(args);
+ retval = class_device_register(class_dev);
+ if (retval)
+ goto error;
+
+ return class_dev;
+
+error:
+ kfree(class_dev);
+ return ERR_PTR(retval);
+}
+
void class_device_del(struct class_device *class_dev)
{
struct class * parent = class_dev->class;
@@ -460,6 +591,11 @@ void class_device_del(struct class_device *class_dev)
if (class_dev->dev)
sysfs_remove_link(&class_dev->kobj, "device");
+ if (class_dev->devt_attr) {
+ class_device_remove_file(class_dev, class_dev->devt_attr);
+ kfree(class_dev->devt_attr);
+ class_dev->devt_attr = NULL;
+ }
class_device_remove_attrs(class_dev);
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
@@ -477,6 +613,32 @@ void class_device_unregister(struct class_device *class_dev)
class_device_put(class_dev);
}
+/**
+ * class_device_destroy - removes a class device that was created with class_device_create()
+ * @cls: the pointer to the struct class that this device was registered * with.
+ * @dev: the dev_t of the device that was previously registered.
+ *
+ * This call unregisters and cleans up a class device that was created with a
+ * call to class_device_create()
+ */
+void class_device_destroy(struct class *cls, dev_t devt)
+{
+ struct class_device *class_dev = NULL;
+ struct class_device *class_dev_tmp;
+
+ down(&cls->sem);
+ list_for_each_entry(class_dev_tmp, &cls->children, node) {
+ if (class_dev_tmp->devt == devt) {
+ class_dev = class_dev_tmp;
+ break;
+ }
+ }
+ up(&cls->sem);
+
+ if (class_dev)
+ class_device_unregister(class_dev);
+}
+
int class_device_rename(struct class_device *class_dev, char *new_name)
{
int error = 0;
@@ -576,6 +738,8 @@ EXPORT_SYMBOL_GPL(class_register);
EXPORT_SYMBOL_GPL(class_unregister);
EXPORT_SYMBOL_GPL(class_get);
EXPORT_SYMBOL_GPL(class_put);
+EXPORT_SYMBOL_GPL(class_create);
+EXPORT_SYMBOL_GPL(class_destroy);
EXPORT_SYMBOL_GPL(class_device_register);
EXPORT_SYMBOL_GPL(class_device_unregister);
@@ -584,6 +748,8 @@ EXPORT_SYMBOL_GPL(class_device_add);
EXPORT_SYMBOL_GPL(class_device_del);
EXPORT_SYMBOL_GPL(class_device_get);
EXPORT_SYMBOL_GPL(class_device_put);
+EXPORT_SYMBOL_GPL(class_device_create);
+EXPORT_SYMBOL_GPL(class_device_destroy);
EXPORT_SYMBOL_GPL(class_device_create_file);
EXPORT_SYMBOL_GPL(class_device_remove_file);
EXPORT_SYMBOL_GPL(class_device_create_bin_file);
diff --git a/drivers/base/class_simple.c b/drivers/base/class_simple.c
deleted file mode 100644
index 27699eb20a37..000000000000
--- a/drivers/base/class_simple.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * class_simple.c - a "simple" interface for classes for simple char devices.
- *
- * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2003-2004 IBM Corp.
- *
- * This file is released under the GPLv2
- *
- */
-
-#include <linux/config.h>
-#include <linux/device.h>
-#include <linux/err.h>
-
-struct class_simple {
- struct class class;
-};
-#define to_class_simple(d) container_of(d, struct class_simple, class)
-
-struct simple_dev {
- struct list_head node;
- struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-
-static LIST_HEAD(simple_dev_list);
-static DEFINE_SPINLOCK(simple_dev_list_lock);
-
-static void release_simple_dev(struct class_device *class_dev)
-{
- struct simple_dev *s_dev = to_simple_dev(class_dev);
- kfree(s_dev);
-}
-
-static void class_simple_release(struct class *class)
-{
- struct class_simple *cs = to_class_simple(class);
- kfree(cs);
-}
-
-/**
- * class_simple_create - create a struct class_simple structure
- * @owner: pointer to the module that is to "own" this struct class_simple
- * @name: pointer to a string for the name of this class.
- *
- * This is used to create a struct class_simple pointer that can then be used
- * in calls to class_simple_device_add(). This is used when you do not wish to
- * create a full blown class support for a type of char devices.
- *
- * Note, the pointer created here is to be destroyed when finished by making a
- * call to class_simple_destroy().
- */
-struct class_simple *class_simple_create(struct module *owner, char *name)
-{
- struct class_simple *cs;
- int retval;
-
- cs = kmalloc(sizeof(*cs), GFP_KERNEL);
- if (!cs) {
- retval = -ENOMEM;
- goto error;
- }
- memset(cs, 0x00, sizeof(*cs));
-
- cs->class.name = name;
- cs->class.class_release = class_simple_release;
- cs->class.release = release_simple_dev;
-
- retval = class_register(&cs->class);
- if (retval)
- goto error;
-
- return cs;
-
-error:
- kfree(cs);
- return ERR_PTR(retval);
-}
-EXPORT_SYMBOL(class_simple_create);
-
-/**
- * class_simple_destroy - destroys a struct class_simple structure
- * @cs: pointer to the struct class_simple that is to be destroyed
- *
- * Note, the pointer to be destroyed must have been created with a call to
- * class_simple_create().
- */
-void class_simple_destroy(struct class_simple *cs)
-{
- if ((cs == NULL) || (IS_ERR(cs)))
- return;
-
- class_unregister(&cs->class);
-}
-EXPORT_SYMBOL(class_simple_destroy);
-
-/**
- * class_simple_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct class_simple that this device should be registered to.
- * @dev: the dev_t for the device to be added.
- * @device: a pointer to a struct device that is assiociated with this class device.
- * @fmt: string for the class device's name
- *
- * This function can be used by simple char device classes that do not
- * implement their own class device registration. A struct class_device will
- * be created in sysfs, registered to the specified class. A "dev" file will
- * be created, showing the dev_t for the device. The pointer to the struct
- * class_device will be returned from the call. Any further sysfs files that
- * might be required can be created using this pointer.
- * Note: the struct class_simple passed to this function must have previously been
- * created with a call to class_simple_create().
- */
-struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...)
-{
- va_list args;
- struct simple_dev *s_dev = NULL;
- int retval;
-
- if ((cs == NULL) || (IS_ERR(cs))) {
- retval = -ENODEV;
- goto error;
- }
-
- s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
- if (!s_dev) {
- retval = -ENOMEM;
- goto error;
- }
- memset(s_dev, 0x00, sizeof(*s_dev));
-
- s_dev->class_dev.devt = dev;
- s_dev->class_dev.dev = device;
- s_dev->class_dev.class = &cs->class;
-
- va_start(args, fmt);
- vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
- va_end(args);
- retval = class_device_register(&s_dev->class_dev);
- if (retval)
- goto error;
-
- spin_lock(&simple_dev_list_lock);
- list_add(&s_dev->node, &simple_dev_list);
- spin_unlock(&simple_dev_list_lock);
-
- return &s_dev->class_dev;
-
-error:
- kfree(s_dev);
- return ERR_PTR(retval);
-}
-EXPORT_SYMBOL(class_simple_device_add);
-
-/**
- * class_simple_set_hotplug - set the hotplug callback in the embedded struct class
- * @cs: pointer to the struct class_simple to hold the pointer
- * @hotplug: function pointer to the hotplug function
- *
- * Implement and set a hotplug function to add environment variables specific to this
- * class on the hotplug event.
- */
-int class_simple_set_hotplug(struct class_simple *cs,
- int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size))
-{
- if ((cs == NULL) || (IS_ERR(cs)))
- return -ENODEV;
- cs->class.hotplug = hotplug;
- return 0;
-}
-EXPORT_SYMBOL(class_simple_set_hotplug);
-
-/**
- * class_simple_device_remove - removes a class device that was created with class_simple_device_add()
- * @dev: the dev_t of the device that was previously registered.
- *
- * This call unregisters and cleans up a class device that was created with a
- * call to class_device_simple_add()
- */
-void class_simple_device_remove(dev_t dev)
-{
- struct simple_dev *s_dev = NULL;
- int found = 0;
-
- spin_lock(&simple_dev_list_lock);
- list_for_each_entry(s_dev, &simple_dev_list, node) {
- if (s_dev->class_dev.devt == dev) {
- found = 1;
- break;
- }
- }
- if (found) {
- list_del(&s_dev->node);
- spin_unlock(&simple_dev_list_lock);
- class_device_unregister(&s_dev->class_dev);
- } else {
- spin_unlock(&simple_dev_list_lock);
- }
-}
-EXPORT_SYMBOL(class_simple_device_remove);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index fbc223486f81..86d79755fbfb 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -36,10 +36,10 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
struct device_attribute * dev_attr = to_dev_attr(attr);
struct device * dev = to_dev(kobj);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (dev_attr->show)
- ret = dev_attr->show(dev, buf);
+ ret = dev_attr->show(dev, dev_attr, buf);
return ret;
}
@@ -49,10 +49,10 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr,
{
struct device_attribute * dev_attr = to_dev_attr(attr);
struct device * dev = to_dev(kobj);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (dev_attr->store)
- ret = dev_attr->store(dev, buf, count);
+ ret = dev_attr->store(dev, dev_attr, buf, count);
return ret;
}
@@ -102,7 +102,7 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
@@ -207,11 +207,9 @@ void device_initialize(struct device *dev)
{
kobj_set_kset_s(dev, devices_subsys);
kobject_init(&dev->kobj);
- INIT_LIST_HEAD(&dev->node);
- INIT_LIST_HEAD(&dev->children);
- INIT_LIST_HEAD(&dev->driver_list);
- INIT_LIST_HEAD(&dev->bus_list);
+ klist_init(&dev->klist_children);
INIT_LIST_HEAD(&dev->dma_pools);
+ init_MUTEX(&dev->sem);
}
/**
@@ -250,10 +248,8 @@ int device_add(struct device *dev)
goto PMError;
if ((error = bus_add_device(dev)))
goto BusError;
- down_write(&devices_subsys.rwsem);
if (parent)
- list_add_tail(&dev->node, &parent->children);
- up_write(&devices_subsys.rwsem);
+ klist_add_tail(&parent->klist_children, &dev->knode_parent);
/* notify platform of device entry */
if (platform_notify)
@@ -336,10 +332,8 @@ void device_del(struct device * dev)
{
struct device * parent = dev->parent;
- down_write(&devices_subsys.rwsem);
if (parent)
- list_del_init(&dev->node);
- up_write(&devices_subsys.rwsem);
+ klist_remove(&dev->knode_parent);
/* Notify the platform of the removal, in case they
* need to do anything...
@@ -373,6 +367,12 @@ void device_unregister(struct device * dev)
}
+static struct device * next_device(struct klist_iter * i)
+{
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
/**
* device_for_each_child - device child iterator.
* @dev: parent struct device.
@@ -385,39 +385,20 @@ void device_unregister(struct device * dev)
* We check the return of @fn each time. If it returns anything
* other than 0, we break out and return that value.
*/
-int device_for_each_child(struct device * dev, void * data,
+int device_for_each_child(struct device * parent, void * data,
int (*fn)(struct device *, void *))
{
+ struct klist_iter i;
struct device * child;
int error = 0;
- down_read(&devices_subsys.rwsem);
- list_for_each_entry(child, &dev->children, node) {
- if((error = fn(child, data)))
- break;
- }
- up_read(&devices_subsys.rwsem);
+ klist_iter_init(&parent->klist_children, &i);
+ while ((child = next_device(&i)) && !error)
+ error = fn(child, data);
+ klist_iter_exit(&i);
return error;
}
-/**
- * device_find - locate device on a bus by name.
- * @name: name of the device.
- * @bus: bus to scan for the device.
- *
- * Call kset_find_obj() to iterate over list of devices on
- * a bus to find device by name. Return device if found.
- *
- * Note that kset_find_obj increments device's reference count.
- */
-struct device *device_find(const char *name, struct bus_type *bus)
-{
- struct kobject *k = kset_find_obj(&bus->devices, name);
- if (k)
- return to_dev(k);
- return NULL;
-}
-
int __init devices_init(void)
{
return subsystem_register(&devices_subsys);
@@ -433,7 +414,6 @@ EXPORT_SYMBOL_GPL(device_del);
EXPORT_SYMBOL_GPL(device_unregister);
EXPORT_SYMBOL_GPL(get_device);
EXPORT_SYMBOL_GPL(put_device);
-EXPORT_SYMBOL_GPL(device_find);
EXPORT_SYMBOL_GPL(device_create_file);
EXPORT_SYMBOL_GPL(device_remove_file);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
new file mode 100644
index 000000000000..6db3a789c54f
--- /dev/null
+++ b/drivers/base/dd.c
@@ -0,0 +1,248 @@
+/*
+ * drivers/base/dd.c - The core device/driver interactions.
+ *
+ * This file contains the (sometimes tricky) code that controls the
+ * interactions between devices and drivers, which primarily includes
+ * driver binding and unbinding.
+ *
+ * All of this code used to exist in drivers/base/bus.c, but was
+ * relocated to here in the name of compartmentalization (since it wasn't
+ * strictly code just for the 'struct bus_type'.
+ *
+ * Copyright (c) 2002-5 Patrick Mochel
+ * Copyright (c) 2002-3 Open Source Development Labs
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include "base.h"
+#include "power/power.h"
+
+#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
+
+
+/**
+ * device_bind_driver - bind a driver to one device.
+ * @dev: device.
+ *
+ * Allow manual attachment of a driver to a device.
+ * Caller must have already set @dev->driver.
+ *
+ * Note that this does not modify the bus reference count
+ * nor take the bus's rwsem. Please verify those are accounted
+ * for before calling this. (It is ok to call with no other effort
+ * from a driver's probe() method.)
+ *
+ * This function must be called with @dev->sem held.
+ */
+void device_bind_driver(struct device * dev)
+{
+ pr_debug("bound device '%s' to driver '%s'\n",
+ dev->bus_id, dev->driver->name);
+ klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver);
+ sysfs_create_link(&dev->driver->kobj, &dev->kobj,
+ kobject_name(&dev->kobj));
+ sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+}
+
+/**
+ * driver_probe_device - attempt to bind device & driver.
+ * @drv: driver.
+ * @dev: device.
+ *
+ * First, we call the bus's match function, if one present, which
+ * should compare the device IDs the driver supports with the
+ * device IDs of the device. Note we don't do this ourselves
+ * because we don't know the format of the ID structures, nor what
+ * is to be considered a match and what is not.
+ *
+ *
+ * This function returns 1 if a match is found, an error if one
+ * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
+ *
+ * This function must be called with @dev->sem held.
+ */
+static int driver_probe_device(struct device_driver * drv, struct device * dev)
+{
+ int ret = 0;
+
+ if (drv->bus->match && !drv->bus->match(dev, drv))
+ goto Done;
+
+ pr_debug("%s: Matched Device %s with Driver %s\n",
+ drv->bus->name, dev->bus_id, drv->name);
+ dev->driver = drv;
+ if (drv->probe) {
+ ret = drv->probe(dev);
+ if (ret) {
+ dev->driver = NULL;
+ goto ProbeFailed;
+ }
+ }
+ device_bind_driver(dev);
+ ret = 1;
+ pr_debug("%s: Bound Device %s to Driver %s\n",
+ drv->bus->name, dev->bus_id, drv->name);
+ goto Done;
+
+ ProbeFailed:
+ if (ret == -ENODEV || ret == -ENXIO) {
+ /* Driver matched, but didn't support device
+ * or device not found.
+ * Not an error; keep going.
+ */
+ ret = 0;
+ } else {
+ /* driver matched but the probe failed */
+ printk(KERN_WARNING
+ "%s: probe of %s failed with error %d\n",
+ drv->name, dev->bus_id, ret);
+ }
+ Done:
+ return ret;
+}
+
+static int __device_attach(struct device_driver * drv, void * data)
+{
+ struct device * dev = data;
+ return driver_probe_device(drv, dev);
+}
+
+/**
+ * device_attach - try to attach device to a driver.
+ * @dev: device.
+ *
+ * Walk the list of drivers that the bus has and call
+ * driver_probe_device() for each pair. If a compatible
+ * pair is found, break out and return.
+ *
+ * Returns 1 if the device was bound to a driver;
+ * 0 if no matching device was found; error code otherwise.
+ */
+int device_attach(struct device * dev)
+{
+ int ret = 0;
+
+ down(&dev->sem);
+ if (dev->driver) {
+ device_bind_driver(dev);
+ ret = 1;
+ } else
+ ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
+ up(&dev->sem);
+ return ret;
+}
+
+static int __driver_attach(struct device * dev, void * data)
+{
+ struct device_driver * drv = data;
+
+ /*
+ * Lock device and try to bind to it. We drop the error
+ * here and always return 0, because we need to keep trying
+ * to bind to devices and some drivers will return an error
+ * simply if it didn't support the device.
+ *
+ * driver_probe_device() will spit a warning if there
+ * is an error.
+ */
+
+ down(&dev->sem);
+ if (!dev->driver)
+ driver_probe_device(drv, dev);
+ up(&dev->sem);
+
+
+ return 0;
+}
+
+/**
+ * driver_attach - try to bind driver to devices.
+ * @drv: driver.
+ *
+ * Walk the list of devices that the bus has on it and try to
+ * match the driver with each one. If driver_probe_device()
+ * returns 0 and the @dev->driver is set, we've found a
+ * compatible pair.
+ */
+void driver_attach(struct device_driver * drv)
+{
+ bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
+}
+
+/**
+ * device_release_driver - manually detach device from driver.
+ * @dev: device.
+ *
+ * Manually detach device from driver.
+ *
+ * __device_release_driver() must be called with @dev->sem held.
+ */
+
+static void __device_release_driver(struct device * dev)
+{
+ struct device_driver * drv;
+
+ drv = dev->driver;
+ if (drv) {
+ get_driver(drv);
+ sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
+ sysfs_remove_link(&dev->kobj, "driver");
+ klist_remove(&dev->knode_driver);
+
+ if (drv->remove)
+ drv->remove(dev);
+ dev->driver = NULL;
+ put_driver(drv);
+ }
+}
+
+void device_release_driver(struct device * dev)
+{
+ /*
+ * If anyone calls device_release_driver() recursively from
+ * within their ->remove callback for the same device, they
+ * will deadlock right here.
+ */
+ down(&dev->sem);
+ __device_release_driver(dev);
+ up(&dev->sem);
+}
+
+
+/**
+ * driver_detach - detach driver from all devices it controls.
+ * @drv: driver.
+ */
+void driver_detach(struct device_driver * drv)
+{
+ struct device * dev;
+
+ for (;;) {
+ spin_lock_irq(&drv->klist_devices.k_lock);
+ if (list_empty(&drv->klist_devices.k_list)) {
+ spin_unlock_irq(&drv->klist_devices.k_lock);
+ break;
+ }
+ dev = list_entry(drv->klist_devices.k_list.prev,
+ struct device, knode_driver.n_node);
+ get_device(dev);
+ spin_unlock_irq(&drv->klist_devices.k_lock);
+
+ down(&dev->sem);
+ if (dev->driver == drv)
+ __device_release_driver(dev);
+ up(&dev->sem);
+ put_device(dev);
+ }
+}
+
+
+EXPORT_SYMBOL_GPL(device_bind_driver);
+EXPORT_SYMBOL_GPL(device_release_driver);
+EXPORT_SYMBOL_GPL(device_attach);
+EXPORT_SYMBOL_GPL(driver_attach);
+
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index f48833df61a2..c4aebf2f522d 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -41,7 +41,7 @@ struct dma_page { /* cacheable header for 'allocation' bytes */
static DECLARE_MUTEX (pools_lock);
static ssize_t
-show_pools (struct device *dev, char *buf)
+show_pools (struct device *dev, struct device_attribute *attr, char *buf)
{
unsigned temp;
unsigned size;
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 3b269f7e5213..1b645886e9eb 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -18,6 +18,43 @@
#define to_dev(node) container_of(node, struct device, driver_list)
#define to_drv(obj) container_of(obj, struct device_driver, kobj)
+
+static struct device * next_device(struct klist_iter * i)
+{
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device, knode_driver) : NULL;
+}
+
+/**
+ * driver_for_each_device - Iterator for devices bound to a driver.
+ * @drv: Driver we're iterating.
+ * @data: Data to pass to the callback.
+ * @fn: Function to call for each device.
+ *
+ * Iterate over the @drv's list of devices calling @fn for each one.
+ */
+
+int driver_for_each_device(struct device_driver * drv, struct device * start,
+ void * data, int (*fn)(struct device *, void *))
+{
+ struct klist_iter i;
+ struct device * dev;
+ int error = 0;
+
+ if (!drv)
+ return -EINVAL;
+
+ klist_iter_init_node(&drv->klist_devices, &i,
+ start ? &start->knode_driver : NULL);
+ while ((dev = next_device(&i)) && !error)
+ error = fn(dev, data);
+ klist_iter_exit(&i);
+ return error;
+}
+
+EXPORT_SYMBOL_GPL(driver_for_each_device);
+
+
/**
* driver_create_file - create sysfs file for driver.
* @drv: driver.
@@ -85,7 +122,7 @@ void put_driver(struct device_driver * drv)
*/
int driver_register(struct device_driver * drv)
{
- INIT_LIST_HEAD(&drv->devices);
+ klist_init(&drv->klist_devices);
init_completion(&drv->unloaded);
return bus_add_driver(drv);
}
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 583d57ec49a8..5d4517ccc422 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -136,7 +136,7 @@ static SYSDEV_ATTR(distance, S_IRUGO, node_read_distance, NULL);
*
* Initialize and register the node device.
*/
-int __init register_node(struct node *node, int num, struct node *parent)
+int register_node(struct node *node, int num, struct node *parent)
{
int error;
@@ -153,8 +153,24 @@ int __init register_node(struct node *node, int num, struct node *parent)
return error;
}
+/**
+ * unregister_node - unregister a node device
+ * @node: node going away
+ *
+ * Unregisters a node device @node. All the devices on the node must be
+ * unregistered before calling this function.
+ */
+void unregister_node(struct node *node)
+{
+ sysdev_remove_file(&node->sysdev, &attr_cpumap);
+ sysdev_remove_file(&node->sysdev, &attr_meminfo);
+ sysdev_remove_file(&node->sysdev, &attr_numastat);
+ sysdev_remove_file(&node->sysdev, &attr_distance);
+
+ sysdev_unregister(&node->sysdev);
+}
-int __init register_node_type(void)
+static int __init register_node_type(void)
{
return sysdev_class_register(&node_class);
}
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 26468971ef5a..bdd96b03b885 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -22,6 +22,9 @@ extern int sysdev_resume(void);
int resume_device(struct device * dev)
{
+ int error = 0;
+
+ down(&dev->sem);
if (dev->power.pm_parent
&& dev->power.pm_parent->power.power_state) {
dev_err(dev, "PM: resume from %d, parent %s still %d\n",
@@ -31,9 +34,10 @@ int resume_device(struct device * dev)
}
if (dev->bus && dev->bus->resume) {
dev_dbg(dev,"resuming\n");
- return dev->bus->resume(dev);
+ error = dev->bus->resume(dev);
}
- return 0;
+ up(&dev->sem);
+ return error;
}
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 0ec44ef840be..2ccee3763acf 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -39,6 +39,7 @@ int suspend_device(struct device * dev, pm_message_t state)
{
int error = 0;
+ down(&dev->sem);
if (dev->power.power_state) {
dev_dbg(dev, "PM: suspend %d-->%d\n",
dev->power.power_state, state);
@@ -58,7 +59,7 @@ int suspend_device(struct device * dev, pm_message_t state)
dev_dbg(dev, "suspending\n");
error = dev->bus->suspend(dev, state);
}
-
+ up(&dev->sem);
return error;
}
@@ -113,8 +114,19 @@ int device_suspend(pm_message_t state)
put_device(dev);
}
up(&dpm_list_sem);
- if (error)
+ if (error) {
+ /* we failed... before resuming, bring back devices from
+ * dpm_off_irq list back to main dpm_off list, we do want
+ * to call resume() on them, in case they partially suspended
+ * despite returning -EAGAIN
+ */
+ while (!list_empty(&dpm_off_irq)) {
+ struct list_head * entry = dpm_off_irq.next;
+ list_del(entry);
+ list_add(entry, &dpm_off);
+ }
dpm_resume();
+ }
up(&dpm_sem);
return error;
}
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 6ac96349a8e8..f82b3df9545f 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -24,12 +24,12 @@
* low-power state.
*/
-static ssize_t state_show(struct device * dev, char * buf)
+static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
{
return sprintf(buf, "%u\n", dev->power.power_state);
}
-static ssize_t state_store(struct device * dev, const char * buf, size_t n)
+static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
{
u32 state;
char * rest;
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 9102e3756f95..f37a13de804a 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -37,7 +37,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
if (sysdev_attr->show)
return sysdev_attr->show(sysdev, buffer);
- return 0;
+ return -EIO;
}
@@ -50,7 +50,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr,
if (sysdev_attr->store)
return sysdev_attr->store(sysdev, buffer, count);
- return 0;
+ return -EIO;
}
static struct sysfs_ops sysfs_ops = {
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 14aeca3e2e8c..45a243096187 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -36,7 +36,7 @@ static int emsgs_head_idx, emsgs_tail_idx;
static struct semaphore emsgs_sema;
static spinlock_t emsgs_lock;
static int nblocked_emsgs_readers;
-static struct class_simple *aoe_class;
+static struct class *aoe_class;
static struct aoe_chardev chardevs[] = {
{ MINOR_ERR, "err" },
{ MINOR_DISCOVER, "discover" },
@@ -218,13 +218,13 @@ aoechr_init(void)
}
sema_init(&emsgs_sema, 0);
spin_lock_init(&emsgs_lock);
- aoe_class = class_simple_create(THIS_MODULE, "aoe");
+ aoe_class = class_create(THIS_MODULE, "aoe");
if (IS_ERR(aoe_class)) {
unregister_chrdev(AOE_MAJOR, "aoechr");
return PTR_ERR(aoe_class);
}
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
- class_simple_device_add(aoe_class,
+ class_device_create(aoe_class,
MKDEV(AOE_MAJOR, chardevs[i].minor),
NULL, chardevs[i].name);
@@ -237,8 +237,8 @@ aoechr_exit(void)
int i;
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
- class_simple_device_remove(MKDEV(AOE_MAJOR, chardevs[i].minor));
- class_simple_destroy(aoe_class);
+ class_device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor));
+ class_destroy(aoe_class);
unregister_chrdev(AOE_MAJOR, "aoechr");
}
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index a9575bb58a5e..638db06de2be 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -2044,7 +2044,7 @@ as_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
struct as_fs_entry *entry = to_as(attr);
if (!entry->show)
- return 0;
+ return -EIO;
return entry->show(e->elevator_data, page);
}
@@ -2057,7 +2057,7 @@ as_attr_store(struct kobject *kobj, struct attribute *attr,
struct as_fs_entry *entry = to_as(attr);
if (!entry->store)
- return -EINVAL;
+ return -EIO;
return entry->store(e->elevator_data, page, length);
}
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
index 2210bacad56a..3ac47dde64da 100644
--- a/drivers/block/cfq-iosched.c
+++ b/drivers/block/cfq-iosched.c
@@ -1775,7 +1775,7 @@ cfq_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
struct cfq_fs_entry *entry = to_cfq(attr);
if (!entry->show)
- return 0;
+ return -EIO;
return entry->show(e->elevator_data, page);
}
@@ -1788,7 +1788,7 @@ cfq_attr_store(struct kobject *kobj, struct attribute *attr,
struct cfq_fs_entry *entry = to_cfq(attr);
if (!entry->store)
- return -EINVAL;
+ return -EIO;
return entry->store(e->elevator_data, page, length);
}
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index d63d34c671f7..7f79f3dd0165 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -886,7 +886,7 @@ deadline_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
struct deadline_fs_entry *entry = to_deadline(attr);
if (!entry->show)
- return 0;
+ return -EIO;
return entry->show(e->elevator_data, page);
}
@@ -899,7 +899,7 @@ deadline_attr_store(struct kobject *kobj, struct attribute *attr,
struct deadline_fs_entry *entry = to_deadline(attr);
if (!entry->store)
- return -EINVAL;
+ return -EIO;
return entry->store(e->elevator_data, page, length);
}
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 8bbe01d4b487..53f7d846b747 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -322,7 +322,7 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
struct gendisk *disk = to_disk(kobj);
struct disk_attribute *disk_attr =
container_of(attr,struct disk_attribute,attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (disk_attr->show)
ret = disk_attr->show(disk,page);
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index f20eba22b14b..81fe3a0c1fe7 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -3574,7 +3574,7 @@ queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
q = container_of(kobj, struct request_queue, kobj);
if (!entry->show)
- return 0;
+ return -EIO;
return entry->show(q, page);
}
@@ -3588,7 +3588,7 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
q = container_of(kobj, struct request_queue, kobj);
if (!entry->store)
- return -EINVAL;
+ return -EIO;
return entry->store(q, page, length);
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index dbeb107bb971..84d8e291ed96 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -222,7 +222,7 @@ static int pg_identify(struct pg *dev, int log);
static char pg_scratch[512]; /* scratch block buffer */
-static struct class_simple *pg_class;
+static struct class *pg_class;
/* kernel glue structures */
@@ -666,7 +666,7 @@ static int __init pg_init(void)
err = -1;
goto out;
}
- pg_class = class_simple_create(THIS_MODULE, "pg");
+ pg_class = class_create(THIS_MODULE, "pg");
if (IS_ERR(pg_class)) {
err = PTR_ERR(pg_class);
goto out_chrdev;
@@ -675,7 +675,7 @@ static int __init pg_init(void)
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present) {
- class_simple_device_add(pg_class, MKDEV(major, unit),
+ class_device_create(pg_class, MKDEV(major, unit),
NULL, "pg%u", unit);
err = devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
@@ -688,8 +688,8 @@ static int __init pg_init(void)
goto out;
out_class:
- class_simple_device_remove(MKDEV(major, unit));
- class_simple_destroy(pg_class);
+ class_device_destroy(pg_class, MKDEV(major, unit));
+ class_destroy(pg_class);
out_chrdev:
unregister_chrdev(major, "pg");
out:
@@ -703,11 +703,11 @@ static void __exit pg_exit(void)
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present) {
- class_simple_device_remove(MKDEV(major, unit));
+ class_device_destroy(pg_class, MKDEV(major, unit));
devfs_remove("pg/%u", unit);
}
}
- class_simple_destroy(pg_class);
+ class_destroy(pg_class);
devfs_remove("pg");
unregister_chrdev(major, name);
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 8fbd6922fe0d..5fe8ee86f095 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -242,7 +242,7 @@ static struct file_operations pt_fops = {
};
/* sysfs class support */
-static struct class_simple *pt_class;
+static struct class *pt_class;
static inline int status_reg(struct pi_adapter *pi)
{
@@ -963,7 +963,7 @@ static int __init pt_init(void)
err = -1;
goto out;
}
- pt_class = class_simple_create(THIS_MODULE, "pt");
+ pt_class = class_create(THIS_MODULE, "pt");
if (IS_ERR(pt_class)) {
err = PTR_ERR(pt_class);
goto out_chrdev;
@@ -972,29 +972,29 @@ static int __init pt_init(void)
devfs_mk_dir("pt");
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present) {
- class_simple_device_add(pt_class, MKDEV(major, unit),
+ class_device_create(pt_class, MKDEV(major, unit),
NULL, "pt%d", unit);
err = devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR,
"pt/%d", unit);
if (err) {
- class_simple_device_remove(MKDEV(major, unit));
+ class_device_destroy(pt_class, MKDEV(major, unit));
goto out_class;
}
- class_simple_device_add(pt_class, MKDEV(major, unit + 128),
+ class_device_create(pt_class, MKDEV(major, unit + 128),
NULL, "pt%dn", unit);
err = devfs_mk_cdev(MKDEV(major, unit + 128),
S_IFCHR | S_IRUSR | S_IWUSR,
"pt/%dn", unit);
if (err) {
- class_simple_device_remove(MKDEV(major, unit + 128));
+ class_device_destroy(pt_class, MKDEV(major, unit + 128));
goto out_class;
}
}
goto out;
out_class:
- class_simple_destroy(pt_class);
+ class_destroy(pt_class);
out_chrdev:
unregister_chrdev(major, "pt");
out:
@@ -1006,12 +1006,12 @@ static void __exit pt_exit(void)
int unit;
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present) {
- class_simple_device_remove(MKDEV(major, unit));
+ class_device_destroy(pt_class, MKDEV(major, unit));
devfs_remove("pt/%d", unit);
- class_simple_device_remove(MKDEV(major, unit + 128));
+ class_device_destroy(pt_class, MKDEV(major, unit + 128));
devfs_remove("pt/%dn", unit);
}
- class_simple_destroy(pt_class);
+ class_destroy(pt_class);
devfs_remove("pt");
unregister_chrdev(major, name);
for (unit = 0; unit < PT_UNITS; unit++)
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 19c5e59bcfa8..685f061e69b2 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -430,7 +430,7 @@ static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
}
}
-static ssize_t ub_diag_show(struct device *dev, char *page)
+static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page)
{
struct usb_interface *intf;
struct ub_dev *sc;
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 37d6649011ad..26271e3ca823 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -144,7 +144,7 @@ static struct dsp56k_device {
int tx_wsize, rx_wsize;
} dsp56k;
-static struct class_simple *dsp56k_class;
+static struct class *dsp56k_class;
static int dsp56k_reset(void)
{
@@ -510,12 +510,12 @@ static int __init dsp56k_init_driver(void)
printk("DSP56k driver: Unable to register driver\n");
return -ENODEV;
}
- dsp56k_class = class_simple_create(THIS_MODULE, "dsp56k");
+ dsp56k_class = class_create(THIS_MODULE, "dsp56k");
if (IS_ERR(dsp56k_class)) {
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
- class_simple_device_add(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
+ class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
@@ -526,8 +526,8 @@ static int __init dsp56k_init_driver(void)
goto out;
out_class:
- class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0));
- class_simple_destroy(dsp56k_class);
+ class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
+ class_destroy(dsp56k_class);
out_chrdev:
unregister_chrdev(DSP56K_MAJOR, "dsp56k");
out:
@@ -537,8 +537,8 @@ module_init(dsp56k_init_driver);
static void __exit dsp56k_cleanup_driver(void)
{
- class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0));
- class_simple_destroy(dsp56k_class);
+ class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
+ class_destroy(dsp56k_class);
unregister_chrdev(DSP56K_MAJOR, "dsp56k");
devfs_remove("dsp56k");
}
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index dbac7e54e8e0..5745b74044ec 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -99,7 +99,7 @@ static struct file_operations zft_cdev =
.release = zft_close,
};
-static struct class_simple *zft_class;
+static struct class *zft_class;
/* Open floppy tape device
*/
@@ -329,29 +329,29 @@ KERN_INFO
"installing zftape VFS interface for ftape driver ...");
TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),);
- zft_class = class_simple_create(THIS_MODULE, "zft");
+ zft_class = class_create(THIS_MODULE, "zft");
for (i = 0; i < 4; i++) {
- class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
+ class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"qft%i", i);
- class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
+ class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
S_IFCHR | S_IRUSR | S_IWUSR,
"nqft%i", i);
- class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
+ class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
S_IFCHR | S_IRUSR | S_IWUSR,
"zqft%i", i);
- class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
+ class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
S_IFCHR | S_IRUSR | S_IWUSR,
"nzqft%i", i);
- class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
+ class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
S_IFCHR | S_IRUSR | S_IWUSR,
"rawqft%i", i);
- class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
+ class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
S_IFCHR | S_IRUSR | S_IWUSR,
"nrawqft%i", i);
@@ -381,19 +381,19 @@ static void zft_exit(void)
}
for (i = 0; i < 4; i++) {
devfs_remove("qft%i", i);
- class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i));
+ class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
devfs_remove("nqft%i", i);
- class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 4));
+ class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
devfs_remove("zqft%i", i);
- class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 16));
+ class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
devfs_remove("nzqft%i", i);
- class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 20));
+ class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
devfs_remove("rawqft%i", i);
- class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 32));
+ class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
devfs_remove("nrawqft%i", i);
- class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 36));
+ class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
}
- class_simple_destroy(zft_class);
+ class_destroy(zft_class);
zft_uninit_mem(); /* release remaining memory, if any */
printk(KERN_INFO "zftape successfully unloaded.\n");
TRACE_EXIT;
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index abfbdcfd4e72..3236d2404905 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -1466,7 +1466,7 @@ static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod)
}
/* The sysfs interface for the driver and devices */
-static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf)
+static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct vio_dev *viod = to_vio_dev(dev);
struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1480,7 +1480,7 @@ static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf)
}
static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL);
-static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf)
+static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct vio_dev *viod = to_vio_dev(dev);
struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1494,7 +1494,7 @@ static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf)
}
static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL);
-static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf,
+static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf,
size_t count)
{
/*
@@ -1505,7 +1505,7 @@ static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf,
return -EPERM;
}
-static ssize_t hvcs_current_vty_show(struct device *dev, char *buf)
+static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct vio_dev *viod = to_vio_dev(dev);
struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1521,7 +1521,7 @@ static ssize_t hvcs_current_vty_show(struct device *dev, char *buf)
static DEVICE_ATTR(current_vty,
S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
-static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf,
+static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct vio_dev *viod = to_vio_dev(dev);
@@ -1559,7 +1559,7 @@ static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf,
return count;
}
-static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf)
+static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct vio_dev *viod = to_vio_dev(dev);
struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1574,7 +1574,7 @@ static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf)
static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR,
hvcs_vterm_state_show, hvcs_vterm_state_store);
-static ssize_t hvcs_index_show(struct device *dev, char *buf)
+static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct vio_dev *viod = to_vio_dev(dev);
struct hvcs_struct *hvcsd = from_vio_dev(viod);
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index fca9a978fb73..3b8314b4249a 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -302,7 +302,7 @@ static char rirqs[IP2_MAX_BOARDS];
static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
/* for sysfs class support */
-static struct class_simple *ip2_class;
+static struct class *ip2_class;
// Some functions to keep track of what irq's we have
@@ -414,9 +414,9 @@ cleanup_module(void)
iiResetDelay( i2BoardPtrTable[i] );
/* free io addresses and Tibet */
release_region( ip2config.addr[i], 8 );
- class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i));
+ class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
devfs_remove("ip2/ipl%d", i);
- class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
+ class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
devfs_remove("ip2/stat%d", i);
}
/* Disable and remove interrupt handler. */
@@ -425,7 +425,7 @@ cleanup_module(void)
clear_requested_irq( ip2config.irq[i]);
}
}
- class_simple_destroy(ip2_class);
+ class_destroy(ip2_class);
devfs_remove("ip2");
if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
@@ -700,7 +700,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
} else {
/* create the sysfs class */
- ip2_class = class_simple_create(THIS_MODULE, "ip2");
+ ip2_class = class_create(THIS_MODULE, "ip2");
if (IS_ERR(ip2_class)) {
err = PTR_ERR(ip2_class);
goto out_chrdev;
@@ -722,25 +722,25 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
}
if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
- class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR,
+ class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
4 * i), NULL, "ipl%d", i);
err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
"ip2/ipl%d", i);
if (err) {
- class_simple_device_remove(MKDEV(IP2_IPL_MAJOR,
- 4 * i));
+ class_device_destroy(ip2_class,
+ MKDEV(IP2_IPL_MAJOR, 4 * i));
goto out_class;
}
- class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR,
+ class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
4 * i + 1), NULL, "stat%d", i);
err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
"ip2/stat%d", i);
if (err) {
- class_simple_device_remove(MKDEV(IP2_IPL_MAJOR,
- 4 * i + 1));
+ class_device_destroy(ip2_class,
+ MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
goto out_class;
}
@@ -798,7 +798,7 @@ retry:
goto out;
out_class:
- class_simple_destroy(ip2_class);
+ class_destroy(ip2_class);
out_chrdev:
unregister_chrdev(IP2_IPL_MAJOR, "ip2");
out:
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 6dc765dc5413..88d1ad656e99 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -520,7 +520,7 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By"
" interface. Other values will set the major device number"
" to that value.");
-static struct class_simple *ipmi_class;
+static struct class *ipmi_class;
static void ipmi_new_smi(int if_num)
{
@@ -529,12 +529,12 @@ static void ipmi_new_smi(int if_num)
devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
"ipmidev/%d", if_num);
- class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num);
+ class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
}
static void ipmi_smi_gone(int if_num)
{
- class_simple_device_remove(MKDEV(ipmi_major, if_num));
+ class_device_destroy(ipmi_class, MKDEV(ipmi_major, if_num));
devfs_remove("ipmidev/%d", if_num);
}
@@ -555,7 +555,7 @@ static __init int init_ipmi_devintf(void)
printk(KERN_INFO "ipmi device interface version "
IPMI_DEVINTF_VERSION "\n");
- ipmi_class = class_simple_create(THIS_MODULE, "ipmi");
+ ipmi_class = class_create(THIS_MODULE, "ipmi");
if (IS_ERR(ipmi_class)) {
printk(KERN_ERR "ipmi: can't register device class\n");
return PTR_ERR(ipmi_class);
@@ -563,7 +563,7 @@ static __init int init_ipmi_devintf(void)
rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
if (rv < 0) {
- class_simple_destroy(ipmi_class);
+ class_destroy(ipmi_class);
printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
return rv;
}
@@ -577,7 +577,7 @@ static __init int init_ipmi_devintf(void)
rv = ipmi_smi_watcher_register(&smi_watcher);
if (rv) {
unregister_chrdev(ipmi_major, DEVICE_NAME);
- class_simple_destroy(ipmi_class);
+ class_destroy(ipmi_class);
printk(KERN_WARNING "ipmi: can't register smi watcher\n");
return rv;
}
@@ -588,7 +588,7 @@ module_init(init_ipmi_devintf);
static __exit void cleanup_ipmi(void)
{
- class_simple_destroy(ipmi_class);
+ class_destroy(ipmi_class);
ipmi_smi_watcher_unregister(&smi_watcher);
devfs_remove(DEVICE_NAME);
unregister_chrdev(ipmi_major, DEVICE_NAME);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 21aed0e8779d..c02a21dbad5d 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -792,7 +792,7 @@ static int stli_timeron;
/*****************************************************************************/
-static struct class_simple *istallion_class;
+static struct class *istallion_class;
#ifdef MODULE
@@ -854,10 +854,10 @@ static void __exit istallion_module_exit(void)
put_tty_driver(stli_serial);
for (i = 0; i < 4; i++) {
devfs_remove("staliomem/%d", i);
- class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i));
+ class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i));
}
devfs_remove("staliomem");
- class_simple_destroy(istallion_class);
+ class_destroy(istallion_class);
if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
printk("STALLION: failed to un-register serial memory device, "
"errno=%d\n", -i);
@@ -5242,12 +5242,12 @@ int __init stli_init(void)
"device\n");
devfs_mk_dir("staliomem");
- istallion_class = class_simple_create(THIS_MODULE, "staliomem");
+ istallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++) {
devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"staliomem/%d", i);
- class_simple_device_add(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
+ class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
NULL, "staliomem%d", i);
}
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 4dee945031d4..59eebe5a035f 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -146,7 +146,7 @@
static struct lp_struct lp_table[LP_NO];
static unsigned int lp_count = 0;
-static struct class_simple *lp_class;
+static struct class *lp_class;
#ifdef CONFIG_LP_CONSOLE
static struct parport *console_registered; // initially NULL
@@ -804,7 +804,7 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
- class_simple_device_add(lp_class, MKDEV(LP_MAJOR, nr), NULL,
+ class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
"lp%d", nr);
devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
"printers/%d", nr);
@@ -907,7 +907,7 @@ static int __init lp_init (void)
}
devfs_mk_dir("printers");
- lp_class = class_simple_create(THIS_MODULE, "printer");
+ lp_class = class_create(THIS_MODULE, "printer");
if (IS_ERR(lp_class)) {
err = PTR_ERR(lp_class);
goto out_devfs;
@@ -930,7 +930,7 @@ static int __init lp_init (void)
return 0;
out_class:
- class_simple_destroy(lp_class);
+ class_destroy(lp_class);
out_devfs:
devfs_remove("printers");
unregister_chrdev(LP_MAJOR, "lp");
@@ -981,10 +981,10 @@ static void lp_cleanup_module (void)
continue;
parport_unregister_device(lp_table[offset].dev);
devfs_remove("printers/%d", offset);
- class_simple_device_remove(MKDEV(LP_MAJOR, offset));
+ class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
}
devfs_remove("printers");
- class_simple_destroy(lp_class);
+ class_destroy(lp_class);
}
__setup("lp=", lp_setup);
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index ac9cfa9701ea..115dbb35334b 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -699,7 +699,7 @@ static inline int mbcs_hw_init(struct mbcs_soft *soft)
return 0;
}
-static ssize_t show_algo(struct device *dev, char *buf)
+static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char *buf)
{
struct cx_dev *cx_dev = to_cx_dev(dev);
struct mbcs_soft *soft = cx_dev->soft;
@@ -715,7 +715,7 @@ static ssize_t show_algo(struct device *dev, char *buf)
(debug0 >> 32), (debug0 & 0xffffffff));
}
-static ssize_t store_algo(struct device *dev, const char *buf, size_t count)
+static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int n;
struct cx_dev *cx_dev = to_cx_dev(dev);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 947cb3cef816..257b8ee605e5 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -856,7 +856,7 @@ static const struct {
{11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops},
};
-static struct class_simple *mem_class;
+static struct class *mem_class;
static int __init chr_dev_init(void)
{
@@ -865,10 +865,9 @@ static int __init chr_dev_init(void)
if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
- mem_class = class_simple_create(THIS_MODULE, "mem");
+ mem_class = class_create(THIS_MODULE, "mem");
for (i = 0; i < ARRAY_SIZE(devlist); i++) {
- class_simple_device_add(mem_class,
- MKDEV(MEM_MAJOR, devlist[i].minor),
+ class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
NULL, devlist[i].name);
devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
S_IFCHR | devlist[i].mode, devlist[i].name);
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 0937544762da..3115d318b997 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -177,10 +177,10 @@ fail:
/*
* TODO for 2.7:
- * - add a struct class_device to struct miscdevice and make all usages of
+ * - add a struct kref to struct miscdevice and make all usages of
* them dynamic.
*/
-static struct class_simple *misc_class;
+static struct class *misc_class;
static struct file_operations misc_fops = {
.owner = THIS_MODULE,
@@ -238,8 +238,8 @@ int misc_register(struct miscdevice * misc)
}
dev = MKDEV(MISC_MAJOR, misc->minor);
- misc->class = class_simple_device_add(misc_class, dev,
- misc->dev, misc->name);
+ misc->class = class_device_create(misc_class, dev, misc->dev,
+ "%s", misc->name);
if (IS_ERR(misc->class)) {
err = PTR_ERR(misc->class);
goto out;
@@ -248,7 +248,7 @@ int misc_register(struct miscdevice * misc)
err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,
misc->devfs_name);
if (err) {
- class_simple_device_remove(dev);
+ class_device_destroy(misc_class, dev);
goto out;
}
@@ -281,7 +281,7 @@ int misc_deregister(struct miscdevice * misc)
down(&misc_sem);
list_del(&misc->list);
- class_simple_device_remove(MKDEV(MISC_MAJOR, misc->minor));
+ class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
devfs_remove(misc->devfs_name);
if (i < DYNAMIC_MINORS && i>0) {
misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
@@ -302,7 +302,7 @@ static int __init misc_init(void)
if (ent)
ent->proc_fops = &misc_proc_fops;
#endif
- misc_class = class_simple_create(THIS_MODULE, "misc");
+ misc_class = class_create(THIS_MODULE, "misc");
if (IS_ERR(misc_class))
return PTR_ERR(misc_class);
#ifdef CONFIG_MVME16x
@@ -323,7 +323,7 @@ static int __init misc_init(void)
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
printk("unable to get major %d for misc devices\n",
MISC_MAJOR);
- class_simple_destroy(misc_class);
+ class_destroy(misc_class);
return -EIO;
}
return 0;
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index d37625d47746..d568991ac6b3 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -472,7 +472,7 @@ struct device mwave_device;
/* Prevent code redundancy, create a macro for mwave_show_* functions. */
#define mwave_show_function(attr_name, format_string, field) \
-static ssize_t mwave_show_##attr_name(struct device *dev, char *buf) \
+static ssize_t mwave_show_##attr_name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
DSP_3780I_CONFIG_SETTINGS *pSettings = \
&mwave_s_mdd.rBDData.rDspSettings; \
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 5eda075c62bd..0e22880432bc 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -737,7 +737,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait)
return mask;
}
-static struct class_simple *ppdev_class;
+static struct class *ppdev_class;
static struct file_operations pp_fops = {
.owner = THIS_MODULE,
@@ -752,13 +752,13 @@ static struct file_operations pp_fops = {
static void pp_attach(struct parport *port)
{
- class_simple_device_add(ppdev_class, MKDEV(PP_MAJOR, port->number),
+ class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number),
NULL, "parport%d", port->number);
}
static void pp_detach(struct parport *port)
{
- class_simple_device_remove(MKDEV(PP_MAJOR, port->number));
+ class_device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number));
}
static struct parport_driver pp_driver = {
@@ -776,7 +776,7 @@ static int __init ppdev_init (void)
PP_MAJOR);
return -EIO;
}
- ppdev_class = class_simple_create(THIS_MODULE, CHRDEV);
+ ppdev_class = class_create(THIS_MODULE, CHRDEV);
if (IS_ERR(ppdev_class)) {
err = PTR_ERR(ppdev_class);
goto out_chrdev;
@@ -798,7 +798,7 @@ out_class:
for (i = 0; i < PARPORT_MAX; i++)
devfs_remove("parports/%d", i);
devfs_remove("parports");
- class_simple_destroy(ppdev_class);
+ class_destroy(ppdev_class);
out_chrdev:
unregister_chrdev(PP_MAJOR, CHRDEV);
out:
@@ -813,7 +813,7 @@ static void __exit ppdev_cleanup (void)
devfs_remove("parports/%d", i);
parport_unregister_driver(&pp_driver);
devfs_remove("parports");
- class_simple_destroy(ppdev_class);
+ class_destroy(ppdev_class);
unregister_chrdev (PP_MAJOR, CHRDEV);
}
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index ca5f42bcaad9..f13e5de02207 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -27,7 +27,7 @@ struct raw_device_data {
int inuse;
};
-static struct class_simple *raw_class;
+static struct class *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS];
static DECLARE_MUTEX(raw_mutex);
static struct file_operations raw_ctl_fops; /* forward declaration */
@@ -127,8 +127,8 @@ raw_ioctl(struct inode *inode, struct file *filp,
static void bind_device(struct raw_config_request *rq)
{
- class_simple_device_remove(MKDEV(RAW_MAJOR, rq->raw_minor));
- class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
+ class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
+ class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
NULL, "raw%d", rq->raw_minor);
}
@@ -200,8 +200,8 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
if (rq.block_major == 0 && rq.block_minor == 0) {
/* unbind */
rawdev->binding = NULL;
- class_simple_device_remove(MKDEV(RAW_MAJOR,
- rq.raw_minor));
+ class_device_destroy(raw_class,
+ MKDEV(RAW_MAJOR, rq.raw_minor));
} else {
rawdev->binding = bdget(dev);
if (rawdev->binding == NULL)
@@ -300,14 +300,14 @@ static int __init raw_init(void)
goto error;
}
- raw_class = class_simple_create(THIS_MODULE, "raw");
+ raw_class = class_create(THIS_MODULE, "raw");
if (IS_ERR(raw_class)) {
printk(KERN_ERR "Error creating raw class.\n");
cdev_del(&raw_cdev);
unregister_chrdev_region(dev, MAX_RAW_MINORS);
goto error;
}
- class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+ class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
S_IFCHR | S_IRUGO | S_IWUGO,
@@ -331,8 +331,8 @@ static void __exit raw_exit(void)
devfs_remove("raw/raw%d", i);
devfs_remove("raw/rawctl");
devfs_remove("raw");
- class_simple_device_remove(MKDEV(RAW_MAJOR, 0));
- class_simple_destroy(raw_class);
+ class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
+ class_destroy(raw_class);
cdev_del(&raw_cdev);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
}
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index e3c0b52d943f..261a41bf6d02 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -357,6 +357,8 @@ static struct file_operations scdrv_fops = {
.release = scdrv_release,
};
+static struct class *snsc_class;
+
/*
* scdrv_init
*
@@ -372,7 +374,6 @@ scdrv_init(void)
char *devnamep;
struct sysctl_data_s *scd;
void *salbuf;
- struct class_simple *snsc_class;
dev_t first_dev, dev;
nasid_t event_nasid = ia64_sn_get_console_nasid();
@@ -382,7 +383,7 @@ scdrv_init(void)
__FUNCTION__);
return -ENODEV;
}
- snsc_class = class_simple_create(THIS_MODULE, SYSCTL_BASENAME);
+ snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);
for (cnode = 0; cnode < numionodes; cnode++) {
geoid = cnodeid_get_geoid(cnode);
@@ -436,7 +437,7 @@ scdrv_init(void)
continue;
}
- class_simple_device_add(snsc_class, dev, NULL,
+ class_device_create(snsc_class, dev, NULL,
"%s", devname);
ia64_sn_irtr_intr_enable(scd->scd_nasid,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index b8899f560b5e..951545a6ef2d 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -719,7 +719,7 @@ static struct file_operations stl_fsiomem = {
/*****************************************************************************/
-static struct class_simple *stallion_class;
+static struct class *stallion_class;
/*
* Loadable module initialization stuff.
@@ -777,13 +777,13 @@ static void __exit stallion_module_exit(void)
}
for (i = 0; i < 4; i++) {
devfs_remove("staliomem/%d", i);
- class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i));
+ class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
}
devfs_remove("staliomem");
if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
printk("STALLION: failed to un-register serial memory device, "
"errno=%d\n", -i);
- class_simple_destroy(stallion_class);
+ class_destroy(stallion_class);
if (stl_tmpwritebuf != (char *) NULL)
kfree(stl_tmpwritebuf);
@@ -3090,12 +3090,12 @@ static int __init stl_init(void)
printk("STALLION: failed to register serial board device\n");
devfs_mk_dir("staliomem");
- stallion_class = class_simple_create(THIS_MODULE, "staliomem");
+ stallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++) {
devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
S_IFCHR|S_IRUSR|S_IWUSR,
"staliomem/%d", i);
- class_simple_device_add(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
+ class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
}
stl_serial->owner = THIS_MODULE;
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 0c5ba9dc9063..659335d80ee7 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -90,7 +90,7 @@ static int timeout = TIMAXTIME; /* timeout in tenth of seconds */
static unsigned int tp_count; /* tipar count */
static unsigned long opened; /* opened devices */
-static struct class_simple *tipar_class;
+static struct class *tipar_class;
/* --- macros for parport access -------------------------------------- */
@@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *port)
goto out;
}
- class_simple_device_add(tipar_class, MKDEV(TIPAR_MAJOR,
+ class_device_create(tipar_class, MKDEV(TIPAR_MAJOR,
TIPAR_MINOR + nr), NULL, "par%d", nr);
/* Use devfs, tree: /dev/ticables/par/[0..2] */
err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
@@ -458,8 +458,8 @@ tipar_register(int nr, struct parport *port)
goto out;
out_class:
- class_simple_device_remove(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr));
- class_simple_destroy(tipar_class);
+ class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr));
+ class_destroy(tipar_class);
out:
return err;
}
@@ -505,7 +505,7 @@ tipar_init_module(void)
/* Use devfs with tree: /dev/ticables/par/[0..2] */
devfs_mk_dir("ticables/par");
- tipar_class = class_simple_create(THIS_MODULE, "ticables");
+ tipar_class = class_create(THIS_MODULE, "ticables");
if (IS_ERR(tipar_class)) {
err = PTR_ERR(tipar_class);
goto out_chrdev;
@@ -539,10 +539,10 @@ tipar_cleanup_module(void)
if (table[i].dev == NULL)
continue;
parport_unregister_device(table[i].dev);
- class_simple_device_remove(MKDEV(TIPAR_MAJOR, i));
+ class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
devfs_remove("ticables/par/%d", i);
}
- class_simple_destroy(tipar_class);
+ class_destroy(tipar_class);
devfs_remove("ticables/par");
pr_info("tipar: module unloaded\n");
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 87235330fdbe..8ce508b29865 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -212,7 +212,7 @@ static u8 pcrread[] = {
0, 0, 0, 0 /* PCR index */
};
-static ssize_t show_pcrs(struct device *dev, char *buf)
+static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf)
{
u8 data[READ_PCR_RESULT_SIZE];
ssize_t len;
@@ -255,7 +255,7 @@ static u8 readpubek[] = {
0, 0, 0, 124, /* TPM_ORD_ReadPubek */
};
-static ssize_t show_pubek(struct device *dev, char *buf)
+static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf)
{
u8 data[READ_PUBEK_RESULT_SIZE];
ssize_t len;
@@ -330,7 +330,7 @@ static u8 cap_manufacturer[] = {
0, 0, 1, 3
};
-static ssize_t show_caps(struct device *dev, char *buf)
+static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf)
{
u8 data[READ_PUBEK_RESULT_SIZE];
ssize_t len;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 26e5e19ed854..31831030f73f 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2654,7 +2654,7 @@ static void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
tty->driver->write(tty, &ch, 1);
}
-static struct class_simple *tty_class;
+static struct class *tty_class;
/**
* tty_register_device - register a tty device
@@ -2687,7 +2687,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
pty_line_name(driver, index, name);
else
tty_line_name(driver, index, name);
- class_simple_device_add(tty_class, dev, device, name);
+ class_device_create(tty_class, dev, device, name);
}
/**
@@ -2701,7 +2701,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
void tty_unregister_device(struct tty_driver *driver, unsigned index)
{
devfs_remove("%s%d", driver->devfs_name, index + driver->name_base);
- class_simple_device_remove(MKDEV(driver->major, driver->minor_start) + index);
+ class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index);
}
EXPORT_SYMBOL(tty_register_device);
@@ -2918,7 +2918,7 @@ extern int vty_init(void);
static int __init tty_class_init(void)
{
- tty_class = class_simple_create(THIS_MODULE, "tty");
+ tty_class = class_create(THIS_MODULE, "tty");
if (IS_ERR(tty_class))
return PTR_ERR(tty_class);
return 0;
@@ -2947,14 +2947,14 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
panic("Couldn't register /dev/tty driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
- class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
+ class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
cdev_init(&console_cdev, &console_fops);
if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
panic("Couldn't register /dev/console driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
- class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
+ class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
#ifdef CONFIG_UNIX98_PTYS
cdev_init(&ptmx_cdev, &ptmx_fops);
@@ -2962,7 +2962,7 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
panic("Couldn't register /dev/ptmx driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
- class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+ class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
#endif
#ifdef CONFIG_VT
@@ -2971,7 +2971,7 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
panic("Couldn't register /dev/tty0 driver\n");
devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
- class_simple_device_add(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+ class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
vty_init();
#endif
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 7abe405b8657..79c2928a8817 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -474,7 +474,7 @@ static struct file_operations vcs_fops = {
.open = vcs_open,
};
-static struct class_simple *vc_class;
+static struct class *vc_class;
void vcs_make_devfs(struct tty_struct *tty)
{
@@ -484,26 +484,26 @@ void vcs_make_devfs(struct tty_struct *tty)
devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
S_IFCHR|S_IRUSR|S_IWUSR,
"vcc/a%u", tty->index + 1);
- class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
- class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
+ class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
+ class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
}
void vcs_remove_devfs(struct tty_struct *tty)
{
devfs_remove("vcc/%u", tty->index + 1);
devfs_remove("vcc/a%u", tty->index + 1);
- class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 1));
- class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 129));
+ class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
+ class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
}
int __init vcs_init(void)
{
if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
panic("unable to get major %d for vcs device", VCS_MAJOR);
- vc_class = class_simple_create(THIS_MODULE, "vc");
+ vc_class = class_create(THIS_MODULE, "vc");
devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
- class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
- class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+ class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+ class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
return 0;
}
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index aea3cbf5219d..4764b4f9555d 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -237,7 +237,7 @@ static dma_addr_t viotape_unitinfo_token;
static struct mtget viomtget[VIOTAPE_MAX_TAPE];
-static struct class_simple *tape_class;
+static struct class *tape_class;
static struct device *tape_device[VIOTAPE_MAX_TAPE];
@@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
- class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
+ class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
"iseries!vt%d", i);
- class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
+ class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
NULL, "iseries!nvt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
"iseries/vt%d", i);
@@ -980,8 +980,8 @@ static int viotape_remove(struct vio_dev *vdev)
devfs_remove("iseries/nvt%d", i);
devfs_remove("iseries/vt%d", i);
devfs_unregister_tape(state[i].dev_handle);
- class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80));
- class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i));
+ class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
+ class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
return 0;
}
@@ -1045,7 +1045,7 @@ int __init viotap_init(void)
goto clear_handler;
}
- tape_class = class_simple_create(THIS_MODULE, "tape");
+ tape_class = class_create(THIS_MODULE, "tape");
if (IS_ERR(tape_class)) {
printk(VIOTAPE_KERN_WARN "Unable to allocat class\n");
ret = PTR_ERR(tape_class);
@@ -1070,7 +1070,7 @@ int __init viotap_init(void)
return 0;
unreg_class:
- class_simple_destroy(tape_class);
+ class_destroy(tape_class);
unreg_chrdev:
unregister_chrdev(VIOTAPE_MAJOR, "viotape");
clear_handler:
@@ -1110,7 +1110,7 @@ static void __exit viotap_exit(void)
remove_proc_entry("iSeries/viotape", NULL);
vio_unregister_driver(&viotape_driver);
- class_simple_destroy(tape_class);
+ class_destroy(tape_class);
ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape");
if (ret < 0)
printk(VIOTAPE_KERN_WARN "Error unregistering device: %d\n",
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index ab659d37b4d2..4e98c215e5b1 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -192,7 +192,12 @@ static struct miscdevice ixp2000_wdt_miscdev =
static int __init ixp2000_wdt_init(void)
{
- wdt_tick_rate = (*IXP2000_T1_CLD * HZ)/ 256;;
+ if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
+ printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
+ return -EIO;
+ }
+
+ wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
return misc_register(&ixp2000_wdt_miscdev);
}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 03b5fb2ddcf4..bf62dfe4976a 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -521,7 +521,7 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
return -EINVAL;
- ret = fattr->show ? fattr->show(policy,buf) : 0;
+ ret = fattr->show ? fattr->show(policy,buf) : -EIO;
cpufreq_cpu_put(policy);
return ret;
}
@@ -535,7 +535,7 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
return -EINVAL;
- ret = fattr->store ? fattr->store(policy,buf,count) : 0;
+ ret = fattr->store ? fattr->store(policy,buf,count) : -EIO;
cpufreq_cpu_put(policy);
return ret;
}
diff --git a/drivers/dio/dio-sysfs.c b/drivers/dio/dio-sysfs.c
index d30591f69dd9..f46463038847 100644
--- a/drivers/dio/dio-sysfs.c
+++ b/drivers/dio/dio-sysfs.c
@@ -17,7 +17,7 @@
/* show configuration fields */
-static ssize_t dio_show_id(struct device *dev, char *buf)
+static ssize_t dio_show_id(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dio_dev *d;
@@ -26,7 +26,7 @@ static ssize_t dio_show_id(struct device *dev, char *buf)
}
static DEVICE_ATTR(id, S_IRUGO, dio_show_id, NULL);
-static ssize_t dio_show_ipl(struct device *dev, char *buf)
+static ssize_t dio_show_ipl(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dio_dev *d;
@@ -35,7 +35,7 @@ static ssize_t dio_show_ipl(struct device *dev, char *buf)
}
static DEVICE_ATTR(ipl, S_IRUGO, dio_show_ipl, NULL);
-static ssize_t dio_show_secid(struct device *dev, char *buf)
+static ssize_t dio_show_secid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dio_dev *d;
@@ -44,7 +44,7 @@ static ssize_t dio_show_secid(struct device *dev, char *buf)
}
static DEVICE_ATTR(secid, S_IRUGO, dio_show_secid, NULL);
-static ssize_t dio_show_name(struct device *dev, char *buf)
+static ssize_t dio_show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dio_dev *d;
@@ -53,7 +53,7 @@ static ssize_t dio_show_name(struct device *dev, char *buf)
}
static DEVICE_ATTR(name, S_IRUGO, dio_show_name, NULL);
-static ssize_t dio_show_resource(struct device *dev, char *buf)
+static ssize_t dio_show_resource(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dio_dev *d = to_dio_dev(dev);
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 6381ba53853c..1937743c8e29 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -149,7 +149,7 @@ void eisa_driver_unregister (struct eisa_driver *edrv)
driver_unregister (&edrv->driver);
}
-static ssize_t eisa_show_sig (struct device *dev, char *buf)
+static ssize_t eisa_show_sig (struct device *dev, struct device_attribute *attr, char *buf)
{
struct eisa_device *edev = to_eisa_device (dev);
return sprintf (buf,"%s\n", edev->id.sig);
@@ -157,7 +157,7 @@ static ssize_t eisa_show_sig (struct device *dev, char *buf)
static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
-static ssize_t eisa_show_state (struct device *dev, char *buf)
+static ssize_t eisa_show_state (struct device *dev, struct device_attribute *attr, char *buf)
{
struct eisa_device *edev = to_eisa_device (dev);
return sprintf (buf,"%d\n", edev->state & EISA_CONFIG_ENABLED);
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index fbd9ff79b7b8..e3c958823533 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -765,8 +765,6 @@ void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */
static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
{
- unsigned long flags;
-
if (FCP_CMND(SCpnt)->done)
FCP_CMND(SCpnt)->done(SCpnt);
}
@@ -907,8 +905,6 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
*/
if (++fc->abort_count < (fc->can_queue >> 1)) {
- unsigned long flags;
-
SCpnt->result = DID_ABORT;
fcmd->done(SCpnt);
printk("FC: soft abort\n");
@@ -931,6 +927,7 @@ void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt)
int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
{
+ unsigned long flags;
fcp_cmd *cmd;
fcp_cmnd *fcmd;
fc_channel *fc = FC_SCMND(SCpnt);
@@ -1028,6 +1025,7 @@ static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
{
+ unsigned long flags;
int rc;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 33b669e6f977..6996476669f1 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -115,7 +115,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
{
struct edd_device *dev = to_edd_device(kobj);
struct edd_attribute *edd_attr = to_edd_attr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (edd_attr->show)
ret = edd_attr->show(dev, buf);
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 0287ff65963b..a3451cb94004 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -352,7 +352,7 @@ static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
{
struct efivar_entry *var = to_efivar_entry(kobj);
struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -368,7 +368,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
{
struct efivar_entry *var = to_efivar_entry(kobj);
struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
diff --git a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
index 9c59a370b6d9..9058c3956710 100644
--- a/drivers/i2c/chips/adm1021.c
+++ b/drivers/i2c/chips/adm1021.c
@@ -137,7 +137,7 @@ static struct i2c_driver adm1021_driver = {
};
#define show(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1021_data *data = adm1021_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
@@ -150,7 +150,7 @@ show(remote_temp_hyst);
show(remote_temp_input);
#define show2(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1021_data *data = adm1021_update_device(dev); \
return sprintf(buf, "%d\n", data->value); \
@@ -159,7 +159,7 @@ show2(alarms);
show2(die_code);
#define set(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1021_data *data = i2c_get_clientdata(client); \
diff --git a/drivers/i2c/chips/adm1025.c b/drivers/i2c/chips/adm1025.c
index e0771a3d05c9..111f0c86c933 100644
--- a/drivers/i2c/chips/adm1025.c
+++ b/drivers/i2c/chips/adm1025.c
@@ -153,19 +153,19 @@ struct adm1025_data {
*/
#define show_in(offset) \
-static ssize_t show_in##offset(struct device *dev, char *buf) \
+static ssize_t show_in##offset(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1025_data *data = adm1025_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
in_scale[offset])); \
} \
-static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1025_data *data = adm1025_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
in_scale[offset])); \
} \
-static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1025_data *data = adm1025_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
@@ -180,17 +180,17 @@ show_in(4);
show_in(5);
#define show_temp(offset) \
-static ssize_t show_temp##offset(struct device *dev, char *buf) \
+static ssize_t show_temp##offset(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1025_data *data = adm1025_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
} \
-static ssize_t show_temp##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1025_data *data = adm1025_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
} \
-static ssize_t show_temp##offset##_max(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct adm1025_data *data = adm1025_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
@@ -200,7 +200,7 @@ show_temp(1);
show_temp(2);
#define set_in(offset) \
-static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -214,7 +214,7 @@ static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
+static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -240,7 +240,7 @@ set_in(4);
set_in(5);
#define set_temp(offset) \
-static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -254,7 +254,7 @@ static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -275,26 +275,26 @@ static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
set_temp(1);
set_temp(2);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1025_data *data = adm1025_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
}
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-static ssize_t show_vid(struct device *dev, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1025_data *data = adm1025_update_device(dev);
return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
}
static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL);
-static ssize_t show_vrm(struct device *dev, char *buf)
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1025_data *data = adm1025_update_device(dev);
return sprintf(buf, "%u\n", data->vrm);
}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
diff --git a/drivers/i2c/chips/adm1026.c b/drivers/i2c/chips/adm1026.c
index 39e2f4a900bf..b15fafe8f111 100644
--- a/drivers/i2c/chips/adm1026.c
+++ b/drivers/i2c/chips/adm1026.c
@@ -30,6 +30,7 @@
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/i2c-sensor.h>
+#include <linux/i2c-sysfs.h>
#include <linux/i2c-vid.h>
/* Addresses to scan */
@@ -711,19 +712,27 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
return data;
}
-static ssize_t show_in(struct device *dev, char *buf, int nr)
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]));
}
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]));
}
-static ssize_t set_in_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -734,14 +743,19 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
up(&data->update_lock);
return count;
}
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]));
}
-static ssize_t set_in_max(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -753,34 +767,13 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
return count;
}
-#define in_reg(offset) \
-static ssize_t show_in##offset (struct device *dev, char *buf) \
-{ \
- return show_in(dev, buf, offset); \
-} \
-static ssize_t show_in##offset##_min (struct device *dev, char *buf) \
-{ \
- return show_in_min(dev, buf, offset); \
-} \
-static ssize_t set_in##offset##_min (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_in_min(dev, buf, count, offset); \
-} \
-static ssize_t show_in##offset##_max (struct device *dev, char *buf) \
-{ \
- return show_in_max(dev, buf, offset); \
-} \
-static ssize_t set_in##offset##_max (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_in_max(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL); \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max);
+#define in_reg(offset) \
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \
+ NULL, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+ show_in_min, set_in_min, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+ show_in_max, set_in_max, offset);
in_reg(0);
@@ -800,19 +793,19 @@ in_reg(13);
in_reg(14);
in_reg(15);
-static ssize_t show_in16(struct device *dev, char *buf)
+static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in[16]) -
NEG12_OFFSET);
}
-static ssize_t show_in16_min(struct device *dev, char *buf)
+static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_min[16])
- NEG12_OFFSET);
}
-static ssize_t set_in16_min(struct device *dev, const char *buf, size_t count)
+static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
@@ -824,13 +817,13 @@ static ssize_t set_in16_min(struct device *dev, const char *buf, size_t count)
up(&data->update_lock);
return count;
}
-static ssize_t show_in16_max(struct device *dev, char *buf)
+static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_max[16])
- NEG12_OFFSET);
}
-static ssize_t set_in16_max(struct device *dev, const char *buf, size_t count)
+static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
@@ -843,30 +836,38 @@ static ssize_t set_in16_max(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL);
-static DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min);
-static DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max);
+static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16);
+static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min, 16);
+static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max, 16);
/* Now add fan read/write functions */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
+static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
data->fan_div[nr]));
}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
data->fan_div[nr]));
}
-static ssize_t set_fan_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -879,23 +880,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
return count;
}
-#define fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
-{ \
- return show_fan(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
-{ \
- return show_fan_min(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_fan_min(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min);
+#define fan_offset(offset) \
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \
+ offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+ show_fan_min, set_fan_min, offset - 1);
fan_offset(1);
fan_offset(2);
@@ -926,14 +915,19 @@ static void fixup_fan_min(struct device *dev, int fan, int old_div)
}
/* Now add fan_div read/write functions */
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", data->fan_div[nr]);
}
-static ssize_t set_fan_div(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val,orig_div,new_div,shift;
@@ -967,17 +961,8 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define fan_offset_div(offset) \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
-{ \
- return show_fan_div(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan_##offset##_div (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_fan_div(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_div, set_fan_##offset##_div);
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+ show_fan_div, set_fan_div, offset - 1);
fan_offset_div(1);
fan_offset_div(2);
@@ -989,19 +974,27 @@ fan_offset_div(7);
fan_offset_div(8);
/* Temps */
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]));
}
-static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]));
}
-static ssize_t set_temp_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -1013,14 +1006,19 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
up(&data->update_lock);
return count;
}
-static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]));
}
-static ssize_t set_temp_max(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -1032,48 +1030,34 @@ static ssize_t set_temp_max(struct device *dev, const char *buf,
up(&data->update_lock);
return count;
}
-#define temp_reg(offset) \
-static ssize_t show_temp_##offset (struct device *dev, char *buf) \
-{ \
- return show_temp(dev, buf, offset - 1); \
-} \
-static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \
-{ \
- return show_temp_min(dev, buf, offset - 1); \
-} \
-static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \
-{ \
- return show_temp_max(dev, buf, offset - 1); \
-} \
-static ssize_t set_temp_##offset##_min (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_temp_min(dev, buf, count, offset - 1); \
-} \
-static ssize_t set_temp_##offset##_max (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_temp_max(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_min, set_temp_##offset##_min); \
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_max, set_temp_##offset##_max);
+
+#define temp_reg(offset) \
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \
+ NULL, offset - 1); \
+static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
+ show_temp_min, set_temp_min, offset - 1); \
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
+ show_temp_max, set_temp_max, offset - 1);
temp_reg(1);
temp_reg(2);
temp_reg(3);
-static ssize_t show_temp_offset(struct device *dev, char *buf, int nr)
+static ssize_t show_temp_offset(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
}
-static ssize_t set_temp_offset(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_temp_offset(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -1086,46 +1070,45 @@ static ssize_t set_temp_offset(struct device *dev, const char *buf,
return count;
}
-#define temp_offset_reg(offset) \
-static ssize_t show_temp_##offset##_offset (struct device *dev, char *buf) \
-{ \
- return show_temp_offset(dev, buf, offset - 1); \
-} \
-static ssize_t set_temp_##offset##_offset (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_temp_offset(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_offset, set_temp_##offset##_offset);
+#define temp_offset_reg(offset) \
+static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \
+ show_temp_offset, set_temp_offset, offset - 1);
temp_offset_reg(1);
temp_offset_reg(2);
temp_offset_reg(3);
-static ssize_t show_temp_auto_point1_temp_hyst(struct device *dev, char *buf,
- int nr)
+static ssize_t show_temp_auto_point1_temp_hyst(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(
ADM1026_FAN_ACTIVATION_TEMP_HYST + data->temp_tmin[nr]));
}
-static ssize_t show_temp_auto_point2_temp(struct device *dev, char *buf,
- int nr)
+static ssize_t show_temp_auto_point2_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr] +
ADM1026_FAN_CONTROL_TEMP_RANGE));
}
-static ssize_t show_temp_auto_point1_temp(struct device *dev, char *buf,
- int nr)
+static ssize_t show_temp_auto_point1_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr]));
}
-static ssize_t set_temp_auto_point1_temp(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_temp_auto_point1_temp(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -1138,46 +1121,27 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev, const char *buf,
return count;
}
-#define temp_auto_point(offset) \
-static ssize_t show_temp##offset##_auto_point1_temp (struct device *dev, \
- char *buf) \
-{ \
- return show_temp_auto_point1_temp(dev, buf, offset - 1); \
-} \
-static ssize_t set_temp##offset##_auto_point1_temp (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_temp_auto_point1_temp(dev, buf, count, offset - 1); \
-} \
-static ssize_t show_temp##offset##_auto_point1_temp_hyst (struct device \
- *dev, char *buf) \
-{ \
- return show_temp_auto_point1_temp_hyst(dev, buf, offset - 1); \
-} \
-static ssize_t show_temp##offset##_auto_point2_temp (struct device *dev, \
- char *buf) \
-{ \
- return show_temp_auto_point2_temp(dev, buf, offset - 1); \
-} \
-static DEVICE_ATTR(temp##offset##_auto_point1_temp, S_IRUGO | S_IWUSR, \
- show_temp##offset##_auto_point1_temp, \
- set_temp##offset##_auto_point1_temp); \
-static DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO, \
- show_temp##offset##_auto_point1_temp_hyst, NULL); \
-static DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO, \
- show_temp##offset##_auto_point2_temp, NULL);
+#define temp_auto_point(offset) \
+static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp, S_IRUGO | S_IWUSR, \
+ show_temp_auto_point1_temp, set_temp_auto_point1_temp, \
+ offset - 1); \
+static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO, \
+ show_temp_auto_point1_temp_hyst, NULL, offset - 1); \
+static SENSOR_DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO, \
+ show_temp_auto_point2_temp, NULL, offset - 1);
temp_auto_point(1);
temp_auto_point(2);
temp_auto_point(3);
-static ssize_t show_temp_crit_enable(struct device *dev, char *buf)
+static ssize_t show_temp_crit_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", (data->config1 & CFG1_THERM_HOT) >> 4);
}
-static ssize_t set_temp_crit_enable(struct device *dev, const char *buf,
- size_t count)
+static ssize_t set_temp_crit_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
@@ -1193,24 +1157,27 @@ static ssize_t set_temp_crit_enable(struct device *dev, const char *buf,
return count;
}
-static DEVICE_ATTR(temp1_crit_enable, S_IRUGO | S_IWUSR,
- show_temp_crit_enable, set_temp_crit_enable);
-
-static DEVICE_ATTR(temp2_crit_enable, S_IRUGO | S_IWUSR,
- show_temp_crit_enable, set_temp_crit_enable);
-
-static DEVICE_ATTR(temp3_crit_enable, S_IRUGO | S_IWUSR,
+#define temp_crit_enable(offset) \
+static DEVICE_ATTR(temp##offset##_crit_enable, S_IRUGO | S_IWUSR, \
show_temp_crit_enable, set_temp_crit_enable);
+temp_crit_enable(1);
+temp_crit_enable(2);
+temp_crit_enable(3);
-static ssize_t show_temp_crit(struct device *dev, char *buf, int nr)
+static ssize_t show_temp_crit(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
}
-static ssize_t set_temp_crit(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
@@ -1223,29 +1190,20 @@ static ssize_t set_temp_crit(struct device *dev, const char *buf,
return count;
}
-#define temp_crit_reg(offset) \
-static ssize_t show_temp_##offset##_crit (struct device *dev, char *buf) \
-{ \
- return show_temp_crit(dev, buf, offset - 1); \
-} \
-static ssize_t set_temp_##offset##_crit (struct device *dev, \
- const char *buf, size_t count) \
-{ \
- return set_temp_crit(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_crit, set_temp_##offset##_crit);
+#define temp_crit_reg(offset) \
+static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR, \
+ show_temp_crit, set_temp_crit, offset - 1);
temp_crit_reg(1);
temp_crit_reg(2);
temp_crit_reg(3);
-static ssize_t show_analog_out_reg(struct device *dev, char *buf)
+static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", DAC_FROM_REG(data->analog_out));
}
-static ssize_t set_analog_out_reg(struct device *dev, const char *buf,
+static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1262,7 +1220,7 @@ static ssize_t set_analog_out_reg(struct device *dev, const char *buf,
static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg,
set_analog_out_reg);
-static ssize_t show_vid_reg(struct device *dev, char *buf)
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
@@ -1270,12 +1228,12 @@ static ssize_t show_vid_reg(struct device *dev, char *buf)
static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL);
-static ssize_t show_vrm_reg(struct device *dev, char *buf)
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", data->vrm);
}
-static ssize_t store_vrm_reg(struct device *dev, const char *buf,
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1287,7 +1245,7 @@ static ssize_t store_vrm_reg(struct device *dev, const char *buf,
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-static ssize_t show_alarms_reg(struct device *dev, char *buf)
+static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf, "%ld\n", (long) (data->alarms));
@@ -1295,12 +1253,12 @@ static ssize_t show_alarms_reg(struct device *dev, char *buf)
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-static ssize_t show_alarm_mask(struct device *dev, char *buf)
+static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%ld\n", data->alarm_mask);
}
-static ssize_t set_alarm_mask(struct device *dev, const char *buf,
+static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1331,12 +1289,12 @@ static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask,
set_alarm_mask);
-static ssize_t show_gpio(struct device *dev, char *buf)
+static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%ld\n", data->gpio);
}
-static ssize_t set_gpio(struct device *dev, const char *buf,
+static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1359,12 +1317,12 @@ static ssize_t set_gpio(struct device *dev, const char *buf,
static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio);
-static ssize_t show_gpio_mask(struct device *dev, char *buf)
+static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%ld\n", data->gpio_mask);
}
-static ssize_t set_gpio_mask(struct device *dev, const char *buf,
+static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1386,12 +1344,12 @@ static ssize_t set_gpio_mask(struct device *dev, const char *buf,
static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask);
-static ssize_t show_pwm_reg(struct device *dev, char *buf)
+static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm1.pwm));
}
-static ssize_t set_pwm_reg(struct device *dev, const char *buf,
+static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1407,12 +1365,12 @@ static ssize_t set_pwm_reg(struct device *dev, const char *buf,
}
return count;
}
-static ssize_t show_auto_pwm_min(struct device *dev, char *buf)
+static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", data->pwm1.auto_pwm_min);
}
-static ssize_t set_auto_pwm_min(struct device *dev, const char *buf,
+static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1429,16 +1387,16 @@ static ssize_t set_auto_pwm_min(struct device *dev, const char *buf,
up(&data->update_lock);
return count;
}
-static ssize_t show_auto_pwm_max(struct device *dev, char *buf)
+static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", ADM1026_PWM_MAX);
}
-static ssize_t show_pwm_enable(struct device *dev, char *buf)
+static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
return sprintf(buf,"%d\n", data->pwm1.enable);
}
-static ssize_t set_pwm_enable(struct device *dev, const char *buf,
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -1597,114 +1555,114 @@ int adm1026_detect(struct i2c_adapter *adapter, int address,
adm1026_init_client(new_client);
/* Register sysfs hooks */
- device_create_file(&new_client->dev, &dev_attr_in0_input);
- device_create_file(&new_client->dev, &dev_attr_in0_max);
- device_create_file(&new_client->dev, &dev_attr_in0_min);
- device_create_file(&new_client->dev, &dev_attr_in1_input);
- device_create_file(&new_client->dev, &dev_attr_in1_max);
- device_create_file(&new_client->dev, &dev_attr_in1_min);
- device_create_file(&new_client->dev, &dev_attr_in2_input);
- device_create_file(&new_client->dev, &dev_attr_in2_max);
- device_create_file(&new_client->dev, &dev_attr_in2_min);
- device_create_file(&new_client->dev, &dev_attr_in3_input);
- device_create_file(&new_client->dev, &dev_attr_in3_max);
- device_create_file(&new_client->dev, &dev_attr_in3_min);
- device_create_file(&new_client->dev, &dev_attr_in4_input);
- device_create_file(&new_client->dev, &dev_attr_in4_max);
- device_create_file(&new_client->dev, &dev_attr_in4_min);
- device_create_file(&new_client->dev, &dev_attr_in5_input);
- device_create_file(&new_client->dev, &dev_attr_in5_max);
- device_create_file(&new_client->dev, &dev_attr_in5_min);
- device_create_file(&new_client->dev, &dev_attr_in6_input);
- device_create_file(&new_client->dev, &dev_attr_in6_max);
- device_create_file(&new_client->dev, &dev_attr_in6_min);
- device_create_file(&new_client->dev, &dev_attr_in7_input);
- device_create_file(&new_client->dev, &dev_attr_in7_max);
- device_create_file(&new_client->dev, &dev_attr_in7_min);
- device_create_file(&new_client->dev, &dev_attr_in8_input);
- device_create_file(&new_client->dev, &dev_attr_in8_max);
- device_create_file(&new_client->dev, &dev_attr_in8_min);
- device_create_file(&new_client->dev, &dev_attr_in9_input);
- device_create_file(&new_client->dev, &dev_attr_in9_max);
- device_create_file(&new_client->dev, &dev_attr_in9_min);
- device_create_file(&new_client->dev, &dev_attr_in10_input);
- device_create_file(&new_client->dev, &dev_attr_in10_max);
- device_create_file(&new_client->dev, &dev_attr_in10_min);
- device_create_file(&new_client->dev, &dev_attr_in11_input);
- device_create_file(&new_client->dev, &dev_attr_in11_max);
- device_create_file(&new_client->dev, &dev_attr_in11_min);
- device_create_file(&new_client->dev, &dev_attr_in12_input);
- device_create_file(&new_client->dev, &dev_attr_in12_max);
- device_create_file(&new_client->dev, &dev_attr_in12_min);
- device_create_file(&new_client->dev, &dev_attr_in13_input);
- device_create_file(&new_client->dev, &dev_attr_in13_max);
- device_create_file(&new_client->dev, &dev_attr_in13_min);
- device_create_file(&new_client->dev, &dev_attr_in14_input);
- device_create_file(&new_client->dev, &dev_attr_in14_max);
- device_create_file(&new_client->dev, &dev_attr_in14_min);
- device_create_file(&new_client->dev, &dev_attr_in15_input);
- device_create_file(&new_client->dev, &dev_attr_in15_max);
- device_create_file(&new_client->dev, &dev_attr_in15_min);
- device_create_file(&new_client->dev, &dev_attr_in16_input);
- device_create_file(&new_client->dev, &dev_attr_in16_max);
- device_create_file(&new_client->dev, &dev_attr_in16_min);
- device_create_file(&new_client->dev, &dev_attr_fan1_input);
- device_create_file(&new_client->dev, &dev_attr_fan1_div);
- device_create_file(&new_client->dev, &dev_attr_fan1_min);
- device_create_file(&new_client->dev, &dev_attr_fan2_input);
- device_create_file(&new_client->dev, &dev_attr_fan2_div);
- device_create_file(&new_client->dev, &dev_attr_fan2_min);
- device_create_file(&new_client->dev, &dev_attr_fan3_input);
- device_create_file(&new_client->dev, &dev_attr_fan3_div);
- device_create_file(&new_client->dev, &dev_attr_fan3_min);
- device_create_file(&new_client->dev, &dev_attr_fan4_input);
- device_create_file(&new_client->dev, &dev_attr_fan4_div);
- device_create_file(&new_client->dev, &dev_attr_fan4_min);
- device_create_file(&new_client->dev, &dev_attr_fan5_input);
- device_create_file(&new_client->dev, &dev_attr_fan5_div);
- device_create_file(&new_client->dev, &dev_attr_fan5_min);
- device_create_file(&new_client->dev, &dev_attr_fan6_input);
- device_create_file(&new_client->dev, &dev_attr_fan6_div);
- device_create_file(&new_client->dev, &dev_attr_fan6_min);
- device_create_file(&new_client->dev, &dev_attr_fan7_input);
- device_create_file(&new_client->dev, &dev_attr_fan7_div);
- device_create_file(&new_client->dev, &dev_attr_fan7_min);
- device_create_file(&new_client->dev, &dev_attr_fan8_input);
- device_create_file(&new_client->dev, &dev_attr_fan8_div);
- device_create_file(&new_client->dev, &dev_attr_fan8_min);
- device_create_file(&new_client->dev, &dev_attr_temp1_input);
- device_create_file(&new_client->dev, &dev_attr_temp1_max);
- device_create_file(&new_client->dev, &dev_attr_temp1_min);
- device_create_file(&new_client->dev, &dev_attr_temp2_input);
- device_create_file(&new_client->dev, &dev_attr_temp2_max);
- device_create_file(&new_client->dev, &dev_attr_temp2_min);
- device_create_file(&new_client->dev, &dev_attr_temp3_input);
- device_create_file(&new_client->dev, &dev_attr_temp3_max);
- device_create_file(&new_client->dev, &dev_attr_temp3_min);
- device_create_file(&new_client->dev, &dev_attr_temp1_offset);
- device_create_file(&new_client->dev, &dev_attr_temp2_offset);
- device_create_file(&new_client->dev, &dev_attr_temp3_offset);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in11_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in11_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in11_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in12_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in12_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in12_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in13_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in13_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in13_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in14_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in14_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in14_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in15_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in15_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in15_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in16_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in16_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_in16_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan4_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan4_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan4_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan5_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan5_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan5_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan6_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan6_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan6_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan7_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan7_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan7_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan8_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan8_div.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_fan8_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp1_offset.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp2_offset.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp3_offset.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp1_auto_point1_temp);
+ &sensor_dev_attr_temp1_auto_point1_temp.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp2_auto_point1_temp);
+ &sensor_dev_attr_temp2_auto_point1_temp.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp3_auto_point1_temp);
+ &sensor_dev_attr_temp3_auto_point1_temp.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp1_auto_point1_temp_hyst);
+ &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp2_auto_point1_temp_hyst);
+ &sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp3_auto_point1_temp_hyst);
+ &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp1_auto_point2_temp);
+ &sensor_dev_attr_temp1_auto_point2_temp.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp2_auto_point2_temp);
+ &sensor_dev_attr_temp2_auto_point2_temp.dev_attr);
device_create_file(&new_client->dev,
- &dev_attr_temp3_auto_point2_temp);
- device_create_file(&new_client->dev, &dev_attr_temp1_crit);
- device_create_file(&new_client->dev, &dev_attr_temp2_crit);
- device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+ &sensor_dev_attr_temp3_auto_point2_temp.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr);
+ device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr);
device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);
device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);
device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);
diff --git a/drivers/i2c/chips/adm1031.c b/drivers/i2c/chips/adm1031.c
index d4385a23f79a..2163dba467c4 100644
--- a/drivers/i2c/chips/adm1031.c
+++ b/drivers/i2c/chips/adm1031.c
@@ -292,11 +292,11 @@ set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
}
#define fan_auto_channel_offset(offset) \
-static ssize_t show_fan_auto_channel_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_auto_channel_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_auto_channel(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_auto_channel_##offset (struct device *dev, \
+static ssize_t set_fan_auto_channel_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_auto_channel(dev, buf, count, offset - 1); \
@@ -357,24 +357,24 @@ set_auto_temp_max(struct device *dev, const char *buf, size_t count, int nr)
}
#define auto_temp_reg(offset) \
-static ssize_t show_auto_temp_##offset##_off (struct device *dev, char *buf) \
+static ssize_t show_auto_temp_##offset##_off (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_auto_temp_off(dev, buf, offset - 1); \
} \
-static ssize_t show_auto_temp_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_auto_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_auto_temp_min(dev, buf, offset - 1); \
} \
-static ssize_t show_auto_temp_##offset##_max (struct device *dev, char *buf) \
+static ssize_t show_auto_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_auto_temp_max(dev, buf, offset - 1); \
} \
-static ssize_t set_auto_temp_##offset##_min (struct device *dev, \
+static ssize_t set_auto_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_auto_temp_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_auto_temp_##offset##_max (struct device *dev, \
+static ssize_t set_auto_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_auto_temp_max(dev, buf, count, offset - 1); \
@@ -421,11 +421,11 @@ set_pwm(struct device *dev, const char *buf, size_t count, int nr)
}
#define pwm_reg(offset) \
-static ssize_t show_pwm_##offset (struct device *dev, char *buf) \
+static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwm(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm_##offset (struct device *dev, \
+static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm(dev, buf, count, offset - 1); \
@@ -557,24 +557,24 @@ set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
}
#define fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_fan_##offset##_div (struct device *dev, \
+static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_div(dev, buf, count, offset - 1); \
@@ -667,33 +667,33 @@ set_temp_crit(struct device *dev, const char *buf, size_t count, int nr)
}
#define temp_reg(offset) \
-static ssize_t show_temp_##offset (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, offset - 1); \
} \
-static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_min(dev, buf, offset - 1); \
} \
-static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_max(dev, buf, offset - 1); \
} \
-static ssize_t show_temp_##offset##_crit (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset##_crit (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_crit(dev, buf, offset - 1); \
} \
-static ssize_t set_temp_##offset##_min (struct device *dev, \
+static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_temp_##offset##_max (struct device *dev, \
+static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_max(dev, buf, count, offset - 1); \
} \
-static ssize_t set_temp_##offset##_crit (struct device *dev, \
+static ssize_t set_temp_##offset##_crit (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_crit(dev, buf, count, offset - 1); \
@@ -712,7 +712,7 @@ temp_reg(2);
temp_reg(3);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1031_data *data = adm1031_update_device(dev);
return sprintf(buf, "%d\n", data->alarm);
diff --git a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
index 7f899002bc54..4a47b4493e34 100644
--- a/drivers/i2c/chips/asb100.c
+++ b/drivers/i2c/chips/asb100.c
@@ -260,28 +260,28 @@ set_in_reg(MAX, max)
#define sysfs_in(offset) \
static ssize_t \
- show_in##offset (struct device *dev, char *buf) \
+ show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL); \
static ssize_t \
- show_in##offset##_min (struct device *dev, char *buf) \
+ show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_min(dev, buf, offset); \
} \
static ssize_t \
- show_in##offset##_max (struct device *dev, char *buf) \
+ show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_max(dev, buf, offset); \
} \
-static ssize_t set_in##offset##_min (struct device *dev, \
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, offset); \
} \
-static ssize_t set_in##offset##_max (struct device *dev, \
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, offset); \
@@ -389,24 +389,24 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define sysfs_fan(offset) \
-static ssize_t show_fan##offset(struct device *dev, char *buf) \
+static ssize_t show_fan##offset(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
+static ssize_t set_fan##offset##_div(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_fan_div(dev, buf, count, offset - 1); \
@@ -482,27 +482,27 @@ set_temp_reg(MAX, temp_max);
set_temp_reg(HYST, temp_hyst);
#define sysfs_temp(num) \
-static ssize_t show_temp##num(struct device *dev, char *buf) \
+static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, num-1); \
} \
static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL); \
-static ssize_t show_temp_max##num(struct device *dev, char *buf) \
+static ssize_t show_temp_max##num(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_max(dev, buf, num-1); \
} \
-static ssize_t set_temp_max##num(struct device *dev, const char *buf, \
+static ssize_t set_temp_max##num(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_temp_max(dev, buf, count, num-1); \
} \
static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \
show_temp_max##num, set_temp_max##num); \
-static ssize_t show_temp_hyst##num(struct device *dev, char *buf) \
+static ssize_t show_temp_hyst##num(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_hyst(dev, buf, num-1); \
} \
-static ssize_t set_temp_hyst##num(struct device *dev, const char *buf, \
+static ssize_t set_temp_hyst##num(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_temp_hyst(dev, buf, count, num-1); \
@@ -522,7 +522,7 @@ sysfs_temp(4);
device_create_file(&client->dev, &dev_attr_temp##num##_max_hyst); \
} while (0)
-static ssize_t show_vid(struct device *dev, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct asb100_data *data = asb100_update_device(dev);
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
@@ -533,13 +533,13 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
device_create_file(&client->dev, &dev_attr_cpu0_vid)
/* VRM */
-static ssize_t show_vrm(struct device *dev, char *buf)
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct asb100_data *data = asb100_update_device(dev);
return sprintf(buf, "%d\n", data->vrm);
}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct asb100_data *data = i2c_get_clientdata(client);
@@ -553,7 +553,7 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct asb100_data *data = asb100_update_device(dev);
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms));
@@ -564,13 +564,13 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
device_create_file(&client->dev, &dev_attr_alarms)
/* 1 PWM */
-static ssize_t show_pwm1(struct device *dev, char *buf)
+static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char *buf)
{
struct asb100_data *data = asb100_update_device(dev);
return sprintf(buf, "%d\n", ASB100_PWM_FROM_REG(data->pwm & 0x0f));
}
-static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
+static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct asb100_data *data = i2c_get_clientdata(client);
@@ -584,13 +584,13 @@ static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
return count;
}
-static ssize_t show_pwm_enable1(struct device *dev, char *buf)
+static ssize_t show_pwm_enable1(struct device *dev, struct device_attribute *attr, char *buf)
{
struct asb100_data *data = asb100_update_device(dev);
return sprintf(buf, "%d\n", (data->pwm & 0x80) ? 1 : 0);
}
-static ssize_t set_pwm_enable1(struct device *dev, const char *buf,
+static ssize_t set_pwm_enable1(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
diff --git a/drivers/i2c/chips/ds1621.c b/drivers/i2c/chips/ds1621.c
index bb1fefb2162e..4ae15bd5dcfb 100644
--- a/drivers/i2c/chips/ds1621.c
+++ b/drivers/i2c/chips/ds1621.c
@@ -137,7 +137,7 @@ static void ds1621_init_client(struct i2c_client *client)
}
#define show(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct ds1621_data *data = ds1621_update_client(dev); \
return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value)); \
@@ -148,7 +148,7 @@ show(temp_min);
show(temp_max);
#define set_temp(suffix, value, reg) \
-static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -165,7 +165,7 @@ static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
set_temp(min, temp_min, DS1621_REG_TEMP_MIN);
set_temp(max, temp_max, DS1621_REG_TEMP_MAX);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ds1621_data *data = ds1621_update_client(dev);
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf));
diff --git a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c
index 18e33ac59d0c..c3f37dbec11a 100644
--- a/drivers/i2c/chips/fscher.c
+++ b/drivers/i2c/chips/fscher.c
@@ -157,8 +157,8 @@ struct fscher_data {
#define sysfs_r(kind, sub, offset, reg) \
static ssize_t show_##kind##sub (struct fscher_data *, char *, int); \
-static ssize_t show_##kind##offset##sub (struct device *, char *); \
-static ssize_t show_##kind##offset##sub (struct device *dev, char *buf) \
+static ssize_t show_##kind##offset##sub (struct device *, struct device_attribute *attr, char *); \
+static ssize_t show_##kind##offset##sub (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct fscher_data *data = fscher_update_device(dev); \
return show_##kind##sub(data, buf, (offset)); \
@@ -166,8 +166,8 @@ static ssize_t show_##kind##offset##sub (struct device *dev, char *buf) \
#define sysfs_w(kind, sub, offset, reg) \
static ssize_t set_##kind##sub (struct i2c_client *, struct fscher_data *, const char *, size_t, int, int); \
-static ssize_t set_##kind##offset##sub (struct device *, const char *, size_t); \
-static ssize_t set_##kind##offset##sub (struct device *dev, const char *buf, size_t count) \
+static ssize_t set_##kind##offset##sub (struct device *, struct device_attribute *attr, const char *, size_t); \
+static ssize_t set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct fscher_data *data = i2c_get_clientdata(client); \
diff --git a/drivers/i2c/chips/fscpos.c b/drivers/i2c/chips/fscpos.c
index 2cac79145c75..3beaa6191ef4 100644
--- a/drivers/i2c/chips/fscpos.c
+++ b/drivers/i2c/chips/fscpos.c
@@ -245,19 +245,19 @@ static void reset_fan_alarm(struct i2c_client *client, int nr)
/* Volts */
#define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255)
-static ssize_t show_volt_12(struct device *dev, char *buf)
+static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fscpos_data *data = fscpos_update_device(dev);
return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200));
}
-static ssize_t show_volt_5(struct device *dev, char *buf)
+static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fscpos_data *data = fscpos_update_device(dev);
return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600));
}
-static ssize_t show_volt_batt(struct device *dev, char *buf)
+static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fscpos_data *data = fscpos_update_device(dev);
return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300));
@@ -327,7 +327,7 @@ static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
}
/* Event */
-static ssize_t show_event(struct device *dev, char *buf)
+static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf)
{
/* bits 5..7 reserved => mask with 0x1f */
struct fscpos_data *data = fscpos_update_device(dev);
@@ -338,14 +338,14 @@ static ssize_t show_event(struct device *dev, char *buf)
* Sysfs stuff
*/
#define create_getter(kind, sub) \
- static ssize_t sysfs_show_##kind##sub(struct device *dev, char *buf) \
+ static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct fscpos_data *data = fscpos_update_device(dev); \
return show_##kind##sub(data, buf); \
}
#define create_getter_n(kind, offset, sub) \
- static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, char\
+ static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
*buf) \
{ \
struct fscpos_data *data = fscpos_update_device(dev); \
@@ -353,7 +353,7 @@ static ssize_t show_event(struct device *dev, char *buf)
}
#define create_setter(kind, sub, reg) \
- static ssize_t sysfs_set_##kind##sub (struct device *dev, const char \
+ static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
*buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -362,7 +362,7 @@ static ssize_t show_event(struct device *dev, char *buf)
}
#define create_setter_n(kind, offset, sub, reg) \
- static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, \
+ static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
diff --git a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c
index c82d6ce21205..4316a1562251 100644
--- a/drivers/i2c/chips/gl518sm.c
+++ b/drivers/i2c/chips/gl518sm.c
@@ -164,14 +164,14 @@ static struct i2c_driver gl518_driver = {
*/
#define show(type, suffix, value) \
-static ssize_t show_##suffix(struct device *dev, char *buf) \
+static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct gl518_data *data = gl518_update_device(dev); \
return sprintf(buf, "%d\n", type##_FROM_REG(data->value)); \
}
#define show_fan(suffix, value, index) \
-static ssize_t show_##suffix(struct device *dev, char *buf) \
+static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct gl518_data *data = gl518_update_device(dev); \
return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[index], \
@@ -205,7 +205,7 @@ show(BOOL, beep_enable, beep_enable);
show(BEEP_MASK, beep_mask, beep_mask);
#define set(type, suffix, value, reg) \
-static ssize_t set_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -220,7 +220,7 @@ static ssize_t set_##suffix(struct device *dev, const char *buf, \
}
#define set_bits(type, suffix, value, reg, mask, shift) \
-static ssize_t set_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -258,7 +258,7 @@ set_high(IN, in_max3, voltage_max[3], GL518_REG_VIN3_LIMIT);
set_bits(BOOL, beep_enable, beep_enable, GL518_REG_CONF, 0x04, 2);
set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM);
-static ssize_t set_fan_min1(struct device *dev, const char *buf, size_t count)
+static ssize_t set_fan_min1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct gl518_data *data = i2c_get_clientdata(client);
@@ -284,7 +284,7 @@ static ssize_t set_fan_min1(struct device *dev, const char *buf, size_t count)
return count;
}
-static ssize_t set_fan_min2(struct device *dev, const char *buf, size_t count)
+static ssize_t set_fan_min2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct gl518_data *data = i2c_get_clientdata(client);
diff --git a/drivers/i2c/chips/gl520sm.c b/drivers/i2c/chips/gl520sm.c
index 3fd17e46ffc6..a13a504f5bfa 100644
--- a/drivers/i2c/chips/gl520sm.c
+++ b/drivers/i2c/chips/gl520sm.c
@@ -148,8 +148,8 @@ struct gl520_data {
#define sysfs_r(type, n, item, reg) \
static ssize_t get_##type##item (struct gl520_data *, char *, int); \
-static ssize_t get_##type##n##item (struct device *, char *); \
-static ssize_t get_##type##n##item (struct device *dev, char *buf) \
+static ssize_t get_##type##n##item (struct device *, struct device_attribute *attr, char *); \
+static ssize_t get_##type##n##item (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct gl520_data *data = gl520_update_device(dev); \
return get_##type##item(data, buf, (n)); \
@@ -157,8 +157,8 @@ static ssize_t get_##type##n##item (struct device *dev, char *buf) \
#define sysfs_w(type, n, item, reg) \
static ssize_t set_##type##item (struct i2c_client *, struct gl520_data *, const char *, size_t, int, int); \
-static ssize_t set_##type##n##item (struct device *, const char *, size_t); \
-static ssize_t set_##type##n##item (struct device *dev, const char *buf, size_t count) \
+static ssize_t set_##type##n##item (struct device *, struct device_attribute *attr, const char *, size_t); \
+static ssize_t set_##type##n##item (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct gl520_data *data = i2c_get_clientdata(client); \
diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
index cf7e6898754f..007bdf9e7e2a 100644
--- a/drivers/i2c/chips/it87.c
+++ b/drivers/i2c/chips/it87.c
@@ -290,7 +290,7 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
#define show_in_offset(offset) \
static ssize_t \
- show_in##offset (struct device *dev, char *buf) \
+ show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
@@ -298,21 +298,21 @@ static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);
#define limit_in_offset(offset) \
static ssize_t \
- show_in##offset##_min (struct device *dev, char *buf) \
+ show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_min(dev, buf, offset); \
} \
static ssize_t \
- show_in##offset##_max (struct device *dev, char *buf) \
+ show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_max(dev, buf, offset); \
} \
-static ssize_t set_in##offset##_min (struct device *dev, \
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, offset); \
} \
-static ssize_t set_in##offset##_max (struct device *dev, \
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, offset); \
@@ -383,26 +383,26 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
return count;
}
#define show_temp_offset(offset) \
-static ssize_t show_temp_##offset (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, offset - 1); \
} \
static ssize_t \
-show_temp_##offset##_max (struct device *dev, char *buf) \
+show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_max(dev, buf, offset - 1); \
} \
static ssize_t \
-show_temp_##offset##_min (struct device *dev, char *buf) \
+show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_min(dev, buf, offset - 1); \
} \
-static ssize_t set_temp_##offset##_max (struct device *dev, \
+static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_max(dev, buf, count, offset - 1); \
} \
-static ssize_t set_temp_##offset##_min (struct device *dev, \
+static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_min(dev, buf, count, offset - 1); \
@@ -453,11 +453,11 @@ static ssize_t set_sensor(struct device *dev, const char *buf,
return count;
}
#define show_sensor_offset(offset) \
-static ssize_t show_sensor_##offset (struct device *dev, char *buf) \
+static ssize_t show_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_sensor(dev, buf, offset - 1); \
} \
-static ssize_t set_sensor_##offset (struct device *dev, \
+static ssize_t set_sensor_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_sensor(dev, buf, count, offset - 1); \
@@ -600,24 +600,24 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
}
#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_fan_##offset##_div (struct device *dev, \
+static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_div(dev, buf, count, offset - 1); \
@@ -633,21 +633,21 @@ show_fan_offset(2);
show_fan_offset(3);
#define show_pwm_offset(offset) \
-static ssize_t show_pwm##offset##_enable (struct device *dev, \
+static ssize_t show_pwm##offset##_enable (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_pwm_enable(dev, buf, offset - 1); \
} \
-static ssize_t show_pwm##offset (struct device *dev, char *buf) \
+static ssize_t show_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwm(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset##_enable (struct device *dev, \
+static ssize_t set_pwm##offset##_enable (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm_enable(dev, buf, count, offset - 1); \
} \
-static ssize_t set_pwm##offset (struct device *dev, \
+static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm(dev, buf, count, offset - 1); \
@@ -663,7 +663,7 @@ show_pwm_offset(2);
show_pwm_offset(3);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
@@ -671,13 +671,13 @@ static ssize_t show_alarms(struct device *dev, char *buf)
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
static ssize_t
-show_vrm_reg(struct device *dev, char *buf)
+show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->vrm);
}
static ssize_t
-store_vrm_reg(struct device *dev, const char *buf, size_t count)
+store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
@@ -693,7 +693,7 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
device_create_file(&client->dev, &dev_attr_vrm)
static ssize_t
-show_vid_reg(struct device *dev, char *buf)
+show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
diff --git a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c
index 14cc5af03739..bc68e031392b 100644
--- a/drivers/i2c/chips/lm63.c
+++ b/drivers/i2c/chips/lm63.c
@@ -177,7 +177,7 @@ struct lm63_data {
*/
#define show_fan(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm63_data *data = lm63_update_device(dev); \
return sprintf(buf, "%d\n", FAN_FROM_REG(data->value)); \
@@ -185,7 +185,7 @@ static ssize_t show_##value(struct device *dev, char *buf) \
show_fan(fan1_input);
show_fan(fan1_low);
-static ssize_t set_fan1_low(struct device *dev, const char *buf,
+static ssize_t set_fan1_low(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -202,7 +202,7 @@ static ssize_t set_fan1_low(struct device *dev, const char *buf,
return count;
}
-static ssize_t show_pwm1(struct device *dev, char *buf)
+static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm63_data *data = lm63_update_device(dev);
return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ?
@@ -210,7 +210,7 @@ static ssize_t show_pwm1(struct device *dev, char *buf)
(2 * data->pwm1_freq));
}
-static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
+static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm63_data *data = i2c_get_clientdata(client);
@@ -229,20 +229,20 @@ static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
return count;
}
-static ssize_t show_pwm1_enable(struct device *dev, char *buf)
+static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm63_data *data = lm63_update_device(dev);
return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
}
#define show_temp8(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm63_data *data = lm63_update_device(dev); \
return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->value)); \
}
#define show_temp11(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm63_data *data = lm63_update_device(dev); \
return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->value)); \
@@ -255,7 +255,7 @@ show_temp11(temp2_low);
show_temp8(temp2_crit);
#define set_temp8(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -269,7 +269,7 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
return count; \
}
#define set_temp11(value, reg_msb, reg_lsb) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -289,7 +289,7 @@ set_temp11(temp2_low, LM63_REG_REMOTE_LOW_MSB, LM63_REG_REMOTE_LOW_LSB);
/* Hysteresis register holds a relative value, while we want to present
an absolute to user-space */
-static ssize_t show_temp2_crit_hyst(struct device *dev, char *buf)
+static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm63_data *data = lm63_update_device(dev);
return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp2_crit)
@@ -298,7 +298,7 @@ static ssize_t show_temp2_crit_hyst(struct device *dev, char *buf)
/* And now the other way around, user-space provides an absolute
hysteresis value and we have to store a relative one */
-static ssize_t set_temp2_crit_hyst(struct device *dev, const char *buf,
+static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -314,7 +314,7 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, const char *buf,
return count;
}
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm63_data *data = lm63_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
diff --git a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
index 0e86cc893981..57c51ac37c04 100644
--- a/drivers/i2c/chips/lm75.c
+++ b/drivers/i2c/chips/lm75.c
@@ -75,7 +75,7 @@ static struct i2c_driver lm75_driver = {
};
#define show(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm75_data *data = lm75_update_device(dev); \
return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value)); \
@@ -85,7 +85,7 @@ show(temp_hyst);
show(temp_input);
#define set(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct lm75_data *data = i2c_get_clientdata(client); \
diff --git a/drivers/i2c/chips/lm77.c b/drivers/i2c/chips/lm77.c
index f56b7a37de75..9d15cd5189f6 100644
--- a/drivers/i2c/chips/lm77.c
+++ b/drivers/i2c/chips/lm77.c
@@ -103,7 +103,7 @@ static inline int LM77_TEMP_FROM_REG(u16 reg)
/* read routines for temperature limits */
#define show(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm77_data *data = lm77_update_device(dev); \
return sprintf(buf, "%d\n", data->value); \
@@ -116,17 +116,17 @@ show(temp_max);
show(alarms);
/* read routines for hysteresis values */
-static ssize_t show_temp_crit_hyst(struct device *dev, char *buf)
+static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm77_data *data = lm77_update_device(dev);
return sprintf(buf, "%d\n", data->temp_crit - data->temp_hyst);
}
-static ssize_t show_temp_min_hyst(struct device *dev, char *buf)
+static ssize_t show_temp_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm77_data *data = lm77_update_device(dev);
return sprintf(buf, "%d\n", data->temp_min + data->temp_hyst);
}
-static ssize_t show_temp_max_hyst(struct device *dev, char *buf)
+static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm77_data *data = lm77_update_device(dev);
return sprintf(buf, "%d\n", data->temp_max - data->temp_hyst);
@@ -134,7 +134,7 @@ static ssize_t show_temp_max_hyst(struct device *dev, char *buf)
/* write routines */
#define set(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct lm77_data *data = i2c_get_clientdata(client); \
@@ -152,7 +152,7 @@ set(temp_max, LM77_REG_TEMP_MAX);
/* hysteresis is stored as a relative value on the chip, so it has to be
converted first */
-static ssize_t set_temp_crit_hyst(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm77_data *data = i2c_get_clientdata(client);
@@ -167,7 +167,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, const char *buf, size_t co
}
/* preserve hysteresis when setting T_crit */
-static ssize_t set_temp_crit(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm77_data *data = i2c_get_clientdata(client);
diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
index 6d52d14eb31c..21b195ff3871 100644
--- a/drivers/i2c/chips/lm78.c
+++ b/drivers/i2c/chips/lm78.c
@@ -224,28 +224,28 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
#define show_in_offset(offset) \
static ssize_t \
- show_in##offset (struct device *dev, char *buf) \
+ show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL); \
static ssize_t \
- show_in##offset##_min (struct device *dev, char *buf) \
+ show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_min(dev, buf, offset); \
} \
static ssize_t \
- show_in##offset##_max (struct device *dev, char *buf) \
+ show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_max(dev, buf, offset); \
} \
-static ssize_t set_in##offset##_min (struct device *dev, \
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, offset); \
} \
-static ssize_t set_in##offset##_max (struct device *dev, \
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, offset); \
@@ -264,19 +264,19 @@ show_in_offset(5);
show_in_offset(6);
/* Temperature */
-static ssize_t show_temp(struct device *dev, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
}
-static ssize_t show_temp_over(struct device *dev, char *buf)
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}
-static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
@@ -289,13 +289,13 @@ static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
return count;
}
-static ssize_t show_temp_hyst(struct device *dev, char *buf)
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
}
-static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
@@ -398,19 +398,19 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
@@ -419,13 +419,13 @@ static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
show_fan_##offset##_min, set_fan_##offset##_min);
-static ssize_t set_fan_1_div(struct device *dev, const char *buf,
+static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
return set_fan_div(dev, buf, count, 0) ;
}
-static ssize_t set_fan_2_div(struct device *dev, const char *buf,
+static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
return set_fan_div(dev, buf, count, 1) ;
@@ -443,7 +443,7 @@ static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
/* VID */
-static ssize_t show_vid(struct device *dev, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", VID_FROM_REG(data->vid));
@@ -451,7 +451,7 @@ static ssize_t show_vid(struct device *dev, char *buf)
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
diff --git a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c
index a72f431971bb..404057b70e90 100644
--- a/drivers/i2c/chips/lm80.c
+++ b/drivers/i2c/chips/lm80.c
@@ -156,7 +156,7 @@ static struct i2c_driver lm80_driver = {
*/
#define show_in(suffix, value) \
-static ssize_t show_in_##suffix(struct device *dev, char *buf) \
+static ssize_t show_in_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm80_data *data = lm80_update_device(dev); \
return sprintf(buf, "%d\n", IN_FROM_REG(data->value)); \
@@ -184,7 +184,7 @@ show_in(input5, in[5]);
show_in(input6, in[6]);
#define set_in(suffix, value, reg) \
-static ssize_t set_in_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_in_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -213,7 +213,7 @@ set_in(max5, in_max[5], LM80_REG_IN_MAX(5));
set_in(max6, in_max[6], LM80_REG_IN_MAX(6));
#define show_fan(suffix, value, div) \
-static ssize_t show_fan_##suffix(struct device *dev, char *buf) \
+static ssize_t show_fan_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm80_data *data = lm80_update_device(dev); \
return sprintf(buf, "%d\n", FAN_FROM_REG(data->value, \
@@ -225,7 +225,7 @@ show_fan(input1, fan[0], fan_div[0]);
show_fan(input2, fan[1], fan_div[1]);
#define show_fan_div(suffix, value) \
-static ssize_t show_fan_div##suffix(struct device *dev, char *buf) \
+static ssize_t show_fan_div##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm80_data *data = lm80_update_device(dev); \
return sprintf(buf, "%d\n", DIV_FROM_REG(data->value)); \
@@ -234,7 +234,7 @@ show_fan_div(1, fan_div[0]);
show_fan_div(2, fan_div[1]);
#define set_fan(suffix, value, reg, div) \
-static ssize_t set_fan_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_fan_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -292,7 +292,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define set_fan_div(number) \
-static ssize_t set_fan_div##number(struct device *dev, const char *buf, \
+static ssize_t set_fan_div##number(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_fan_div(dev, buf, count, number - 1); \
@@ -300,14 +300,14 @@ static ssize_t set_fan_div##number(struct device *dev, const char *buf, \
set_fan_div(1);
set_fan_div(2);
-static ssize_t show_temp_input1(struct device *dev, char *buf)
+static ssize_t show_temp_input1(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm80_data *data = lm80_update_device(dev);
return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp));
}
#define show_temp(suffix, value) \
-static ssize_t show_temp_##suffix(struct device *dev, char *buf) \
+static ssize_t show_temp_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm80_data *data = lm80_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \
@@ -318,7 +318,7 @@ show_temp(os_max, temp_os_max);
show_temp(os_hyst, temp_os_hyst);
#define set_temp(suffix, value, reg) \
-static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -336,7 +336,7 @@ set_temp(hot_hyst, temp_hot_hyst, LM80_REG_TEMP_HOT_HYST);
set_temp(os_max, temp_os_max, LM80_REG_TEMP_OS_MAX);
set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm80_data *data = lm80_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
diff --git a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
index 3dafe60766ad..4d6d7d21e14b 100644
--- a/drivers/i2c/chips/lm83.c
+++ b/drivers/i2c/chips/lm83.c
@@ -155,7 +155,7 @@ struct lm83_data {
*/
#define show_temp(suffix, value) \
-static ssize_t show_temp_##suffix(struct device *dev, char *buf) \
+static ssize_t show_temp_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm83_data *data = lm83_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
@@ -171,7 +171,7 @@ show_temp(high4, temp_high[3]);
show_temp(crit, temp_crit);
#define set_temp(suffix, value, reg) \
-static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
+static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -190,7 +190,7 @@ set_temp(high3, temp_high[2], LM83_REG_W_REMOTE2_HIGH);
set_temp(high4, temp_high[3], LM83_REG_W_REMOTE3_HIGH);
set_temp(crit, temp_crit, LM83_REG_W_TCRIT);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm83_data *data = lm83_update_device(dev);
return sprintf(buf, "%d\n", data->alarms);
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
index b1a0dc5f6b34..b1976775b4ba 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/i2c/chips/lm85.c
@@ -426,15 +426,15 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
}
#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
@@ -451,7 +451,7 @@ show_fan_offset(4);
/* vid, vrm, alarms */
-static ssize_t show_vid_reg(struct device *dev, char *buf)
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm85_data *data = lm85_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
@@ -459,13 +459,13 @@ static ssize_t show_vid_reg(struct device *dev, char *buf)
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-static ssize_t show_vrm_reg(struct device *dev, char *buf)
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm85_data *data = lm85_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->vrm);
}
-static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count)
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
@@ -478,7 +478,7 @@ static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-static ssize_t show_alarms_reg(struct device *dev, char *buf)
+static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm85_data *data = lm85_update_device(dev);
return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));
@@ -516,16 +516,16 @@ static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
}
#define show_pwm_reg(offset) \
-static ssize_t show_pwm_##offset (struct device *dev, char *buf) \
+static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwm(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm_##offset (struct device *dev, \
+static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm(dev, buf, count, offset - 1); \
} \
-static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \
+static ssize_t show_pwm_enable##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwm_enable(dev, buf, offset - 1); \
} \
@@ -585,24 +585,24 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
return count;
}
#define show_in_reg(offset) \
-static ssize_t show_in_##offset (struct device *dev, char *buf) \
+static ssize_t show_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
-static ssize_t show_in_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_in_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_min(dev, buf, offset); \
} \
-static ssize_t show_in_##offset##_max (struct device *dev, char *buf) \
+static ssize_t show_in_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_max(dev, buf, offset); \
} \
-static ssize_t set_in_##offset##_min (struct device *dev, \
+static ssize_t set_in_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, offset); \
} \
-static ssize_t set_in_##offset##_max (struct device *dev, \
+static ssize_t set_in_##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, offset); \
@@ -666,24 +666,24 @@ static ssize_t set_temp_max(struct device *dev, const char *buf,
return count;
}
#define show_temp_reg(offset) \
-static ssize_t show_temp_##offset (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, offset - 1); \
} \
-static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_min(dev, buf, offset - 1); \
} \
-static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_max(dev, buf, offset - 1); \
} \
-static ssize_t set_temp_##offset##_min (struct device *dev, \
+static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_temp_##offset##_max (struct device *dev, \
+static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_max(dev, buf, count, offset - 1); \
@@ -786,42 +786,42 @@ static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf,
return count;
}
#define pwm_auto(offset) \
-static ssize_t show_pwm##offset##_auto_channels (struct device *dev, \
+static ssize_t show_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_pwm_auto_channels(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset##_auto_channels (struct device *dev, \
+static ssize_t set_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm_auto_channels(dev, buf, count, offset - 1); \
} \
-static ssize_t show_pwm##offset##_auto_pwm_min (struct device *dev, \
+static ssize_t show_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_pwm_auto_pwm_min(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset##_auto_pwm_min (struct device *dev, \
+static ssize_t set_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm_auto_pwm_min(dev, buf, count, offset - 1); \
} \
-static ssize_t show_pwm##offset##_auto_pwm_minctl (struct device *dev, \
+static ssize_t show_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_pwm_auto_pwm_minctl(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset##_auto_pwm_minctl (struct device *dev, \
+static ssize_t set_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm_auto_pwm_minctl(dev, buf, count, offset - 1); \
} \
-static ssize_t show_pwm##offset##_auto_pwm_freq (struct device *dev, \
+static ssize_t show_pwm##offset##_auto_pwm_freq (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_pwm_auto_pwm_freq(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset##_auto_pwm_freq(struct device *dev, \
+static ssize_t set_pwm##offset##_auto_pwm_freq(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm_auto_pwm_freq(dev, buf, count, offset - 1); \
@@ -962,42 +962,42 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf,
return count;
}
#define temp_auto(offset) \
-static ssize_t show_temp##offset##_auto_temp_off (struct device *dev, \
+static ssize_t show_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_temp_auto_temp_off(dev, buf, offset - 1); \
} \
-static ssize_t set_temp##offset##_auto_temp_off (struct device *dev, \
+static ssize_t set_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_auto_temp_off(dev, buf, count, offset - 1); \
} \
-static ssize_t show_temp##offset##_auto_temp_min (struct device *dev, \
+static ssize_t show_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_temp_auto_temp_min(dev, buf, offset - 1); \
} \
-static ssize_t set_temp##offset##_auto_temp_min (struct device *dev, \
+static ssize_t set_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_auto_temp_min(dev, buf, count, offset - 1); \
} \
-static ssize_t show_temp##offset##_auto_temp_max (struct device *dev, \
+static ssize_t show_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_temp_auto_temp_max(dev, buf, offset - 1); \
} \
-static ssize_t set_temp##offset##_auto_temp_max (struct device *dev, \
+static ssize_t set_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_auto_temp_max(dev, buf, count, offset - 1); \
} \
-static ssize_t show_temp##offset##_auto_temp_crit (struct device *dev, \
+static ssize_t show_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_temp_auto_temp_crit(dev, buf, offset - 1); \
} \
-static ssize_t set_temp##offset##_auto_temp_crit (struct device *dev, \
+static ssize_t set_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_auto_temp_crit(dev, buf, count, offset - 1); \
diff --git a/drivers/i2c/chips/lm87.c b/drivers/i2c/chips/lm87.c
index 98cabd665063..4372b61a0882 100644
--- a/drivers/i2c/chips/lm87.c
+++ b/drivers/i2c/chips/lm87.c
@@ -218,19 +218,19 @@ static inline int lm87_write_value(struct i2c_client *client, u8 reg, u8 value)
}
#define show_in(offset) \
-static ssize_t show_in##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
data->in_scale[offset])); \
} \
-static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
data->in_scale[offset])); \
} \
-static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
@@ -274,13 +274,13 @@ static void set_in_max(struct device *dev, const char *buf, int nr)
}
#define set_in(offset) \
-static ssize_t set_in##offset##_min(struct device *dev, \
+static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
set_in_min(dev, buf, offset); \
return count; \
} \
-static ssize_t set_in##offset##_max(struct device *dev, \
+static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
set_in_max(dev, buf, offset); \
@@ -300,17 +300,17 @@ set_in(6);
set_in(7);
#define show_temp(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
} \
-static ssize_t show_temp##offset##_low(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_low(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[offset-1])); \
} \
-static ssize_t show_temp##offset##_high(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_high(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[offset-1])); \
@@ -346,13 +346,13 @@ static void set_temp_high(struct device *dev, const char *buf, int nr)
}
#define set_temp(offset) \
-static ssize_t set_temp##offset##_low(struct device *dev, \
+static ssize_t set_temp##offset##_low(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
set_temp_low(dev, buf, offset-1); \
return count; \
} \
-static ssize_t set_temp##offset##_high(struct device *dev, \
+static ssize_t set_temp##offset##_high(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
set_temp_high(dev, buf, offset-1); \
@@ -366,13 +366,13 @@ set_temp(1);
set_temp(2);
set_temp(3);
-static ssize_t show_temp_crit_int(struct device *dev, char *buf)
+static ssize_t show_temp_crit_int(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm87_data *data = lm87_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int));
}
-static ssize_t show_temp_crit_ext(struct device *dev, char *buf)
+static ssize_t show_temp_crit_ext(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm87_data *data = lm87_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext));
@@ -383,19 +383,19 @@ static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit_ext, NULL);
static DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit_ext, NULL);
#define show_fan(offset) \
-static ssize_t show_fan##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[offset-1], \
FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
} \
-static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[offset-1], \
FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
} \
-static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm87_data *data = lm87_update_device(dev); \
return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[offset-1])); \
@@ -465,13 +465,13 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define set_fan(offset) \
-static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
set_fan_min(dev, buf, offset-1); \
return count; \
} \
-static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
+static ssize_t set_fan##offset##_div(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_fan_div(dev, buf, count, offset-1); \
@@ -483,26 +483,26 @@ static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
set_fan(1);
set_fan(2);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm87_data *data = lm87_update_device(dev);
return sprintf(buf, "%d\n", data->alarms);
}
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-static ssize_t show_vid(struct device *dev, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm87_data *data = lm87_update_device(dev);
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
}
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-static ssize_t show_vrm(struct device *dev, char *buf)
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm87_data *data = lm87_update_device(dev);
return sprintf(buf, "%d\n", data->vrm);
}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
@@ -511,12 +511,12 @@ static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
}
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-static ssize_t show_aout(struct device *dev, char *buf)
+static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm87_data *data = lm87_update_device(dev);
return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
}
-static ssize_t set_aout(struct device *dev, const char *buf, size_t count)
+static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
index 2c00ff83babc..9b127a07f56b 100644
--- a/drivers/i2c/chips/lm90.c
+++ b/drivers/i2c/chips/lm90.c
@@ -218,7 +218,7 @@ struct lm90_data {
*/
#define show_temp(value, converter) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm90_data *data = lm90_update_device(dev); \
return sprintf(buf, "%d\n", converter(data->value)); \
@@ -233,7 +233,7 @@ show_temp(temp_crit1, TEMP1_FROM_REG);
show_temp(temp_crit2, TEMP1_FROM_REG);
#define set_temp1(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -250,7 +250,7 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
return count; \
}
#define set_temp2(value, regh, regl) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -275,7 +275,7 @@ set_temp1(temp_crit1, LM90_REG_W_LOCAL_CRIT);
set_temp1(temp_crit2, LM90_REG_W_REMOTE_CRIT);
#define show_temp_hyst(value, basereg) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm90_data *data = lm90_update_device(dev); \
return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->basereg) \
@@ -284,7 +284,7 @@ static ssize_t show_##value(struct device *dev, char *buf) \
show_temp_hyst(temp_hyst1, temp_crit1);
show_temp_hyst(temp_hyst2, temp_crit2);
-static ssize_t set_temp_hyst1(struct device *dev, const char *buf,
+static ssize_t set_temp_hyst1(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -300,7 +300,7 @@ static ssize_t set_temp_hyst1(struct device *dev, const char *buf,
return count;
}
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm90_data *data = lm90_update_device(dev);
return sprintf(buf, "%d\n", data->alarms);
diff --git a/drivers/i2c/chips/lm92.c b/drivers/i2c/chips/lm92.c
index fe6e83d70a72..215c8e40ffdd 100644
--- a/drivers/i2c/chips/lm92.c
+++ b/drivers/i2c/chips/lm92.c
@@ -140,7 +140,7 @@ static struct lm92_data *lm92_update_device(struct device *dev)
}
#define show_temp(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct lm92_data *data = lm92_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
@@ -151,7 +151,7 @@ show_temp(temp1_min);
show_temp(temp1_max);
#define set_temp(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -168,26 +168,26 @@ set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
set_temp(temp1_min, LM92_REG_TEMP_LOW);
set_temp(temp1_max, LM92_REG_TEMP_HIGH);
-static ssize_t show_temp1_crit_hyst(struct device *dev, char *buf)
+static ssize_t show_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm92_data *data = lm92_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit)
- TEMP_FROM_REG(data->temp1_hyst));
}
-static ssize_t show_temp1_max_hyst(struct device *dev, char *buf)
+static ssize_t show_temp1_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm92_data *data = lm92_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max)
- TEMP_FROM_REG(data->temp1_hyst));
}
-static ssize_t show_temp1_min_hyst(struct device *dev, char *buf)
+static ssize_t show_temp1_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm92_data *data = lm92_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min)
+ TEMP_FROM_REG(data->temp1_hyst));
}
-static ssize_t set_temp1_crit_hyst(struct device *dev, const char *buf,
+static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -202,7 +202,7 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, const char *buf,
return count;
}
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lm92_data *data = lm92_update_device(dev);
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
diff --git a/drivers/i2c/chips/max1619.c b/drivers/i2c/chips/max1619.c
index 5afa961a5e10..30a196155fd9 100644
--- a/drivers/i2c/chips/max1619.c
+++ b/drivers/i2c/chips/max1619.c
@@ -122,7 +122,7 @@ struct max1619_data {
*/
#define show_temp(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct max1619_data *data = max1619_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
@@ -135,7 +135,7 @@ show_temp(temp_crit2);
show_temp(temp_hyst2);
#define set_temp2(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -154,7 +154,7 @@ set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH);
set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT);
set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST);
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct max1619_data *data = max1619_update_device(dev);
return sprintf(buf, "%d\n", data->alarms);
diff --git a/drivers/i2c/chips/pc87360.c b/drivers/i2c/chips/pc87360.c
index 6d94c36c9218..65637b2cd170 100644
--- a/drivers/i2c/chips/pc87360.c
+++ b/drivers/i2c/chips/pc87360.c
@@ -282,31 +282,31 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
}
#define show_and_set_fan(offset) \
-static ssize_t show_fan##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[offset-1], \
FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
} \
-static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[offset-1], \
FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
} \
-static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", \
FAN_DIV_FROM_REG(data->fan_status[offset-1])); \
} \
-static ssize_t show_fan##offset##_status(struct device *dev, char *buf) \
+static ssize_t show_fan##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", \
FAN_STATUS_FROM_REG(data->fan_status[offset-1])); \
} \
-static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
return set_fan_min(dev, buf, count, offset-1); \
@@ -324,7 +324,7 @@ show_and_set_fan(2)
show_and_set_fan(3)
#define show_and_set_pwm(offset) \
-static ssize_t show_pwm##offset(struct device *dev, char *buf) \
+static ssize_t show_pwm##offset(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", \
@@ -332,7 +332,7 @@ static ssize_t show_pwm##offset(struct device *dev, char *buf) \
FAN_CONFIG_INVERT(data->fan_conf, \
offset-1))); \
} \
-static ssize_t set_pwm##offset(struct device *dev, const char *buf, \
+static ssize_t set_pwm##offset(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -354,30 +354,30 @@ show_and_set_pwm(2)
show_and_set_pwm(3)
#define show_and_set_in(offset) \
-static ssize_t show_in##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
data->in_vref)); \
} \
-static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
data->in_vref)); \
} \
-static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
data->in_vref)); \
} \
-static ssize_t show_in##offset##_status(struct device *dev, char *buf) \
+static ssize_t show_in##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", data->in_status[offset]); \
} \
-static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -391,7 +391,7 @@ static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
+static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -427,36 +427,36 @@ show_and_set_in(9)
show_and_set_in(10)
#define show_and_set_therm(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset+7], \
data->in_vref)); \
} \
-static ssize_t show_temp##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset+7], \
data->in_vref)); \
} \
-static ssize_t show_temp##offset##_max(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset+7], \
data->in_vref)); \
} \
-static ssize_t show_temp##offset##_crit(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[offset-4], \
data->in_vref)); \
} \
-static ssize_t show_temp##offset##_status(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%u\n", data->in_status[offset+7]); \
} \
-static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -470,7 +470,7 @@ static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -484,7 +484,7 @@ static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -512,19 +512,19 @@ show_and_set_therm(4)
show_and_set_therm(5)
show_and_set_therm(6)
-static ssize_t show_vid(struct device *dev, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pc87360_data *data = pc87360_update_device(dev);
return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
}
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-static ssize_t show_vrm(struct device *dev, char *buf)
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pc87360_data *data = pc87360_update_device(dev);
return sprintf(buf, "%u\n", data->vrm);
}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct pc87360_data *data = i2c_get_clientdata(client);
@@ -533,7 +533,7 @@ static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
}
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-static ssize_t show_in_alarms(struct device *dev, char *buf)
+static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pc87360_data *data = pc87360_update_device(dev);
return sprintf(buf, "%u\n", data->in_alarms);
@@ -541,32 +541,32 @@ static ssize_t show_in_alarms(struct device *dev, char *buf)
static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
#define show_and_set_temp(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
} \
-static ssize_t show_temp##offset##_min(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
} \
-static ssize_t show_temp##offset##_max(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
}\
-static ssize_t show_temp##offset##_crit(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[offset-1])); \
}\
-static ssize_t show_temp##offset##_status(struct device *dev, char *buf) \
+static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pc87360_data *data = pc87360_update_device(dev); \
return sprintf(buf, "%d\n", data->temp_status[offset-1]); \
}\
-static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -580,7 +580,7 @@ static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -594,7 +594,7 @@ static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
up(&data->update_lock); \
return count; \
} \
-static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
+static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
@@ -622,7 +622,7 @@ show_and_set_temp(1)
show_and_set_temp(2)
show_and_set_temp(3)
-static ssize_t show_temp_alarms(struct device *dev, char *buf)
+static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pc87360_data *data = pc87360_update_device(dev);
return sprintf(buf, "%u\n", data->temp_alarms);
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
index 48b4e22eaffe..4956e9effd75 100644
--- a/drivers/i2c/chips/pcf8574.c
+++ b/drivers/i2c/chips/pcf8574.c
@@ -76,7 +76,7 @@ static struct i2c_driver pcf8574_driver = {
};
/* following are the sysfs callback functions */
-static ssize_t show_read(struct device *dev, char *buf)
+static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8574_data *data = i2c_get_clientdata(client);
@@ -86,13 +86,13 @@ static ssize_t show_read(struct device *dev, char *buf)
static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
-static ssize_t show_write(struct device *dev, char *buf)
+static ssize_t show_write(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcf8574_data *data = i2c_get_clientdata(to_i2c_client(dev));
return sprintf(buf, "%u\n", data->write);
}
-static ssize_t set_write(struct device *dev, const char *buf,
+static ssize_t set_write(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
index b6b927d8b372..db812ade8564 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -100,7 +100,7 @@ static struct i2c_driver pcf8591_driver = {
/* following are the sysfs callback functions */
#define show_in_channel(channel) \
-static ssize_t show_in##channel##_input(struct device *dev, char *buf) \
+static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
} \
@@ -112,13 +112,13 @@ show_in_channel(1);
show_in_channel(2);
show_in_channel(3);
-static ssize_t show_out0_ouput(struct device *dev, char *buf)
+static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
return sprintf(buf, "%d\n", data->aout * 10);
}
-static ssize_t set_out0_output(struct device *dev, const char *buf, size_t count)
+static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
unsigned int value;
struct i2c_client *client = to_i2c_client(dev);
@@ -134,13 +134,13 @@ static ssize_t set_out0_output(struct device *dev, const char *buf, size_t count
static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
show_out0_ouput, set_out0_output);
-static ssize_t show_out0_enable(struct device *dev, char *buf)
+static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
}
-static ssize_t set_out0_enable(struct device *dev, const char *buf, size_t count)
+static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8591_data *data = i2c_get_clientdata(client);
diff --git a/drivers/i2c/chips/sis5595.c b/drivers/i2c/chips/sis5595.c
index 7ea84532df32..c6650727a27d 100644
--- a/drivers/i2c/chips/sis5595.c
+++ b/drivers/i2c/chips/sis5595.c
@@ -256,28 +256,28 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
#define show_in_offset(offset) \
static ssize_t \
- show_in##offset (struct device *dev, char *buf) \
+ show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL); \
static ssize_t \
- show_in##offset##_min (struct device *dev, char *buf) \
+ show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_min(dev, buf, offset); \
} \
static ssize_t \
- show_in##offset##_max (struct device *dev, char *buf) \
+ show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_max(dev, buf, offset); \
} \
-static ssize_t set_in##offset##_min (struct device *dev, \
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, offset); \
} \
-static ssize_t set_in##offset##_max (struct device *dev, \
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, offset); \
@@ -294,19 +294,19 @@ show_in_offset(3);
show_in_offset(4);
/* Temperature */
-static ssize_t show_temp(struct device *dev, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sis5595_data *data = sis5595_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
}
-static ssize_t show_temp_over(struct device *dev, char *buf)
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sis5595_data *data = sis5595_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}
-static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
@@ -319,13 +319,13 @@ static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
return count;
}
-static ssize_t show_temp_hyst(struct device *dev, char *buf)
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sis5595_data *data = sis5595_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
}
-static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
@@ -426,19 +426,19 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
@@ -450,13 +450,13 @@ static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
show_fan_offset(1);
show_fan_offset(2);
-static ssize_t set_fan_1_div(struct device *dev, const char *buf,
+static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
return set_fan_div(dev, buf, count, 0) ;
}
-static ssize_t set_fan_2_div(struct device *dev, const char *buf,
+static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
return set_fan_div(dev, buf, count, 1) ;
@@ -467,7 +467,7 @@ static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
show_fan_2_div, set_fan_2_div);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sis5595_data *data = sis5595_update_device(dev);
return sprintf(buf, "%d\n", data->alarms);
diff --git a/drivers/i2c/chips/smsc47b397.c b/drivers/i2c/chips/smsc47b397.c
index 1119c76791d9..251ac2659554 100644
--- a/drivers/i2c/chips/smsc47b397.c
+++ b/drivers/i2c/chips/smsc47b397.c
@@ -172,7 +172,7 @@ static ssize_t show_temp(struct device *dev, char *buf, int nr)
}
#define sysfs_temp(num) \
-static ssize_t show_temp##num(struct device *dev, char *buf) \
+static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, num-1); \
} \
@@ -201,7 +201,7 @@ static ssize_t show_fan(struct device *dev, char *buf, int nr)
}
#define sysfs_fan(num) \
-static ssize_t show_fan##num(struct device *dev, char *buf) \
+static ssize_t show_fan##num(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, num-1); \
} \
diff --git a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c
index 0e12ca369413..13d6d4a8bc7d 100644
--- a/drivers/i2c/chips/smsc47m1.c
+++ b/drivers/i2c/chips/smsc47m1.c
@@ -184,7 +184,7 @@ static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
}
-static ssize_t get_alarms(struct device *dev, char *buf)
+static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
return sprintf(buf, "%d\n", data->alarms);
@@ -298,42 +298,42 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
}
#define fan_present(offset) \
-static ssize_t get_fan##offset (struct device *dev, char *buf) \
+static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return get_fan(dev, buf, offset - 1); \
} \
-static ssize_t get_fan##offset##_min (struct device *dev, char *buf) \
+static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return get_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t set_fan##offset##_min (struct device *dev, \
+static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
} \
-static ssize_t get_fan##offset##_div (struct device *dev, char *buf) \
+static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return get_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan##offset##_div (struct device *dev, \
+static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_div(dev, buf, count, offset - 1); \
} \
-static ssize_t get_pwm##offset (struct device *dev, char *buf) \
+static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return get_pwm(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset (struct device *dev, \
+static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm(dev, buf, count, offset - 1); \
} \
-static ssize_t get_pwm##offset##_en (struct device *dev, char *buf) \
+static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return get_pwm_en(dev, buf, offset - 1); \
} \
-static ssize_t set_pwm##offset##_en (struct device *dev, \
+static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_pwm_en(dev, buf, count, offset - 1); \
diff --git a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
index 6614a59cecd4..fefc24a9251a 100644
--- a/drivers/i2c/chips/via686a.c
+++ b/drivers/i2c/chips/via686a.c
@@ -386,26 +386,26 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
}
#define show_in_offset(offset) \
static ssize_t \
- show_in##offset (struct device *dev, char *buf) \
+ show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
static ssize_t \
- show_in##offset##_min (struct device *dev, char *buf) \
+ show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_min(dev, buf, offset); \
} \
static ssize_t \
- show_in##offset##_max (struct device *dev, char *buf) \
+ show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_max(dev, buf, offset); \
} \
-static ssize_t set_in##offset##_min (struct device *dev, \
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, offset); \
} \
-static ssize_t set_in##offset##_max (struct device *dev, \
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, offset); \
@@ -460,26 +460,26 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf,
return count;
}
#define show_temp_offset(offset) \
-static ssize_t show_temp_##offset (struct device *dev, char *buf) \
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, offset - 1); \
} \
static ssize_t \
-show_temp_##offset##_over (struct device *dev, char *buf) \
+show_temp_##offset##_over (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_over(dev, buf, offset - 1); \
} \
static ssize_t \
-show_temp_##offset##_hyst (struct device *dev, char *buf) \
+show_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_hyst(dev, buf, offset - 1); \
} \
-static ssize_t set_temp_##offset##_over (struct device *dev, \
+static ssize_t set_temp_##offset##_over (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_over(dev, buf, count, offset - 1); \
} \
-static ssize_t set_temp_##offset##_hyst (struct device *dev, \
+static ssize_t set_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_temp_hyst(dev, buf, count, offset - 1); \
@@ -538,24 +538,24 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
}
#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset - 1); \
} \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, offset - 1); \
} \
-static ssize_t set_fan_##offset##_div (struct device *dev, \
+static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return set_fan_div(dev, buf, count, offset - 1); \
@@ -570,7 +570,7 @@ show_fan_offset(1);
show_fan_offset(2);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf) {
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
struct via686a_data *data = via686a_update_device(dev);
return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
}
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
index b1da5ed696d3..4f1bff572c1c 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ b/drivers/i2c/chips/w83627hf.c
@@ -368,19 +368,19 @@ store_in_reg(MAX, max)
#define sysfs_in_offset(offset) \
static ssize_t \
-show_regs_in_##offset (struct device *dev, char *buf) \
+show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
#define sysfs_in_reg_offset(reg, offset) \
-static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_##reg (dev, buf, offset); \
} \
static ssize_t \
-store_regs_in_##reg##offset (struct device *dev, \
+store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_in_##reg (dev, buf, count, offset); \
@@ -419,25 +419,25 @@ static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
return sprintf(buf,"%ld\n", in0);
}
-static ssize_t show_regs_in_0(struct device *dev, char *buf)
+static ssize_t show_regs_in_0(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627hf_data *data = w83627hf_update_device(dev);
return show_in_0(data, buf, data->in[0]);
}
-static ssize_t show_regs_in_min0(struct device *dev, char *buf)
+static ssize_t show_regs_in_min0(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627hf_data *data = w83627hf_update_device(dev);
return show_in_0(data, buf, data->in_min[0]);
}
-static ssize_t show_regs_in_max0(struct device *dev, char *buf)
+static ssize_t show_regs_in_max0(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627hf_data *data = w83627hf_update_device(dev);
return show_in_0(data, buf, data->in_max[0]);
}
-static ssize_t store_regs_in_min0(struct device *dev,
+static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -462,7 +462,7 @@ static ssize_t store_regs_in_min0(struct device *dev,
return count;
}
-static ssize_t store_regs_in_max0(struct device *dev,
+static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -531,19 +531,19 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_fan_offset(offset) \
-static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
#define sysfs_fan_min_offset(offset) \
-static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset); \
} \
static ssize_t \
-store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
+store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_fan_min(dev, buf, count, offset); \
} \
@@ -608,19 +608,19 @@ store_temp_reg(HYST, max_hyst);
#define sysfs_temp_offset(offset) \
static ssize_t \
-show_regs_temp_##offset (struct device *dev, char *buf) \
+show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, offset); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
-static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_##reg (dev, buf, offset); \
} \
static ssize_t \
-store_regs_temp_##reg##offset (struct device *dev, \
+store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_temp_##reg (dev, buf, count, offset); \
@@ -645,7 +645,7 @@ device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
} while (0)
static ssize_t
-show_vid_reg(struct device *dev, char *buf)
+show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
@@ -655,13 +655,13 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
device_create_file(&client->dev, &dev_attr_cpu0_vid)
static ssize_t
-show_vrm_reg(struct device *dev, char *buf)
+show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->vrm);
}
static ssize_t
-store_vrm_reg(struct device *dev, const char *buf, size_t count)
+store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83627hf_data *data = i2c_get_clientdata(client);
@@ -677,7 +677,7 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
device_create_file(&client->dev, &dev_attr_vrm)
static ssize_t
-show_alarms_reg(struct device *dev, char *buf)
+show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->alarms);
@@ -687,7 +687,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
device_create_file(&client->dev, &dev_attr_alarms)
#define show_beep_reg(REG, reg) \
-static ssize_t show_beep_##reg (struct device *dev, char *buf) \
+static ssize_t show_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct w83627hf_data *data = w83627hf_update_device(dev); \
return sprintf(buf,"%ld\n", \
@@ -732,12 +732,12 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
}
#define sysfs_beep(REG, reg) \
-static ssize_t show_regs_beep_##reg (struct device *dev, char *buf) \
+static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
- return show_beep_##reg(dev, buf); \
+ return show_beep_##reg(dev, attr, buf); \
} \
static ssize_t \
-store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \
+store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \
@@ -801,12 +801,12 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_fan_div(offset) \
-static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div_reg(dev, buf, offset); \
} \
static ssize_t \
-store_regs_fan_div_##offset (struct device *dev, \
+store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_fan_div_reg(dev, buf, count, offset - 1); \
@@ -861,12 +861,12 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_pwm(offset) \
-static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwm_reg(dev, buf, offset); \
} \
static ssize_t \
-store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \
+store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_pwm_reg(dev, buf, count, offset); \
} \
@@ -937,12 +937,12 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_sensor(offset) \
-static ssize_t show_regs_sensor_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_sensor_reg(dev, buf, offset); \
} \
static ssize_t \
-store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \
+store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_sensor_reg(dev, buf, count, offset); \
} \
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
index 4954e465c419..c3926d2d8ac6 100644
--- a/drivers/i2c/chips/w83781d.c
+++ b/drivers/i2c/chips/w83781d.c
@@ -309,18 +309,18 @@ store_in_reg(MAX, max);
#define sysfs_in_offset(offset) \
static ssize_t \
-show_regs_in_##offset (struct device *dev, char *buf) \
+show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
#define sysfs_in_reg_offset(reg, offset) \
-static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_in_##reg (dev, buf, offset); \
} \
-static ssize_t store_regs_in_##reg##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_in_##reg (dev, buf, count, offset); \
} \
@@ -378,18 +378,18 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_fan_offset(offset) \
-static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan(dev, buf, offset); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
#define sysfs_fan_min_offset(offset) \
-static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_min(dev, buf, offset); \
} \
-static ssize_t store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_fan_min(dev, buf, count, offset); \
} \
@@ -452,18 +452,18 @@ store_temp_reg(HYST, max_hyst);
#define sysfs_temp_offset(offset) \
static ssize_t \
-show_regs_temp_##offset (struct device *dev, char *buf) \
+show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp(dev, buf, offset); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
-static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_temp_##reg (dev, buf, offset); \
} \
-static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_temp_##reg (dev, buf, count, offset); \
} \
@@ -486,7 +486,7 @@ device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
} while (0)
static ssize_t
-show_vid_reg(struct device *dev, char *buf)
+show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
@@ -497,14 +497,14 @@ DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_cpu0_vid);
static ssize_t
-show_vrm_reg(struct device *dev, char *buf)
+show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->vrm);
}
static ssize_t
-store_vrm_reg(struct device *dev, const char *buf, size_t count)
+store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client);
@@ -521,7 +521,7 @@ DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm);
static ssize_t
-show_alarms_reg(struct device *dev, char *buf)
+show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));
@@ -531,13 +531,13 @@ static
DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms);
-static ssize_t show_beep_mask (struct device *dev, char *buf)
+static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
return sprintf(buf, "%ld\n",
(long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));
}
-static ssize_t show_beep_enable (struct device *dev, char *buf)
+static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
return sprintf(buf, "%ld\n",
@@ -583,11 +583,11 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
}
#define sysfs_beep(REG, reg) \
-static ssize_t show_regs_beep_##reg (struct device *dev, char *buf) \
+static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
- return show_beep_##reg(dev, buf); \
+ return show_beep_##reg(dev, attr, buf); \
} \
-static ssize_t store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \
@@ -653,11 +653,11 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_fan_div(offset) \
-static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_fan_div_reg(dev, buf, offset); \
} \
-static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_fan_div_reg(dev, buf, count, offset - 1); \
} \
@@ -737,11 +737,11 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_pwm(offset) \
-static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwm_reg(dev, buf, offset); \
} \
-static ssize_t store_regs_pwm_##offset (struct device *dev, \
+static ssize_t store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_pwm_reg(dev, buf, count, offset); \
@@ -750,11 +750,11 @@ static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_regs_pwm_##offset, store_regs_pwm_##offset);
#define sysfs_pwmenable(offset) \
-static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_pwmenable_reg(dev, buf, offset); \
} \
-static ssize_t store_regs_pwmenable_##offset (struct device *dev, \
+static ssize_t store_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_pwmenable_reg(dev, buf, count, offset); \
@@ -832,11 +832,11 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
}
#define sysfs_sensor(offset) \
-static ssize_t show_regs_sensor_##offset (struct device *dev, char *buf) \
+static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return show_sensor_reg(dev, buf, offset); \
} \
-static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
return store_sensor_reg(dev, buf, count, offset); \
} \
diff --git a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c
index 59bbc5881fa6..74d4b58e4237 100644
--- a/drivers/i2c/chips/w83l785ts.c
+++ b/drivers/i2c/chips/w83l785ts.c
@@ -118,13 +118,13 @@ struct w83l785ts_data {
* Sysfs stuff
*/
-static ssize_t show_temp(struct device *dev, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83l785ts_data *data = w83l785ts_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
}
-static ssize_t show_temp_over(struct device *dev, char *buf)
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83l785ts_data *data = w83l785ts_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 9011627d7eb0..a22e53badacb 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -103,7 +103,7 @@ static struct class i2c_adapter_class = {
.release = &i2c_adapter_class_dev_release,
};
-static ssize_t show_adapter_name(struct device *dev, char *buf)
+static ssize_t show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
return sprintf(buf, "%s\n", adap->name);
@@ -117,7 +117,7 @@ static void i2c_client_release(struct device *dev)
complete(&client->released);
}
-static ssize_t show_client_name(struct device *dev, char *buf)
+static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return sprintf(buf, "%s\n", client->name);
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 68c7a5f07842..4538b0235ca3 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2343,8 +2343,8 @@ static void dv1394_remove_host (struct hpsb_host *host)
dv1394_un_init(video);
} while (video != NULL);
- class_simple_device_remove(MKDEV(
- IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
+ class_device_destroy(hpsb_protocol_class,
+ MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
devfs_remove("ieee1394/dv/host%d/NTSC", id);
devfs_remove("ieee1394/dv/host%d/PAL", id);
devfs_remove("ieee1394/dv/host%d", id);
@@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
- class_simple_device_add(hpsb_protocol_class, MKDEV(
+ class_device_create(hpsb_protocol_class, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
NULL, "dv1394-%d", id);
devfs_mk_dir("ieee1394/dv/host%d", id);
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index a294e45c77cd..2d9a9b74e687 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -67,7 +67,7 @@ MODULE_LICENSE("GPL");
/* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
-struct class_simple *hpsb_protocol_class;
+struct class *hpsb_protocol_class;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
static void dump_packet(const char *text, quadlet_t *data, int size)
@@ -1121,7 +1121,7 @@ static int __init ieee1394_init(void)
if (ret < 0)
goto release_all_bus;
- hpsb_protocol_class = class_simple_create(THIS_MODULE, "ieee1394_protocol");
+ hpsb_protocol_class = class_create(THIS_MODULE, "ieee1394_protocol");
if (IS_ERR(hpsb_protocol_class)) {
ret = PTR_ERR(hpsb_protocol_class);
goto release_class_host;
@@ -1159,7 +1159,7 @@ static int __init ieee1394_init(void)
cleanup_csr:
cleanup_csr();
release_class_protocol:
- class_simple_destroy(hpsb_protocol_class);
+ class_destroy(hpsb_protocol_class);
release_class_host:
class_unregister(&hpsb_host_class);
release_all_bus:
@@ -1189,7 +1189,7 @@ static void __exit ieee1394_cleanup(void)
cleanup_csr();
- class_simple_destroy(hpsb_protocol_class);
+ class_destroy(hpsb_protocol_class);
class_unregister(&hpsb_host_class);
for (i = 0; fw_bus_attrs[i]; i++)
bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index c4b4408e2e05..73bd8efd2b6c 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -223,6 +223,7 @@ extern int hpsb_disable_irm;
/* Our sysfs bus entry */
extern struct bus_type ieee1394_bus_type;
extern struct class hpsb_host_class;
-extern struct class_simple *hpsb_protocol_class;
+extern struct class *hpsb_protocol_class;
#endif /* _IEEE1394_CORE_H */
+
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 83e66ed97ab5..32abb6dda888 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -220,7 +220,7 @@ struct device nodemgr_dev_template_host = {
#define fw_attr(class, class_type, field, type, format_string) \
-static ssize_t fw_show_##class##_##field (struct device *dev, char *buf)\
+static ssize_t fw_show_##class##_##field (struct device *dev, struct device_attribute *attr, char *buf)\
{ \
class_type *class; \
class = container_of(dev, class_type, device); \
@@ -232,7 +232,7 @@ static struct device_attribute dev_attr_##class##_##field = { \
};
#define fw_attr_td(class, class_type, td_kv) \
-static ssize_t fw_show_##class##_##td_kv (struct device *dev, char *buf)\
+static ssize_t fw_show_##class##_##td_kv (struct device *dev, struct device_attribute *attr, char *buf)\
{ \
int len; \
class_type *class = container_of(dev, class_type, device); \
@@ -265,7 +265,7 @@ static struct driver_attribute driver_attr_drv_##field = { \
};
-static ssize_t fw_show_ne_bus_options(struct device *dev, char *buf)
+static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribute *attr, char *buf)
{
struct node_entry *ne = container_of(dev, struct node_entry, device);
@@ -281,7 +281,7 @@ static ssize_t fw_show_ne_bus_options(struct device *dev, char *buf)
static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL);
-static ssize_t fw_show_ne_tlabels_free(struct device *dev, char *buf)
+static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf)
{
struct node_entry *ne = container_of(dev, struct node_entry, device);
return sprintf(buf, "%d\n", atomic_read(&ne->tpool->count.count) + 1);
@@ -289,7 +289,7 @@ static ssize_t fw_show_ne_tlabels_free(struct device *dev, char *buf)
static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
-static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, char *buf)
+static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, struct device_attribute *attr, char *buf)
{
struct node_entry *ne = container_of(dev, struct node_entry, device);
return sprintf(buf, "%u\n", ne->tpool->allocations);
@@ -297,7 +297,7 @@ static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, char *buf)
static DEVICE_ATTR(tlabels_allocations,S_IRUGO,fw_show_ne_tlabels_allocations,NULL);
-static ssize_t fw_show_ne_tlabels_mask(struct device *dev, char *buf)
+static ssize_t fw_show_ne_tlabels_mask(struct device *dev, struct device_attribute *attr, char *buf)
{
struct node_entry *ne = container_of(dev, struct node_entry, device);
#if (BITS_PER_LONG <= 32)
@@ -309,7 +309,7 @@ static ssize_t fw_show_ne_tlabels_mask(struct device *dev, char *buf)
static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
-static ssize_t fw_set_ignore_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct unit_directory *ud = container_of(dev, struct unit_directory, device);
int state = simple_strtoul(buf, NULL, 10);
@@ -324,7 +324,7 @@ static ssize_t fw_set_ignore_driver(struct device *dev, const char *buf, size_t
return count;
}
-static ssize_t fw_get_ignore_driver(struct device *dev, char *buf)
+static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute *attr, char *buf)
{
struct unit_directory *ud = container_of(dev, struct unit_directory, device);
@@ -695,14 +695,15 @@ static void nodemgr_remove_ne(struct node_entry *ne)
put_device(dev);
}
+static int __nodemgr_remove_host_dev(struct device *dev, void *data)
+{
+ nodemgr_remove_ne(container_of(dev, struct node_entry, device));
+ return 0;
+}
static void nodemgr_remove_host_dev(struct device *dev)
{
- struct device *ne_dev, *next;
-
- list_for_each_entry_safe(ne_dev, next, &dev->children, node)
- nodemgr_remove_ne(container_of(ne_dev, struct node_entry, device));
-
+ device_for_each_child(dev, NULL, __nodemgr_remove_host_dev);
sysfs_remove_link(&dev->kobj, "irm_id");
sysfs_remove_link(&dev->kobj, "busmgr_id");
sysfs_remove_link(&dev->kobj, "host_id");
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 6a08a8982ea8..7419af450bd1 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2901,7 +2901,7 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
- if (IS_ERR(class_simple_device_add(hpsb_protocol_class, MKDEV(
+ if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
@@ -2934,8 +2934,8 @@ static int __init init_raw1394(void)
out_dev:
devfs_remove(RAW1394_DEVICE_NAME);
- class_simple_device_remove(MKDEV(
- IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+ class_device_destroy(hpsb_protocol_class,
+ MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
out_unreg:
hpsb_unregister_highlevel(&raw1394_highlevel);
out:
@@ -2944,8 +2944,8 @@ out:
static void __exit cleanup_raw1394(void)
{
- class_simple_device_remove(MKDEV(
- IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+ class_device_destroy(hpsb_protocol_class,
+ MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
cdev_del(&raw1394_cdev);
devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(&raw1394_highlevel);
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 2bae300aad46..32368f3428ec 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -2648,7 +2648,7 @@ static const char *sbp2scsi_info (struct Scsi_Host *host)
return "SCSI emulation for IEEE-1394 SBP-2 Devices";
}
-static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, char *buf)
+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev;
struct scsi_id_instance_data *scsi_id;
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index d68c4658f2fc..06759b36afea 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
- class_simple_device_add(hpsb_protocol_class, MKDEV(
+ class_device_create(hpsb_protocol_class, MKDEV(
IEEE1394_MAJOR, minor),
NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
@@ -1384,7 +1384,7 @@ static void video1394_remove_host (struct hpsb_host *host)
struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
if (ohci) {
- class_simple_device_remove(MKDEV(IEEE1394_MAJOR,
+ class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
}
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 3a413f72ff6d..90d51b179abe 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -40,9 +40,7 @@ struct ib_port {
struct kobject kobj;
struct ib_device *ibdev;
struct attribute_group gid_group;
- struct attribute **gid_attr;
struct attribute_group pkey_group;
- struct attribute **pkey_attr;
u8 port_num;
};
@@ -60,8 +58,9 @@ struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store)
struct port_attribute port_attr_##_name = __ATTR_RO(_name)
struct port_table_attribute {
- struct port_attribute attr;
- int index;
+ struct port_attribute attr;
+ char name[8];
+ int index;
};
static ssize_t port_attr_show(struct kobject *kobj,
@@ -72,7 +71,7 @@ static ssize_t port_attr_show(struct kobject *kobj,
struct ib_port *p = container_of(kobj, struct ib_port, kobj);
if (!port_attr->show)
- return 0;
+ return -EIO;
return port_attr->show(p, port_attr, buf);
}
@@ -398,17 +397,16 @@ static void ib_port_release(struct kobject *kobj)
struct attribute *a;
int i;
- for (i = 0; (a = p->gid_attr[i]); ++i) {
- kfree(a->name);
+ for (i = 0; (a = p->gid_group.attrs[i]); ++i)
kfree(a);
- }
- for (i = 0; (a = p->pkey_attr[i]); ++i) {
- kfree(a->name);
+ kfree(p->gid_group.attrs);
+
+ for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
kfree(a);
- }
- kfree(p->gid_attr);
+ kfree(p->pkey_group.attrs);
+
kfree(p);
}
@@ -449,58 +447,45 @@ static int ib_device_hotplug(struct class_device *cdev, char **envp,
return 0;
}
-static int alloc_group(struct attribute ***attr,
- ssize_t (*show)(struct ib_port *,
- struct port_attribute *, char *buf),
- int len)
+static struct attribute **
+alloc_group_attrs(ssize_t (*show)(struct ib_port *,
+ struct port_attribute *, char *buf),
+ int len)
{
- struct port_table_attribute ***tab_attr =
- (struct port_table_attribute ***) attr;
+ struct attribute **tab_attr;
+ struct port_table_attribute *element;
int i;
- int ret;
-
- *tab_attr = kmalloc((1 + len) * sizeof *tab_attr, GFP_KERNEL);
- if (!*tab_attr)
- return -ENOMEM;
- memset(*tab_attr, 0, (1 + len) * sizeof *tab_attr);
+ tab_attr = kcalloc(1 + len, sizeof(struct attribute *), GFP_KERNEL);
+ if (!tab_attr)
+ return NULL;
- for (i = 0; i < len; ++i) {
- (*tab_attr)[i] = kmalloc(sizeof *(*tab_attr)[i], GFP_KERNEL);
- if (!(*tab_attr)[i]) {
- ret = -ENOMEM;
+ for (i = 0; i < len; i++) {
+ element = kcalloc(1, sizeof(struct port_table_attribute),
+ GFP_KERNEL);
+ if (!element)
goto err;
- }
- memset((*tab_attr)[i], 0, sizeof *(*tab_attr)[i]);
- (*tab_attr)[i]->attr.attr.name = kmalloc(8, GFP_KERNEL);
- if (!(*tab_attr)[i]->attr.attr.name) {
- ret = -ENOMEM;
- goto err;
- }
- if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) {
- ret = -ENOMEM;
+ if (snprintf(element->name, sizeof(element->name),
+ "%d", i) >= sizeof(element->name))
goto err;
- }
- (*tab_attr)[i]->attr.attr.mode = S_IRUGO;
- (*tab_attr)[i]->attr.attr.owner = THIS_MODULE;
- (*tab_attr)[i]->attr.show = show;
- (*tab_attr)[i]->index = i;
- }
-
- return 0;
+ element->attr.attr.name = element->name;
+ element->attr.attr.mode = S_IRUGO;
+ element->attr.attr.owner = THIS_MODULE;
+ element->attr.show = show;
+ element->index = i;
-err:
- for (i = 0; i < len; ++i) {
- if ((*tab_attr)[i])
- kfree((*tab_attr)[i]->attr.attr.name);
- kfree((*tab_attr)[i]);
+ tab_attr[i] = &element->attr.attr;
}
- kfree(*tab_attr);
+ return tab_attr;
- return ret;
+err:
+ while (--i >= 0)
+ kfree(tab_attr[i]);
+ kfree(tab_attr);
+ return NULL;
}
static int add_port(struct ib_device *device, int port_num)
@@ -541,23 +526,20 @@ static int add_port(struct ib_device *device, int port_num)
if (ret)
goto err_put;
- ret = alloc_group(&p->gid_attr, show_port_gid, attr.gid_tbl_len);
- if (ret)
- goto err_remove_pma;
-
p->gid_group.name = "gids";
- p->gid_group.attrs = p->gid_attr;
+ p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
+ if (!p->gid_group.attrs)
+ goto err_remove_pma;
ret = sysfs_create_group(&p->kobj, &p->gid_group);
if (ret)
goto err_free_gid;
- ret = alloc_group(&p->pkey_attr, show_port_pkey, attr.pkey_tbl_len);
- if (ret)
- goto err_remove_gid;
-
p->pkey_group.name = "pkeys";
- p->pkey_group.attrs = p->pkey_attr;
+ p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,
+ attr.pkey_tbl_len);
+ if (!p->pkey_group.attrs)
+ goto err_remove_gid;
ret = sysfs_create_group(&p->kobj, &p->pkey_group);
if (ret)
@@ -568,23 +550,19 @@ static int add_port(struct ib_device *device, int port_num)
return 0;
err_free_pkey:
- for (i = 0; i < attr.pkey_tbl_len; ++i) {
- kfree(p->pkey_attr[i]->name);
- kfree(p->pkey_attr[i]);
- }
+ for (i = 0; i < attr.pkey_tbl_len; ++i)
+ kfree(p->pkey_group.attrs[i]);
- kfree(p->pkey_attr);
+ kfree(p->pkey_group.attrs);
err_remove_gid:
sysfs_remove_group(&p->kobj, &p->gid_group);
err_free_gid:
- for (i = 0; i < attr.gid_tbl_len; ++i) {
- kfree(p->gid_attr[i]->name);
- kfree(p->gid_attr[i]);
- }
+ for (i = 0; i < attr.gid_tbl_len; ++i)
+ kfree(p->gid_group.attrs[i]);
- kfree(p->gid_attr);
+ kfree(p->gid_group.attrs);
err_remove_pma:
sysfs_remove_group(&p->kobj, &pma_group);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 17552a29978b..556264b43425 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -431,9 +431,9 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
- class_simple_device_add(input_class,
- MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
- dev->dev, "event%d", minor);
+ class_device_create(input_class,
+ MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+ dev->dev, "event%d", minor);
return &evdev->handle;
}
@@ -443,7 +443,8 @@ static void evdev_disconnect(struct input_handle *handle)
struct evdev *evdev = handle->private;
struct evdev_list *list;
- class_simple_device_remove(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
+ class_device_destroy(input_class,
+ MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
devfs_remove("input/event%d", evdev->minor);
evdev->exist = 0;
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index f20c3f23388b..9b8ff396e6f8 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -453,13 +453,13 @@ static int gameport_thread(void *nothing)
* Gameport port operations
*/
-static ssize_t gameport_show_description(struct device *dev, char *buf)
+static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf)
{
struct gameport *gameport = to_gameport_port(dev);
return sprintf(buf, "%s\n", gameport->name);
}
-static ssize_t gameport_rebind_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct gameport *gameport = to_gameport_port(dev);
struct device_driver *drv;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3385dd03abfc..83c77c990dda 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -702,13 +702,13 @@ static int __init input_proc_init(void)
static inline int input_proc_init(void) { return 0; }
#endif
-struct class_simple *input_class;
+struct class *input_class;
static int __init input_init(void)
{
int retval = -ENOMEM;
- input_class = class_simple_create(THIS_MODULE, "input");
+ input_class = class_create(THIS_MODULE, "input");
if (IS_ERR(input_class))
return PTR_ERR(input_class);
input_proc_init();
@@ -718,7 +718,7 @@ static int __init input_init(void)
remove_proc_entry("devices", proc_bus_input_dir);
remove_proc_entry("handlers", proc_bus_input_dir);
remove_proc_entry("input", proc_bus);
- class_simple_destroy(input_class);
+ class_destroy(input_class);
return retval;
}
@@ -728,7 +728,7 @@ static int __init input_init(void)
remove_proc_entry("handlers", proc_bus_input_dir);
remove_proc_entry("input", proc_bus);
unregister_chrdev(INPUT_MAJOR, "input");
- class_simple_destroy(input_class);
+ class_destroy(input_class);
}
return retval;
}
@@ -741,7 +741,7 @@ static void __exit input_exit(void)
devfs_remove("input");
unregister_chrdev(INPUT_MAJOR, "input");
- class_simple_destroy(input_class);
+ class_destroy(input_class);
}
subsys_initcall(input_init);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 627d343dfba1..39775fc380c7 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -452,9 +452,9 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
- class_simple_device_add(input_class,
- MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
- dev->dev, "js%d", minor);
+ class_device_create(input_class,
+ MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+ dev->dev, "js%d", minor);
return &joydev->handle;
}
@@ -464,7 +464,7 @@ static void joydev_disconnect(struct input_handle *handle)
struct joydev *joydev = handle->private;
struct joydev_list *list;
- class_simple_device_remove(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
+ class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
devfs_remove("input/js%d", joydev->minor);
joydev->exist = 0;
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 48fdf1e517cf..82fad9a23ace 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -219,11 +219,11 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t
#define ATKBD_DEFINE_ATTR(_name) \
static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \
-static ssize_t atkbd_do_show_##_name(struct device *d, char *b) \
+static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \
{ \
return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
} \
-static ssize_t atkbd_do_set_##_name(struct device *d, const char *b, size_t s) \
+static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s) \
{ \
return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \
} \
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index bda5b065d03c..79e17a0c4664 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -91,11 +91,11 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
#define PSMOUSE_DEFINE_ATTR(_name) \
static ssize_t psmouse_attr_show_##_name(struct psmouse *, char *); \
static ssize_t psmouse_attr_set_##_name(struct psmouse *, const char *, size_t);\
-static ssize_t psmouse_do_show_##_name(struct device *d, char *b) \
+static ssize_t psmouse_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \
{ \
return psmouse_attr_show_helper(d, b, psmouse_attr_show_##_name); \
} \
-static ssize_t psmouse_do_set_##_name(struct device *d, const char *b, size_t s)\
+static ssize_t psmouse_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s)\
{ \
return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name); \
} \
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 96fb9870834a..062848ac7e6b 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -647,9 +647,9 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
- class_simple_device_add(input_class,
- MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
- dev->dev, "mouse%d", minor);
+ class_device_create(input_class,
+ MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+ dev->dev, "mouse%d", minor);
return &mousedev->handle;
}
@@ -659,7 +659,8 @@ static void mousedev_disconnect(struct input_handle *handle)
struct mousedev *mousedev = handle->private;
struct mousedev_list *list;
- class_simple_device_remove(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
+ class_device_destroy(input_class,
+ MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
devfs_remove("input/mouse%d", mousedev->minor);
mousedev->exist = 0;
@@ -735,8 +736,8 @@ static int __init mousedev_init(void)
devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
S_IFCHR|S_IRUGO|S_IWUSR, "input/mice");
- class_simple_device_add(input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
- NULL, "mice");
+ class_device_create(input_class,
+ MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
if (!(psaux_registered = !misc_register(&psaux_mouse)))
@@ -755,7 +756,8 @@ static void __exit mousedev_exit(void)
misc_deregister(&psaux_mouse);
#endif
devfs_remove("input/mice");
- class_simple_device_remove(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
+ class_device_destroy(input_class,
+ MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
input_unregister_handler(&mousedev_handler);
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 0beacb77ee18..feab4970406e 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -358,31 +358,31 @@ static int serio_thread(void *nothing)
* Serio port operations
*/
-static ssize_t serio_show_description(struct device *dev, char *buf)
+static ssize_t serio_show_description(struct device *dev, struct device_attribute *attr, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%s\n", serio->name);
}
-static ssize_t serio_show_id_type(struct device *dev, char *buf)
+static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%02x\n", serio->id.type);
}
-static ssize_t serio_show_id_proto(struct device *dev, char *buf)
+static ssize_t serio_show_id_proto(struct device *dev, struct device_attribute *attr, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%02x\n", serio->id.proto);
}
-static ssize_t serio_show_id_id(struct device *dev, char *buf)
+static ssize_t serio_show_id_id(struct device *dev, struct device_attribute *attr, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%02x\n", serio->id.id);
}
-static ssize_t serio_show_id_extra(struct device *dev, char *buf)
+static ssize_t serio_show_id_extra(struct device *dev, struct device_attribute *attr, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%02x\n", serio->id.extra);
@@ -406,7 +406,7 @@ static struct attribute_group serio_id_attr_group = {
.attrs = serio_device_id_attrs,
};
-static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct serio *serio = to_serio_port(dev);
struct device_driver *drv;
@@ -437,13 +437,13 @@ static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t c
return retval;
}
-static ssize_t serio_show_bind_mode(struct device *dev, char *buf)
+static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct serio *serio = to_serio_port(dev);
return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto");
}
-static ssize_t serio_set_bind_mode(struct device *dev, const char *buf, size_t count)
+static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct serio *serio = to_serio_port(dev);
int retval;
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index d0afba85720b..50c63a155156 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -414,9 +414,9 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
- class_simple_device_add(input_class,
- MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
- dev->dev, "ts%d", minor);
+ class_device_create(input_class,
+ MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+ dev->dev, "ts%d", minor);
return &tsdev->handle;
}
@@ -426,7 +426,8 @@ static void tsdev_disconnect(struct input_handle *handle)
struct tsdev *tsdev = handle->private;
struct tsdev_list *list;
- class_simple_device_remove(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
+ class_device_destroy(input_class,
+ MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
devfs_remove("input/ts%d", tsdev->minor);
devfs_remove("input/tsraw%d", tsdev->minor);
tsdev->exist = 0;
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 12dee8e9fbbe..04fb606b5ddd 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -58,7 +58,7 @@ MODULE_LICENSE("GPL");
/* -------- driver information -------------------------------------- */
-static struct class_simple *capi_class;
+static struct class *capi_class;
static int capi_major = 68; /* allocated */
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -1499,20 +1499,20 @@ static int __init capi_init(void)
return -EIO;
}
- capi_class = class_simple_create(THIS_MODULE, "capi");
+ capi_class = class_create(THIS_MODULE, "capi");
if (IS_ERR(capi_class)) {
unregister_chrdev(capi_major, "capi20");
return PTR_ERR(capi_class);
}
- class_simple_device_add(capi_class, MKDEV(capi_major, 0), NULL, "capi");
+ class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi");
devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
"isdn/capi20");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
if (capinc_tty_init() < 0) {
- class_simple_device_remove(MKDEV(capi_major, 0));
- class_simple_destroy(capi_class);
+ class_device_destroy(capi_class, MKDEV(capi_major, 0));
+ class_destroy(capi_class);
unregister_chrdev(capi_major, "capi20");
return -ENOMEM;
}
@@ -1539,8 +1539,8 @@ static void __exit capi_exit(void)
{
proc_exit();
- class_simple_device_remove(MKDEV(capi_major, 0));
- class_simple_destroy(capi_class);
+ class_device_destroy(capi_class, MKDEV(capi_major, 0));
+ class_destroy(capi_class);
unregister_chrdev(capi_major, "capi20");
devfs_remove("isdn/capi20");
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 7297c77f99cf..493e2afa191c 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -77,7 +77,7 @@ static struct adb_driver *adb_driver_list[] = {
NULL
};
-static struct class_simple *adb_dev_class;
+static struct class *adb_dev_class;
struct adb_driver *adb_controller;
struct notifier_block *adb_client_list = NULL;
@@ -902,9 +902,8 @@ adbdev_init(void)
devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb");
- adb_dev_class = class_simple_create(THIS_MODULE, "adb");
- if (IS_ERR(adb_dev_class)) {
+ adb_dev_class = class_create(THIS_MODULE, "adb");
+ if (IS_ERR(adb_dev_class))
return;
- }
- class_simple_device_add(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
+ class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index d09308f30960..5ba190ce14a0 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -455,21 +455,22 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
* pass around to the attribute functions, so we don't really have
* choice but implement a bunch of them...
*
+ * FIXME, it does now...
*/
#define BUILD_SHOW_FUNC_INT(name, data) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return sprintf(buf, "%d\n", data); \
}
#define BUILD_SHOW_FUNC_STR(name, data) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return sprintf(buf, "%s\n", data); \
}
#define BUILD_SHOW_FUNC_FAN(name, data) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return sprintf(buf, "%d (%d rpm)\n", \
thermostat->last_speed[data], \
@@ -478,7 +479,7 @@ static ssize_t show_##name(struct device *dev, char *buf) \
}
#define BUILD_STORE_FUNC_DEG(name, data) \
-static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
+static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
{ \
int val; \
int i; \
@@ -491,7 +492,7 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
}
#define BUILD_STORE_FUNC_INT(name, data) \
-static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
+static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
{ \
u32 val; \
val = simple_strtoul(buf, NULL, 10); \
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 82336a5a5474..feb4e2413858 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -685,7 +685,7 @@ static void fetch_cpu_pumps_minmax(void)
* the input twice... I accept patches :)
*/
#define BUILD_SHOW_FUNC_FIX(name, data) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
ssize_t r; \
down(&driver_lock); \
@@ -694,7 +694,7 @@ static ssize_t show_##name(struct device *dev, char *buf) \
return r; \
}
#define BUILD_SHOW_FUNC_INT(name, data) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
return sprintf(buf, "%d", data); \
}
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index c153699d0f84..0bdb47f08c2a 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -107,13 +107,13 @@ print_temp( const char *s, int temp )
}
static ssize_t
-show_cpu_temperature( struct device *dev, char *buf )
+show_cpu_temperature( struct device *dev, struct device_attribute *attr, char *buf )
{
return sprintf(buf, "%d.%d\n", x.temp>>8, (x.temp & 255)*10/256 );
}
static ssize_t
-show_case_temperature( struct device *dev, char *buf )
+show_case_temperature( struct device *dev, struct device_attribute *attr, char *buf )
{
return sprintf(buf, "%d.%d\n", x.casetemp>>8, (x.casetemp & 255)*10/256 );
}
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
index ff9be67c2a15..09baa43b2599 100644
--- a/drivers/mca/mca-bus.c
+++ b/drivers/mca/mca-bus.c
@@ -69,7 +69,7 @@ struct bus_type mca_bus_type = {
};
EXPORT_SYMBOL (mca_bus_type);
-static ssize_t mca_show_pos_id(struct device *dev, char *buf)
+static ssize_t mca_show_pos_id(struct device *dev, struct device_attribute *attr, char *buf)
{
/* four digits, \n and trailing \0 */
struct mca_device *mca_dev = to_mca_device(dev);
@@ -81,7 +81,7 @@ static ssize_t mca_show_pos_id(struct device *dev, char *buf)
len = sprintf(buf, "none\n");
return len;
}
-static ssize_t mca_show_pos(struct device *dev, char *buf)
+static ssize_t mca_show_pos(struct device *dev, struct device_attribute *attr, char *buf)
{
/* enough for 8 two byte hex chars plus space and new line */
int j, len=0;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 9d9662f4b8e6..4b7adca3e286 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -56,8 +56,7 @@ static const char * const dnames[] = {
#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
-struct class_simple *dvb_class;
-EXPORT_SYMBOL(dvb_class);
+static struct class *dvb_class;
static struct dvb_device* dvbdev_find_device (int minor)
{
@@ -236,8 +235,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
S_IFCHR | S_IRUSR | S_IWUSR,
"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
- class_simple_device_add(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
- NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
+ class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+ NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
adap->num, dnames[type], id, nums2minor(adap->num, type, id),
@@ -256,7 +255,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num,
dnames[dvbdev->type], dvbdev->id);
- class_simple_device_remove(MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
+ class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
dvbdev->type, dvbdev->id)));
list_del (&dvbdev->list_head);
@@ -412,7 +411,7 @@ static int __init init_dvbdev(void)
devfs_mk_dir("dvb");
- dvb_class = class_simple_create(THIS_MODULE, "dvb");
+ dvb_class = class_create(THIS_MODULE, "dvb");
if (IS_ERR(dvb_class)) {
retval = PTR_ERR(dvb_class);
goto error;
@@ -429,7 +428,7 @@ error:
static void __exit exit_dvbdev(void)
{
devfs_remove("dvb");
- class_simple_destroy(dvb_class);
+ class_destroy(dvb_class);
cdev_del(&dvb_device_cdev);
unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
}
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 48ff314cdfbf..a0078ae5b9b8 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2338,7 +2338,7 @@ slave_configure_exit:
}
ssize_t
-mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
+mptscsih_store_queue_depth(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int depth;
struct scsi_device *sdev = to_scsi_device(dev);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 9f519836effa..d73aec33e16a 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -103,5 +103,5 @@ extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_F
extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
-extern ssize_t mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count);
+extern ssize_t mptscsih_store_queue_depth(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
extern void mptscsih_timer_expired(unsigned long data);
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index 29a56e9cd5b3..5556cd3b5559 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -22,7 +22,7 @@
#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
#define MMC_ATTR(name, fmt, args...) \
-static ssize_t mmc_##name##_show (struct device *dev, char *buf) \
+static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct mmc_card *card = dev_to_mmc_card(dev); \
return sprintf(buf, fmt, args); \
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index ad4b58af6b76..ab726ab43798 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -273,7 +273,7 @@ static int ppp_connect_channel(struct channel *pch, int unit);
static int ppp_disconnect_channel(struct channel *pch);
static void ppp_destroy_channel(struct channel *pch);
-static struct class_simple *ppp_class;
+static struct class *ppp_class;
/* Translates a PPP protocol number to a NP index (NP == network protocol) */
static inline int proto_to_npindex(int proto)
@@ -858,12 +858,12 @@ static int __init ppp_init(void)
printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
if (!err) {
- ppp_class = class_simple_create(THIS_MODULE, "ppp");
+ ppp_class = class_create(THIS_MODULE, "ppp");
if (IS_ERR(ppp_class)) {
err = PTR_ERR(ppp_class);
goto out_chrdev;
}
- class_simple_device_add(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+ class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
if (err)
@@ -876,8 +876,8 @@ out:
return err;
out_class:
- class_simple_device_remove(MKDEV(PPP_MAJOR,0));
- class_simple_destroy(ppp_class);
+ class_device_destroy(ppp_class, MKDEV(PPP_MAJOR,0));
+ class_destroy(ppp_class);
out_chrdev:
unregister_chrdev(PPP_MAJOR, "ppp");
goto out;
@@ -2654,8 +2654,8 @@ static void __exit ppp_cleanup(void)
if (unregister_chrdev(PPP_MAJOR, "ppp") != 0)
printk(KERN_ERR "PPP: failed to unregister PPP device\n");
devfs_remove("ppp");
- class_simple_device_remove(MKDEV(PPP_MAJOR, 0));
- class_simple_destroy(ppp_class);
+ class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_destroy(ppp_class);
}
/*
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 921a573372e9..7ff814fd65d0 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -235,7 +235,7 @@ static int dma[MAX_CARDS+1];
static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, };
/* for class stuff*/
-static struct class_simple *cosa_class;
+static struct class *cosa_class;
#ifdef MODULE
module_param_array(io, int, NULL, 0);
@@ -394,19 +394,19 @@ static int __init cosa_init(void)
goto out;
}
devfs_mk_dir("cosa");
- cosa_class = class_simple_create(THIS_MODULE, "cosa");
+ cosa_class = class_create(THIS_MODULE, "cosa");
if (IS_ERR(cosa_class)) {
err = PTR_ERR(cosa_class);
goto out_chrdev;
}
for (i=0; i<nr_cards; i++) {
- class_simple_device_add(cosa_class, MKDEV(cosa_major, i),
+ class_device_create(cosa_class, MKDEV(cosa_major, i),
NULL, "cosa%d", i);
err = devfs_mk_cdev(MKDEV(cosa_major, i),
S_IFCHR|S_IRUSR|S_IWUSR,
"cosa/%d", i);
if (err) {
- class_simple_device_remove(MKDEV(cosa_major, i));
+ class_device_destroy(cosa_class, MKDEV(cosa_major, i));
goto out_chrdev;
}
}
@@ -427,10 +427,10 @@ static void __exit cosa_exit(void)
printk(KERN_INFO "Unloading the cosa module\n");
for (i=0; i<nr_cards; i++) {
- class_simple_device_remove(MKDEV(cosa_major, i));
+ class_device_destroy(cosa_class, MKDEV(cosa_major, i));
devfs_remove("cosa/%d", i);
}
- class_simple_destroy(cosa_class);
+ class_destroy(cosa_class);
devfs_remove("cosa");
for (cosa=cosa_cards; nr_cards--; cosa++) {
/* Clean up the per-channel data */
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 41c7971d06c5..4c11048ad51b 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -38,7 +38,7 @@
/* A few routines that create sysfs entries for the hot plug controller */
-static ssize_t show_ctrl (struct device *dev, char *buf)
+static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pci_dev;
struct controller *ctrl;
@@ -82,7 +82,7 @@ static ssize_t show_ctrl (struct device *dev, char *buf)
}
static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
-static ssize_t show_dev (struct device *dev, char *buf)
+static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pci_dev;
struct controller *ctrl;
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index c802f6270b89..c4282902cb52 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -73,7 +73,7 @@ static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
{
struct hotplug_slot *slot = to_hotplug_slot(kobj);
struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
- return attribute->show ? attribute->show(slot, buf) : 0;
+ return attribute->show ? attribute->show(slot, buf) : -EIO;
}
static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
@@ -81,7 +81,7 @@ static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
{
struct hotplug_slot *slot = to_hotplug_slot(kobj);
struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
- return attribute->store ? attribute->store(slot, buf, len) : 0;
+ return attribute->store ? attribute->store(slot, buf, len) : -EIO;
}
static struct sysfs_ops hotplug_slot_sysfs_ops = {
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
index 3285b822478d..752e6513c447 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -48,7 +48,7 @@ dlpar_attr_store(struct kobject * kobj, struct attribute * attr,
struct dlpar_io_attr *dlpar_attr = container_of(attr,
struct dlpar_io_attr, attr);
return dlpar_attr->store ?
- dlpar_attr->store(dlpar_attr, buf, nbytes) : 0;
+ dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO;
}
static struct sysfs_ops dlpar_attr_sysfs_ops = {
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index 9a1ee132d12c..c9445ebda5c7 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -38,7 +38,7 @@
/* A few routines that create sysfs entries for the hot plug controller */
-static ssize_t show_ctrl (struct device *dev, char *buf)
+static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pci_dev;
struct controller *ctrl;
@@ -82,7 +82,7 @@ static ssize_t show_ctrl (struct device *dev, char *buf)
}
static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
-static ssize_t show_dev (struct device *dev, char *buf)
+static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pci_dev;
struct controller *ctrl;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index cf2cff7480f1..e65bf2b395aa 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -335,13 +335,14 @@ pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
{
struct device_driver *driver = kobj_to_pci_driver(kobj);
struct driver_attribute *dattr = attr_to_driver_attribute(attr);
- ssize_t ret = 0;
+ ssize_t ret;
- if (get_driver(driver)) {
- if (dattr->show)
- ret = dattr->show(driver, buf);
- put_driver(driver);
- }
+ if (!get_driver(driver))
+ return -ENODEV;
+
+ ret = dattr->show ? dattr->show(driver, buf) : -EIO;
+
+ put_driver(driver);
return ret;
}
@@ -351,13 +352,14 @@ pci_driver_attr_store(struct kobject * kobj, struct attribute *attr,
{
struct device_driver *driver = kobj_to_pci_driver(kobj);
struct driver_attribute *dattr = attr_to_driver_attribute(attr);
- ssize_t ret = 0;
+ ssize_t ret;
- if (get_driver(driver)) {
- if (dattr->store)
- ret = dattr->store(driver, buf, count);
- put_driver(driver);
- }
+ if (!get_driver(driver))
+ return -ENODEV;
+
+ ret = dattr->store ? dattr->store(driver, buf, count) : -EIO;
+
+ put_driver(driver);
return ret;
}
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6ca0061137a6..a15f94072a6f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -29,7 +29,7 @@ static int sysfs_initialized; /* = 0 */
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
-field##_show(struct device *dev, char *buf) \
+field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pci_dev *pdev; \
\
@@ -44,7 +44,7 @@ pci_config_attr(subsystem_device, "0x%04x\n");
pci_config_attr(class, "0x%06x\n");
pci_config_attr(irq, "%u\n");
-static ssize_t local_cpus_show(struct device *dev, char *buf)
+static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf)
{
cpumask_t mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
int len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
@@ -54,7 +54,7 @@ static ssize_t local_cpus_show(struct device *dev, char *buf)
/* show resources */
static ssize_t
-resource_show(struct device * dev, char * buf)
+resource_show(struct device * dev, struct device_attribute *attr, char * buf)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
char * str = buf;
@@ -73,7 +73,7 @@ resource_show(struct device * dev, char * buf)
return (str - buf);
}
-static ssize_t modalias_show(struct device *dev, char *buf)
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -339,16 +339,17 @@ pci_create_resource_files(struct pci_dev *pdev)
if (!pci_resource_len(pdev, i))
continue;
- res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
+ /* allocate attribute structure, piggyback attribute name */
+ res_attr = kcalloc(1, sizeof(*res_attr) + 10, GFP_ATOMIC);
if (res_attr) {
- memset(res_attr, 0, sizeof(*res_attr) + 10);
+ char *res_attr_name = (char *)(res_attr + 1);
+
pdev->res_attr[i] = res_attr;
- /* Allocated above after the res_attr struct */
- res_attr->attr.name = (char *)(res_attr + 1);
- sprintf(res_attr->attr.name, "resource%d", i);
- res_attr->size = pci_resource_len(pdev, i);
+ sprintf(res_attr_name, "resource%d", i);
+ res_attr->attr.name = res_attr_name;
res_attr->attr.mode = S_IRUSR | S_IWUSR;
res_attr->attr.owner = THIS_MODULE;
+ res_attr->size = pci_resource_len(pdev, i);
res_attr->mmap = pci_mmap_resource;
res_attr->private = &pdev->resource[i];
sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 576285765e98..f5c5f10a3d2f 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -232,19 +232,16 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
/* Initialize generic device interface */
device = &dev->device;
memset(device, 0, sizeof(struct device));
- INIT_LIST_HEAD(&device->node);
- INIT_LIST_HEAD(&device->children);
- INIT_LIST_HEAD(&device->bus_list);
device->bus = &pcie_port_bus_type;
device->driver = NULL;
- device->driver_data = NULL;
+ device->driver_data = NULL;
device->release = release_pcie_device; /* callback to free pcie dev */
- sprintf(&device->bus_id[0], "pcie%02x",
+ sprintf(&device->bus_id[0], "pcie%02x",
get_descriptor_id(port_type, service_type));
device->parent = &parent->dev;
}
-static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
+static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
int port_type, int service_type, int irq, int irq_mode)
{
struct pcie_device *device;
@@ -270,9 +267,9 @@ int pcie_port_device_probe(struct pci_dev *dev)
pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
type = (reg >> 4) & PORT_TYPE_MASK;
if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
- type == PCIE_SW_DOWNSTREAM_PORT )
+ type == PCIE_SW_DOWNSTREAM_PORT )
return 0;
-
+
return -ENODEV;
}
@@ -283,8 +280,8 @@ int pcie_port_device_register(struct pci_dev *dev)
u16 reg16;
/* Get port type */
- pci_read_config_word(dev,
- pci_find_capability(dev, PCI_CAP_ID_EXP) +
+ pci_read_config_word(dev,
+ pci_find_capability(dev, PCI_CAP_ID_EXP) +
PCIE_CAPABILITIES_REG, &reg16);
type = (reg16 >> 4) & PORT_TYPE_MASK;
@@ -299,11 +296,11 @@ int pcie_port_device_register(struct pci_dev *dev)
if (capabilities & (1 << i)) {
child = alloc_pcie_device(
dev, /* parent */
- type, /* port type */
+ type, /* port type */
i, /* service type */
vectors[i], /* irq */
irq_mode /* interrupt mode */);
- if (child) {
+ if (child) {
status = device_register(&child->device);
if (status) {
kfree(child);
@@ -317,84 +314,78 @@ int pcie_port_device_register(struct pci_dev *dev)
}
#ifdef CONFIG_PM
-int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+static int suspend_iter(struct device *dev, void *data)
{
- struct list_head *head, *tmp;
- struct device *parent, *child;
- struct device_driver *driver;
struct pcie_port_service_driver *service_driver;
+ u32 state = (u32)data;
+
+ if ((dev->bus == &pcie_port_bus_type) &&
+ (dev->driver)) {
+ service_driver = to_service_driver(dev->driver);
+ if (service_driver->suspend)
+ service_driver->suspend(to_pcie_device(dev), state);
+ }
+ return 0;
+}
- parent = &dev->dev;
- head = &parent->children;
- tmp = head->next;
- while (head != tmp) {
- child = container_of(tmp, struct device, node);
- tmp = tmp->next;
- if (child->bus != &pcie_port_bus_type)
- continue;
- driver = child->driver;
- if (!driver)
- continue;
- service_driver = to_service_driver(driver);
- if (service_driver->suspend)
- service_driver->suspend(to_pcie_device(child), state);
- }
- return 0;
+int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
+{
+ device_for_each_child(&dev->dev, (void *)state, suspend_iter);
+ return 0;
}
-int pcie_port_device_resume(struct pci_dev *dev)
-{
- struct list_head *head, *tmp;
- struct device *parent, *child;
- struct device_driver *driver;
+static int resume_iter(struct device *dev, void *data)
+{
struct pcie_port_service_driver *service_driver;
- parent = &dev->dev;
- head = &parent->children;
- tmp = head->next;
- while (head != tmp) {
- child = container_of(tmp, struct device, node);
- tmp = tmp->next;
- if (child->bus != &pcie_port_bus_type)
- continue;
- driver = child->driver;
- if (!driver)
- continue;
- service_driver = to_service_driver(driver);
- if (service_driver->resume)
- service_driver->resume(to_pcie_device(child));
+ if ((dev->bus == &pcie_port_bus_type) &&
+ (dev->driver)) {
+ service_driver = to_service_driver(dev->driver);
+ if (service_driver->resume)
+ service_driver->resume(to_pcie_device(dev));
}
- return 0;
+ return 0;
+}
+int pcie_port_device_resume(struct pci_dev *dev)
+{
+ device_for_each_child(&dev->dev, NULL, resume_iter);
+ return 0;
}
#endif
-void pcie_port_device_remove(struct pci_dev *dev)
+static int remove_iter(struct device *dev, void *data)
{
- struct list_head *head, *tmp;
- struct device *parent, *child;
- struct device_driver *driver;
struct pcie_port_service_driver *service_driver;
- int interrupt_mode = PCIE_PORT_INTx_MODE;
- parent = &dev->dev;
- head = &parent->children;
- tmp = head->next;
- while (head != tmp) {
- child = container_of(tmp, struct device, node);
- tmp = tmp->next;
- if (child->bus != &pcie_port_bus_type)
- continue;
- driver = child->driver;
- if (driver) {
- service_driver = to_service_driver(driver);
- if (service_driver->remove)
- service_driver->remove(to_pcie_device(child));
+ if (dev->bus == &pcie_port_bus_type) {
+ if (dev->driver) {
+ service_driver = to_service_driver(dev->driver);
+ if (service_driver->remove)
+ service_driver->remove(to_pcie_device(dev));
}
- interrupt_mode = (to_pcie_device(child))->interrupt_mode;
- put_device(child);
- device_unregister(child);
+ *(unsigned long*)data = (unsigned long)dev;
+ return 1;
}
+ return 0;
+}
+
+void pcie_port_device_remove(struct pci_dev *dev)
+{
+ struct device *device;
+ unsigned long device_addr;
+ int interrupt_mode = PCIE_PORT_INTx_MODE;
+ int status;
+
+ do {
+ status = device_for_each_child(&dev->dev, &device_addr, remove_iter);
+ if (status) {
+ device = (struct device*)device_addr;
+ interrupt_mode = (to_pcie_device(device))->interrupt_mode;
+ put_device(device);
+ device_unregister(device);
+ }
+ } while (status);
/* Switch to INTx by default if MSI enabled */
if (interrupt_mode == PCIE_PORT_MSIX_MODE)
pci_disable_msix(dev);
@@ -423,7 +414,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new)
new->driver.resume = pcie_port_resume_service;
return driver_register(&new->driver);
-}
+}
void pcie_port_service_unregister(struct pcie_port_service_driver *new)
{
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index c4ade288c5da..569e55feecfd 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -604,14 +604,14 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
/************************ per-device sysfs output ***************************/
#define pcmcia_device_attr(field, test, format) \
-static ssize_t field##_show (struct device *dev, char *buf) \
+static ssize_t field##_show (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pcmcia_device *p_dev = to_pcmcia_dev(dev); \
return p_dev->test ? sprintf (buf, format, p_dev->field) : -ENODEV; \
}
#define pcmcia_device_stringattr(name, field) \
-static ssize_t name##_show (struct device *dev, char *buf) \
+static ssize_t name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct pcmcia_device *p_dev = to_pcmcia_dev(dev); \
return p_dev->field ? sprintf (buf, "%s\n", p_dev->field) : -ENODEV; \
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index 97eeecfaef1b..3252662958d3 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -140,7 +140,7 @@ static void pnp_release_card(struct device *dmdev)
}
-static ssize_t pnp_show_card_name(struct device *dmdev, char *buf)
+static ssize_t pnp_show_card_name(struct device *dmdev, struct device_attribute *attr, char *buf)
{
char *str = buf;
struct pnp_card *card = to_pnp_card(dmdev);
@@ -150,7 +150,7 @@ static ssize_t pnp_show_card_name(struct device *dmdev, char *buf)
static DEVICE_ATTR(name,S_IRUGO,pnp_show_card_name,NULL);
-static ssize_t pnp_show_card_ids(struct device *dmdev, char *buf)
+static ssize_t pnp_show_card_ids(struct device *dmdev, struct device_attribute *attr, char *buf)
{
char *str = buf;
struct pnp_card *card = to_pnp_card(dmdev);
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index d64c1ca4fa76..1d037c2a82ac 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -160,10 +160,16 @@ struct bus_type pnp_bus_type = {
};
+static int count_devices(struct device * dev, void * c)
+{
+ int * count = c;
+ (*count)++;
+ return 0;
+}
+
int pnp_register_driver(struct pnp_driver *drv)
{
int count;
- struct list_head *pos;
pnp_dbg("the driver '%s' has been registered", drv->name);
@@ -177,9 +183,7 @@ int pnp_register_driver(struct pnp_driver *drv)
/* get the number of initial matches */
if (count >= 0){
count = 0;
- list_for_each(pos,&drv->driver.devices){
- count++;
- }
+ driver_for_each_device(&drv->driver, NULL, &count, count_devices);
}
return count;
}
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 53fac8ba5d5c..a2d8ce7fef9c 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -205,7 +205,7 @@ static void pnp_print_option(pnp_info_buffer_t *buffer, char *space,
}
-static ssize_t pnp_show_options(struct device *dmdev, char *buf)
+static ssize_t pnp_show_options(struct device *dmdev, struct device_attribute *attr, char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_option * independent = dev->independent;
@@ -236,7 +236,7 @@ static ssize_t pnp_show_options(struct device *dmdev, char *buf)
static DEVICE_ATTR(options,S_IRUGO,pnp_show_options,NULL);
-static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
+static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_attribute *attr, char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
int i, ret;
@@ -308,7 +308,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
extern struct semaphore pnp_res_mutex;
static ssize_t
-pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count)
+pnp_set_current_resources(struct device * dmdev, struct device_attribute *attr, const char * ubuf, size_t count)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
char *buf = (void *)ubuf;
@@ -444,7 +444,7 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR,
pnp_show_current_resources,pnp_set_current_resources);
-static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf)
+static ssize_t pnp_show_current_ids(struct device *dmdev, struct device_attribute *attr, char *buf)
{
char *str = buf;
struct pnp_dev *dev = to_pnp_dev(dmdev);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 1aedc48e5f85..d948566bb24a 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -615,7 +615,7 @@ dasd_device_from_cdev(struct ccw_device *cdev)
* readonly controls the readonly status of a dasd
*/
static ssize_t
-dasd_ro_show(struct device *dev, char *buf)
+dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dasd_devmap *devmap;
int ro_flag;
@@ -629,7 +629,7 @@ dasd_ro_show(struct device *dev, char *buf)
}
static ssize_t
-dasd_ro_store(struct device *dev, const char *buf, size_t count)
+dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct dasd_devmap *devmap;
int ro_flag;
@@ -656,7 +656,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
* to talk to the device
*/
static ssize_t
-dasd_use_diag_show(struct device *dev, char *buf)
+dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dasd_devmap *devmap;
int use_diag;
@@ -670,7 +670,7 @@ dasd_use_diag_show(struct device *dev, char *buf)
}
static ssize_t
-dasd_use_diag_store(struct device *dev, const char *buf, size_t count)
+dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct dasd_devmap *devmap;
ssize_t rc;
@@ -698,7 +698,7 @@ static
DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
static ssize_t
-dasd_discipline_show(struct device *dev, char *buf)
+dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dasd_devmap *devmap;
char *dname;
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a66b17b65296..16ab8d363ac6 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -45,16 +45,16 @@ static struct block_device_operations dcssblk_devops = {
.release = dcssblk_release,
};
-static ssize_t dcssblk_add_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
-static ssize_t dcssblk_remove_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
-static ssize_t dcssblk_save_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
-static ssize_t dcssblk_save_show(struct device *dev, char *buf);
-static ssize_t dcssblk_shared_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
-static ssize_t dcssblk_shared_show(struct device *dev, char *buf);
+static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
@@ -195,7 +195,7 @@ dcssblk_segment_warn(int rc, char* seg_name)
* operation (show + store)
*/
static ssize_t
-dcssblk_shared_show(struct device *dev, char *buf)
+dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dcssblk_dev_info *dev_info;
@@ -204,7 +204,7 @@ dcssblk_shared_show(struct device *dev, char *buf)
}
static ssize_t
-dcssblk_shared_store(struct device *dev, const char *inbuf, size_t count)
+dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count)
{
struct dcssblk_dev_info *dev_info;
int rc;
@@ -288,7 +288,7 @@ out:
* (show + store)
*/
static ssize_t
-dcssblk_save_show(struct device *dev, char *buf)
+dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dcssblk_dev_info *dev_info;
@@ -297,7 +297,7 @@ dcssblk_save_show(struct device *dev, char *buf)
}
static ssize_t
-dcssblk_save_store(struct device *dev, const char *inbuf, size_t count)
+dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count)
{
struct dcssblk_dev_info *dev_info;
@@ -343,7 +343,7 @@ dcssblk_save_store(struct device *dev, const char *inbuf, size_t count)
* device attribute for adding devices
*/
static ssize_t
-dcssblk_add_store(struct device *dev, const char *buf, size_t count)
+dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int rc, i;
struct dcssblk_dev_info *dev_info;
@@ -517,7 +517,7 @@ out_nobuf:
* device attribute for removing devices
*/
static ssize_t
-dcssblk_remove_store(struct device *dev, const char *buf, size_t count)
+dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct dcssblk_dev_info *dev_info;
int rc, i;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 8e16a9716686..d5eefeaba50c 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1084,7 +1084,7 @@ raw3270_probe (struct ccw_device *cdev)
* Additional attributes for a 3270 device
*/
static ssize_t
-raw3270_model_show(struct device *dev, char *buf)
+raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%i\n",
((struct raw3270 *) dev->driver_data)->model);
@@ -1092,7 +1092,7 @@ raw3270_model_show(struct device *dev, char *buf)
static DEVICE_ATTR(model, 0444, raw3270_model_show, 0);
static ssize_t
-raw3270_rows_show(struct device *dev, char *buf)
+raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%i\n",
((struct raw3270 *) dev->driver_data)->rows);
@@ -1100,7 +1100,7 @@ raw3270_rows_show(struct device *dev, char *buf)
static DEVICE_ATTR(rows, 0444, raw3270_rows_show, 0);
static ssize_t
-raw3270_columns_show(struct device *dev, char *buf)
+raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%i\n",
((struct raw3270 *) dev->driver_data)->cols);
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 0f8ffd4167ca..ed0cb1f15b4c 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -16,7 +16,7 @@ MODULE_DESCRIPTION(
);
MODULE_LICENSE("GPL");
-struct class_simple *tape_class;
+static struct class *tape_class;
/*
* Register a tape device and return a pointer to the cdev structure.
@@ -70,7 +70,7 @@ struct tape_class_device *register_tape_dev(
if (rc)
goto fail_with_cdev;
- tcd->class_device = class_simple_device_add(
+ tcd->class_device = class_device_create(
tape_class,
tcd->char_device->dev,
device,
@@ -101,7 +101,7 @@ void unregister_tape_dev(struct tape_class_device *tcd)
&tcd->class_device->dev->kobj,
tcd->mode_name
);
- class_simple_device_remove(tcd->char_device->dev);
+ class_device_destroy(tape_class, tcd->char_device->dev);
cdev_del(tcd->char_device);
kfree(tcd);
}
@@ -111,14 +111,14 @@ EXPORT_SYMBOL(unregister_tape_dev);
static int __init tape_init(void)
{
- tape_class = class_simple_create(THIS_MODULE, "tape390");
+ tape_class = class_create(THIS_MODULE, "tape390");
return 0;
}
static void __exit tape_exit(void)
{
- class_simple_destroy(tape_class);
+ class_destroy(tape_class);
tape_class = NULL;
}
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index e51046ab8adc..b4df4a515b12 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -107,7 +107,7 @@ busid_to_int(char *bus_id)
* replaced by a link to the cdev tree.
*/
static ssize_t
-tape_medium_state_show(struct device *dev, char *buf)
+tape_medium_state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct tape_device *tdev;
@@ -119,7 +119,7 @@ static
DEVICE_ATTR(medium_state, 0444, tape_medium_state_show, NULL);
static ssize_t
-tape_first_minor_show(struct device *dev, char *buf)
+tape_first_minor_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct tape_device *tdev;
@@ -131,7 +131,7 @@ static
DEVICE_ATTR(first_minor, 0444, tape_first_minor_show, NULL);
static ssize_t
-tape_state_show(struct device *dev, char *buf)
+tape_state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct tape_device *tdev;
@@ -144,7 +144,7 @@ static
DEVICE_ATTR(state, 0444, tape_state_show, NULL);
static ssize_t
-tape_operation_show(struct device *dev, char *buf)
+tape_operation_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct tape_device *tdev;
ssize_t rc;
@@ -171,7 +171,7 @@ static
DEVICE_ATTR(operation, 0444, tape_operation_show, NULL);
static ssize_t
-tape_blocksize_show(struct device *dev, char *buf)
+tape_blocksize_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct tape_device *tdev;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index edf50d2bd10b..f7717327d15e 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -548,7 +548,7 @@ vmlogrdr_read (struct file *filp, char *data, size_t count, loff_t * ppos)
}
static ssize_t
-vmlogrdr_autopurge_store(struct device * dev, const char * buf, size_t count) {
+vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret = count;
@@ -567,7 +567,7 @@ vmlogrdr_autopurge_store(struct device * dev, const char * buf, size_t count) {
static ssize_t
-vmlogrdr_autopurge_show(struct device *dev, char *buf) {
+vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) {
struct vmlogrdr_priv_t *priv = dev->driver_data;
return sprintf(buf, "%u\n", priv->autopurge);
}
@@ -578,7 +578,7 @@ static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show,
static ssize_t
-vmlogrdr_purge_store(struct device * dev, const char * buf, size_t count) {
+vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
char cp_command[80];
char cp_response[80];
@@ -619,7 +619,7 @@ static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store);
static ssize_t
-vmlogrdr_autorecording_store(struct device *dev, const char *buf,
+vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count) {
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret = count;
@@ -639,7 +639,7 @@ vmlogrdr_autorecording_store(struct device *dev, const char *buf,
static ssize_t
-vmlogrdr_autorecording_show(struct device *dev, char *buf) {
+vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) {
struct vmlogrdr_priv_t *priv = dev->driver_data;
return sprintf(buf, "%u\n", priv->autorecording);
}
@@ -650,7 +650,7 @@ static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show,
static ssize_t
-vmlogrdr_recording_store(struct device * dev, const char * buf, size_t count) {
+vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret;
@@ -703,7 +703,7 @@ static struct attribute_group vmlogrdr_attr_group = {
.attrs = vmlogrdr_attrs,
};
-static struct class_simple *vmlogrdr_class;
+static struct class *vmlogrdr_class;
static struct device_driver vmlogrdr_driver = {
.name = "vmlogrdr",
.bus = &iucv_bus,
@@ -727,7 +727,7 @@ vmlogrdr_register_driver(void) {
goto unregdriver;
}
- vmlogrdr_class = class_simple_create(THIS_MODULE, "vmlogrdr");
+ vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr");
if (IS_ERR(vmlogrdr_class)) {
printk(KERN_ERR "vmlogrdr: failed to create class.\n");
ret=PTR_ERR(vmlogrdr_class);
@@ -746,7 +746,7 @@ unregdriver:
static void
vmlogrdr_unregister_driver(void) {
- class_simple_destroy(vmlogrdr_class);
+ class_destroy(vmlogrdr_class);
vmlogrdr_class = NULL;
driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
driver_unregister(&vmlogrdr_driver);
@@ -786,7 +786,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
device_unregister(dev);
return ret;
}
- priv->class_device = class_simple_device_add(
+ priv->class_device = class_device_create(
vmlogrdr_class,
MKDEV(vmlogrdr_major, priv->minor_num),
dev,
@@ -806,7 +806,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
static int
vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
- class_simple_device_remove(MKDEV(vmlogrdr_major, priv->minor_num));
+ class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
if (priv->device != NULL) {
sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
device_unregister(priv->device);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 21a75ee28b80..306525acb9f8 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -77,7 +77,7 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
* longer needed or accidentially created. Saves memory :)
*/
static ssize_t
-ccwgroup_ungroup_store(struct device *dev, const char *buf, size_t count)
+ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct ccwgroup_device *gdev;
@@ -310,7 +310,7 @@ ccwgroup_set_offline(struct ccwgroup_device *gdev)
}
static ssize_t
-ccwgroup_online_store (struct device *dev, const char *buf, size_t count)
+ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct ccwgroup_device *gdev;
struct ccwgroup_driver *gdrv;
@@ -338,7 +338,7 @@ ccwgroup_online_store (struct device *dev, const char *buf, size_t count)
}
static ssize_t
-ccwgroup_online_show (struct device *dev, char *buf)
+ccwgroup_online_show (struct device *dev, struct device_attribute *attr, char *buf)
{
int online;
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index b35fe12e6bfc..b86f94ecd874 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -852,7 +852,7 @@ out:
* Files for the channel path entries.
*/
static ssize_t
-chp_status_show(struct device *dev, char *buf)
+chp_status_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct channel_path *chp = container_of(dev, struct channel_path, dev);
@@ -863,7 +863,7 @@ chp_status_show(struct device *dev, char *buf)
}
static ssize_t
-chp_status_write(struct device *dev, const char *buf, size_t count)
+chp_status_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct channel_path *cp = container_of(dev, struct channel_path, dev);
char cmd[10];
@@ -888,7 +888,7 @@ chp_status_write(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
static ssize_t
-chp_type_show(struct device *dev, char *buf)
+chp_type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct channel_path *chp = container_of(dev, struct channel_path, dev);
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 49def26ba383..8cc4f1a940dc 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -796,7 +796,7 @@ cmb_show_attr(struct device *dev, char *buf, enum cmb_index idx)
}
static ssize_t
-cmb_show_avg_sample_interval(struct device *dev, char *buf)
+cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev;
long interval;
@@ -813,7 +813,7 @@ cmb_show_avg_sample_interval(struct device *dev, char *buf)
}
static ssize_t
-cmb_show_avg_utilization(struct device *dev, char *buf)
+cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char *buf)
{
struct cmbdata data;
u64 utilization;
@@ -842,12 +842,12 @@ cmb_show_avg_utilization(struct device *dev, char *buf)
}
#define cmf_attr(name) \
-static ssize_t show_ ## name (struct device * dev, char * buf) \
+static ssize_t show_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \
{ return cmb_show_attr((dev), buf, cmb_ ## name); } \
static DEVICE_ATTR(name, 0444, show_ ## name, NULL);
#define cmf_attr_avg(name) \
-static ssize_t show_avg_ ## name (struct device * dev, char * buf) \
+static ssize_t show_avg_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \
{ return cmb_show_attr((dev), buf, cmb_ ## name); } \
static DEVICE_ATTR(avg_ ## name, 0444, show_avg_ ## name, NULL);
@@ -902,12 +902,12 @@ static struct attribute_group cmf_attr_group_ext = {
.attrs = cmf_attributes_ext,
};
-static ssize_t cmb_enable_show(struct device *dev, char *buf)
+static ssize_t cmb_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", to_ccwdev(dev)->private->cmb ? 1 : 0);
}
-static ssize_t cmb_enable_store(struct device *dev, const char *buf, size_t c)
+static ssize_t cmb_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t c)
{
struct ccw_device *cdev;
int ret;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index df0325505e4e..809e1108a06e 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -204,7 +204,7 @@ module_exit(cleanup_ccw_bus_type);
* TODO: Split chpids and pimpampom up? Where is "in use" in the tree?
*/
static ssize_t
-chpids_show (struct device * dev, char * buf)
+chpids_show (struct device * dev, struct device_attribute *attr, char * buf)
{
struct subchannel *sch = to_subchannel(dev);
struct ssd_info *ssd = &sch->ssd_info;
@@ -219,7 +219,7 @@ chpids_show (struct device * dev, char * buf)
}
static ssize_t
-pimpampom_show (struct device * dev, char * buf)
+pimpampom_show (struct device * dev, struct device_attribute *attr, char * buf)
{
struct subchannel *sch = to_subchannel(dev);
struct pmcw *pmcw = &sch->schib.pmcw;
@@ -229,7 +229,7 @@ pimpampom_show (struct device * dev, char * buf)
}
static ssize_t
-devtype_show (struct device *dev, char *buf)
+devtype_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev = to_ccwdev(dev);
struct ccw_device_id *id = &(cdev->id);
@@ -242,7 +242,7 @@ devtype_show (struct device *dev, char *buf)
}
static ssize_t
-cutype_show (struct device *dev, char *buf)
+cutype_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev = to_ccwdev(dev);
struct ccw_device_id *id = &(cdev->id);
@@ -252,7 +252,7 @@ cutype_show (struct device *dev, char *buf)
}
static ssize_t
-online_show (struct device *dev, char *buf)
+online_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev = to_ccwdev(dev);
@@ -350,7 +350,7 @@ ccw_device_set_online(struct ccw_device *cdev)
}
static ssize_t
-online_store (struct device *dev, const char *buf, size_t count)
+online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct ccw_device *cdev = to_ccwdev(dev);
int i, force, ret;
@@ -422,7 +422,7 @@ online_store (struct device *dev, const char *buf, size_t count)
}
static ssize_t
-available_show (struct device *dev, char *buf)
+available_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev = to_ccwdev(dev);
struct subchannel *sch;
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 06804d39a9c6..a99927d54ebb 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -241,20 +241,20 @@ static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
static void dumpit (char *buf, int len);
#endif
/* sysfs Functions */
-static ssize_t claw_hname_show(struct device *dev, char *buf);
-static ssize_t claw_hname_write(struct device *dev,
+static ssize_t claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_hname_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_adname_show(struct device *dev, char *buf);
-static ssize_t claw_adname_write(struct device *dev,
+static ssize_t claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_adname_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_apname_show(struct device *dev, char *buf);
-static ssize_t claw_apname_write(struct device *dev,
+static ssize_t claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_apname_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_wbuff_show(struct device *dev, char *buf);
-static ssize_t claw_wbuff_write(struct device *dev,
+static ssize_t claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_wbuff_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_rbuff_show(struct device *dev, char *buf);
-static ssize_t claw_rbuff_write(struct device *dev,
+static ssize_t claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
static int claw_add_files(struct device *dev);
static void claw_remove_files(struct device *dev);
@@ -4149,7 +4149,7 @@ claw_remove_device(struct ccwgroup_device *cgdev)
* sysfs attributes
*/
static ssize_t
-claw_hname_show(struct device *dev, char *buf)
+claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4162,7 +4162,7 @@ claw_hname_show(struct device *dev, char *buf)
}
static ssize_t
-claw_hname_write(struct device *dev, const char *buf, size_t count)
+claw_hname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4186,7 +4186,7 @@ claw_hname_write(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(host_name, 0644, claw_hname_show, claw_hname_write);
static ssize_t
-claw_adname_show(struct device *dev, char *buf)
+claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4199,7 +4199,7 @@ claw_adname_show(struct device *dev, char *buf)
}
static ssize_t
-claw_adname_write(struct device *dev, const char *buf, size_t count)
+claw_adname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4223,7 +4223,7 @@ claw_adname_write(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(adapter_name, 0644, claw_adname_show, claw_adname_write);
static ssize_t
-claw_apname_show(struct device *dev, char *buf)
+claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4237,7 +4237,7 @@ claw_apname_show(struct device *dev, char *buf)
}
static ssize_t
-claw_apname_write(struct device *dev, const char *buf, size_t count)
+claw_apname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4271,7 +4271,7 @@ claw_apname_write(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(api_type, 0644, claw_apname_show, claw_apname_write);
static ssize_t
-claw_wbuff_show(struct device *dev, char *buf)
+claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4284,7 +4284,7 @@ claw_wbuff_show(struct device *dev, char *buf)
}
static ssize_t
-claw_wbuff_write(struct device *dev, const char *buf, size_t count)
+claw_wbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4312,7 +4312,7 @@ claw_wbuff_write(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(write_buffer, 0644, claw_wbuff_show, claw_wbuff_write);
static ssize_t
-claw_rbuff_show(struct device *dev, char *buf)
+claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -4325,7 +4325,7 @@ claw_rbuff_show(struct device *dev, char *buf)
}
static ssize_t
-claw_rbuff_write(struct device *dev, const char *buf, size_t count)
+claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env *p_env;
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index ff3e95e07e89..96ca863eaff2 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -2469,7 +2469,7 @@ ctc_stats(struct net_device * dev)
*/
static ssize_t
-buffer_show(struct device *dev, char *buf)
+buffer_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ctc_priv *priv;
@@ -2481,7 +2481,7 @@ buffer_show(struct device *dev, char *buf)
}
static ssize_t
-buffer_write(struct device *dev, const char *buf, size_t count)
+buffer_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct ctc_priv *priv;
struct net_device *ndev;
@@ -2530,13 +2530,13 @@ einval:
}
static ssize_t
-loglevel_show(struct device *dev, char *buf)
+loglevel_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", loglevel);
}
static ssize_t
-loglevel_write(struct device *dev, const char *buf, size_t count)
+loglevel_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int ll1;
@@ -2589,7 +2589,7 @@ ctc_print_statistics(struct ctc_priv *priv)
}
static ssize_t
-stats_show(struct device *dev, char *buf)
+stats_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ctc_priv *priv = dev->driver_data;
if (!priv)
@@ -2599,7 +2599,7 @@ stats_show(struct device *dev, char *buf)
}
static ssize_t
-stats_write(struct device *dev, const char *buf, size_t count)
+stats_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct ctc_priv *priv = dev->driver_data;
if (!priv)
@@ -2654,7 +2654,7 @@ ctc_free_netdevice(struct net_device * dev, int free_dev)
}
static ssize_t
-ctc_proto_show(struct device *dev, char *buf)
+ctc_proto_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ctc_priv *priv;
@@ -2666,7 +2666,7 @@ ctc_proto_show(struct device *dev, char *buf)
}
static ssize_t
-ctc_proto_store(struct device *dev, const char *buf, size_t count)
+ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct ctc_priv *priv;
int value;
@@ -2687,7 +2687,7 @@ ctc_proto_store(struct device *dev, const char *buf, size_t count)
static ssize_t
-ctc_type_show(struct device *dev, char *buf)
+ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccwgroup_device *cgdev;
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index cccfed248e70..ab086242d305 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1984,7 +1984,7 @@ lcs_open_device(struct net_device *dev)
* show function for portno called by cat or similar things
*/
static ssize_t
-lcs_portno_show (struct device *dev, char *buf)
+lcs_portno_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct lcs_card *card;
@@ -2000,7 +2000,7 @@ lcs_portno_show (struct device *dev, char *buf)
* store the value which is piped to file portno
*/
static ssize_t
-lcs_portno_store (struct device *dev, const char *buf, size_t count)
+lcs_portno_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct lcs_card *card;
int value;
@@ -2021,7 +2021,7 @@ lcs_portno_store (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
static ssize_t
-lcs_type_show(struct device *dev, char *buf)
+lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccwgroup_device *cgdev;
@@ -2035,7 +2035,7 @@ lcs_type_show(struct device *dev, char *buf)
static DEVICE_ATTR(type, 0444, lcs_type_show, NULL);
static ssize_t
-lcs_timeout_show(struct device *dev, char *buf)
+lcs_timeout_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lcs_card *card;
@@ -2045,7 +2045,7 @@ lcs_timeout_show(struct device *dev, char *buf)
}
static ssize_t
-lcs_timeout_store (struct device *dev, const char *buf, size_t count)
+lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct lcs_card *card;
int value;
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 16e8e69afb10..3fd4fb754b2d 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1356,7 +1356,7 @@ netiucv_change_mtu (struct net_device * dev, int new_mtu)
*****************************************************************************/
static ssize_t
-user_show (struct device *dev, char *buf)
+user_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1365,7 +1365,7 @@ user_show (struct device *dev, char *buf)
}
static ssize_t
-user_write (struct device *dev, const char *buf, size_t count)
+user_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
struct net_device *ndev = priv->conn->netdev;
@@ -1422,7 +1422,7 @@ user_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(user, 0644, user_show, user_write);
static ssize_t
-buffer_show (struct device *dev, char *buf)
+buffer_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1431,7 +1431,7 @@ buffer_show (struct device *dev, char *buf)
}
static ssize_t
-buffer_write (struct device *dev, const char *buf, size_t count)
+buffer_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
struct net_device *ndev = priv->conn->netdev;
@@ -1486,7 +1486,7 @@ buffer_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
static ssize_t
-dev_fsm_show (struct device *dev, char *buf)
+dev_fsm_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1497,7 +1497,7 @@ dev_fsm_show (struct device *dev, char *buf)
static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
static ssize_t
-conn_fsm_show (struct device *dev, char *buf)
+conn_fsm_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1508,7 +1508,7 @@ conn_fsm_show (struct device *dev, char *buf)
static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
static ssize_t
-maxmulti_show (struct device *dev, char *buf)
+maxmulti_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1517,7 +1517,7 @@ maxmulti_show (struct device *dev, char *buf)
}
static ssize_t
-maxmulti_write (struct device *dev, const char *buf, size_t count)
+maxmulti_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1529,7 +1529,7 @@ maxmulti_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
static ssize_t
-maxcq_show (struct device *dev, char *buf)
+maxcq_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1538,7 +1538,7 @@ maxcq_show (struct device *dev, char *buf)
}
static ssize_t
-maxcq_write (struct device *dev, const char *buf, size_t count)
+maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1550,7 +1550,7 @@ maxcq_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
static ssize_t
-sdoio_show (struct device *dev, char *buf)
+sdoio_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1559,7 +1559,7 @@ sdoio_show (struct device *dev, char *buf)
}
static ssize_t
-sdoio_write (struct device *dev, const char *buf, size_t count)
+sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1571,7 +1571,7 @@ sdoio_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
static ssize_t
-mdoio_show (struct device *dev, char *buf)
+mdoio_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1580,7 +1580,7 @@ mdoio_show (struct device *dev, char *buf)
}
static ssize_t
-mdoio_write (struct device *dev, const char *buf, size_t count)
+mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1592,7 +1592,7 @@ mdoio_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
static ssize_t
-txlen_show (struct device *dev, char *buf)
+txlen_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1601,7 +1601,7 @@ txlen_show (struct device *dev, char *buf)
}
static ssize_t
-txlen_write (struct device *dev, const char *buf, size_t count)
+txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1613,7 +1613,7 @@ txlen_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
static ssize_t
-txtime_show (struct device *dev, char *buf)
+txtime_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1622,7 +1622,7 @@ txtime_show (struct device *dev, char *buf)
}
static ssize_t
-txtime_write (struct device *dev, const char *buf, size_t count)
+txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1634,7 +1634,7 @@ txtime_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);
static ssize_t
-txpend_show (struct device *dev, char *buf)
+txpend_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1643,7 +1643,7 @@ txpend_show (struct device *dev, char *buf)
}
static ssize_t
-txpend_write (struct device *dev, const char *buf, size_t count)
+txpend_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1655,7 +1655,7 @@ txpend_write (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write);
static ssize_t
-txmpnd_show (struct device *dev, char *buf)
+txmpnd_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct netiucv_priv *priv = dev->driver_data;
@@ -1664,7 +1664,7 @@ txmpnd_show (struct device *dev, char *buf)
}
static ssize_t
-txmpnd_write (struct device *dev, const char *buf, size_t count)
+txmpnd_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct netiucv_priv *priv = dev->driver_data;
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 240348398211..98bedb0cb387 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -30,7 +30,7 @@ const char *VERSION_QETH_SYS_C = "$Revision: 1.51 $";
//low/high watermark
static ssize_t
-qeth_dev_state_show(struct device *dev, char *buf)
+qeth_dev_state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
if (!card)
@@ -58,7 +58,7 @@ qeth_dev_state_show(struct device *dev, char *buf)
static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
static ssize_t
-qeth_dev_chpid_show(struct device *dev, char *buf)
+qeth_dev_chpid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
if (!card)
@@ -70,7 +70,7 @@ qeth_dev_chpid_show(struct device *dev, char *buf)
static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
static ssize_t
-qeth_dev_if_name_show(struct device *dev, char *buf)
+qeth_dev_if_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
if (!card)
@@ -81,7 +81,7 @@ qeth_dev_if_name_show(struct device *dev, char *buf)
static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
static ssize_t
-qeth_dev_card_type_show(struct device *dev, char *buf)
+qeth_dev_card_type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
if (!card)
@@ -93,7 +93,7 @@ qeth_dev_card_type_show(struct device *dev, char *buf)
static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
static ssize_t
-qeth_dev_portno_show(struct device *dev, char *buf)
+qeth_dev_portno_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
if (!card)
@@ -103,7 +103,7 @@ qeth_dev_portno_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_portno_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_portno_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -129,7 +129,7 @@ qeth_dev_portno_store(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
static ssize_t
-qeth_dev_portname_show(struct device *dev, char *buf)
+qeth_dev_portname_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
char portname[9] = {0, };
@@ -146,7 +146,7 @@ qeth_dev_portname_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_portname_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -177,7 +177,7 @@ static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
qeth_dev_portname_store);
static ssize_t
-qeth_dev_checksum_show(struct device *dev, char *buf)
+qeth_dev_checksum_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -188,7 +188,7 @@ qeth_dev_checksum_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_checksum_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_checksum_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -218,7 +218,7 @@ static DEVICE_ATTR(checksumming, 0644, qeth_dev_checksum_show,
qeth_dev_checksum_store);
static ssize_t
-qeth_dev_prioqing_show(struct device *dev, char *buf)
+qeth_dev_prioqing_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -237,7 +237,7 @@ qeth_dev_prioqing_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_prioqing_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_prioqing_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -290,7 +290,7 @@ static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
qeth_dev_prioqing_store);
static ssize_t
-qeth_dev_bufcnt_show(struct device *dev, char *buf)
+qeth_dev_bufcnt_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -301,7 +301,7 @@ qeth_dev_bufcnt_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_bufcnt_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -360,7 +360,7 @@ qeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route,
}
static ssize_t
-qeth_dev_route4_show(struct device *dev, char *buf)
+qeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -410,7 +410,7 @@ qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
}
static ssize_t
-qeth_dev_route4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_route4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -425,7 +425,7 @@ static DEVICE_ATTR(route4, 0644, qeth_dev_route4_show, qeth_dev_route4_store);
#ifdef CONFIG_QETH_IPV6
static ssize_t
-qeth_dev_route6_show(struct device *dev, char *buf)
+qeth_dev_route6_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -439,7 +439,7 @@ qeth_dev_route6_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_route6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_route6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -461,7 +461,7 @@ static DEVICE_ATTR(route6, 0644, qeth_dev_route6_show, qeth_dev_route6_store);
#endif
static ssize_t
-qeth_dev_add_hhlen_show(struct device *dev, char *buf)
+qeth_dev_add_hhlen_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -472,7 +472,7 @@ qeth_dev_add_hhlen_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_add_hhlen_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_add_hhlen_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -499,7 +499,7 @@ static DEVICE_ATTR(add_hhlen, 0644, qeth_dev_add_hhlen_show,
qeth_dev_add_hhlen_store);
static ssize_t
-qeth_dev_fake_ll_show(struct device *dev, char *buf)
+qeth_dev_fake_ll_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -510,7 +510,7 @@ qeth_dev_fake_ll_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_fake_ll_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_fake_ll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -536,7 +536,7 @@ static DEVICE_ATTR(fake_ll, 0644, qeth_dev_fake_ll_show,
qeth_dev_fake_ll_store);
static ssize_t
-qeth_dev_fake_broadcast_show(struct device *dev, char *buf)
+qeth_dev_fake_broadcast_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -547,7 +547,7 @@ qeth_dev_fake_broadcast_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_fake_broadcast_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_fake_broadcast_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -574,7 +574,7 @@ static DEVICE_ATTR(fake_broadcast, 0644, qeth_dev_fake_broadcast_show,
qeth_dev_fake_broadcast_store);
static ssize_t
-qeth_dev_recover_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -596,7 +596,7 @@ qeth_dev_recover_store(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
static ssize_t
-qeth_dev_broadcast_mode_show(struct device *dev, char *buf)
+qeth_dev_broadcast_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -613,7 +613,7 @@ qeth_dev_broadcast_mode_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_broadcast_mode_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_broadcast_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -651,7 +651,7 @@ static DEVICE_ATTR(broadcast_mode, 0644, qeth_dev_broadcast_mode_show,
qeth_dev_broadcast_mode_store);
static ssize_t
-qeth_dev_canonical_macaddr_show(struct device *dev, char *buf)
+qeth_dev_canonical_macaddr_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -667,7 +667,7 @@ qeth_dev_canonical_macaddr_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_canonical_macaddr_store(struct device *dev, const char *buf,
+qeth_dev_canonical_macaddr_store(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -703,7 +703,7 @@ static DEVICE_ATTR(canonical_macaddr, 0644, qeth_dev_canonical_macaddr_show,
qeth_dev_canonical_macaddr_store);
static ssize_t
-qeth_dev_layer2_show(struct device *dev, char *buf)
+qeth_dev_layer2_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -714,7 +714,7 @@ qeth_dev_layer2_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_layer2_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -742,7 +742,7 @@ static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
qeth_dev_layer2_store);
static ssize_t
-qeth_dev_large_send_show(struct device *dev, char *buf)
+qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -762,7 +762,7 @@ qeth_dev_large_send_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_large_send_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
enum qeth_large_send_types type;
@@ -832,7 +832,7 @@ qeth_dev_blkt_store(struct qeth_card *card, const char *buf, size_t count,
}
static ssize_t
-qeth_dev_blkt_total_show(struct device *dev, char *buf)
+qeth_dev_blkt_total_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -841,7 +841,7 @@ qeth_dev_blkt_total_show(struct device *dev, char *buf)
static ssize_t
-qeth_dev_blkt_total_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_blkt_total_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -855,7 +855,7 @@ static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
qeth_dev_blkt_total_store);
static ssize_t
-qeth_dev_blkt_inter_show(struct device *dev, char *buf)
+qeth_dev_blkt_inter_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -864,7 +864,7 @@ qeth_dev_blkt_inter_show(struct device *dev, char *buf)
static ssize_t
-qeth_dev_blkt_inter_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_blkt_inter_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -876,7 +876,7 @@ static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
qeth_dev_blkt_inter_store);
static ssize_t
-qeth_dev_blkt_inter_jumbo_show(struct device *dev, char *buf)
+qeth_dev_blkt_inter_jumbo_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -886,7 +886,7 @@ qeth_dev_blkt_inter_jumbo_show(struct device *dev, char *buf)
static ssize_t
-qeth_dev_blkt_inter_jumbo_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_blkt_inter_jumbo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -956,7 +956,7 @@ qeth_check_layer2(struct qeth_card *card)
static ssize_t
-qeth_dev_ipato_enable_show(struct device *dev, char *buf)
+qeth_dev_ipato_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -969,7 +969,7 @@ qeth_dev_ipato_enable_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_ipato_enable_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -1004,7 +1004,7 @@ static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
qeth_dev_ipato_enable_store);
static ssize_t
-qeth_dev_ipato_invert4_show(struct device *dev, char *buf)
+qeth_dev_ipato_invert4_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1018,7 +1018,7 @@ qeth_dev_ipato_invert4_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_ipato_invert4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_invert4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -1084,7 +1084,7 @@ qeth_dev_ipato_add_show(char *buf, struct qeth_card *card,
}
static ssize_t
-qeth_dev_ipato_add4_show(struct device *dev, char *buf)
+qeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1153,7 +1153,7 @@ qeth_dev_ipato_add_store(const char *buf, size_t count,
}
static ssize_t
-qeth_dev_ipato_add4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1186,7 +1186,7 @@ qeth_dev_ipato_del_store(const char *buf, size_t count,
}
static ssize_t
-qeth_dev_ipato_del4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1201,7 +1201,7 @@ static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
#ifdef CONFIG_QETH_IPV6
static ssize_t
-qeth_dev_ipato_invert6_show(struct device *dev, char *buf)
+qeth_dev_ipato_invert6_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1215,7 +1215,7 @@ qeth_dev_ipato_invert6_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_ipato_invert6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_invert6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
@@ -1247,7 +1247,7 @@ static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
static ssize_t
-qeth_dev_ipato_add6_show(struct device *dev, char *buf)
+qeth_dev_ipato_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1258,7 +1258,7 @@ qeth_dev_ipato_add6_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_ipato_add6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1273,7 +1273,7 @@ static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
qeth_dev_ipato_add6_store);
static ssize_t
-qeth_dev_ipato_del6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1341,7 +1341,7 @@ qeth_dev_vipa_add_show(char *buf, struct qeth_card *card,
}
static ssize_t
-qeth_dev_vipa_add4_show(struct device *dev, char *buf)
+qeth_dev_vipa_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1381,7 +1381,7 @@ qeth_dev_vipa_add_store(const char *buf, size_t count,
}
static ssize_t
-qeth_dev_vipa_add4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1413,7 +1413,7 @@ qeth_dev_vipa_del_store(const char *buf, size_t count,
}
static ssize_t
-qeth_dev_vipa_del4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1428,7 +1428,7 @@ static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
#ifdef CONFIG_QETH_IPV6
static ssize_t
-qeth_dev_vipa_add6_show(struct device *dev, char *buf)
+qeth_dev_vipa_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1439,7 +1439,7 @@ qeth_dev_vipa_add6_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_vipa_add6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1454,7 +1454,7 @@ static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
qeth_dev_vipa_add6_store);
static ssize_t
-qeth_dev_vipa_del6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1522,7 +1522,7 @@ qeth_dev_rxip_add_show(char *buf, struct qeth_card *card,
}
static ssize_t
-qeth_dev_rxip_add4_show(struct device *dev, char *buf)
+qeth_dev_rxip_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1562,7 +1562,7 @@ qeth_dev_rxip_add_store(const char *buf, size_t count,
}
static ssize_t
-qeth_dev_rxip_add4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1594,7 +1594,7 @@ qeth_dev_rxip_del_store(const char *buf, size_t count,
}
static ssize_t
-qeth_dev_rxip_del4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1609,7 +1609,7 @@ static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
#ifdef CONFIG_QETH_IPV6
static ssize_t
-qeth_dev_rxip_add6_show(struct device *dev, char *buf)
+qeth_dev_rxip_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -1620,7 +1620,7 @@ qeth_dev_rxip_add6_show(struct device *dev, char *buf)
}
static ssize_t
-qeth_dev_rxip_add6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
@@ -1635,7 +1635,7 @@ static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
qeth_dev_rxip_add6_store);
static ssize_t
-qeth_dev_rxip_del6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 6965992ddbbf..b61d309352c3 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -924,7 +924,7 @@ struct fc_function_template zfcp_transport_functions = {
* Generates attribute for a unit.
*/
#define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \
-static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \
+static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct scsi_device *sdev; \
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c
index 23e2dca55bb8..e7345a74800a 100644
--- a/drivers/s390/scsi/zfcp_sysfs_adapter.c
+++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c
@@ -50,7 +50,7 @@ static const char fc_topologies[5][25] = {
* Generates attributes for an adapter.
*/
#define ZFCP_DEFINE_ADAPTER_ATTR(_name, _format, _value) \
-static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, \
+static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct zfcp_adapter *adapter; \
@@ -90,7 +90,7 @@ ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask
* Store function of the "port_add" attribute of an adapter.
*/
static ssize_t
-zfcp_sysfs_port_add_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
wwn_t wwpn;
char *endp;
@@ -135,7 +135,7 @@ static DEVICE_ATTR(port_add, S_IWUSR, NULL, zfcp_sysfs_port_add_store);
* Store function of the "port_remove" attribute of an adapter.
*/
static ssize_t
-zfcp_sysfs_port_remove_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct zfcp_adapter *adapter;
struct zfcp_port *port;
@@ -196,7 +196,7 @@ static DEVICE_ATTR(port_remove, S_IWUSR, NULL, zfcp_sysfs_port_remove_store);
* started for the belonging adapter.
*/
static ssize_t
-zfcp_sysfs_adapter_failed_store(struct device *dev,
+zfcp_sysfs_adapter_failed_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct zfcp_adapter *adapter;
@@ -236,7 +236,7 @@ zfcp_sysfs_adapter_failed_store(struct device *dev,
* "0" if adapter is working, otherwise "1".
*/
static ssize_t
-zfcp_sysfs_adapter_failed_show(struct device *dev, char *buf)
+zfcp_sysfs_adapter_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct zfcp_adapter *adapter;
diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c
index 6aafb2abb4b5..7a84c7d474d9 100644
--- a/drivers/s390/scsi/zfcp_sysfs_port.c
+++ b/drivers/s390/scsi/zfcp_sysfs_port.c
@@ -53,7 +53,7 @@ zfcp_sysfs_port_release(struct device *dev)
* Generates attributes for a port.
*/
#define ZFCP_DEFINE_PORT_ATTR(_name, _format, _value) \
-static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, \
+static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct zfcp_port *port; \
@@ -82,7 +82,7 @@ ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask
* Store function of the "unit_add" attribute of a port.
*/
static ssize_t
-zfcp_sysfs_unit_add_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
fcp_lun_t fcp_lun;
char *endp;
@@ -125,7 +125,7 @@ static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
* @count: number of bytes in buffer
*/
static ssize_t
-zfcp_sysfs_unit_remove_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct zfcp_port *port;
struct zfcp_unit *unit;
@@ -186,7 +186,7 @@ static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
* started for the belonging port.
*/
static ssize_t
-zfcp_sysfs_port_failed_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct zfcp_port *port;
unsigned int val;
@@ -224,7 +224,7 @@ zfcp_sysfs_port_failed_store(struct device *dev, const char *buf, size_t count)
* "0" if port is working, otherwise "1".
*/
static ssize_t
-zfcp_sysfs_port_failed_show(struct device *dev, char *buf)
+zfcp_sysfs_port_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct zfcp_port *port;
diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c
index 87c0b461831f..0556642c9e1d 100644
--- a/drivers/s390/scsi/zfcp_sysfs_unit.c
+++ b/drivers/s390/scsi/zfcp_sysfs_unit.c
@@ -53,7 +53,7 @@ zfcp_sysfs_unit_release(struct device *dev)
* Generates attribute for a unit.
*/
#define ZFCP_DEFINE_UNIT_ATTR(_name, _format, _value) \
-static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev, \
+static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct zfcp_unit *unit; \
@@ -86,7 +86,7 @@ ZFCP_DEFINE_UNIT_ATTR(access_readonly, "%d\n", atomic_test_mask
* started for the belonging unit.
*/
static ssize_t
-zfcp_sysfs_unit_failed_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_unit_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct zfcp_unit *unit;
unsigned int val;
@@ -123,7 +123,7 @@ zfcp_sysfs_unit_failed_store(struct device *dev, const char *buf, size_t count)
* "0" if unit is working, otherwise "1".
*/
static ssize_t
-zfcp_sysfs_unit_failed_show(struct device *dev, char *buf)
+zfcp_sysfs_unit_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct zfcp_unit *unit;
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index d151af9a6f15..a7620fc368e7 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -2125,7 +2125,7 @@ static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
}
static ssize_t
-NCR_700_show_active_tags(struct device *dev, char *buf)
+NCR_700_show_active_tags(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *SDp = to_scsi_device(dev);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index c4eaaad2c69b..5f526dd0aaa1 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -941,7 +941,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
*/
cmd->scsi_done = scsi_done;
- ahd_lock(ahd, &flags);
+ ahd_midlayer_entrypoint_lock(ahd, &flags);
/*
* Close the race of a command that was in the process of
@@ -955,7 +955,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
ahd_linux_queue_cmd_complete(ahd, cmd);
ahd_schedule_completeq(ahd);
- ahd_unlock(ahd, &flags);
+ ahd_midlayer_entrypoint_unlock(ahd, &flags);
return (0);
}
dev = ahd_linux_get_device(ahd, cmd->device->channel,
@@ -965,7 +965,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
ahd_linux_queue_cmd_complete(ahd, cmd);
ahd_schedule_completeq(ahd);
- ahd_unlock(ahd, &flags);
+ ahd_midlayer_entrypoint_unlock(ahd, &flags);
printf("%s: aic79xx_linux_queue - Unable to allocate device!\n",
ahd_name(ahd));
return (0);
@@ -979,7 +979,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
dev->flags |= AHD_DEV_ON_RUN_LIST;
ahd_linux_run_device_queues(ahd);
}
- ahd_unlock(ahd, &flags);
+ ahd_midlayer_entrypoint_unlock(ahd, &flags);
return (0);
}
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index 78b7e543471b..ce711f166cfb 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -466,7 +466,7 @@ int eesoxscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_
return pos;
}
-static ssize_t eesoxscsi_show_term(struct device *dev, char *buf)
+static ssize_t eesoxscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
struct Scsi_Host *host = ecard_get_drvdata(ec);
@@ -475,7 +475,7 @@ static ssize_t eesoxscsi_show_term(struct device *dev, char *buf)
return sprintf(buf, "%d\n", info->control & EESOX_TERM_ENABLE ? 1 : 0);
}
-static ssize_t eesoxscsi_store_term(struct device *dev, const char *buf, size_t len)
+static ssize_t eesoxscsi_store_term(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)
{
struct expansion_card *ec = ECARD_DEV(dev);
struct Scsi_Host *host = ecard_get_drvdata(ec);
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index 54f23be6460f..abda216113f1 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -269,7 +269,7 @@ int powertecscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, o
return pos;
}
-static ssize_t powertecscsi_show_term(struct device *dev, char *buf)
+static ssize_t powertecscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
struct Scsi_Host *host = ecard_get_drvdata(ec);
@@ -279,7 +279,7 @@ static ssize_t powertecscsi_show_term(struct device *dev, char *buf)
}
static ssize_t
-powertecscsi_store_term(struct device *dev, const char *buf, size_t len)
+powertecscsi_store_term(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)
{
struct expansion_card *ec = ECARD_DEV(dev);
struct Scsi_Host *host = ecard_get_drvdata(ec);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 17b106b79f72..80d022625c82 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2716,7 +2716,7 @@ static int ipr_change_queue_type(struct scsi_device *sdev, int tag_type)
* Return value:
* number of bytes printed to buffer
**/
-static ssize_t ipr_show_adapter_handle(struct device *dev, char *buf)
+static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 057ed45b54b2..cbe430246276 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -124,7 +124,7 @@ static irqreturn_t megaraid_isr(int, void *, struct pt_regs *);
static void megaraid_mbox_dpc(unsigned long);
static ssize_t megaraid_sysfs_show_app_hndl(struct class_device *, char *);
-static ssize_t megaraid_sysfs_show_ldnum(struct device *, char *);
+static ssize_t megaraid_sysfs_show_ldnum(struct device *, struct device_attribute *attr, char *);
static int megaraid_cmm_register(adapter_t *);
static int megaraid_cmm_unregister(adapter_t *);
@@ -4145,7 +4145,7 @@ megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf)
* @param buf : buffer to send data to
*/
static ssize_t
-megaraid_sysfs_show_ldnum(struct device *dev, char *buf)
+megaraid_sysfs_show_ldnum(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
adapter_t *adapter = (adapter_t *)SCSIHOST2ADAP(sdev->host);
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index c585c7bef247..89a4a0615c22 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5608,13 +5608,13 @@ static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
-static struct class_simple * osst_sysfs_class;
+static struct class *osst_sysfs_class;
static int osst_sysfs_valid = 0;
static void osst_sysfs_init(void)
{
- osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape");
+ osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
if ( IS_ERR(osst_sysfs_class) )
printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
else
@@ -5627,7 +5627,7 @@ static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape *
if (!osst_sysfs_valid) return;
- osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name);
+ osst_class_member = class_device_create(osst_sysfs_class, dev, device, "%s", name);
if (IS_ERR(osst_class_member)) {
printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
return;
@@ -5645,13 +5645,13 @@ static void osst_sysfs_destroy(dev_t dev)
{
if (!osst_sysfs_valid) return;
- class_simple_device_remove(dev);
+ class_device_destroy(osst_sysfs_class, dev);
}
static void osst_sysfs_cleanup(void)
{
if (osst_sysfs_valid) {
- class_simple_destroy(osst_sysfs_class);
+ class_destroy(osst_sysfs_class);
osst_sysfs_valid = 0;
}
}
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index e75ee4671ee3..93b41100a6d8 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -230,7 +230,7 @@ void scsi_sysfs_unregister(void)
*/
#define sdev_show_function(field, format_string) \
static ssize_t \
-sdev_show_##field (struct device *dev, char *buf) \
+sdev_show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct scsi_device *sdev; \
sdev = to_scsi_device(dev); \
@@ -254,7 +254,7 @@ static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL);
sdev_show_function(field, format_string) \
\
static ssize_t \
-sdev_store_##field (struct device *dev, const char *buf, size_t count) \
+sdev_store_##field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct scsi_device *sdev; \
sdev = to_scsi_device(dev); \
@@ -274,7 +274,7 @@ static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##fie
sdev_show_function(field, "%d\n") \
\
static ssize_t \
-sdev_store_##field (struct device *dev, const char *buf, size_t count) \
+sdev_store_##field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
int ret; \
struct scsi_device *sdev; \
@@ -317,7 +317,7 @@ sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n");
static ssize_t
-sdev_show_timeout (struct device *dev, char *buf)
+sdev_show_timeout (struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev;
sdev = to_scsi_device(dev);
@@ -325,7 +325,7 @@ sdev_show_timeout (struct device *dev, char *buf)
}
static ssize_t
-sdev_store_timeout (struct device *dev, const char *buf, size_t count)
+sdev_store_timeout (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct scsi_device *sdev;
int timeout;
@@ -337,14 +337,14 @@ sdev_store_timeout (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
static ssize_t
-store_rescan_field (struct device *dev, const char *buf, size_t count)
+store_rescan_field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
scsi_rescan_device(dev);
return count;
}
static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
-static ssize_t sdev_store_delete(struct device *dev, const char *buf,
+static ssize_t sdev_store_delete(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
scsi_remove_device(to_scsi_device(dev));
@@ -353,7 +353,7 @@ static ssize_t sdev_store_delete(struct device *dev, const char *buf,
static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
static ssize_t
-store_state_field(struct device *dev, const char *buf, size_t count)
+store_state_field(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int i;
struct scsi_device *sdev = to_scsi_device(dev);
@@ -376,7 +376,7 @@ store_state_field(struct device *dev, const char *buf, size_t count)
}
static ssize_t
-show_state_field(struct device *dev, char *buf)
+show_state_field(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
const char *name = scsi_device_state_name(sdev->sdev_state);
@@ -390,7 +390,7 @@ show_state_field(struct device *dev, char *buf)
static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);
static ssize_t
-show_queue_type_field(struct device *dev, char *buf)
+show_queue_type_field(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
const char *name = "none";
@@ -406,7 +406,7 @@ show_queue_type_field(struct device *dev, char *buf)
static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
static ssize_t
-show_iostat_counterbits(struct device *dev, char *buf)
+show_iostat_counterbits(struct device *dev, struct device_attribute *attr, char *buf)
{
return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
}
@@ -415,7 +415,7 @@ static DEVICE_ATTR(iocounterbits, S_IRUGO, show_iostat_counterbits, NULL);
#define show_sdev_iostat(field) \
static ssize_t \
-show_iostat_##field(struct device *dev, char *buf) \
+show_iostat_##field(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct scsi_device *sdev = to_scsi_device(dev); \
unsigned long long count = atomic_read(&sdev->field); \
@@ -449,7 +449,7 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
NULL
};
-static ssize_t sdev_store_queue_depth_rw(struct device *dev, const char *buf,
+static ssize_t sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
int depth, retval;
@@ -475,7 +475,7 @@ static struct device_attribute sdev_attr_queue_depth_rw =
__ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
sdev_store_queue_depth_rw);
-static ssize_t sdev_store_queue_type_rw(struct device *dev, const char *buf,
+static ssize_t sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct scsi_device *sdev = to_scsi_device(dev);
@@ -669,6 +669,13 @@ void __scsi_remove_target(struct scsi_target *starget)
scsi_target_reap(starget);
}
+static int __remove_child (struct device * dev, void * data)
+{
+ if (scsi_is_target_device(dev))
+ __scsi_remove_target(to_scsi_target(dev));
+ return 0;
+}
+
/**
* scsi_remove_target - try to remove a target and all its devices
* @dev: generic starget or parent of generic stargets to be removed
@@ -679,7 +686,7 @@ void __scsi_remove_target(struct scsi_target *starget)
*/
void scsi_remove_target(struct device *dev)
{
- struct device *rdev, *idev, *next;
+ struct device *rdev;
if (scsi_is_target_device(dev)) {
__scsi_remove_target(to_scsi_target(dev));
@@ -687,10 +694,7 @@ void scsi_remove_target(struct device *dev)
}
rdev = get_device(dev);
- list_for_each_entry_safe(idev, next, &dev->children, node) {
- if (scsi_is_target_device(idev))
- __scsi_remove_target(to_scsi_target(idev));
- }
+ device_for_each_child(dev, NULL, __remove_child);
put_device(rdev);
}
EXPORT_SYMBOL(scsi_remove_target);
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index c87ae469d707..2918b9600db7 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -348,17 +348,21 @@ spi_transport_rd_attr(rd_strm, "%d\n");
spi_transport_rd_attr(rti, "%d\n");
spi_transport_rd_attr(pcomp_en, "%d\n");
+/* we only care about the first child device so we return 1 */
+static int child_iter(struct device *dev, void *data)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+
+ spi_dv_device(sdev);
+ return 1;
+}
+
static ssize_t
store_spi_revalidate(struct class_device *cdev, const char *buf, size_t count)
{
struct scsi_target *starget = transport_class_to_starget(cdev);
- /* FIXME: we're relying on an awful lot of device internals
- * here. We really need a function to get the first available
- * child */
- struct device *dev = container_of(starget->dev.children.next, struct device, node);
- struct scsi_device *sdev = to_scsi_device(dev);
- spi_dv_device(sdev);
+ device_for_each_child(&starget->dev, NULL, child_iter);
return count;
}
static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 3d1d7bff38ed..51292f269ce5 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1430,7 +1430,7 @@ static struct file_operations sg_fops = {
.fasync = sg_fasync,
};
-static struct class_simple * sg_sysfs_class;
+static struct class *sg_sysfs_class;
static int sg_sysfs_valid = 0;
@@ -1551,13 +1551,13 @@ sg_add(struct class_device *cl_dev)
if (sg_sysfs_valid) {
struct class_device * sg_class_member;
- sg_class_member = class_simple_device_add(sg_sysfs_class,
+ sg_class_member = class_device_create(sg_sysfs_class,
MKDEV(SCSI_GENERIC_MAJOR, k),
cl_dev->dev, "%s",
disk->disk_name);
if (IS_ERR(sg_class_member))
printk(KERN_WARNING "sg_add: "
- "class_simple_device_add failed\n");
+ "class_device_create failed\n");
class_set_devdata(sg_class_member, sdp);
error = sysfs_create_link(&scsidp->sdev_gendev.kobj,
&sg_class_member->kobj, "generic");
@@ -1636,7 +1636,7 @@ sg_remove(struct class_device *cl_dev)
if (sdp) {
sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic");
- class_simple_device_remove(MKDEV(SCSI_GENERIC_MAJOR, k));
+ class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k));
cdev_del(sdp->cdev);
sdp->cdev = NULL;
devfs_remove("%s/generic", scsidp->devfs_name);
@@ -1677,7 +1677,7 @@ init_sg(void)
SG_MAX_DEVS, "sg");
if (rc)
return rc;
- sg_sysfs_class = class_simple_create(THIS_MODULE, "scsi_generic");
+ sg_sysfs_class = class_create(THIS_MODULE, "scsi_generic");
if ( IS_ERR(sg_sysfs_class) ) {
rc = PTR_ERR(sg_sysfs_class);
goto err_out;
@@ -1690,7 +1690,7 @@ init_sg(void)
#endif /* CONFIG_SCSI_PROC_FS */
return 0;
}
- class_simple_destroy(sg_sysfs_class);
+ class_destroy(sg_sysfs_class);
err_out:
unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS);
return rc;
@@ -1703,7 +1703,7 @@ exit_sg(void)
sg_proc_cleanup();
#endif /* CONFIG_SCSI_PROC_FS */
scsi_unregister_interface(&sg_interface);
- class_simple_destroy(sg_sysfs_class);
+ class_destroy(sg_sysfs_class);
sg_sysfs_valid = 0;
unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
SG_MAX_DEVS);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 03b902c20e09..0291a8fb654d 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -84,7 +84,7 @@ static int try_wdio = 1;
static int st_dev_max;
static int st_nr_dev;
-static struct class_simple *st_sysfs_class;
+static struct class *st_sysfs_class;
MODULE_AUTHOR("Kai Makisara");
MODULE_DESCRIPTION("SCSI Tape Driver");
@@ -4024,8 +4024,9 @@ out_free_tape:
if (STm->cdevs[j]) {
if (cdev == STm->cdevs[j])
cdev = NULL;
- class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(i, mode, j)));
+ class_device_destroy(st_sysfs_class,
+ MKDEV(SCSI_TAPE_MAJOR,
+ TAPE_MINOR(i, mode, j)));
cdev_del(STm->cdevs[j]);
}
}
@@ -4068,8 +4069,9 @@ static int st_remove(struct device *dev)
devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]);
devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]);
for (j=0; j < 2; j++) {
- class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(i, mode, j)));
+ class_device_destroy(st_sysfs_class,
+ MKDEV(SCSI_TAPE_MAJOR,
+ TAPE_MINOR(i, mode, j)));
cdev_del(tpnt->modes[mode].cdevs[j]);
tpnt->modes[mode].cdevs[j] = NULL;
}
@@ -4134,7 +4136,7 @@ static int __init init_st(void)
"st: Version %s, fixed bufsize %d, s/g segs %d\n",
verstr, st_fixed_buffer_size, st_max_sg_segs);
- st_sysfs_class = class_simple_create(THIS_MODULE, "scsi_tape");
+ st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
if (IS_ERR(st_sysfs_class)) {
st_sysfs_class = NULL;
printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
@@ -4148,7 +4150,7 @@ static int __init init_st(void)
return 0;
}
if (st_sysfs_class)
- class_simple_destroy(st_sysfs_class);
+ class_destroy(st_sysfs_class);
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
ST_MAX_TAPE_ENTRIES);
@@ -4161,7 +4163,7 @@ static int __init init_st(void)
static void __exit exit_st(void)
{
if (st_sysfs_class)
- class_simple_destroy(st_sysfs_class);
+ class_destroy(st_sysfs_class);
st_sysfs_class = NULL;
do_remove_driverfs_files();
scsi_unregister_driver(&st_template.gendrv);
@@ -4284,12 +4286,12 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
snprintf(name, 10, "%s%s%s", rew ? "n" : "",
STp->disk->disk_name, st_formats[i]);
st_class_member =
- class_simple_device_add(st_sysfs_class,
- MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(dev_num, mode, rew)),
- &STp->device->sdev_gendev, "%s", name);
+ class_device_create(st_sysfs_class,
+ MKDEV(SCSI_TAPE_MAJOR,
+ TAPE_MINOR(dev_num, mode, rew)),
+ &STp->device->sdev_gendev, "%s", name);
if (IS_ERR(st_class_member)) {
- printk(KERN_WARNING "st%d: class_simple_device_add failed\n",
+ printk(KERN_WARNING "st%d: class_device_create failed\n",
dev_num);
goto out;
}
diff --git a/drivers/sh/superhyway/superhyway-sysfs.c b/drivers/sh/superhyway/superhyway-sysfs.c
index 39ab6a12da76..dc119ce68e3e 100644
--- a/drivers/sh/superhyway/superhyway-sysfs.c
+++ b/drivers/sh/superhyway/superhyway-sysfs.c
@@ -15,7 +15,7 @@
#include <linux/superhyway.h>
#define superhyway_ro_attr(name, fmt, field) \
-static ssize_t name##_show(struct device *dev, char *buf) \
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct superhyway_device *s = to_superhyway_device(dev); \
return sprintf(buf, fmt, s->field); \
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index ef0b35731ff0..83e815d3cd52 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -239,7 +239,7 @@ static char *usb_dump_interface_descriptor(char *start, char *end,
int setno)
{
const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc;
- char *driver_name = "";
+ const char *driver_name = "";
if (start > end)
return start;
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 38ed2220c9fc..65ca131cc44c 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -68,7 +68,7 @@ static struct file_operations usb_fops = {
.open = usb_open,
};
-static struct class_simple *usb_class;
+static struct class *usb_class;
int usb_major_init(void)
{
@@ -80,9 +80,10 @@ int usb_major_init(void)
goto out;
}
- usb_class = class_simple_create(THIS_MODULE, "usb");
+ usb_class = class_create(THIS_MODULE, "usb");
if (IS_ERR(usb_class)) {
- err("class_simple_create failed for usb devices");
+ error = PTR_ERR(usb_class);
+ err("class_create failed for usb devices");
unregister_chrdev(USB_MAJOR, "usb");
goto out;
}
@@ -95,7 +96,7 @@ out:
void usb_major_cleanup(void)
{
- class_simple_destroy(usb_class);
+ class_destroy(usb_class);
devfs_remove("usb");
unregister_chrdev(USB_MAJOR, "usb");
}
@@ -171,7 +172,7 @@ int usb_register_dev(struct usb_interface *intf,
++temp;
else
temp = name;
- intf->class_dev = class_simple_device_add(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
+ intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL;
@@ -220,7 +221,7 @@ void usb_deregister_dev(struct usb_interface *intf,
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
devfs_remove (name);
- class_simple_device_remove(MKDEV(USB_MAJOR, intf->minor));
+ class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor));
intf->class_dev = NULL;
intf->minor = -1;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 266e9e06a9f5..d041782e0c8b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -651,50 +651,45 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
/*-------------------------------------------------------------------------*/
/* exported only within usbcore */
-struct usb_bus *usb_bus_get (struct usb_bus *bus)
+struct usb_bus *usb_bus_get(struct usb_bus *bus)
{
- struct class_device *tmp;
+ if (bus)
+ kref_get(&bus->kref);
+ return bus;
+}
- if (!bus)
- return NULL;
+static void usb_host_release(struct kref *kref)
+{
+ struct usb_bus *bus = container_of(kref, struct usb_bus, kref);
- tmp = class_device_get(&bus->class_dev);
- if (tmp)
- return to_usb_bus(tmp);
- else
- return NULL;
+ if (bus->release)
+ bus->release(bus);
}
/* exported only within usbcore */
-void usb_bus_put (struct usb_bus *bus)
+void usb_bus_put(struct usb_bus *bus)
{
if (bus)
- class_device_put(&bus->class_dev);
+ kref_put(&bus->kref, usb_host_release);
}
/*-------------------------------------------------------------------------*/
-static void usb_host_release(struct class_device *class_dev)
-{
- struct usb_bus *bus = to_usb_bus(class_dev);
-
- if (bus->release)
- bus->release(bus);
-}
-
-static struct class usb_host_class = {
- .name = "usb_host",
- .release = &usb_host_release,
-};
+static struct class *usb_host_class;
int usb_host_init(void)
{
- return class_register(&usb_host_class);
+ int retval = 0;
+
+ usb_host_class = class_create(THIS_MODULE, "usb_host");
+ if (IS_ERR(usb_host_class))
+ retval = PTR_ERR(usb_host_class);
+ return retval;
}
void usb_host_cleanup(void)
{
- class_unregister(&usb_host_class);
+ class_destroy(usb_host_class);
}
/**
@@ -719,8 +714,7 @@ static void usb_bus_init (struct usb_bus *bus)
INIT_LIST_HEAD (&bus->bus_list);
- class_device_initialize(&bus->class_dev);
- bus->class_dev.class = &usb_host_class;
+ kref_init(&bus->kref);
}
/**
@@ -761,7 +755,6 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op)
static int usb_register_bus(struct usb_bus *bus)
{
int busnum;
- int retval;
down (&usb_bus_list_lock);
busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
@@ -774,15 +767,15 @@ static int usb_register_bus(struct usb_bus *bus)
return -E2BIG;
}
- snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
- bus->class_dev.dev = bus->controller;
- retval = class_device_add(&bus->class_dev);
- if (retval) {
+ bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum);
+ if (IS_ERR(bus->class_dev)) {
clear_bit(busnum, busmap.busmap);
up(&usb_bus_list_lock);
- return retval;
+ return PTR_ERR(bus->class_dev);
}
+ class_set_devdata(bus->class_dev, bus);
+
/* Add it to the local list of buses */
list_add (&bus->bus_list, &usb_bus_list);
up (&usb_bus_list_lock);
@@ -820,7 +813,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
clear_bit (bus->busnum, busmap.busmap);
- class_device_del(&bus->class_dev);
+ class_device_unregister(bus->class_dev);
}
/**
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 4d0c9e65cd03..740cb4c668df 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -24,7 +24,7 @@
/* Active configuration fields */
#define usb_actconfig_show(field, multiplier, format_string) \
-static ssize_t show_##field (struct device *dev, char *buf) \
+static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
struct usb_host_config *actconfig; \
@@ -46,7 +46,7 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n")
usb_actconfig_attr (bmAttributes, 1, "%2x\n")
usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
-static ssize_t show_configuration_string(struct device *dev, char *buf)
+static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
struct usb_host_config *actconfig;
@@ -69,7 +69,7 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL);
usb_actconfig_show(bConfigurationValue, 1, "%u\n");
static ssize_t
-set_bConfigurationValue (struct device *dev, const char *buf, size_t count)
+set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_device *udev = udev = to_usb_device (dev);
int config, value;
@@ -87,7 +87,7 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR,
/* String fields */
#define usb_string_attr(name) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
int len; \
@@ -107,7 +107,7 @@ usb_string_attr(manufacturer);
usb_string_attr(serial);
static ssize_t
-show_speed (struct device *dev, char *buf)
+show_speed (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
char *speed;
@@ -133,7 +133,7 @@ show_speed (struct device *dev, char *buf)
static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
static ssize_t
-show_devnum (struct device *dev, char *buf)
+show_devnum (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
@@ -143,7 +143,7 @@ show_devnum (struct device *dev, char *buf)
static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
static ssize_t
-show_version (struct device *dev, char *buf)
+show_version (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
u16 bcdUSB;
@@ -155,7 +155,7 @@ show_version (struct device *dev, char *buf)
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
static ssize_t
-show_maxchild (struct device *dev, char *buf)
+show_maxchild (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
@@ -167,7 +167,7 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
/* Descriptor fields */
#define usb_descriptor_attr_le16(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
\
@@ -183,7 +183,7 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n")
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
\
@@ -254,7 +254,7 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev)
/* Interface fields */
#define usb_intf_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface (dev); \
\
@@ -269,7 +269,7 @@ usb_intf_attr (bInterfaceClass, "%02x\n")
usb_intf_attr (bInterfaceSubClass, "%02x\n")
usb_intf_attr (bInterfaceProtocol, "%02x\n")
-static ssize_t show_interface_string(struct device *dev, char *buf)
+static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf;
struct usb_device *udev;
@@ -286,7 +286,7 @@ static ssize_t show_interface_string(struct device *dev, char *buf)
}
static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
-static ssize_t show_modalias(struct device *dev, char *buf)
+static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf;
struct usb_device *udev;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 25cf7e9eccfa..a3c42203213a 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -293,7 +293,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
/* if interface was already added, bind now; else let
* the future device_add() bind it, bypassing probe()
*/
- if (!list_empty (&dev->bus_list))
+ if (klist_node_attached(&dev->knode_bus))
device_bind_driver(dev);
return 0;
@@ -322,9 +322,15 @@ void usb_driver_release_interface(struct usb_driver *driver,
if (!dev->driver || dev->driver != &driver->driver)
return;
- /* don't disconnect from disconnect(), or before dev_add() */
- if (!list_empty (&dev->driver_list) && !list_empty (&dev->bus_list))
+ /* don't release from within disconnect() */
+ if (iface->condition != USB_INTERFACE_BOUND)
+ return;
+
+ /* release only after device_add() */
+ if (klist_node_attached(&dev->knode_bus)) {
+ iface->condition = USB_INTERFACE_UNBINDING;
device_release_driver(dev);
+ }
dev->driver = NULL;
usb_set_intfdata(iface, NULL);
@@ -462,6 +468,25 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
return NULL;
}
+
+static int __find_interface(struct device * dev, void * data)
+{
+ struct usb_interface ** ret = (struct usb_interface **)data;
+ struct usb_interface * intf = *ret;
+ int *minor = (int *)data;
+
+ /* can't look at usb devices, only interfaces */
+ if (dev->driver == &usb_generic_driver)
+ return 0;
+
+ intf = to_usb_interface(dev);
+ if (intf->minor != -1 && intf->minor == *minor) {
+ *ret = intf;
+ return 1;
+ }
+ return 0;
+}
+
/**
* usb_find_interface - find usb_interface pointer for driver and device
* @drv: the driver whose current configuration is considered
@@ -473,26 +498,12 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
*/
struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
{
- struct list_head *entry;
- struct device *dev;
- struct usb_interface *intf;
+ struct usb_interface *intf = (struct usb_interface *)(long)minor;
+ int ret;
- list_for_each(entry, &drv->driver.devices) {
- dev = container_of(entry, struct device, driver_list);
-
- /* can't look at usb devices, only interfaces */
- if (dev->driver == &usb_generic_driver)
- continue;
-
- intf = to_usb_interface(dev);
- if (intf->minor == -1)
- continue;
- if (intf->minor == minor)
- return intf;
- }
+ ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
- /* no device found that matches */
- return NULL;
+ return ret ? intf : NULL;
}
static int usb_device_match (struct device *dev, struct device_driver *drv)
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 8ef8a9cd9ac4..c039d2fbe7ab 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -633,7 +633,7 @@ static const struct usb_gadget_ops dummy_ops = {
/* "function" sysfs attribute */
static ssize_t
-show_function (struct device *dev, char *buf)
+show_function (struct device *dev, struct device_attribute *attr, char *buf)
{
struct dummy *dum = gadget_dev_to_dummy (dev);
@@ -1600,7 +1600,7 @@ show_urb (char *buf, size_t size, struct urb *urb)
}
static ssize_t
-show_urbs (struct device *dev, char *buf)
+show_urbs (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_hcd *hcd = dev_get_drvdata (dev);
struct dummy *dum = hcd_to_dummy (hcd);
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 4857f0e4ef44..037a7f163822 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3554,14 +3554,14 @@ static void close_all_backing_files(struct fsg_dev *fsg)
}
-static ssize_t show_ro(struct device *dev, char *buf)
+static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lun *curlun = dev_to_lun(dev);
return sprintf(buf, "%d\n", curlun->ro);
}
-static ssize_t show_file(struct device *dev, char *buf)
+static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf)
{
struct lun *curlun = dev_to_lun(dev);
struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
@@ -3589,7 +3589,7 @@ static ssize_t show_file(struct device *dev, char *buf)
}
-static ssize_t store_ro(struct device *dev, const char *buf, size_t count)
+static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
ssize_t rc = count;
struct lun *curlun = dev_to_lun(dev);
@@ -3613,7 +3613,7 @@ static ssize_t store_ro(struct device *dev, const char *buf, size_t count)
return rc;
}
-static ssize_t store_file(struct device *dev, const char *buf, size_t count)
+static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct lun *curlun = dev_to_lun(dev);
struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index e5457f2026cc..e47e398daeb5 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -1469,7 +1469,7 @@ static const struct usb_gadget_ops net2280_ops = {
/* "function" sysfs attribute */
static ssize_t
-show_function (struct device *_dev, char *buf)
+show_function (struct device *_dev, struct device_attribute *attr, char *buf)
{
struct net2280 *dev = dev_get_drvdata (_dev);
@@ -1482,7 +1482,7 @@ show_function (struct device *_dev, char *buf)
static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
static ssize_t
-show_registers (struct device *_dev, char *buf)
+show_registers (struct device *_dev, struct device_attribute *attr, char *buf)
{
struct net2280 *dev;
char *next;
@@ -1637,7 +1637,7 @@ show_registers (struct device *_dev, char *buf)
static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
static ssize_t
-show_queues (struct device *_dev, char *buf)
+show_queues (struct device *_dev, struct device_attribute *attr, char *buf)
{
struct net2280 *dev;
char *next;
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 6390c5726d81..b8b4524ed746 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -1429,7 +1429,7 @@ done:
/* "function" sysfs attribute */
static ssize_t
-show_function (struct device *_dev, char *buf)
+show_function (struct device *_dev, struct device_attribute *attr, char *buf)
{
struct pxa2xx_udc *dev = dev_get_drvdata (_dev);
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 9b347d765383..2ff11d53567b 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -450,7 +450,7 @@ show_async (struct class_device *class_dev, char *buf)
*buf = 0;
- bus = to_usb_bus(class_dev);
+ bus = class_get_devdata(class_dev);
hcd = bus->hcpriv;
ehci = hcd_to_ehci (hcd);
next = buf;
@@ -496,7 +496,7 @@ show_periodic (struct class_device *class_dev, char *buf)
return 0;
seen_count = 0;
- bus = to_usb_bus(class_dev);
+ bus = class_get_devdata(class_dev);
hcd = bus->hcpriv;
ehci = hcd_to_ehci (hcd);
next = buf;
@@ -633,7 +633,7 @@ show_registers (struct class_device *class_dev, char *buf)
static char fmt [] = "%*s\n";
static char label [] = "";
- bus = to_usb_bus(class_dev);
+ bus = class_get_devdata(class_dev);
hcd = bus->hcpriv;
ehci = hcd_to_ehci (hcd);
next = buf;
@@ -735,7 +735,7 @@ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
static inline void create_debug_files (struct ehci_hcd *ehci)
{
- struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev;
+ struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev;
class_device_create_file(cldev, &class_device_attr_async);
class_device_create_file(cldev, &class_device_attr_periodic);
@@ -744,7 +744,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci)
static inline void remove_debug_files (struct ehci_hcd *ehci)
{
- struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev;
+ struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev;
class_device_remove_file(cldev, &class_device_attr_async);
class_device_remove_file(cldev, &class_device_attr_periodic);
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 62f53a213808..c58408c95c3d 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -481,7 +481,7 @@ show_async (struct class_device *class_dev, char *buf)
size_t temp;
unsigned long flags;
- bus = to_usb_bus(class_dev);
+ bus = class_get_devdata(class_dev);
hcd = bus->hcpriv;
ohci = hcd_to_ohci(hcd);
@@ -514,7 +514,7 @@ show_periodic (struct class_device *class_dev, char *buf)
return 0;
seen_count = 0;
- bus = to_usb_bus(class_dev);
+ bus = class_get_devdata(class_dev);
hcd = bus->hcpriv;
ohci = hcd_to_ohci(hcd);
next = buf;
@@ -611,7 +611,7 @@ show_registers (struct class_device *class_dev, char *buf)
char *next;
u32 rdata;
- bus = to_usb_bus(class_dev);
+ bus = class_get_devdata(class_dev);
hcd = bus->hcpriv;
ohci = hcd_to_ohci(hcd);
regs = ohci->regs;
@@ -684,7 +684,7 @@ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
static inline void create_debug_files (struct ohci_hcd *ohci)
{
- struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev;
+ struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev;
class_device_create_file(cldev, &class_device_attr_async);
class_device_create_file(cldev, &class_device_attr_periodic);
@@ -694,7 +694,7 @@ static inline void create_debug_files (struct ohci_hcd *ohci)
static inline void remove_debug_files (struct ohci_hcd *ohci)
{
- struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev;
+ struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev;
class_device_remove_file(cldev, &class_device_attr_async);
class_device_remove_file(cldev, &class_device_attr_periodic);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index 94ce2a9ad50f..e991f7ed7330 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -1025,7 +1025,7 @@ static int aiptek_program_tablet(struct aiptek *aiptek)
/***********************************************************************
* support the 'size' file -- display support
*/
-static ssize_t show_tabletSize(struct device *dev, char *buf)
+static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1048,7 +1048,7 @@ static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);
/***********************************************************************
* support routines for the 'product_id' file
*/
-static ssize_t show_tabletProductId(struct device *dev, char *buf)
+static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1064,7 +1064,7 @@ static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
/***********************************************************************
* support routines for the 'vendor_id' file
*/
-static ssize_t show_tabletVendorId(struct device *dev, char *buf)
+static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1079,7 +1079,7 @@ static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
/***********************************************************************
* support routines for the 'vendor' file
*/
-static ssize_t show_tabletManufacturer(struct device *dev, char *buf)
+static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
int retval;
@@ -1096,7 +1096,7 @@ static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL);
/***********************************************************************
* support routines for the 'product' file
*/
-static ssize_t show_tabletProduct(struct device *dev, char *buf)
+static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
int retval;
@@ -1114,7 +1114,7 @@ static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL);
* support routines for the 'pointer_mode' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletPointerMode(struct device *dev, char *buf)
+static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1143,7 +1143,7 @@ static ssize_t show_tabletPointerMode(struct device *dev, char *buf)
}
static ssize_t
-store_tabletPointerMode(struct device *dev, const char *buf, size_t count)
+store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
if (aiptek == NULL)
@@ -1168,7 +1168,7 @@ static DEVICE_ATTR(pointer_mode,
* support routines for the 'coordinate_mode' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletCoordinateMode(struct device *dev, char *buf)
+static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1193,7 +1193,7 @@ static ssize_t show_tabletCoordinateMode(struct device *dev, char *buf)
}
static ssize_t
-store_tabletCoordinateMode(struct device *dev, const char *buf, size_t count)
+store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
if (aiptek == NULL)
@@ -1217,7 +1217,7 @@ static DEVICE_ATTR(coordinate_mode,
* support routines for the 'tool_mode' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletToolMode(struct device *dev, char *buf)
+static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1262,7 +1262,7 @@ static ssize_t show_tabletToolMode(struct device *dev, char *buf)
}
static ssize_t
-store_tabletToolMode(struct device *dev, const char *buf, size_t count)
+store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
if (aiptek == NULL)
@@ -1295,7 +1295,7 @@ static DEVICE_ATTR(tool_mode,
* support routines for the 'xtilt' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletXtilt(struct device *dev, char *buf)
+static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1311,7 +1311,7 @@ static ssize_t show_tabletXtilt(struct device *dev, char *buf)
}
static ssize_t
-store_tabletXtilt(struct device *dev, const char *buf, size_t count)
+store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
int x;
@@ -1337,7 +1337,7 @@ static DEVICE_ATTR(xtilt,
* support routines for the 'ytilt' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletYtilt(struct device *dev, char *buf)
+static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1353,7 +1353,7 @@ static ssize_t show_tabletYtilt(struct device *dev, char *buf)
}
static ssize_t
-store_tabletYtilt(struct device *dev, const char *buf, size_t count)
+store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
int y;
@@ -1379,7 +1379,7 @@ static DEVICE_ATTR(ytilt,
* support routines for the 'jitter' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletJitterDelay(struct device *dev, char *buf)
+static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1390,7 +1390,7 @@ static ssize_t show_tabletJitterDelay(struct device *dev, char *buf)
}
static ssize_t
-store_tabletJitterDelay(struct device *dev, const char *buf, size_t count)
+store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1409,7 +1409,7 @@ static DEVICE_ATTR(jitter,
* support routines for the 'delay' file. Note that this file
* both displays current setting and allows reprogramming.
*/
-static ssize_t show_tabletProgrammableDelay(struct device *dev, char *buf)
+static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1421,7 +1421,7 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, char *buf)
}
static ssize_t
-store_tabletProgrammableDelay(struct device *dev, const char *buf, size_t count)
+store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1440,7 +1440,7 @@ static DEVICE_ATTR(delay,
* support routines for the 'input_path' file. Note that this file
* only displays current setting.
*/
-static ssize_t show_tabletInputDevice(struct device *dev, char *buf)
+static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1457,7 +1457,7 @@ static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL);
* support routines for the 'event_count' file. Note that this file
* only displays current setting.
*/
-static ssize_t show_tabletEventsReceived(struct device *dev, char *buf)
+static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1473,7 +1473,7 @@ static DEVICE_ATTR(event_count, S_IRUGO, show_tabletEventsReceived, NULL);
* support routines for the 'diagnostic' file. Note that this file
* only displays current setting.
*/
-static ssize_t show_tabletDiagnosticMessage(struct device *dev, char *buf)
+static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *retMsg;
@@ -1515,7 +1515,7 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL);
* support routines for the 'stylus_upper' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletStylusUpper(struct device *dev, char *buf)
+static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1540,7 +1540,7 @@ static ssize_t show_tabletStylusUpper(struct device *dev, char *buf)
}
static ssize_t
-store_tabletStylusUpper(struct device *dev, const char *buf, size_t count)
+store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1565,7 +1565,7 @@ static DEVICE_ATTR(stylus_upper,
* support routines for the 'stylus_lower' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletStylusLower(struct device *dev, char *buf)
+static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1590,7 +1590,7 @@ static ssize_t show_tabletStylusLower(struct device *dev, char *buf)
}
static ssize_t
-store_tabletStylusLower(struct device *dev, const char *buf, size_t count)
+store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1615,7 +1615,7 @@ static DEVICE_ATTR(stylus_lower,
* support routines for the 'mouse_left' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletMouseLeft(struct device *dev, char *buf)
+static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1644,7 +1644,7 @@ static ssize_t show_tabletMouseLeft(struct device *dev, char *buf)
}
static ssize_t
-store_tabletMouseLeft(struct device *dev, const char *buf, size_t count)
+store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1669,7 +1669,7 @@ static DEVICE_ATTR(mouse_left,
* support routines for the 'mouse_middle' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletMouseMiddle(struct device *dev, char *buf)
+static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1698,7 +1698,7 @@ static ssize_t show_tabletMouseMiddle(struct device *dev, char *buf)
}
static ssize_t
-store_tabletMouseMiddle(struct device *dev, const char *buf, size_t count)
+store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1725,7 +1725,7 @@ static DEVICE_ATTR(mouse_middle,
* support routines for the 'mouse_right' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletMouseRight(struct device *dev, char *buf)
+static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
char *s;
@@ -1754,7 +1754,7 @@ static ssize_t show_tabletMouseRight(struct device *dev, char *buf)
}
static ssize_t
-store_tabletMouseRight(struct device *dev, const char *buf, size_t count)
+store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1780,7 +1780,7 @@ static DEVICE_ATTR(mouse_right,
* support routines for the 'wheel' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletWheel(struct device *dev, char *buf)
+static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1796,7 +1796,7 @@ static ssize_t show_tabletWheel(struct device *dev, char *buf)
}
static ssize_t
-store_tabletWheel(struct device *dev, const char *buf, size_t count)
+store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1814,7 +1814,7 @@ static DEVICE_ATTR(wheel,
* support routines for the 'execute' file. Note that this file
* both displays current setting and allows for setting changing.
*/
-static ssize_t show_tabletExecute(struct device *dev, char *buf)
+static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1829,7 +1829,7 @@ static ssize_t show_tabletExecute(struct device *dev, char *buf)
}
static ssize_t
-store_tabletExecute(struct device *dev, const char *buf, size_t count)
+store_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1855,7 +1855,7 @@ static DEVICE_ATTR(execute,
* support routines for the 'odm_code' file. Note that this file
* only displays current setting.
*/
-static ssize_t show_tabletODMCode(struct device *dev, char *buf)
+static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1871,7 +1871,7 @@ static DEVICE_ATTR(odm_code, S_IRUGO, show_tabletODMCode, NULL);
* support routines for the 'model_code' file. Note that this file
* only displays current setting.
*/
-static ssize_t show_tabletModelCode(struct device *dev, char *buf)
+static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
@@ -1887,7 +1887,7 @@ static DEVICE_ATTR(model_code, S_IRUGO, show_tabletModelCode, NULL);
* support routines for the 'firmware_code' file. Note that this file
* only displays current setting.
*/
-static ssize_t show_firmwareCode(struct device *dev, char *buf)
+static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index 626e2b05f719..b33044d56a1e 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -85,7 +85,7 @@ static int vendor_command(struct usb_device *dev, unsigned char request,
#define BRIGHTNESS 0x2c /* RAM location for brightness value */
#define BRIGHTNESS_SEM 0x2b /* RAM location for brightness semaphore */
-static ssize_t show_brightness(struct device *dev, char *buf)
+static ssize_t show_brightness(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -93,7 +93,7 @@ static ssize_t show_brightness(struct device *dev, char *buf)
return sprintf(buf, "%i", cytherm->brightness);
}
-static ssize_t set_brightness(struct device *dev, const char *buf,
+static ssize_t set_brightness(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct usb_interface *intf = to_usb_interface(dev);
@@ -138,7 +138,7 @@ static DEVICE_ATTR(brightness, S_IRUGO | S_IWUSR | S_IWGRP,
#define TEMP 0x33 /* RAM location for temperature */
#define SIGN 0x34 /* RAM location for temperature sign */
-static ssize_t show_temp(struct device *dev, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf = to_usb_interface(dev);
@@ -174,7 +174,7 @@ static ssize_t show_temp(struct device *dev, char *buf)
}
-static ssize_t set_temp(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
return count;
}
@@ -184,7 +184,7 @@ static DEVICE_ATTR(temp, S_IRUGO, show_temp, set_temp);
#define BUTTON 0x7a
-static ssize_t show_button(struct device *dev, char *buf)
+static ssize_t show_button(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf = to_usb_interface(dev);
@@ -215,7 +215,7 @@ static ssize_t show_button(struct device *dev, char *buf)
}
-static ssize_t set_button(struct device *dev, const char *buf, size_t count)
+static ssize_t set_button(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
return count;
}
@@ -223,7 +223,7 @@ static ssize_t set_button(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(button, S_IRUGO, show_button, set_button);
-static ssize_t show_port0(struct device *dev, char *buf)
+static ssize_t show_port0(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -249,7 +249,7 @@ static ssize_t show_port0(struct device *dev, char *buf)
}
-static ssize_t set_port0(struct device *dev, const char *buf, size_t count)
+static ssize_t set_port0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -283,7 +283,7 @@ static ssize_t set_port0(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR | S_IWGRP, show_port0, set_port0);
-static ssize_t show_port1(struct device *dev, char *buf)
+static ssize_t show_port1(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -309,7 +309,7 @@ static ssize_t show_port1(struct device *dev, char *buf)
}
-static ssize_t set_port1(struct device *dev, const char *buf, size_t count)
+static ssize_t set_port1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usb_cytherm *cytherm = usb_get_intfdata(intf);
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index ddbf8e992368..067a81486921 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -173,7 +173,7 @@ exit:
}
#define set_lcd_line(number) \
-static ssize_t lcd_line_##number(struct device *dev, const char *buf, size_t count) \
+static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct phidget_interfacekit *kit = usb_get_intfdata(intf); \
@@ -184,7 +184,7 @@ static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number);
set_lcd_line(1);
set_lcd_line(2);
-static ssize_t set_backlight(struct device *dev, const char *buf, size_t count)
+static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_interface *intf = to_usb_interface(dev);
struct phidget_interfacekit *kit = usb_get_intfdata(intf);
@@ -232,7 +232,7 @@ static void remove_lcd_files(struct phidget_interfacekit *kit)
}
}
-static ssize_t enable_lcd_files(struct device *dev, const char *buf, size_t count)
+static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_interface *intf = to_usb_interface(dev);
struct phidget_interfacekit *kit = usb_get_intfdata(intf);
@@ -307,7 +307,7 @@ resubmit:
}
#define show_set_output(value) \
-static ssize_t set_output##value(struct device *dev, const char *buf, \
+static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \
size_t count) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
@@ -324,7 +324,7 @@ static ssize_t set_output##value(struct device *dev, const char *buf, \
return retval ? retval : count; \
} \
\
-static ssize_t show_output##value(struct device *dev, char *buf) \
+static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct phidget_interfacekit *kit = usb_get_intfdata(intf); \
@@ -343,7 +343,7 @@ show_set_output(7);
show_set_output(8); /* should be MAX_INTERFACES - 1 */
#define show_input(value) \
-static ssize_t show_input##value(struct device *dev, char *buf) \
+static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct phidget_interfacekit *kit = usb_get_intfdata(intf); \
@@ -362,7 +362,7 @@ show_input(7);
show_input(8); /* should be MAX_INTERFACES - 1 */
#define show_sensor(value) \
-static ssize_t show_sensor##value(struct device *dev, char *buf) \
+static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct phidget_interfacekit *kit = usb_get_intfdata(intf); \
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index 4bd291502a3c..b84eda631ab5 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -207,7 +207,7 @@ change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
}
#define show_set(value) \
-static ssize_t set_servo##value (struct device *dev, \
+static ssize_t set_servo##value (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
int degrees, minutes, retval; \
@@ -233,7 +233,7 @@ static ssize_t set_servo##value (struct device *dev, \
return retval < 0 ? retval : count; \
} \
\
-static ssize_t show_servo##value (struct device *dev, char *buf) \
+static ssize_t show_servo##value (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface (dev); \
struct phidget_servo *servo = usb_get_intfdata (intf); \
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index ee329d5e1c5e..f6ba4c788dbc 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -81,14 +81,14 @@ static void change_color(struct usb_led *led)
}
#define show_set(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct usb_led *led = usb_get_intfdata(intf); \
\
return sprintf(buf, "%d\n", led->value); \
} \
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct usb_led *led = usb_get_intfdata(intf); \
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 3bfcc7b9f861..d882fa3ad19a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1218,7 +1218,7 @@ check_and_exit:
* ***************************************************************************
*/
-static ssize_t show_latency_timer(struct device *dev, char *buf)
+static ssize_t show_latency_timer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1245,7 +1245,7 @@ static ssize_t show_latency_timer(struct device *dev, char *buf)
}
/* Write a new value of the latency timer, in units of milliseconds. */
-static ssize_t store_latency_timer(struct device *dev, const char *valbuf,
+static ssize_t store_latency_timer(struct device *dev, struct device_attribute *attr, const char *valbuf,
size_t count)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
@@ -1276,7 +1276,7 @@ static ssize_t store_latency_timer(struct device *dev, const char *valbuf,
/* Write an event character directly to the FTDI register. The ASCII
value is in the low 8 bits, with the enable bit in the 9th bit. */
-static ssize_t store_event_char(struct device *dev, const char *valbuf,
+static ssize_t store_event_char(struct device *dev, struct device_attribute *attr, const char *valbuf,
size_t count)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 1035b248eff4..e43eddc3d44b 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -398,7 +398,7 @@ US_DO_ALL_FLAGS
***********************************************************************/
/* Output routine for the sysfs max_sectors file */
-static ssize_t show_max_sectors(struct device *dev, char *buf)
+static ssize_t show_max_sectors(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
@@ -406,7 +406,7 @@ static ssize_t show_max_sectors(struct device *dev, char *buf)
}
/* Input routine for the sysfs max_sectors file */
-static ssize_t store_max_sectors(struct device *dev, const char *buf,
+static ssize_t store_max_sectors(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct scsi_device *sdev = to_scsi_device(dev);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 7705070191d9..8cef020d1801 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1040,7 +1040,7 @@ static struct file_operations fb_fops = {
#endif
};
-static struct class_simple *fb_class;
+static struct class *fb_class;
/**
* register_framebuffer - registers a frame buffer device
@@ -1066,7 +1066,7 @@ register_framebuffer(struct fb_info *fb_info)
break;
fb_info->node = i;
- fb_info->class_device = class_simple_device_add(fb_class, MKDEV(FB_MAJOR, i),
+ fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i),
fb_info->device, "fb%d", i);
if (IS_ERR(fb_info->class_device)) {
/* Not fatal */
@@ -1134,7 +1134,7 @@ unregister_framebuffer(struct fb_info *fb_info)
registered_fb[i]=NULL;
num_registered_fb--;
fb_cleanup_class_device(fb_info);
- class_simple_device_remove(MKDEV(FB_MAJOR, i));
+ class_device_destroy(fb_class, MKDEV(FB_MAJOR, i));
return 0;
}
@@ -1197,7 +1197,7 @@ fbmem_init(void)
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
- fb_class = class_simple_create(THIS_MODULE, "graphics");
+ fb_class = class_create(THIS_MODULE, "graphics");
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
@@ -1210,7 +1210,7 @@ module_init(fbmem_init);
static void __exit
fbmem_exit(void)
{
- class_simple_destroy(fb_class);
+ class_destroy(fb_class);
}
module_exit(fbmem_exit);
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 2a023282d7a3..d3c1922cb13a 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1045,14 +1045,14 @@ static struct fb_ops gbefb_ops = {
* sysfs
*/
-static ssize_t gbefb_show_memsize(struct device *dev, char *buf)
+static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
}
static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
-static ssize_t gbefb_show_rev(struct device *device, char *buf)
+static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
}
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 58cd2ad84afb..adcda697ea60 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -101,7 +101,7 @@ static void(*w100fb_ssp_send)(u8 adrs, u8 data);
* Sysfs functions
*/
-static ssize_t rotation_show(struct device *dev, char *buf)
+static ssize_t rotation_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fb_info *info = dev_get_drvdata(dev);
struct w100fb_par *par=info->par;
@@ -109,7 +109,7 @@ static ssize_t rotation_show(struct device *dev, char *buf)
return sprintf(buf, "%d\n",par->rotation_flag);
}
-static ssize_t rotation_store(struct device *dev, const char *buf, size_t count)
+static ssize_t rotation_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
unsigned int rotate;
struct fb_info *info = dev_get_drvdata(dev);
@@ -134,7 +134,7 @@ static ssize_t rotation_store(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store);
-static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count)
+static ssize_t w100fb_reg_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
unsigned long param;
unsigned long regs;
@@ -146,7 +146,7 @@ static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count
static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read);
-static ssize_t w100fb_reg_write(struct device *dev, const char *buf, size_t count)
+static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
unsigned long regs;
unsigned long param;
@@ -163,7 +163,7 @@ static ssize_t w100fb_reg_write(struct device *dev, const char *buf, size_t coun
static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
-static ssize_t fastsysclk_show(struct device *dev, char *buf)
+static ssize_t fastsysclk_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fb_info *info = dev_get_drvdata(dev);
struct w100fb_par *par=info->par;
@@ -171,7 +171,7 @@ static ssize_t fastsysclk_show(struct device *dev, char *buf)
return sprintf(buf, "%d\n",par->fastsysclk_mode);
}
-static ssize_t fastsysclk_store(struct device *dev, const char *buf, size_t count)
+static ssize_t fastsysclk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int param;
struct fb_info *info = dev_get_drvdata(dev);
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 8d7821899cc1..24a192e3b8b4 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -88,7 +88,7 @@ static void w1_slave_release(struct device *dev)
complete(&sl->dev_released);
}
-static ssize_t w1_default_read_name(struct device *dev, char *buf)
+static ssize_t w1_default_read_name(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "No family registered.\n");
}
@@ -137,7 +137,7 @@ static struct device_attribute w1_slave_attribute_val = {
.show = &w1_default_read_name,
};
-static ssize_t w1_master_attribute_show_name(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = container_of (dev, struct w1_master, dev);
ssize_t count;
@@ -152,7 +152,7 @@ static ssize_t w1_master_attribute_show_name(struct device *dev, char *buf)
return count;
}
-static ssize_t w1_master_attribute_show_pointer(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = container_of(dev, struct w1_master, dev);
ssize_t count;
@@ -166,14 +166,14 @@ static ssize_t w1_master_attribute_show_pointer(struct device *dev, char *buf)
return count;
}
-static ssize_t w1_master_attribute_show_timeout(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t count;
count = sprintf(buf, "%d\n", w1_timeout);
return count;
}
-static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = container_of(dev, struct w1_master, dev);
ssize_t count;
@@ -187,7 +187,7 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, char
return count;
}
-static ssize_t w1_master_attribute_show_attempts(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = container_of(dev, struct w1_master, dev);
ssize_t count;
@@ -201,7 +201,7 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, char *buf)
return count;
}
-static ssize_t w1_master_attribute_show_slave_count(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = container_of(dev, struct w1_master, dev);
ssize_t count;
@@ -215,7 +215,7 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, char *bu
return count;
}
-static ssize_t w1_master_attribute_show_slaves(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = container_of(dev, struct w1_master, dev);
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 03a2de7a601f..07fa49412a90 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -34,10 +34,10 @@
struct w1_family_ops
{
- ssize_t (* rname)(struct device *, char *);
+ ssize_t (* rname)(struct device *, struct device_attribute *, char *);
ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);
- ssize_t (* rval)(struct device *, char *);
+ ssize_t (* rval)(struct device *, struct device_attribute *, char *);
unsigned char rvalname[MAXNAMELEN];
};
diff --git a/drivers/w1/w1_smem.c b/drivers/w1/w1_smem.c
index a54e425217a0..674eb75a9bad 100644
--- a/drivers/w1/w1_smem.c
+++ b/drivers/w1/w1_smem.c
@@ -36,8 +36,8 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family.");
-static ssize_t w1_smem_read_name(struct device *, char *);
-static ssize_t w1_smem_read_val(struct device *, char *);
+static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *);
+static ssize_t w1_smem_read_val(struct device *, struct device_attribute *attr, char *);
static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
static struct w1_family_ops w1_smem_fops = {
@@ -47,14 +47,14 @@ static struct w1_family_ops w1_smem_fops = {
.rvalname = "id",
};
-static ssize_t w1_smem_read_name(struct device *dev, char *buf)
+static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
return sprintf(buf, "%s\n", sl->name);
}
-static ssize_t w1_smem_read_val(struct device *dev, char *buf)
+static ssize_t w1_smem_read_val(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
int i;
diff --git a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
index 0b1817890503..70310f7a722e 100644
--- a/drivers/w1/w1_therm.c
+++ b/drivers/w1/w1_therm.c
@@ -42,8 +42,8 @@ static u8 bad_roms[][9] = {
{}
};
-static ssize_t w1_therm_read_name(struct device *, char *);
-static ssize_t w1_therm_read_temp(struct device *, char *);
+static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *);
+static ssize_t w1_therm_read_temp(struct device *, struct device_attribute *attr, char *);
static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
static struct w1_family_ops w1_therm_fops = {
@@ -53,7 +53,7 @@ static struct w1_family_ops w1_therm_fops = {
.rvalname = "temp1_input",
};
-static ssize_t w1_therm_read_name(struct device *dev, char *buf)
+static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
@@ -77,7 +77,7 @@ static inline int w1_convert_temp(u8 rom[9])
return t;
}
-static ssize_t w1_therm_read_temp(struct device *dev, char *buf)
+static ssize_t w1_therm_read_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index dad03fc33a44..04ca8840acf1 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -21,7 +21,7 @@
/* show configuration fields */
#define zorro_config_attr(name, field, format_string) \
static ssize_t \
-show_##name(struct device *dev, char *buf) \
+show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct zorro_dev *z; \
\
@@ -36,7 +36,7 @@ zorro_config_attr(serial, rom.er_SerialNumber, "0x%08x\n");
zorro_config_attr(slotaddr, slotaddr, "0x%04x\n");
zorro_config_attr(slotsize, slotsize, "0x%04x\n");
-static ssize_t zorro_show_resource(struct device *dev, char *buf)
+static ssize_t zorro_show_resource(struct device *dev, struct device_attribute *attr, char *buf)
{
struct zorro_dev *z = to_zorro_dev(dev);
diff --git a/fs/Kconfig b/fs/Kconfig
index 6a4ad4bb7a54..178e27494b74 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -741,56 +741,6 @@ config SYSFS
Designers of embedded systems may wish to say N here to conserve space.
-config DEVFS_FS
- bool "/dev file system support (OBSOLETE)"
- depends on EXPERIMENTAL
- help
- This is support for devfs, a virtual file system (like /proc) which
- provides the file system interface to device drivers, normally found
- in /dev. Devfs does not depend on major and minor number
- allocations. Device drivers register entries in /dev which then
- appear automatically, which means that the system administrator does
- not have to create character and block special device files in the
- /dev directory using the mknod command (or MAKEDEV script) anymore.
-
- This is work in progress. If you want to use this, you *must* read
- the material in <file:Documentation/filesystems/devfs/>, especially
- the file README there.
-
- Note that devfs no longer manages /dev/pts! If you are using UNIX98
- ptys, you will also need to mount the /dev/pts filesystem (devpts).
-
- Note that devfs has been obsoleted by udev,
- <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
- It has been stripped down to a bare minimum and is only provided for
- legacy installations that use its naming scheme which is
- unfortunately different from the names normal Linux installations
- use.
-
- If unsure, say N.
-
-config DEVFS_MOUNT
- bool "Automatically mount at boot"
- depends on DEVFS_FS
- help
- This option appears if you have CONFIG_DEVFS_FS enabled. Setting
- this to 'Y' will make the kernel automatically mount devfs onto /dev
- when the system is booted, before the init thread is started.
- You can override this with the "devfs=nomount" boot option.
-
- If unsure, say N.
-
-config DEVFS_DEBUG
- bool "Debug devfs"
- depends on DEVFS_FS
- help
- If you say Y here, then the /dev file system code will generate
- debugging messages. See the file
- <file:Documentation/filesystems/devfs/boot-options> for more
- details.
-
- If unsure, say N.
-
config DEVPTS_FS_XATTR
bool "/dev/pts Extended Attributes"
depends on UNIX98_PTYS
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index ef001a9313e6..3d1cce3653b8 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -61,7 +61,7 @@ unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */
struct venus_comm coda_comms[MAX_CODADEVS];
-static struct class_simple *coda_psdev_class;
+static struct class *coda_psdev_class;
/*
* Device operations
@@ -363,14 +363,14 @@ static int init_coda_psdev(void)
CODA_PSDEV_MAJOR);
return -EIO;
}
- coda_psdev_class = class_simple_create(THIS_MODULE, "coda");
+ coda_psdev_class = class_create(THIS_MODULE, "coda");
if (IS_ERR(coda_psdev_class)) {
err = PTR_ERR(coda_psdev_class);
goto out_chrdev;
}
devfs_mk_dir ("coda");
for (i = 0; i < MAX_CODADEVS; i++) {
- class_simple_device_add(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
+ class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
NULL, "cfs%d", i);
err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
@@ -382,8 +382,8 @@ static int init_coda_psdev(void)
out_class:
for (i = 0; i < MAX_CODADEVS; i++)
- class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
- class_simple_destroy(coda_psdev_class);
+ class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
+ class_destroy(coda_psdev_class);
out_chrdev:
unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
out:
@@ -425,10 +425,10 @@ static int __init init_coda(void)
return 0;
out:
for (i = 0; i < MAX_CODADEVS; i++) {
- class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
+ class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
devfs_remove("coda/%d", i);
}
- class_simple_destroy(coda_psdev_class);
+ class_destroy(coda_psdev_class);
devfs_remove("coda");
unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
coda_sysctl_clean();
@@ -447,10 +447,10 @@ static void __exit exit_coda(void)
printk("coda: failed to unregister filesystem\n");
}
for (i = 0; i < MAX_CODADEVS; i++) {
- class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
+ class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
devfs_remove("coda/%d", i);
}
- class_simple_destroy(coda_psdev_class);
+ class_destroy(coda_psdev_class);
devfs_remove("coda");
unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
coda_sysctl_clean();
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 548556ff2506..efc97d9b7860 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -45,44 +45,15 @@ struct file_operations debugfs_file_operations = {
.open = default_open,
};
-#define simple_type(type, format, temptype, strtolfn) \
-static ssize_t read_file_##type(struct file *file, char __user *user_buf, \
- size_t count, loff_t *ppos) \
-{ \
- char buf[32]; \
- type *val = file->private_data; \
- \
- snprintf(buf, sizeof(buf), format "\n", *val); \
- return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));\
-} \
-static ssize_t write_file_##type(struct file *file, const char __user *user_buf,\
- size_t count, loff_t *ppos) \
-{ \
- char *endp; \
- char buf[32]; \
- int buf_size; \
- type *val = file->private_data; \
- temptype tmp; \
- \
- memset(buf, 0x00, sizeof(buf)); \
- buf_size = min(count, (sizeof(buf)-1)); \
- if (copy_from_user(buf, user_buf, buf_size)) \
- return -EFAULT; \
- \
- tmp = strtolfn(buf, &endp, 0); \
- if ((endp == buf) || ((type)tmp != tmp)) \
- return -EINVAL; \
- *val = tmp; \
- return count; \
-} \
-static struct file_operations fops_##type = { \
- .read = read_file_##type, \
- .write = write_file_##type, \
- .open = default_open, \
-};
-simple_type(u8, "%c", unsigned long, simple_strtoul);
-simple_type(u16, "%hi", unsigned long, simple_strtoul);
-simple_type(u32, "%i", unsigned long, simple_strtoul);
+static void debugfs_u8_set(void *data, u64 val)
+{
+ *(u8 *)data = val;
+}
+static u64 debugfs_u8_get(void *data)
+{
+ return *(u8 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
/**
* debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
@@ -116,6 +87,16 @@ struct dentry *debugfs_create_u8(const char *name, mode_t mode,
}
EXPORT_SYMBOL_GPL(debugfs_create_u8);
+static void debugfs_u16_set(void *data, u64 val)
+{
+ *(u16 *)data = val;
+}
+static u64 debugfs_u16_get(void *data)
+{
+ return *(u16 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
+
/**
* debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
*
@@ -148,6 +129,16 @@ struct dentry *debugfs_create_u16(const char *name, mode_t mode,
}
EXPORT_SYMBOL_GPL(debugfs_create_u16);
+static void debugfs_u32_set(void *data, u64 val)
+{
+ *(u32 *)data = val;
+}
+static u64 debugfs_u32_get(void *data)
+{
+ return *(u32 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
+
/**
* debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
*
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 8d2a9ab981d4..30a2bf9eeda5 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -70,8 +70,7 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
if (!IS_ERR(acl))
*p_acl = posix_acl_dup(acl);
}
- if (value)
- kfree(value);
+ kfree(value);
return acl;
}
@@ -112,8 +111,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
}
rc = __jfs_setxattr(inode, ea_name, value, size, 0);
out:
- if (value)
- kfree(value);
+ kfree(value);
if (!rc) {
if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED))
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index a87b06fa8ff8..c2c19c9ed9a4 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
- * Portions Copyright (c) Christoph Hellwig, 2001-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
+ * Portions Copyright (C) Christoph Hellwig, 2001-2002
*
* 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
@@ -19,16 +19,13 @@
#include <linux/fs.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_dmap.h"
#include "jfs_txnmgr.h"
#include "jfs_xattr.h"
#include "jfs_acl.h"
#include "jfs_debug.h"
-
-extern int jfs_commit_inode(struct inode *, int);
-extern void jfs_truncate(struct inode *);
-
int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
{
struct inode *inode = dentry->d_inode;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 24a689179af2..2137138c59b0 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -23,6 +23,7 @@
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_filsys.h"
#include "jfs_imap.h"
#include "jfs_extent.h"
@@ -30,14 +31,6 @@
#include "jfs_debug.h"
-extern struct inode_operations jfs_dir_inode_operations;
-extern struct inode_operations jfs_file_inode_operations;
-extern struct inode_operations jfs_symlink_inode_operations;
-extern struct file_operations jfs_dir_operations;
-extern struct file_operations jfs_file_operations;
-struct address_space_operations jfs_aops;
-extern int freeZeroLink(struct inode *);
-
void jfs_read_inode(struct inode *inode)
{
if (diRead(inode)) {
@@ -136,7 +129,7 @@ void jfs_delete_inode(struct inode *inode)
jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
if (test_cflag(COMMIT_Freewmap, inode))
- freeZeroLink(inode);
+ jfs_free_zero_link(inode);
diFree(inode);
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
index 91a0a889ebc5..4caea6b43b92 100644
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -58,8 +58,6 @@ void dump_mem(char *label, void *data, int length)
static struct proc_dir_entry *base;
#ifdef CONFIG_JFS_DEBUG
-extern read_proc_t jfs_txanchor_read;
-
static int loglevel_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -97,14 +95,6 @@ static int loglevel_write(struct file *file, const char __user *buffer,
}
#endif
-
-#ifdef CONFIG_JFS_STATISTICS
-extern read_proc_t jfs_lmstats_read;
-extern read_proc_t jfs_txstats_read;
-extern read_proc_t jfs_xtstat_read;
-extern read_proc_t jfs_mpstat_read;
-#endif
-
static struct {
const char *name;
read_proc_t *read_fn;
diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
index a38079ae1e00..ddffbbd4d955 100644
--- a/fs/jfs/jfs_debug.h
+++ b/fs/jfs/jfs_debug.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
- * Portions Copyright (c) Christoph Hellwig, 2001-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
+ * Portions Copyright (C) Christoph Hellwig, 2001-2002
*
* 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
@@ -31,7 +31,9 @@
* CONFIG_JFS_DEBUG or CONFIG_JFS_STATISTICS is defined
*/
#if defined(CONFIG_PROC_FS) && (defined(CONFIG_JFS_DEBUG) || defined(CONFIG_JFS_STATISTICS))
- #define PROC_FS_JFS
+#define PROC_FS_JFS
+extern void jfs_proc_init(void);
+extern void jfs_proc_clean(void);
#endif
/*
@@ -65,8 +67,8 @@
extern int jfsloglevel;
-/* dump memory contents */
extern void dump_mem(char *label, void *data, int length);
+extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
/* information message: e.g., configuration, major event */
#define jfs_info(fmt, arg...) do { \
@@ -110,6 +112,11 @@ extern void dump_mem(char *label, void *data, int length);
* ----------
*/
#ifdef CONFIG_JFS_STATISTICS
+extern int jfs_lmstats_read(char *, char **, off_t, int, int *, void *);
+extern int jfs_txstats_read(char *, char **, off_t, int, int *, void *);
+extern int jfs_mpstat_read(char *, char **, off_t, int, int *, void *);
+extern int jfs_xtstat_read(char *, char **, off_t, int, int *, void *);
+
#define INCREMENT(x) ((x)++)
#define DECREMENT(x) ((x)--)
#define HIGHWATERMARK(x,y) ((x) = max((x), (y)))
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 69007fd546ef..cced2fed9d0f 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -272,7 +272,6 @@ int dbMount(struct inode *ipbmap)
int dbUnmount(struct inode *ipbmap, int mounterror)
{
struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
- int i;
if (!(mounterror || isReadOnly(ipbmap)))
dbSync(ipbmap);
@@ -282,14 +281,6 @@ int dbUnmount(struct inode *ipbmap, int mounterror)
*/
truncate_inode_pages(ipbmap->i_mapping, 0);
- /*
- * Sanity Check
- */
- for (i = 0; i < bmp->db_numag; i++)
- if (atomic_read(&bmp->db_active[i]))
- printk(KERN_ERR "dbUnmount: db_active[%d] = %d\n",
- i, atomic_read(&bmp->db_active[i]));
-
/* free the memory for the in-memory bmap. */
kfree(bmp);
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index ac41f72d6d50..8676aee3ae48 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2931,6 +2931,9 @@ static void add_missing_indices(struct inode *inode, s64 bn)
ASSERT(p->header.flag & BT_LEAF);
tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY);
+ if (BT_IS_ROOT(mp))
+ tlck->type |= tlckBTROOT;
+
dtlck = (struct dt_lock *) &tlck->lock;
stbl = DT_GETSTBL(p);
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 1953acb79266..4879603daa1c 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -19,6 +19,7 @@
#include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
#include "jfs_extent.h"
@@ -33,12 +34,6 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
#endif
static s64 extRoundDown(s64 nb);
-/*
- * external references
- */
-extern int jfs_commit_inode(struct inode *, int);
-
-
#define DPD(a) (printk("(a): %d\n",(a)))
#define DPC(a) (printk("(a): %c\n",(a)))
#define DPL1(a) \
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 7acff2ce3c80..971af2977eff 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -47,6 +47,7 @@
#include <linux/quotaops.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_filsys.h"
#include "jfs_dinode.h"
#include "jfs_dmap.h"
@@ -69,11 +70,6 @@
#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno])
/*
- * external references
- */
-extern struct address_space_operations jfs_aops;
-
-/*
* forward references
*/
static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index 84f2459b2191..2af5efbfd06f 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -19,6 +19,7 @@
#include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_filsys.h"
#include "jfs_imap.h"
#include "jfs_dinode.h"
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 3df91fbfe781..b54bac576cb3 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2001
+ * Copyright (C) International Business Machines Corp., 2000-2001
*
* 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
@@ -19,5 +19,22 @@
#define _H_JFS_INODE
extern struct inode *ialloc(struct inode *, umode_t);
+extern int jfs_fsync(struct file *, struct dentry *, int);
+extern void jfs_read_inode(struct inode *);
+extern int jfs_commit_inode(struct inode *, int);
+extern int jfs_write_inode(struct inode*, int);
+extern void jfs_delete_inode(struct inode *);
+extern void jfs_dirty_inode(struct inode *);
+extern void jfs_truncate(struct inode *);
+extern void jfs_truncate_nolock(struct inode *, loff_t);
+extern void jfs_free_zero_link(struct inode *);
+extern struct dentry *jfs_get_parent(struct dentry *dentry);
+extern struct address_space_operations jfs_aops;
+extern struct inode_operations jfs_dir_inode_operations;
+extern struct file_operations jfs_dir_operations;
+extern struct inode_operations jfs_file_inode_operations;
+extern struct file_operations jfs_file_operations;
+extern struct inode_operations jfs_symlink_inode_operations;
+extern struct dentry_operations jfs_ci_dentry_operations;
#endif /* _H_JFS_INODE */
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index dfa1200daa61..7c8387ed4192 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -71,6 +71,7 @@
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
+#include "jfs_superblock.h"
#include "jfs_txnmgr.h"
#include "jfs_debug.h"
@@ -167,14 +168,6 @@ static struct jfs_log *dummy_log = NULL;
static DECLARE_MUTEX(jfs_log_sem);
/*
- * external references
- */
-extern void txLazyUnlock(struct tblock * tblk);
-extern int jfs_stop_threads;
-extern struct completion jfsIOwait;
-extern int jfs_tlocks_low;
-
-/*
* forward references
*/
static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
@@ -1624,6 +1617,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
}
}
assert(list_empty(&log->cqueue));
+
+#ifdef CONFIG_JFS_DEBUG
if (!list_empty(&log->synclist)) {
struct logsyncblk *lp;
@@ -1638,9 +1633,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
dump_mem("orphan tblock", lp,
sizeof(struct tblock));
}
-// current->state = TASK_INTERRUPTIBLE;
-// schedule();
}
+#endif
//assert(list_empty(&log->synclist));
clear_bit(log_FLUSH, &log->flag);
}
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 51291fbc420c..747114cd38b8 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -507,6 +507,8 @@ extern int lmLogClose(struct super_block *sb);
extern int lmLogShutdown(struct jfs_log * log);
extern int lmLogInit(struct jfs_log * log);
extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
+extern int lmGroupCommit(struct jfs_log *, struct tblock *);
+extern int jfsIOWait(void *);
extern void jfs_flush_journal(struct jfs_log * log, int wait);
extern void jfs_syncpt(struct jfs_log *log);
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 41bf078dce05..6c5485d16c39 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
}
}
-static inline struct metapage *alloc_metapage(int gfp_mask)
+static inline struct metapage *alloc_metapage(unsigned int gfp_mask)
{
return mempool_alloc(metapage_mempool, gfp_mask);
}
@@ -726,12 +726,12 @@ void force_metapage(struct metapage *mp)
page_cache_release(page);
}
-extern void hold_metapage(struct metapage *mp)
+void hold_metapage(struct metapage *mp)
{
lock_page(mp->page);
}
-extern void put_metapage(struct metapage *mp)
+void put_metapage(struct metapage *mp)
{
if (mp->count || mp->nohomeok) {
/* Someone else will release this */
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index 991e9fb84c75..f0b7d3282b07 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) International Business Machines Corp., 2000-2002
- * Portions Copyright (c) Christoph Hellwig, 2001-2002
+ * Copyright (C) International Business Machines Corp., 2000-2002
+ * Portions Copyright (C) Christoph Hellwig, 2001-2002
*
* 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
@@ -58,6 +58,8 @@ struct metapage {
#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
/* function prototypes */
+extern int metapage_init(void);
+extern void metapage_exit(void);
extern struct metapage *__get_metapage(struct inode *inode,
unsigned long lblock, unsigned int size,
int absolute, unsigned long new);
diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h
index ab0566f70cfa..fcf781bf31cb 100644
--- a/fs/jfs/jfs_superblock.h
+++ b/fs/jfs/jfs_superblock.h
@@ -109,5 +109,16 @@ struct jfs_superblock {
extern int readSuper(struct super_block *, struct buffer_head **);
extern int updateSuper(struct super_block *, uint);
extern void jfs_error(struct super_block *, const char *, ...);
+extern int jfs_mount(struct super_block *);
+extern int jfs_mount_rw(struct super_block *, int);
+extern int jfs_umount(struct super_block *);
+extern int jfs_umount_rw(struct super_block *);
+
+extern int jfs_stop_threads;
+extern struct completion jfsIOwait;
+extern wait_queue_head_t jfs_IO_thread_wait;
+extern wait_queue_head_t jfs_commit_thread_wait;
+extern wait_queue_head_t jfs_sync_thread_wait;
+extern int jfs_extendfs(struct super_block *, s64, int);
#endif /*_H_JFS_SUPERBLOCK */
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index e93d01aa12c4..8cbaaff1d5fa 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -42,7 +42,6 @@
* hold on to mp+lock thru update of maps
*/
-
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
@@ -51,6 +50,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
#include "jfs_dinode.h"
@@ -109,7 +109,6 @@ static int TxLockHWM; /* High water mark for number of txLocks used */
static int TxLockVHWM; /* Very High water mark */
struct tlock *TxLock; /* transaction lock table */
-
/*
* transaction management lock
*/
@@ -149,7 +148,6 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
#define TXN_WAKEUP(event) wake_up_all(event)
-
/*
* statistics
*/
@@ -161,16 +159,6 @@ static struct {
int waitlock; /* 4: # of tlock wait */
} stattx;
-
-/*
- * external references
- */
-extern int lmGroupCommit(struct jfs_log *, struct tblock *);
-extern int jfs_commit_inode(struct inode *, int);
-extern int jfs_stop_threads;
-
-extern struct completion jfsIOwait;
-
/*
* forward references
*/
@@ -358,7 +346,6 @@ void txExit(void)
TxBlock = NULL;
}
-
/*
* NAME: txBegin()
*
@@ -460,7 +447,6 @@ tid_t txBegin(struct super_block *sb, int flag)
return t;
}
-
/*
* NAME: txBeginAnon()
*
@@ -503,7 +489,6 @@ void txBeginAnon(struct super_block *sb)
TXN_UNLOCK();
}
-
/*
* txEnd()
*
@@ -592,7 +577,6 @@ wakeup:
TXN_WAKEUP(&TxAnchor.freewait);
}
-
/*
* txLock()
*
@@ -868,7 +852,6 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
return NULL;
}
-
/*
* NAME: txRelease()
*
@@ -908,7 +891,6 @@ static void txRelease(struct tblock * tblk)
TXN_UNLOCK();
}
-
/*
* NAME: txUnlock()
*
@@ -996,7 +978,6 @@ static void txUnlock(struct tblock * tblk)
}
}
-
/*
* txMaplock()
*
@@ -1069,7 +1050,6 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
return tlck;
}
-
/*
* txLinelock()
*
@@ -1103,8 +1083,6 @@ struct linelock *txLinelock(struct linelock * tlock)
return linelock;
}
-
-
/*
* transaction commit management
* -----------------------------
@@ -1373,7 +1351,6 @@ int txCommit(tid_t tid, /* transaction identifier */
return rc;
}
-
/*
* NAME: txLog()
*
@@ -1437,7 +1414,6 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
return rc;
}
-
/*
* diLog()
*
@@ -1465,7 +1441,6 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
if (tlck->type & tlckENTRY) {
/* log after-image for logredo(): */
lrd->type = cpu_to_le16(LOG_REDOPAGE);
-// *pxd = mp->cm_pxd;
PXDaddress(pxd, mp->index);
PXDlength(pxd,
mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -1552,7 +1527,6 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
return rc;
}
-
/*
* dataLog()
*
@@ -1599,7 +1573,6 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
return 0;
}
-
/*
* dtLog()
*
@@ -1639,7 +1612,6 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND);
else
lrd->log.redopage.type |= cpu_to_le16(LOG_NEW);
-// *pxd = mp->cm_pxd;
PXDaddress(pxd, mp->index);
PXDlength(pxd,
mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -1704,7 +1676,6 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
return;
}
-
/*
* xtLog()
*
@@ -1760,7 +1731,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
* applying the after-image to the meta-data page.
*/
lrd->type = cpu_to_le16(LOG_REDOPAGE);
-// *page_pxd = mp->cm_pxd;
PXDaddress(page_pxd, mp->index);
PXDlength(page_pxd,
mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -2093,7 +2063,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
return;
}
-
/*
* mapLog()
*
@@ -2180,7 +2149,6 @@ void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
}
}
-
/*
* txEA()
*
@@ -2233,7 +2201,6 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
}
}
-
/*
* txForce()
*
@@ -2300,7 +2267,6 @@ void txForce(struct tblock * tblk)
}
}
-
/*
* txUpdateMap()
*
@@ -2437,7 +2403,6 @@ static void txUpdateMap(struct tblock * tblk)
}
}
-
/*
* txAllocPMap()
*
@@ -2509,7 +2474,6 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
}
}
-
/*
* txFreeMap()
*
@@ -2611,7 +2575,6 @@ void txFreeMap(struct inode *ip,
}
}
-
/*
* txFreelock()
*
@@ -2652,7 +2615,6 @@ void txFreelock(struct inode *ip)
TXN_UNLOCK();
}
-
/*
* txAbort()
*
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
index b71b82c2df04..59ad0f6b7231 100644
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -285,34 +285,26 @@ struct commit {
/*
* external declarations
*/
-extern struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage *mp,
- int flag);
-
-extern struct tlock *txMaplock(tid_t tid, struct inode *ip, int flag);
-
-extern int txCommit(tid_t tid, int nip, struct inode **iplist, int flag);
-
-extern tid_t txBegin(struct super_block *sb, int flag);
-
-extern void txBeginAnon(struct super_block *sb);
-
-extern void txEnd(tid_t tid);
-
-extern void txAbort(tid_t tid, int dirty);
-
-extern struct linelock *txLinelock(struct linelock * tlock);
-
-extern void txFreeMap(struct inode *ip, struct maplock * maplock,
- struct tblock * tblk, int maptype);
-
-extern void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea);
-
-extern void txFreelock(struct inode *ip);
-
-extern int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
- struct tlock * tlck);
-
-extern void txQuiesce(struct super_block *sb);
-
-extern void txResume(struct super_block *sb);
+extern int jfs_tlocks_low;
+
+extern int txInit(void);
+extern void txExit(void);
+extern struct tlock *txLock(tid_t, struct inode *, struct metapage *, int);
+extern struct tlock *txMaplock(tid_t, struct inode *, int);
+extern int txCommit(tid_t, int, struct inode **, int);
+extern tid_t txBegin(struct super_block *, int);
+extern void txBeginAnon(struct super_block *);
+extern void txEnd(tid_t);
+extern void txAbort(tid_t, int);
+extern struct linelock *txLinelock(struct linelock *);
+extern void txFreeMap(struct inode *, struct maplock *, struct tblock *, int);
+extern void txEA(tid_t, struct inode *, dxd_t *, dxd_t *);
+extern void txFreelock(struct inode *);
+extern int lmLog(struct jfs_log *, struct tblock *, struct lrd *,
+ struct tlock *);
+extern void txQuiesce(struct super_block *);
+extern void txResume(struct super_block *);
+extern void txLazyUnlock(struct tblock *);
+extern int jfs_lazycommit(void *);
+extern int jfs_sync(void *);
#endif /* _H_JFS_TXNMGR */
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 8413a368f449..1cae14e741eb 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -31,20 +31,9 @@
#include "jfs_acl.h"
#include "jfs_debug.h"
-extern struct inode_operations jfs_file_inode_operations;
-extern struct inode_operations jfs_symlink_inode_operations;
-extern struct file_operations jfs_file_operations;
-extern struct address_space_operations jfs_aops;
-
-extern int jfs_fsync(struct file *, struct dentry *, int);
-extern void jfs_truncate_nolock(struct inode *, loff_t);
-extern int jfs_init_acl(struct inode *, struct inode *);
-
/*
* forward references
*/
-struct inode_operations jfs_dir_inode_operations;
-struct file_operations jfs_dir_operations;
struct dentry_operations jfs_ci_dentry_operations;
static s64 commitZeroLink(tid_t, struct inode *);
@@ -655,7 +644,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
/*
- * NAME: freeZeroLink()
+ * NAME: jfs_free_zero_link()
*
* FUNCTION: for non-directory, called by iClose(),
* free resources of a file from cache and WORKING map
@@ -663,15 +652,12 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
* while associated with a pager object,
*
* PARAMETER: ip - pointer to inode of file.
- *
- * RETURN: 0 -ok
*/
-int freeZeroLink(struct inode *ip)
+void jfs_free_zero_link(struct inode *ip)
{
- int rc = 0;
int type;
- jfs_info("freeZeroLink: ip = 0x%p", ip);
+ jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
/* return if not reg or symbolic link or if size is
* already ok.
@@ -684,10 +670,10 @@ int freeZeroLink(struct inode *ip)
case S_IFLNK:
/* if its contained in inode nothing to do */
if (ip->i_size < IDATASIZE)
- return 0;
+ return;
break;
default:
- return 0;
+ return;
}
/*
@@ -737,9 +723,7 @@ int freeZeroLink(struct inode *ip)
* free xtree/data blocks from working block map;
*/
if (ip->i_size)
- rc = xtTruncate(0, ip, 0, COMMIT_WMAP);
-
- return rc;
+ xtTruncate(0, ip, 0, COMMIT_WMAP);
}
/*
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 5e774ed7fb64..810a3653d8b3 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -28,6 +28,7 @@
#include "jfs_incore.h"
#include "jfs_filsys.h"
+#include "jfs_inode.h"
#include "jfs_metapage.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
@@ -62,37 +63,6 @@ module_param(jfsloglevel, int, 0644);
MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)");
#endif
-/*
- * External declarations
- */
-extern int jfs_mount(struct super_block *);
-extern int jfs_mount_rw(struct super_block *, int);
-extern int jfs_umount(struct super_block *);
-extern int jfs_umount_rw(struct super_block *);
-
-extern int jfsIOWait(void *);
-extern int jfs_lazycommit(void *);
-extern int jfs_sync(void *);
-
-extern void jfs_read_inode(struct inode *inode);
-extern void jfs_dirty_inode(struct inode *inode);
-extern void jfs_delete_inode(struct inode *inode);
-extern int jfs_write_inode(struct inode *inode, int wait);
-
-extern struct dentry *jfs_get_parent(struct dentry *dentry);
-extern int jfs_extendfs(struct super_block *, s64, int);
-
-extern struct dentry_operations jfs_ci_dentry_operations;
-
-#ifdef PROC_FS_JFS /* see jfs_debug.h */
-extern void jfs_proc_init(void);
-extern void jfs_proc_clean(void);
-#endif
-
-extern wait_queue_head_t jfs_IO_thread_wait;
-extern wait_queue_head_t jfs_commit_thread_wait;
-extern wait_queue_head_t jfs_sync_thread_wait;
-
static void jfs_handle_error(struct super_block *sb)
{
struct jfs_sb_info *sbi = JFS_SBI(sb);
@@ -593,11 +563,6 @@ static struct file_system_type jfs_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
-extern int metapage_init(void);
-extern int txInit(void);
-extern void txExit(void);
-extern void metapage_exit(void);
-
static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
{
struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index ef4c07ee92b2..287d8d6c3cfd 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) Christoph Hellwig, 2001-2002
+ * Copyright (C) Christoph Hellwig, 2001-2002
*
* 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
@@ -19,6 +19,7 @@
#include <linux/fs.h>
#include <linux/namei.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_xattr.h"
static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 7a9ffd5d03dc..6016373701a3 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -946,8 +946,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
out:
up_write(&JFS_IP(inode)->xattr_sem);
- if (os2name)
- kfree(os2name);
+ kfree(os2name);
return rc;
}
@@ -1042,8 +1041,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
out:
up_read(&JFS_IP(inode)->xattr_sem);
- if (os2name)
- kfree(os2name);
+ kfree(os2name);
return size;
}
diff --git a/fs/libfs.c b/fs/libfs.c
index f90b29595927..5025563e7379 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -519,6 +519,102 @@ int simple_transaction_release(struct inode *inode, struct file *file)
return 0;
}
+/* Simple attribute files */
+
+struct simple_attr {
+ u64 (*get)(void *);
+ void (*set)(void *, u64);
+ char get_buf[24]; /* enough to store a u64 and "\n\0" */
+ char set_buf[24];
+ void *data;
+ const char *fmt; /* format for read operation */
+ struct semaphore sem; /* protects access to these buffers */
+};
+
+/* simple_attr_open is called by an actual attribute open file operation
+ * to set the attribute specific access operations. */
+int simple_attr_open(struct inode *inode, struct file *file,
+ u64 (*get)(void *), void (*set)(void *, u64),
+ const char *fmt)
+{
+ struct simple_attr *attr;
+
+ attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+ if (!attr)
+ return -ENOMEM;
+
+ attr->get = get;
+ attr->set = set;
+ attr->data = inode->u.generic_ip;
+ attr->fmt = fmt;
+ init_MUTEX(&attr->sem);
+
+ file->private_data = attr;
+
+ return nonseekable_open(inode, file);
+}
+
+int simple_attr_close(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+/* read from the buffer that is filled with the get function */
+ssize_t simple_attr_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct simple_attr *attr;
+ size_t size;
+ ssize_t ret;
+
+ attr = file->private_data;
+
+ if (!attr->get)
+ return -EACCES;
+
+ down(&attr->sem);
+ if (*ppos) /* continued read */
+ size = strlen(attr->get_buf);
+ else /* first read */
+ size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
+ attr->fmt,
+ (unsigned long long)attr->get(attr->data));
+
+ ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
+ up(&attr->sem);
+ return ret;
+}
+
+/* interpret the buffer as a number to call the set function with */
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct simple_attr *attr;
+ u64 val;
+ size_t size;
+ ssize_t ret;
+
+ attr = file->private_data;
+
+ if (!attr->set)
+ return -EACCES;
+
+ down(&attr->sem);
+ ret = -EFAULT;
+ size = min(sizeof(attr->set_buf) - 1, len);
+ if (copy_from_user(attr->set_buf, buf, size))
+ goto out;
+
+ ret = len; /* claim we got the whole input */
+ attr->set_buf[size] = '\0';
+ val = simple_strtol(attr->set_buf, NULL, 0);
+ attr->set(attr->data, val);
+out:
+ up(&attr->sem);
+ return ret;
+}
+
EXPORT_SYMBOL(dcache_dir_close);
EXPORT_SYMBOL(dcache_dir_lseek);
EXPORT_SYMBOL(dcache_dir_open);
@@ -547,3 +643,7 @@ EXPORT_SYMBOL(simple_read_from_buffer);
EXPORT_SYMBOL(simple_transaction_get);
EXPORT_SYMBOL(simple_transaction_read);
EXPORT_SYMBOL(simple_transaction_release);
+EXPORT_SYMBOL_GPL(simple_attr_open);
+EXPORT_SYMBOL_GPL(simple_attr_close);
+EXPORT_SYMBOL_GPL(simple_attr_read);
+EXPORT_SYMBOL_GPL(simple_attr_write);
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index d4aaa88d0214..78899eeab974 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -25,7 +25,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
struct kobject * kobj = to_kobj(dentry->d_parent);
if (!attr->read)
- return -EINVAL;
+ return -EIO;
return attr->read(kobj, buffer, off, count);
}
@@ -71,7 +71,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
struct kobject *kobj = to_kobj(dentry->d_parent);
if (!attr->write)
- return -EINVAL;
+ return -EIO;
return attr->write(kobj, buffer, offset, count);
}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index fe198210bc2d..37d7a6875d86 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -101,18 +101,19 @@ static int create_dir(struct kobject * k, struct dentry * p,
down(&p->d_inode->i_sem);
*d = sysfs_get_dentry(p,n);
if (!IS_ERR(*d)) {
- error = sysfs_create(*d, mode, init_dir);
+ error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
if (!error) {
- error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
- SYSFS_DIR);
+ error = sysfs_create(*d, mode, init_dir);
if (!error) {
p->d_inode->i_nlink++;
(*d)->d_op = &sysfs_dentry_ops;
d_rehash(*d);
}
}
- if (error && (error != -EEXIST))
+ if (error && (error != -EEXIST)) {
+ sysfs_put((*d)->d_fsdata);
d_drop(*d);
+ }
dput(*d);
} else
error = PTR_ERR(*d);
@@ -171,17 +172,19 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
init = init_file;
}
+ dentry->d_fsdata = sysfs_get(sd);
+ sd->s_dentry = dentry;
error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
- if (error)
+ if (error) {
+ sysfs_put(sd);
return error;
+ }
if (bin_attr) {
dentry->d_inode->i_size = bin_attr->size;
dentry->d_inode->i_fop = &bin_fops;
}
dentry->d_op = &sysfs_dentry_ops;
- dentry->d_fsdata = sysfs_get(sd);
- sd->s_dentry = dentry;
d_rehash(dentry);
return 0;
@@ -191,13 +194,15 @@ static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
{
int err = 0;
+ dentry->d_fsdata = sysfs_get(sd);
+ sd->s_dentry = dentry;
err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
if (!err) {
dentry->d_op = &sysfs_dentry_ops;
- dentry->d_fsdata = sysfs_get(sd);
- sd->s_dentry = dentry;
d_rehash(dentry);
- }
+ } else
+ sysfs_put(sd);
+
return err;
}
@@ -228,6 +233,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
struct inode_operations sysfs_dir_inode_operations = {
.lookup = sysfs_lookup,
+ .setattr = sysfs_setattr,
};
static void remove_dir(struct dentry * d)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 364208071e17..849aac115460 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -23,7 +23,7 @@ subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (sattr->show)
ret = sattr->show(s,page);
@@ -36,7 +36,7 @@ subsys_attr_store(struct kobject * kobj, struct attribute * attr,
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (sattr->store)
ret = sattr->store(s,page,count);
@@ -182,7 +182,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
return -ENOMEM;
if (count >= PAGE_SIZE)
- count = PAGE_SIZE - 1;
+ count = PAGE_SIZE;
error = copy_from_user(buffer->page,buf,count);
buffer->needs_read_fill = 1;
return error ? -EFAULT : count;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index aff7b2dfa8ee..565cac1d4200 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -26,18 +26,107 @@ static struct backing_dev_info sysfs_backing_dev_info = {
.capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
};
-struct inode * sysfs_new_inode(mode_t mode)
+static struct inode_operations sysfs_inode_operations ={
+ .setattr = sysfs_setattr,
+};
+
+int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
+{
+ struct inode * inode = dentry->d_inode;
+ struct sysfs_dirent * sd = dentry->d_fsdata;
+ struct iattr * sd_iattr;
+ unsigned int ia_valid = iattr->ia_valid;
+ int error;
+
+ if (!sd)
+ return -EINVAL;
+
+ sd_iattr = sd->s_iattr;
+
+ error = inode_change_ok(inode, iattr);
+ if (error)
+ return error;
+
+ error = inode_setattr(inode, iattr);
+ if (error)
+ return error;
+
+ if (!sd_iattr) {
+ /* setting attributes for the first time, allocate now */
+ sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
+ if (!sd_iattr)
+ return -ENOMEM;
+ /* assign default attributes */
+ memset(sd_iattr, 0, sizeof(struct iattr));
+ sd_iattr->ia_mode = sd->s_mode;
+ sd_iattr->ia_uid = 0;
+ sd_iattr->ia_gid = 0;
+ sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
+ sd->s_iattr = sd_iattr;
+ }
+
+ /* attributes were changed atleast once in past */
+
+ if (ia_valid & ATTR_UID)
+ sd_iattr->ia_uid = iattr->ia_uid;
+ if (ia_valid & ATTR_GID)
+ sd_iattr->ia_gid = iattr->ia_gid;
+ if (ia_valid & ATTR_ATIME)
+ sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
+ inode->i_sb->s_time_gran);
+ if (ia_valid & ATTR_MTIME)
+ sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
+ inode->i_sb->s_time_gran);
+ if (ia_valid & ATTR_CTIME)
+ sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
+ inode->i_sb->s_time_gran);
+ if (ia_valid & ATTR_MODE) {
+ umode_t mode = iattr->ia_mode;
+
+ if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+ mode &= ~S_ISGID;
+ sd_iattr->ia_mode = mode;
+ }
+
+ return error;
+}
+
+static inline void set_default_inode_attr(struct inode * inode, mode_t mode)
+{
+ inode->i_mode = mode;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+}
+
+static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
+{
+ inode->i_mode = iattr->ia_mode;
+ inode->i_uid = iattr->ia_uid;
+ inode->i_gid = iattr->ia_gid;
+ inode->i_atime = iattr->ia_atime;
+ inode->i_mtime = iattr->ia_mtime;
+ inode->i_ctime = iattr->ia_ctime;
+}
+
+struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
{
struct inode * inode = new_inode(sysfs_sb);
if (inode) {
- inode->i_mode = mode;
- inode->i_uid = 0;
- inode->i_gid = 0;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_mapping->a_ops = &sysfs_aops;
inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
+ inode->i_op = &sysfs_inode_operations;
+
+ if (sd->s_iattr) {
+ /* sysfs_dirent has non-default attributes
+ * get them for the new inode from persistent copy
+ * in sysfs_dirent
+ */
+ set_inode_attr(inode, sd->s_iattr);
+ } else
+ set_default_inode_attr(inode, mode);
}
return inode;
}
@@ -48,7 +137,8 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
struct inode * inode = NULL;
if (dentry) {
if (!dentry->d_inode) {
- if ((inode = sysfs_new_inode(mode))) {
+ struct sysfs_dirent * sd = dentry->d_fsdata;
+ if ((inode = sysfs_new_inode(mode, sd))) {
if (dentry->d_parent && dentry->d_parent->d_inode) {
struct inode *p_inode = dentry->d_parent->d_inode;
p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 5c805bb1a4b7..f1117e885bd6 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -28,6 +28,7 @@ static struct sysfs_dirent sysfs_root = {
.s_children = LIST_HEAD_INIT(sysfs_root.s_children),
.s_element = NULL,
.s_type = SYSFS_ROOT,
+ .s_iattr = NULL,
};
static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -42,7 +43,8 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_time_gran = 1;
sysfs_sb = sb;
- inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+ inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+ &sysfs_root);
if (inode) {
inode->i_op = &sysfs_dir_inode_operations;
inode->i_fop = &sysfs_dir_operations;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index dfdf70174354..fae57c83a722 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -43,7 +43,7 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length)
}
}
-static int sysfs_add_link(struct dentry * parent, char * name, struct kobject * target)
+static int sysfs_add_link(struct dentry * parent, const char * name, struct kobject * target)
{
struct sysfs_dirent * parent_sd = parent->d_fsdata;
struct sysfs_symlink * sl;
@@ -79,7 +79,7 @@ exit1:
* @target: object we're pointing to.
* @name: name of the symlink.
*/
-int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name)
+int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
{
struct dentry * dentry = kobj->dentry;
int error = 0;
@@ -99,13 +99,13 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * nam
* @name: name of the symlink to remove.
*/
-void sysfs_remove_link(struct kobject * kobj, char * name)
+void sysfs_remove_link(struct kobject * kobj, const char * name)
{
sysfs_hash_and_remove(kobj->dentry,name);
}
static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
- char *path)
+ char *path)
{
char * s;
int depth, size;
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index a8a24a0c0b3b..29da6f5f07c8 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -2,7 +2,7 @@
extern struct vfsmount * sysfs_mount;
extern kmem_cache_t *sysfs_dir_cachep;
-extern struct inode * sysfs_new_inode(mode_t mode);
+extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
@@ -17,6 +17,7 @@ extern void sysfs_remove_subdir(struct dentry *);
extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd);
extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
+extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
extern struct rw_semaphore sysfs_rename_sem;
extern struct super_block * sysfs_sb;
@@ -75,6 +76,7 @@ static inline void release_sysfs_dirent(struct sysfs_dirent * sd)
kobject_put(sl->target_kobj);
kfree(sl);
}
+ kfree(sd->s_iattr);
kmem_cache_free(sysfs_dir_cachep, sd);
}
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
new file mode 100644
index 000000000000..0e9b7e18af05
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -0,0 +1,151 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/aaec2000.h
+ *
+ * AAEC-2000 registers definition
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_AAEC2000_H
+#define __ASM_ARCH_AAEC2000_H
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error You must include hardware.h not this file
+#endif /* __ASM_ARCH_HARDWARE_H */
+
+/* Interrupt controller */
+#define IRQ_BASE __REG(0x80000500)
+#define IRQ_INTSR __REG(0x80000500) /* Int Status Register */
+#define IRQ_INTRSR __REG(0x80000504) /* Int Raw (unmasked) Status */
+#define IRQ_INTENS __REG(0x80000508) /* Int Enable Set */
+#define IRQ_INTENC __REG(0x8000050c) /* Int Enable Clear */
+
+/* UART 1 */
+#define UART1_BASE __REG(0x80000600)
+#define UART1_DR __REG(0x80000600) /* Data/FIFO Register */
+#define UART1_LCR __REG(0x80000604) /* Link Control Register */
+#define UART1_BRCR __REG(0x80000608) /* Baud Rate Control Register */
+#define UART1_CR __REG(0x8000060c) /* Control Register */
+#define UART1_SR __REG(0x80000610) /* Status Register */
+#define UART1_INT __REG(0x80000614) /* Interrupt Status Register */
+#define UART1_INTM __REG(0x80000618) /* Interrupt Mask Register */
+#define UART1_INTRES __REG(0x8000061c) /* Int Result (masked status) Register */
+
+/* UART 2 */
+#define UART2_BASE __REG(0x80000700)
+#define UART2_DR __REG(0x80000700) /* Data/FIFO Register */
+#define UART2_LCR __REG(0x80000704) /* Link Control Register */
+#define UART2_BRCR __REG(0x80000708) /* Baud Rate Control Register */
+#define UART2_CR __REG(0x8000070c) /* Control Register */
+#define UART2_SR __REG(0x80000710) /* Status Register */
+#define UART2_INT __REG(0x80000714) /* Interrupt Status Register */
+#define UART2_INTM __REG(0x80000718) /* Interrupt Mask Register */
+#define UART2_INTRES __REG(0x8000071c) /* Int Result (masked status) Register */
+
+/* UART 3 */
+#define UART3_BASE __REG(0x80000800)
+#define UART3_DR __REG(0x80000800) /* Data/FIFO Register */
+#define UART3_LCR __REG(0x80000804) /* Link Control Register */
+#define UART3_BRCR __REG(0x80000808) /* Baud Rate Control Register */
+#define UART3_CR __REG(0x8000080c) /* Control Register */
+#define UART3_SR __REG(0x80000810) /* Status Register */
+#define UART3_INT __REG(0x80000814) /* Interrupt Status Register */
+#define UART3_INTM __REG(0x80000818) /* Interrupt Mask Register */
+#define UART3_INTRES __REG(0x8000081c) /* Int Result (masked status) Register */
+
+/* These are used in some places */
+#define _UART1_BASE __PREG(UART1_BASE)
+#define _UART2_BASE __PREG(UART2_BASE)
+#define _UART3_BASE __PREG(UART3_BASE)
+
+/* UART Registers Offsets */
+#define UART_DR 0x00
+#define UART_LCR 0x04
+#define UART_BRCR 0x08
+#define UART_CR 0x0c
+#define UART_SR 0x10
+#define UART_INT 0x14
+#define UART_INTM 0x18
+#define UART_INTRES 0x1c
+
+/* UART_LCR Bitmask */
+#define UART_LCR_BRK (1 << 0) /* Send Break */
+#define UART_LCR_PEN (1 << 1) /* Parity Enable */
+#define UART_LCR_EP (1 << 2) /* Even/Odd Parity */
+#define UART_LCR_S2 (1 << 3) /* One/Two Stop bits */
+#define UART_LCR_FIFO (1 << 4) /* FIFO Enable */
+#define UART_LCR_WL5 (0 << 5) /* Word Length - 5 bits */
+#define UART_LCR_WL6 (1 << 5) /* Word Length - 6 bits */
+#define UART_LCR_WL7 (1 << 6) /* Word Length - 7 bits */
+#define UART_LCR_WL8 (1 << 7) /* Word Length - 8 bits */
+
+/* UART_CR Bitmask */
+#define UART_CR_EN (1 << 0) /* UART Enable */
+#define UART_CR_SIR (1 << 1) /* IrDA SIR Enable */
+#define UART_CR_SIRLP (1 << 2) /* Low Power IrDA Enable */
+#define UART_CR_RXP (1 << 3) /* Receive Pin Polarity */
+#define UART_CR_TXP (1 << 4) /* Transmit Pin Polarity */
+#define UART_CR_MXP (1 << 5) /* Modem Pin Polarity */
+#define UART_CR_LOOP (1 << 6) /* Loopback Mode */
+
+/* UART_SR Bitmask */
+#define UART_SR_CTS (1 << 0) /* Clear To Send Status */
+#define UART_SR_DSR (1 << 1) /* Data Set Ready Status */
+#define UART_SR_DCD (1 << 2) /* Data Carrier Detect Status */
+#define UART_SR_TxBSY (1 << 3) /* Transmitter Busy Status */
+#define UART_SR_RxFE (1 << 4) /* Receive FIFO Empty Status */
+#define UART_SR_TxFF (1 << 5) /* Transmit FIFO Full Status */
+#define UART_SR_RxFF (1 << 6) /* Receive FIFO Full Status */
+#define UART_SR_TxFE (1 << 7) /* Transmit FIFO Empty Status */
+
+/* UART_INT Bitmask */
+#define UART_INT_RIS (1 << 0) /* Rx Interrupt */
+#define UART_INT_TIS (1 << 1) /* Tx Interrupt */
+#define UART_INT_MIS (1 << 2) /* Modem Interrupt */
+#define UART_INT_RTIS (1 << 3) /* Receive Timeout Interrupt */
+
+/* Timer 1 */
+#define TIMER1_BASE __REG(0x80000c00)
+#define TIMER1_LOAD __REG(0x80000c00) /* Timer 1 Load Register */
+#define TIMER1_VAL __REG(0x80000c04) /* Timer 1 Value Register */
+#define TIMER1_CTRL __REG(0x80000c08) /* Timer 1 Control Register */
+#define TIMER1_CLEAR __REG(0x80000c0c) /* Timer 1 Clear Register */
+
+/* Timer 2 */
+#define TIMER2_BASE __REG(0x80000d00)
+#define TIMER2_LOAD __REG(0x80000d00) /* Timer 2 Load Register */
+#define TIMER2_VAL __REG(0x80000d04) /* Timer 2 Value Register */
+#define TIMER2_CTRL __REG(0x80000d08) /* Timer 2 Control Register */
+#define TIMER2_CLEAR __REG(0x80000d0c) /* Timer 2 Clear Register */
+
+/* Timer 3 */
+#define TIMER3_BASE __REG(0x80000e00)
+#define TIMER3_LOAD __REG(0x80000e00) /* Timer 3 Load Register */
+#define TIMER3_VAL __REG(0x80000e04) /* Timer 3 Value Register */
+#define TIMER3_CTRL __REG(0x80000e08) /* Timer 3 Control Register */
+#define TIMER3_CLEAR __REG(0x80000e0c) /* Timer 3 Clear Register */
+
+/* Timer Control register bits */
+#define TIMER_CTRL_ENABLE (1 << 7) /* Enable (Start° Timer */
+#define TIMER_CTRL_PERIODIC (1 << 6) /* Periodic Running Mode */
+#define TIMER_CTRL_FREE_RUNNING (0 << 6) /* Normal Running Mode */
+#define TIMER_CTRL_CLKSEL_508K (1 << 3) /* 508KHz Clock select (Timer 1, 2) */
+#define TIMER_CTRL_CLKSEL_2K (0 << 3) /* 2KHz Clock Select (Timer 1, 2)*/
+
+/* Power and State Control */
+#define POWER_BASE __REG(0x80000400)
+#define POWER_PWRSR __REG(0x80000400) /* Power Status Register */
+#define POWER_PWRCNT __REG(0x80000404) /* Power/Clock control */
+#define POWER_HALT __REG(0x80000408) /* Power Idle Mode */
+#define POWER_STDBY __REG(0x8000040c) /* Power Standby Mode */
+#define POWER_BLEOI __REG(0x80000410) /* Battery Low End of Interrupt */
+#define POWER_MCEOI __REG(0x80000414) /* Media Changed EoI */
+#define POWER_TEOI __REG(0x80000418) /* Tick EoI */
+#define POWER_STFCLR __REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */
+#define POWER_CLKSET __REG(0x80000420) /* Clock Speed Control */
+
+#endif /* __ARM_ARCH_AAEC2000_H */
diff --git a/include/asm-arm/arch-aaec2000/debug-macro.S b/include/asm-arm/arch-aaec2000/debug-macro.S
new file mode 100644
index 000000000000..e4f1fa539a74
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/debug-macro.S
@@ -0,0 +1,36 @@
+/* linux/include/asm-arm/arch-aaec2000/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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.
+ */
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x80000000 @ physical
+ movne \rx, #io_p2v(0x80000000) @ virtual
+ orr \rx, \rx, #0x00000800
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #0x10]
+ tst \rd, #(1 << 7)
+ beq 1002b
+ .endm
+
+ .macro waituart,rd,rx
+#if 0
+1001: ldr \rd, [\rx, #0x10]
+ tst \rd, #(1 << 5)
+ beq 1001b
+#endif
+ .endm
diff --git a/include/asm-arm/arch-aaec2000/dma.h b/include/asm-arm/arch-aaec2000/dma.h
new file mode 100644
index 000000000000..28c890b4a1d3
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/dma.h
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/dma.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS 0xffffffff
+#define MAX_DMA_CHANNELS 0
+
+#endif
diff --git a/include/asm-arm/arch-aaec2000/entry-macro.S b/include/asm-arm/arch-aaec2000/entry-macro.S
new file mode 100644
index 000000000000..df31313ab07e
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/entry-macro.S
+ *
+ * Low-level IRQ helper for aaec-2000 based platforms
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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.
+ *
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ mov r4, #0xf8000000
+ add r4, r4, #0x00000500
+ mov \base, r4
+ ldr \irqstat, [\base, #0]
+ cmp \irqstat, #0
+ bne 1001f
+ ldr \irqnr, =NR_IRQS+1
+ b 1003f
+1001: mov \irqnr, #0
+1002: ands \tmp, \irqstat, #1
+ mov \irqstat, \irqstat, LSR #1
+ add \irqnr, \irqnr, #1
+ beq 1002b
+ sub \irqnr, \irqnr, #1
+1003:
+ .endm
diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h
new file mode 100644
index 000000000000..4c37219e030e
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/hardware.h
@@ -0,0 +1,49 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/hardware.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+/* The kernel is loaded at physical address 0xf8000000.
+ * We map the IO space a bit after
+ */
+#define PIO_APB_BASE 0x80000000
+#define VIO_APB_BASE 0xf8000000
+#define IO_APB_LENGTH 0x2000
+#define PIO_AHB_BASE 0x80002000
+#define VIO_AHB_BASE 0xf8002000
+#define IO_AHB_LENGTH 0x2000
+
+#define VIO_BASE VIO_APB_BASE
+#define PIO_BASE PIO_APB_BASE
+
+#define io_p2v(x) ( (x) - PIO_BASE + VIO_BASE )
+#define io_v2p(x) ( (x) + PIO_BASE - VIO_BASE )
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+
+/* FIXME: Is it needed to optimize this a la pxa ?? */
+#define __REG(x) (*((volatile u32 *)io_p2v(x)))
+#define __PREG(x) (io_v2p((u32)&(x)))
+
+#else /* __ASSEMBLY__ */
+
+#define __REG(x) io_p2v(x)
+#define __PREG(x) io_v2p(x)
+
+#endif
+
+#include "aaec2000.h"
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
new file mode 100644
index 000000000000..c58a8d10425a
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/io.h
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/io.h
+ *
+ * Copied from asm/arch/sa1100/io.h
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) ((void __iomem *)(a))
+#define __mem_pci(a) (a)
+#define __mem_isa(a) (a)
+
+#endif
diff --git a/include/asm-arm/arch-aaec2000/irqs.h b/include/asm-arm/arch-aaec2000/irqs.h
new file mode 100644
index 000000000000..de252220e806
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/irqs.h
@@ -0,0 +1,46 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/irqs.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+
+#define INT_GPIOF0_FIQ 0 /* External GPIO Port F O Fast Interrupt Input */
+#define INT_BL_FIQ 1 /* Battery Low Fast Interrupt */
+#define INT_WE_FIQ 2 /* Watchdog Expired Fast Interrupt */
+#define INT_MV_FIQ 3 /* Media Changed Interrupt */
+#define INT_SC 4 /* Sound Codec Interrupt */
+#define INT_GPIO1 5 /* GPIO Port F Configurable Int 1 */
+#define INT_GPIO2 6 /* GPIO Port F Configurable Int 2 */
+#define INT_GPIO3 7 /* GPIO Port F Configurable Int 3 */
+#define INT_TMR1_OFL 8 /* Timer 1 Overflow Interrupt */
+#define INT_TMR2_OFL 9 /* Timer 2 Overflow Interrupt */
+#define INT_RTC_CM 10 /* RTC Compare Match Interrupt */
+#define INT_TICK 11 /* 64Hz Tick Interrupt */
+#define INT_UART1 12 /* UART1 Interrupt */
+#define INT_UART2 13 /* UART2 & Modem State Changed Interrupt */
+#define INT_LCD 14 /* LCD Interrupt */
+#define INT_SSI 15 /* SSI End of Transfer Interrupt */
+#define INT_UART3 16 /* UART3 Interrupt */
+#define INT_SCI 17 /* SCI Interrupt */
+#define INT_AAC 18 /* Advanced Audio Codec Interrupt */
+#define INT_MMC 19 /* MMC Interrupt */
+#define INT_USB 20 /* USB Interrupt */
+#define INT_DMA 21 /* DMA Interrupt */
+#define INT_TMR3_UOFL 22 /* Timer 3 Underflow Interrupt */
+#define INT_GPIO4 23 /* GPIO Port F Configurable Int 4 */
+#define INT_GPIO5 24 /* GPIO Port F Configurable Int 4 */
+#define INT_GPIO6 25 /* GPIO Port F Configurable Int 4 */
+#define INT_GPIO7 26 /* GPIO Port F Configurable Int 4 */
+#define INT_BMI 27 /* BMI Interrupt */
+
+#define NR_IRQS (INT_BMI + 1)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
new file mode 100644
index 000000000000..681b6a6171a1
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -0,0 +1,73 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/memory.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/config.h>
+
+#define PHYS_OFFSET (0xf0000000UL)
+
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * The nodes are the followings:
+ *
+ * node 0: 0xf000.0000 - 0xf3ff.ffff
+ * node 1: 0xf400.0000 - 0xf7ff.ffff
+ * node 2: 0xf800.0000 - 0xfbff.ffff
+ * node 3: 0xfc00.0000 - 0xffff.ffff
+ */
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) \
+ (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a page frame number, convert it to a node id.
+ */
+#define PFN_TO_NID(pfn) \
+ (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and return the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
+
+/*
+ * Given a page frame number, find the owning node of the memory
+ * and return the mem_map of that node.
+ */
+#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
+
+/*
+ * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
+ */
+#define LOCAL_MAP_NR(addr) \
+ (((unsigned long)(addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT)
+
+#define NODE_MAX_MEM_SHIFT 26
+#define NODE_MAX_MEM_SIZE (1 << NODE_MAX_MEM_SHIFT)
+
+#else
+
+#define PFN_TO_NID(addr) (0)
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/include/asm-arm/arch-aaec2000/param.h b/include/asm-arm/arch-aaec2000/param.h
new file mode 100644
index 000000000000..139936c2faf2
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/param.h
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/param.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_PARAM_H
+#define __ASM_ARCH_PARAM_H
+
+#endif /* __ASM_ARCH_PARAM_H */
+
diff --git a/include/asm-arm/arch-aaec2000/system.h b/include/asm-arm/arch-aaec2000/system.h
new file mode 100644
index 000000000000..08de97b407a8
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/system.h
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-aaed2000/system.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+ cpu_reset(0);
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/include/asm-arm/arch-aaec2000/timex.h b/include/asm-arm/arch-aaec2000/timex.h
new file mode 100644
index 000000000000..f5708b38fb7f
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/timex.h
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/timex.h
+ *
+ * AAEC-2000 Architecture timex specification
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE 508000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/include/asm-arm/arch-aaec2000/uncompress.h b/include/asm-arm/arch-aaec2000/uncompress.h
new file mode 100644
index 000000000000..fff0c94b75c4
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/uncompress.h
@@ -0,0 +1,47 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/uncompress.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include "hardware.h"
+
+#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
+
+static void putstr( const char *s )
+{
+ unsigned long serial_port;
+ do {
+ serial_port = _UART3_BASE;
+ if (UART(UART_CR) & UART_CR_EN) break;
+ serial_port = _UART1_BASE;
+ if (UART(UART_CR) & UART_CR_EN) break;
+ serial_port = _UART2_BASE;
+ if (UART(UART_CR) & UART_CR_EN) break;
+ return;
+ } while (0);
+
+ for (; *s; s++) {
+ /* wait for space in the UART's transmitter */
+ while ((UART(UART_SR) & UART_SR_TxFF));
+ /* send the character out. */
+ UART(UART_DR) = *s;
+ /* if a LF, also do CR... */
+ if (*s == 10) {
+ while ((UART(UART_SR) & UART_SR_TxFF));
+ UART(UART_DR) = 13;
+ }
+ }
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/include/asm-arm/arch-aaec2000/vmalloc.h b/include/asm-arm/arch-aaec2000/vmalloc.h
new file mode 100644
index 000000000000..ecb991e2e4ff
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/vmalloc.h
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/vmalloc.h
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * 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 __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index 6c56708d0ff0..a1d9e181b10f 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -363,6 +363,7 @@
#define IXP2000_MIN_REV_MASK 0x0000000F
#define IXP2000_PROD_ID_MASK 0xFFFFFFFF
+#define IXP2000_PRODUCT_ID GLOBAL_REG(0x00)
#define IXP2000_MISC_CONTROL GLOBAL_REG(0x04)
#define IXP2000_MSF_CLK_CNTRL GLOBAL_REG(0x08)
#define IXP2000_RESET0 GLOBAL_REG(0x0c)
diff --git a/include/asm-arm/arch-versatile/hardware.h b/include/asm-arm/arch-versatile/hardware.h
index d5fb4a251e7f..41c1bee342ad 100644
--- a/include/asm-arm/arch-versatile/hardware.h
+++ b/include/asm-arm/arch-versatile/hardware.h
@@ -25,19 +25,26 @@
#include <asm/sizes.h>
#include <asm/arch/platform.h>
-// FIXME = PCI settings need to be fixed!!!!!
-
/*
- * Similar to above, but for PCI addresses (memory, IO, Config and the
- * V3 chip itself). WARNING: this has to mirror definitions in platform.h
+ * PCI space virtual addresses
*/
-#define PCI_MEMORY_VADDR 0xe8000000
-#define PCI_CONFIG_VADDR 0xec000000
-#define PCI_V3_VADDR 0xed000000
-#define PCI_IO_VADDR 0xee000000
+#define VERSATILE_PCI_VIRT_BASE 0xe8000000
+#define VERSATILE_PCI_CFG_VIRT_BASE 0xe9000000
+
+#if 0
+#define VERSATILE_PCI_VIRT_MEM_BASE0 0xf4000000
+#define VERSATILE_PCI_VIRT_MEM_BASE1 0xf5000000
+#define VERSATILE_PCI_VIRT_MEM_BASE2 0xf6000000
+
+#define PCIO_BASE VERSATILE_PCI_VIRT_MEM_BASE0
+#define PCIMEM_BASE VERSATILE_PCI_VIRT_MEM_BASE1
+#endif
+
+/* CIK guesswork */
+#define PCIBIOS_MIN_IO 0x44000000
+#define PCIBIOS_MIN_MEM 0x50000000
-#define PCIO_BASE PCI_IO_VADDR
-#define PCIMEM_BASE PCI_MEMORY_VADDR
+#define pcibios_assign_all_busses() 1
/* macro to get at IO space when running virtually */
#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h
index dbb7158788fc..9f895bf61494 100644
--- a/include/asm-arm/arch-versatile/io.h
+++ b/include/asm-arm/arch-versatile/io.h
@@ -20,7 +20,7 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define IO_SPACE_LIMIT 0xffff
+#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(a))
#define __mem_pci(a) (a)
diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h
index a71093e44c58..cbdd9fb96332 100644
--- a/include/asm-arm/arch-versatile/platform.h
+++ b/include/asm-arm/arch-versatile/platform.h
@@ -76,7 +76,7 @@
#define VERSATILE_SYS_NVFLAGSSET_OFFSET 0x38
#define VERSATILE_SYS_NVFLAGSCLR_OFFSET 0x3C
#define VERSATILE_SYS_RESETCTL_OFFSET 0x40
-#define VERSATILE_SYS_PICCTL_OFFSET 0x44
+#define VERSATILE_SYS_PCICTL_OFFSET 0x44
#define VERSATILE_SYS_MCI_OFFSET 0x48
#define VERSATILE_SYS_FLASH_OFFSET 0x4C
#define VERSATILE_SYS_CLCD_OFFSET 0x50
@@ -114,7 +114,7 @@
#define VERSATILE_SYS_NVFLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
#define VERSATILE_SYS_NVFLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
#define VERSATILE_SYS_RESETCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
-#define VERSATILE_SYS_PICCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_PICCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
#define VERSATILE_SYS_MCI (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
#define VERSATILE_SYS_FLASH (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
#define VERSATILE_SYS_CLCD (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
@@ -225,7 +225,20 @@
#define VERSATILE_SSMC_BASE 0x20000000 /* SSMC */
#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */
#define VERSATILE_MBX_BASE 0x40000000 /* MBX */
+
+/* PCI space */
#define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE 0x42000000
+#define VERSATILE_PCI_MEM_BASE0 0x44000000
+#define VERSATILE_PCI_MEM_BASE1 0x50000000
+#define VERSATILE_PCI_MEM_BASE2 0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE 0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE 0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
+
#define VERSATILE_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
#define VERSATILE_LT_BASE 0x80000000 /* Logic Tile expansion */
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 09ffeed507c2..035cdcff43d2 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -16,6 +16,9 @@
#include <asm/mman.h>
#include <asm/glue.h>
+#include <asm/shmparam.h>
+
+#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
/*
* Cache Model
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 658ffa384fda..08a46302d265 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -273,6 +273,33 @@ extern void __iounmap(void __iomem *addr);
#endif
/*
+ * io{read,write}{8,16,32} macros
+ */
+#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; })
+#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
+#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
+
+#define iowrite8(v,p) __raw_writeb(v, p)
+#define iowrite16(v,p) __raw_writew(cpu_to_le16(v), p)
+#define iowrite32(v,p) __raw_writel(cpu_to_le32(v), p)
+
+#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
+#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
+#define ioread32_rep(p,d,c) __raw_readsl(p,d,c)
+
+#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c)
+#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c)
+#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c)
+
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *addr);
+
+struct pci_dev;
+
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen);
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
+
+/*
* can the hardware map this into one segment or not, given no other
* constraints.
*/
diff --git a/include/asm-ppc/ocp.h b/include/asm-ppc/ocp.h
index b98db3cdae83..c726f1845190 100644
--- a/include/asm-ppc/ocp.h
+++ b/include/asm-ppc/ocp.h
@@ -189,7 +189,7 @@ extern void ocp_for_each_device(void(*callback)(struct ocp_device *, void *arg),
/* Sysfs support */
#define OCP_SYSFS_ADDTL(type, format, name, field) \
static ssize_t \
-show_##name##_##field(struct device *dev, char *buf) \
+show_##name##_##field(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct ocp_device *odev = to_ocp_dev(dev); \
type *add = odev->def->additions; \
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 31d3fc25ccbd..09a1451c1159 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -20,7 +20,7 @@
#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
struct atalk_addr {
- __u16 s_net;
+ __be16 s_net;
__u8 s_node;
};
@@ -33,8 +33,8 @@ struct sockaddr_at {
struct atalk_netrange {
__u8 nr_phase;
- __u16 nr_firstnet;
- __u16 nr_lastnet;
+ __be16 nr_firstnet;
+ __be16 nr_lastnet;
};
#ifdef __KERNEL__
@@ -70,8 +70,8 @@ struct atalk_iface {
struct atalk_sock {
/* struct sock has to be the first member of atalk_sock */
struct sock sk;
- unsigned short dest_net;
- unsigned short src_net;
+ __be16 dest_net;
+ __be16 src_net;
unsigned char dest_node;
unsigned char src_node;
unsigned char dest_port;
@@ -95,9 +95,9 @@ struct ddpehdr {
deh_hops:4,
deh_len:10;
#endif
- __u16 deh_sum;
- __u16 deh_dnet;
- __u16 deh_snet;
+ __be16 deh_sum;
+ __be16 deh_dnet;
+ __be16 deh_snet;
__u8 deh_dnode;
__u8 deh_snode;
__u8 deh_dport;
@@ -142,24 +142,24 @@ struct ddpshdr {
/* AppleTalk AARP headers */
struct elapaarp {
- __u16 hw_type;
+ __be16 hw_type;
#define AARP_HW_TYPE_ETHERNET 1
#define AARP_HW_TYPE_TOKENRING 2
- __u16 pa_type;
+ __be16 pa_type;
__u8 hw_len;
__u8 pa_len;
#define AARP_PA_ALEN 4
- __u16 function;
+ __be16 function;
#define AARP_REQUEST 1
#define AARP_REPLY 2
#define AARP_PROBE 3
__u8 hw_src[ETH_ALEN] __attribute__ ((packed));
__u8 pa_src_zero __attribute__ ((packed));
- __u16 pa_src_net __attribute__ ((packed));
+ __be16 pa_src_net __attribute__ ((packed));
__u8 pa_src_node __attribute__ ((packed));
__u8 hw_dst[ETH_ALEN] __attribute__ ((packed));
__u8 pa_dst_zero __attribute__ ((packed));
- __u16 pa_dst_net __attribute__ ((packed));
+ __be16 pa_dst_net __attribute__ ((packed));
__u8 pa_dst_node __attribute__ ((packed));
};
diff --git a/include/linux/device.h b/include/linux/device.h
index df94c0de53f2..7b781a72b293 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -14,6 +14,7 @@
#include <linux/config.h>
#include <linux/ioport.h>
#include <linux/kobject.h>
+#include <linux/klist.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/module.h>
@@ -44,14 +45,15 @@ struct device;
struct device_driver;
struct class;
struct class_device;
-struct class_simple;
struct bus_type {
- char * name;
+ const char * name;
struct subsystem subsys;
struct kset drivers;
struct kset devices;
+ struct klist klist_devices;
+ struct klist klist_drivers;
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
@@ -98,17 +100,18 @@ extern int bus_create_file(struct bus_type *, struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
struct device_driver {
- char * name;
+ const char * name;
struct bus_type * bus;
struct completion unloaded;
struct kobject kobj;
- struct list_head devices;
+ struct klist klist_devices;
+ struct klist_node knode_bus;
- struct module * owner;
+ struct module * owner;
int (*probe) (struct device * dev);
- int (*remove) (struct device * dev);
+ int (*remove) (struct device * dev);
void (*shutdown) (struct device * dev);
int (*suspend) (struct device * dev, pm_message_t state, u32 level);
int (*resume) (struct device * dev, u32 level);
@@ -137,12 +140,16 @@ struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int driver_create_file(struct device_driver *, struct driver_attribute *);
extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
+extern int driver_for_each_device(struct device_driver * drv, struct device * start,
+ void * data, int (*fn)(struct device *, void *));
+
/*
* device classes
*/
struct class {
- char * name;
+ const char * name;
+ struct module * owner;
struct subsystem subsys;
struct list_head children;
@@ -185,6 +192,7 @@ struct class_device {
struct kobject kobj;
struct class * class; /* required */
dev_t devt; /* dev_t, creates the sysfs "dev" */
+ struct class_device_attribute *devt_attr;
struct device * dev; /* not necessary, but nice to have */
void * class_data; /* class-specific data */
@@ -245,26 +253,28 @@ struct class_interface {
extern int class_interface_register(struct class_interface *);
extern void class_interface_unregister(struct class_interface *);
-/* interface for class simple stuff */
-extern struct class_simple *class_simple_create(struct module *owner, char *name);
-extern void class_simple_destroy(struct class_simple *cs);
-extern struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...)
- __attribute__((format(printf,4,5)));
-extern int class_simple_set_hotplug(struct class_simple *,
- int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size));
-extern void class_simple_device_remove(dev_t dev);
+extern struct class *class_create(struct module *owner, char *name);
+extern void class_destroy(struct class *cls);
+extern struct class_device *class_device_create(struct class *cls, dev_t devt,
+ struct device *device, char *fmt, ...)
+ __attribute__((format(printf,4,5)));
+extern void class_device_destroy(struct class *cls, dev_t devt);
struct device {
- struct list_head node; /* node in sibling list */
- struct list_head bus_list; /* node in bus's list */
- struct list_head driver_list;
- struct list_head children;
+ struct klist klist_children;
+ struct klist_node knode_parent; /* node in sibling list */
+ struct klist_node knode_driver;
+ struct klist_node knode_bus;
struct device * parent;
struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
+ struct semaphore sem; /* semaphore to synchronize calls to
+ * its driver.
+ */
+
struct bus_type * bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
@@ -288,12 +298,6 @@ struct device {
void (*release)(struct device * dev);
};
-static inline struct device *
-list_to_dev(struct list_head *node)
-{
- return list_entry(node, struct device, node);
-}
-
static inline void *
dev_get_drvdata (struct device *dev)
{
@@ -321,7 +325,6 @@ extern int device_for_each_child(struct device *, void *,
* Manual binding of a device to driver. See drivers/base/bus.c
* for information on use.
*/
-extern int driver_probe_device(struct device_driver * drv, struct device * dev);
extern void device_bind_driver(struct device * dev);
extern void device_release_driver(struct device * dev);
extern int device_attach(struct device * dev);
@@ -332,8 +335,10 @@ extern void driver_attach(struct device_driver * drv);
struct device_attribute {
struct attribute attr;
- ssize_t (*show)(struct device * dev, char * buf);
- ssize_t (*store)(struct device * dev, const char * buf, size_t count);
+ ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
};
#define DEVICE_ATTR(_name,_mode,_show,_store) \
@@ -360,13 +365,12 @@ extern int (*platform_notify_remove)(struct device * dev);
*/
extern struct device * get_device(struct device * dev);
extern void put_device(struct device * dev);
-extern struct device *device_find(const char *name, struct bus_type *bus);
/* drivers/base/platform.c */
struct platform_device {
- char * name;
+ const char * name;
u32 id;
struct device dev;
u32 num_resources;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0180102dace1..9b8b696d4f15 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1657,6 +1657,52 @@ static inline void simple_transaction_set(struct file *file, size_t n)
ar->size = n;
}
+/*
+ * simple attribute files
+ *
+ * These attributes behave similar to those in sysfs:
+ *
+ * Writing to an attribute immediately sets a value, an open file can be
+ * written to multiple times.
+ *
+ * Reading from an attribute creates a buffer from the value that might get
+ * read with multiple read calls. When the attribute has been read
+ * completely, no further read calls are possible until the file is opened
+ * again.
+ *
+ * All attributes contain a text representation of a numeric value
+ * that are accessed with the get() and set() functions.
+ */
+#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
+static int __fops ## _open(struct inode *inode, struct file *file) \
+{ \
+ __simple_attr_check_format(__fmt, 0ull); \
+ return simple_attr_open(inode, file, __get, __set, __fmt); \
+} \
+static struct file_operations __fops = { \
+ .owner = THIS_MODULE, \
+ .open = __fops ## _open, \
+ .release = simple_attr_close, \
+ .read = simple_attr_read, \
+ .write = simple_attr_write, \
+};
+
+static inline void __attribute__((format(printf, 1, 2)))
+__simple_attr_check_format(const char *fmt, ...)
+{
+ /* don't do anything, just let the compiler check the arguments; */
+}
+
+int simple_attr_open(struct inode *inode, struct file *file,
+ u64 (*get)(void *), void (*set)(void *, u64),
+ const char *fmt);
+int simple_attr_close(struct inode *inode, struct file *file);
+ssize_t simple_attr_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos);
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos);
+
+
#ifdef CONFIG_SECURITY
static inline char *alloc_secdata(void)
{
diff --git a/include/linux/i2c-sysfs.h b/include/linux/i2c-sysfs.h
new file mode 100644
index 000000000000..d7bf6ce11679
--- /dev/null
+++ b/include/linux/i2c-sysfs.h
@@ -0,0 +1,36 @@
+/*
+ * i2c-sysfs.h - i2c chip driver sysfs defines
+ *
+ * Copyright (C) 2005 Yani Ioannou <yani.ioannou@gmail.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _LINUX_I2C_SYSFS_H
+#define _LINUX_I2C_SYSFS_H
+
+struct sensor_device_attribute{
+ struct device_attribute dev_attr;
+ int index;
+};
+#define to_sensor_dev_attr(_dev_attr) \
+ container_of(_dev_attr, struct sensor_device_attribute, dev_attr)
+
+#define SENSOR_DEVICE_ATTR(_name,_mode,_show,_store,_index) \
+struct sensor_device_attribute sensor_dev_attr_##_name = { \
+ .dev_attr = __ATTR(_name,_mode,_show,_store), \
+ .index = _index, \
+}
+
+#endif /* _LINUX_I2C_SYSFS_H */
diff --git a/include/linux/input.h b/include/linux/input.h
index 72731d7d189e..9d9598ed760d 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1015,7 +1015,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
dev->absbit[LONG(axis)] |= BIT(axis);
}
-extern struct class_simple *input_class;
+extern struct class *input_class;
#endif
#endif
diff --git a/include/linux/klist.h b/include/linux/klist.h
new file mode 100644
index 000000000000..eebf5e5696ec
--- /dev/null
+++ b/include/linux/klist.h
@@ -0,0 +1,55 @@
+/*
+ * klist.h - Some generic list helpers, extending struct list_head a bit.
+ *
+ * Implementations are found in lib/klist.c
+ *
+ *
+ * Copyright (C) 2005 Patrick Mochel
+ *
+ * This file is rleased under the GPL v2.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+
+
+struct klist {
+ spinlock_t k_lock;
+ struct list_head k_list;
+};
+
+
+extern void klist_init(struct klist * k);
+
+
+struct klist_node {
+ struct klist * n_klist;
+ struct list_head n_node;
+ struct kref n_ref;
+ struct completion n_removed;
+};
+
+extern void klist_add_tail(struct klist * k, struct klist_node * n);
+extern void klist_add_head(struct klist * k, struct klist_node * n);
+
+extern void klist_del(struct klist_node * n);
+extern void klist_remove(struct klist_node * n);
+
+extern int klist_node_attached(struct klist_node * n);
+
+
+struct klist_iter {
+ struct klist * i_klist;
+ struct list_head * i_head;
+ struct klist_node * i_cur;
+};
+
+
+extern void klist_iter_init(struct klist * k, struct klist_iter * i);
+extern void klist_iter_init_node(struct klist * k, struct klist_iter * i,
+ struct klist_node * n);
+extern void klist_iter_exit(struct klist_iter * i);
+extern struct klist_node * klist_next(struct klist_iter * i);
+
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 765d660d3bea..3b22304f12fd 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -33,7 +33,7 @@
extern u64 hotplug_seqnum;
struct kobject {
- char * k_name;
+ const char * k_name;
char name[KOBJ_NAME_LEN];
struct kref kref;
struct list_head entry;
@@ -46,7 +46,7 @@ struct kobject {
extern int kobject_set_name(struct kobject *, const char *, ...)
__attribute__((format(printf,2,3)));
-static inline char * kobject_name(struct kobject * kobj)
+static inline const char * kobject_name(const struct kobject * kobj)
{
return kobj->k_name;
}
@@ -57,7 +57,7 @@ extern void kobject_cleanup(struct kobject *);
extern int kobject_add(struct kobject *);
extern void kobject_del(struct kobject *);
-extern int kobject_rename(struct kobject *, char *new_name);
+extern int kobject_rename(struct kobject *, const char *new_name);
extern int kobject_register(struct kobject *);
extern void kobject_unregister(struct kobject *);
@@ -94,7 +94,7 @@ struct kobj_type {
*/
struct kset_hotplug_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
- char *(*name)(struct kset *kset, struct kobject *kobj);
+ const char *(*name)(struct kset *kset, struct kobject *kobj);
int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size);
};
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index 9e5750079e09..3ebc36afae1a 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -75,12 +75,6 @@ enum nf_ip_hook_priorities {
#define SO_ORIGINAL_DST 80
#ifdef __KERNEL__
-#ifdef CONFIG_NETFILTER_DEBUG
-void nf_debug_ip_local_deliver(struct sk_buff *skb);
-void nf_debug_ip_loopback_xmit(struct sk_buff *newskb);
-void nf_debug_ip_finish_output2(struct sk_buff *skb);
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
extern int ip_route_me_harder(struct sk_buff **pskb);
/* Call this before modifying an existing IP packet: ensures it is
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h
index d84be02cb4fc..694aec9b4784 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_core.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h
@@ -1,7 +1,6 @@
#ifndef _IP_CONNTRACK_CORE_H
#define _IP_CONNTRACK_CORE_H
#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
/* This header is used to share core functionality between the
standalone connection tracking module, and the compatibility layer's use
@@ -47,6 +46,6 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb)
extern struct list_head *ip_conntrack_hash;
extern struct list_head ip_conntrack_expect_list;
-DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
+extern rwlock_t ip_conntrack_lock;
#endif /* _IP_CONNTRACK_CORE_H */
diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index 2b72b86176f0..e201ec6e9905 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -50,10 +50,9 @@ struct ip_nat_multi_range_compat
#ifdef __KERNEL__
#include <linux/list.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
/* Protects NAT hash tables, and NAT-private part of conntracks. */
-DECLARE_RWLOCK_EXTERN(ip_nat_lock);
+extern rwlock_t ip_nat_lock;
/* The structure embedded in the conntrack structure. */
struct ip_nat_info
diff --git a/include/linux/netfilter_ipv4/listhelp.h b/include/linux/netfilter_ipv4/listhelp.h
index f2ae7c5e57bb..360429f48737 100644
--- a/include/linux/netfilter_ipv4/listhelp.h
+++ b/include/linux/netfilter_ipv4/listhelp.h
@@ -2,7 +2,6 @@
#define _LISTHELP_H
#include <linux/config.h>
#include <linux/list.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
/* Header to do more comprehensive job than linux/list.h; assume list
is first entry in structure. */
diff --git a/include/linux/netfilter_ipv4/lockhelp.h b/include/linux/netfilter_ipv4/lockhelp.h
deleted file mode 100644
index a3288633ab46..000000000000
--- a/include/linux/netfilter_ipv4/lockhelp.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef _LOCKHELP_H
-#define _LOCKHELP_H
-#include <linux/config.h>
-
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-
-/* Header to do help in lock debugging. */
-
-#ifdef CONFIG_NETFILTER_DEBUG
-struct spinlock_debug
-{
- spinlock_t l;
- atomic_t locked_by;
-};
-
-struct rwlock_debug
-{
- rwlock_t l;
- long read_locked_map;
- long write_locked_map;
-};
-
-#define DECLARE_LOCK(l) \
-struct spinlock_debug l = { SPIN_LOCK_UNLOCKED, ATOMIC_INIT(-1) }
-#define DECLARE_LOCK_EXTERN(l) \
-extern struct spinlock_debug l
-#define DECLARE_RWLOCK(l) \
-struct rwlock_debug l = { RW_LOCK_UNLOCKED, 0, 0 }
-#define DECLARE_RWLOCK_EXTERN(l) \
-extern struct rwlock_debug l
-
-#define MUST_BE_LOCKED(l) \
-do { if (atomic_read(&(l)->locked_by) != smp_processor_id()) \
- printk("ASSERT %s:%u %s unlocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define MUST_BE_UNLOCKED(l) \
-do { if (atomic_read(&(l)->locked_by) == smp_processor_id()) \
- printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-/* Write locked OK as well. */
-#define MUST_BE_READ_LOCKED(l) \
-do { if (!((l)->read_locked_map & (1UL << smp_processor_id())) \
- && !((l)->write_locked_map & (1UL << smp_processor_id()))) \
- printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define MUST_BE_WRITE_LOCKED(l) \
-do { if (!((l)->write_locked_map & (1UL << smp_processor_id()))) \
- printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define MUST_BE_READ_WRITE_UNLOCKED(l) \
-do { if ((l)->read_locked_map & (1UL << smp_processor_id())) \
- printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l); \
- else if ((l)->write_locked_map & (1UL << smp_processor_id())) \
- printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define LOCK_BH(lk) \
-do { \
- MUST_BE_UNLOCKED(lk); \
- spin_lock_bh(&(lk)->l); \
- atomic_set(&(lk)->locked_by, smp_processor_id()); \
-} while(0)
-
-#define UNLOCK_BH(lk) \
-do { \
- MUST_BE_LOCKED(lk); \
- atomic_set(&(lk)->locked_by, -1); \
- spin_unlock_bh(&(lk)->l); \
-} while(0)
-
-#define READ_LOCK(lk) \
-do { \
- MUST_BE_READ_WRITE_UNLOCKED(lk); \
- read_lock_bh(&(lk)->l); \
- set_bit(smp_processor_id(), &(lk)->read_locked_map); \
-} while(0)
-
-#define WRITE_LOCK(lk) \
-do { \
- MUST_BE_READ_WRITE_UNLOCKED(lk); \
- write_lock_bh(&(lk)->l); \
- set_bit(smp_processor_id(), &(lk)->write_locked_map); \
-} while(0)
-
-#define READ_UNLOCK(lk) \
-do { \
- if (!((lk)->read_locked_map & (1UL << smp_processor_id()))) \
- printk("ASSERT: %s:%u %s not readlocked\n", \
- __FILE__, __LINE__, #lk); \
- clear_bit(smp_processor_id(), &(lk)->read_locked_map); \
- read_unlock_bh(&(lk)->l); \
-} while(0)
-
-#define WRITE_UNLOCK(lk) \
-do { \
- MUST_BE_WRITE_LOCKED(lk); \
- clear_bit(smp_processor_id(), &(lk)->write_locked_map); \
- write_unlock_bh(&(lk)->l); \
-} while(0)
-
-#else
-#define DECLARE_LOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
-#define DECLARE_LOCK_EXTERN(l) extern spinlock_t l
-#define DECLARE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED
-#define DECLARE_RWLOCK_EXTERN(l) extern rwlock_t l
-
-#define MUST_BE_LOCKED(l)
-#define MUST_BE_UNLOCKED(l)
-#define MUST_BE_READ_LOCKED(l)
-#define MUST_BE_WRITE_LOCKED(l)
-#define MUST_BE_READ_WRITE_UNLOCKED(l)
-
-#define LOCK_BH(l) spin_lock_bh(l)
-#define UNLOCK_BH(l) spin_unlock_bh(l)
-
-#define READ_LOCK(l) read_lock_bh(l)
-#define WRITE_LOCK(l) write_lock_bh(l)
-#define READ_UNLOCK(l) read_unlock_bh(l)
-#define WRITE_UNLOCK(l) write_unlock_bh(l)
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
-#endif /* _LOCKHELP_H */
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index e38407a23d04..3029cad63a01 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -14,6 +14,7 @@
#define NETLINK_SELINUX 7 /* SELinux event notifications */
#define NETLINK_ARPD 8
#define NETLINK_AUDIT 9 /* auditing */
+#define NETLINK_FIB_LOOKUP 10
#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
@@ -146,7 +147,7 @@ struct netlink_callback
int (*dump)(struct sk_buff * skb, struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
int family;
- long args[4];
+ long args[5];
};
struct netlink_notify
diff --git a/include/linux/node.h b/include/linux/node.h
index 6e0a697e594e..254dc3de650b 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -27,6 +27,7 @@ struct node {
};
extern int register_node(struct node *, int, struct node *);
+extern void unregister_node(struct node *node);
#define to_node(sys_device) container_of(sys_device, struct node, sysdev)
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index e6b519220245..724066778aff 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -245,6 +245,7 @@ struct sadb_x_nat_t_port {
/* Security Association flags */
#define SADB_SAFLAGS_PFS 1
+#define SADB_SAFLAGS_NOPMTUDISC 0x20000000
#define SADB_SAFLAGS_DECAP_DSCP 0x40000000
#define SADB_SAFLAGS_NOECN 0x80000000
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index cc04f5cd2286..d7c839a21842 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -193,7 +193,6 @@ struct skb_shared_info {
* @nfcache: Cache info
* @nfct: Associated connection, if any
* @nfctinfo: Relationship of this skb to the connection
- * @nf_debug: Netfilter debugging
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
* @private: Data which is private to the HIPPI implementation
* @tc_index: Traffic control index
@@ -264,9 +263,6 @@ struct sk_buff {
__u32 nfcache;
__u32 nfctinfo;
struct nf_conntrack *nfct;
-#ifdef CONFIG_NETFILTER_DEBUG
- unsigned int nf_debug;
-#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
@@ -1219,15 +1215,6 @@ static inline void nf_reset(struct sk_buff *skb)
{
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-}
-static inline void nf_reset_debug(struct sk_buff *skb)
-{
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
}
#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 38b58b30814a..392da5a6dacb 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -16,13 +16,13 @@ struct kobject;
struct module;
struct attribute {
- char * name;
+ const char * name;
struct module * owner;
mode_t mode;
};
struct attribute_group {
- char * name;
+ const char * name;
struct attribute ** attrs;
};
@@ -73,6 +73,7 @@ struct sysfs_dirent {
int s_type;
umode_t s_mode;
struct dentry * s_dentry;
+ struct iattr * s_iattr;
};
#define SYSFS_ROOT 0x0001
@@ -105,11 +106,11 @@ sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode);
extern void
sysfs_remove_file(struct kobject *, const struct attribute *);
-extern int
-sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name);
+extern int
+sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name);
extern void
-sysfs_remove_link(struct kobject *, char * name);
+sysfs_remove_link(struct kobject *, const char * name);
int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
@@ -153,12 +154,12 @@ static inline void sysfs_remove_file(struct kobject * k, const struct attribute
;
}
-static inline int sysfs_create_link(struct kobject * k, struct kobject * t, char * n)
+static inline int sysfs_create_link(struct kobject * k, struct kobject * t, const char * n)
{
return 0;
}
-static inline void sysfs_remove_link(struct kobject * k, char * name)
+static inline void sysfs_remove_link(struct kobject * k, const char * name)
{
;
}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 2d1ac5058534..3d508bf08402 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -287,15 +287,14 @@ struct usb_bus {
struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */
- struct class_device class_dev; /* class device for this bus */
+ struct class_device *class_dev; /* class device for this bus */
+ struct kref kref; /* handles reference counting this bus */
void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */
#endif
};
-#define to_usb_bus(d) container_of(d, struct usb_bus, class_dev)
-
/* -------------------------------------------------------------------------- */
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index d68391a9b9f3..f0d423300d84 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -196,6 +196,7 @@ struct xfrm_usersa_info {
__u8 flags;
#define XFRM_STATE_NOECN 1
#define XFRM_STATE_DECAP_DSCP 2
+#define XFRM_STATE_NOPMTUDISC 4
};
struct xfrm_usersa_id {
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 9e6368a54547..828a3a93dda1 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -220,7 +220,7 @@ static __inline__ void ax25_cb_put(ax25_cb *ax25)
}
}
-static inline unsigned short ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
+static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
{
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 319904518194..a66e9de16a6c 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -167,14 +167,17 @@ extern int fib6_walk_continue(struct fib6_walker_t *w);
extern int fib6_add(struct fib6_node *root,
struct rt6_info *rt,
struct nlmsghdr *nlh,
- void *rtattr);
+ void *rtattr,
+ struct netlink_skb_parms *req);
extern int fib6_del(struct rt6_info *rt,
struct nlmsghdr *nlh,
- void *rtattr);
+ void *rtattr,
+ struct netlink_skb_parms *req);
extern void inet6_rt_notify(int event, struct rt6_info *rt,
- struct nlmsghdr *nlh);
+ struct nlmsghdr *nlh,
+ struct netlink_skb_parms *req);
extern void fib6_run_gc(unsigned long dummy);
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index d5d1dd10cdb8..f920706d526b 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -41,13 +41,16 @@ extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
extern int ip6_route_add(struct in6_rtmsg *rtmsg,
struct nlmsghdr *,
- void *rtattr);
+ void *rtattr,
+ struct netlink_skb_parms *req);
extern int ip6_ins_rt(struct rt6_info *,
struct nlmsghdr *,
- void *rtattr);
+ void *rtattr,
+ struct netlink_skb_parms *req);
extern int ip6_del_rt(struct rt6_info *,
struct nlmsghdr *,
- void *rtattr);
+ void *rtattr,
+ struct netlink_skb_parms *req);
extern int ip6_rt_addr_add(struct in6_addr *addr,
struct net_device *dev,
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e5a5f6b62f88..a4208a336ac0 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -109,6 +109,20 @@ struct fib_result {
#endif
};
+struct fib_result_nl {
+ u32 fl_addr; /* To be looked up*/
+ u32 fl_fwmark;
+ unsigned char fl_tos;
+ unsigned char fl_scope;
+ unsigned char tb_id_in;
+
+ unsigned char tb_id; /* Results */
+ unsigned char prefixlen;
+ unsigned char nh_sel;
+ unsigned char type;
+ unsigned char scope;
+ int err;
+};
#ifdef CONFIG_IP_ROUTE_MULTIPATH
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index ebc5282e6d58..dc107ffad483 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -65,9 +65,11 @@ typedef enum {
SCTP_CMD_TIMER_START, /* Start a timer. */
SCTP_CMD_TIMER_RESTART, /* Restart a timer. */
SCTP_CMD_TIMER_STOP, /* Stop a timer. */
- SCTP_CMD_COUNTER_RESET, /* Reset a counter. */
- SCTP_CMD_COUNTER_INC, /* Increment a counter. */
+ SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */
+ SCTP_CMD_INIT_COUNTER_RESET, /* Reset init counter. */
+ SCTP_CMD_INIT_COUNTER_INC, /* Increment init counter. */
SCTP_CMD_INIT_RESTART, /* High level, do init timer work. */
+ SCTP_CMD_COOKIEECHO_RESTART, /* High level, do cookie-echo timer work. */
SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */
SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */
SCTP_CMD_STRIKE, /* Mark a strike against a transport. */
@@ -118,7 +120,6 @@ typedef union {
int error;
sctp_state_t state;
sctp_event_timeout_t to;
- sctp_counter_t counter;
void *ptr;
struct sctp_chunk *chunk;
struct sctp_association *asoc;
@@ -165,7 +166,6 @@ SCTP_ARG_CONSTRUCTOR(U16, __u16, u16)
SCTP_ARG_CONSTRUCTOR(U8, __u8, u8)
SCTP_ARG_CONSTRUCTOR(ERROR, int, error)
SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state)
-SCTP_ARG_CONSTRUCTOR(COUNTER, sctp_counter_t, counter)
SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to)
SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr)
SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk)
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 2b76c0f4babc..4868c7f7749d 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -263,13 +263,6 @@ enum { SCTP_MIN_PMTU = 576 };
enum { SCTP_MAX_DUP_TSNS = 16 };
enum { SCTP_MAX_GABS = 16 };
-typedef enum {
- SCTP_COUNTER_INIT_ERROR,
-} sctp_counter_t;
-
-/* How many counters does an association need? */
-#define SCTP_NUMBER_COUNTERS 5
-
/* Here we define the default timers. */
/* cookie timer def = ? seconds */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 960abfa48d68..ef2738159ab3 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -223,6 +223,22 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics);
extern int sctp_debug_flag;
#define SCTP_DEBUG_PRINTK(whatever...) \
((void) (sctp_debug_flag && printk(KERN_DEBUG whatever)))
+#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \
+ if (sctp_debug_flag) { \
+ if (saddr->sa.sa_family == AF_INET6) { \
+ printk(KERN_DEBUG \
+ lead "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" trail, \
+ leadparm, \
+ NIP6(saddr->v6.sin6_addr), \
+ otherparms); \
+ } else { \
+ printk(KERN_DEBUG \
+ lead "%u.%u.%u.%u" trail, \
+ leadparm, \
+ NIPQUAD(saddr->v4.sin_addr.s_addr), \
+ otherparms); \
+ } \
+ }
#define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; }
#define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; }
@@ -236,6 +252,7 @@ extern int sctp_debug_flag;
#else /* SCTP_DEBUG */
#define SCTP_DEBUG_PRINTK(whatever...)
+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
#define SCTP_ENABLE_DEBUG
#define SCTP_DISABLE_DEBUG
#define SCTP_ASSERT(expr, str, func)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index f4fcee104707..a53e08a45e32 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -116,7 +116,8 @@ sctp_state_fn_t sctp_sf_eat_data_fast_4_4;
sctp_state_fn_t sctp_sf_eat_sack_6_2;
sctp_state_fn_t sctp_sf_tabort_8_4_8;
sctp_state_fn_t sctp_sf_operr_notify;
-sctp_state_fn_t sctp_sf_t1_timer_expire;
+sctp_state_fn_t sctp_sf_t1_init_timer_expire;
+sctp_state_fn_t sctp_sf_t1_cookie_timer_expire;
sctp_state_fn_t sctp_sf_t2_timer_expire;
sctp_state_fn_t sctp_sf_t4_timer_expire;
sctp_state_fn_t sctp_sf_t5_timer_expire;
@@ -258,7 +259,10 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
-void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error);
+sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
+ __u16 error,
+ const struct sctp_association *asoc,
+ struct sctp_transport *transport);
/* Prototypes for statetable processing. */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 6c24d9cd3d66..dfad4d3c581c 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -867,10 +867,13 @@ struct sctp_transport {
*/
unsigned long last_time_ecne_reduced;
- /* active : The current active state of this destination,
- * : i.e. DOWN, UP, etc.
+ /* The number of times INIT has been sent on this transport. */
+ int init_sent_count;
+
+ /* state : The current state of this destination,
+ * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN.
*/
- int active;
+ int state;
/* hb_allowed : The current heartbeat state of this destination,
* : i.e. ALLOW-HB, NO-HEARTBEAT, etc.
@@ -1222,9 +1225,6 @@ struct sctp_endpoint {
/* sendbuf acct. policy. */
__u32 sndbuf_policy;
-
- /* Name for debugging output... */
- char *debug_name;
};
/* Recover the outter endpoint structure. */
@@ -1314,11 +1314,23 @@ struct sctp_association {
* : association. Normally this information is
* : hashed or keyed for quick lookup and access
* : of the TCB.
+ * : The list is also initialized with the list
+ * : of addresses passed with the sctp_connectx()
+ * : call.
*
* It is a list of SCTP_transport's.
*/
struct list_head transport_addr_list;
+ /* transport_count
+ *
+ * Peer : A count of the number of peer addresses
+ * Transport : in the Peer Transport Address List.
+ * Address :
+ * Count :
+ */
+ __u16 transport_count;
+
/* port
* The transport layer port number.
*/
@@ -1486,6 +1498,9 @@ struct sctp_association {
/* Transport to which SHUTDOWN chunk was last sent. */
struct sctp_transport *shutdown_last_sent_to;
+ /* Transport to which INIT chunk was last sent. */
+ struct sctp_transport *init_last_sent_to;
+
/* Next TSN : The next TSN number to be assigned to a new
* : DATA chunk. This is sent in the INIT or INIT
* : ACK chunk to the peer and incremented each
@@ -1549,8 +1564,11 @@ struct sctp_association {
/* The message size at which SCTP fragmentation will occur. */
__u32 frag_point;
- /* Currently only one counter is used to count INIT errors. */
- int counters[SCTP_NUMBER_COUNTERS];
+ /* Counter used to count INIT errors. */
+ int init_err_counter;
+
+ /* Count the number of INIT cycles (for doubling timeout). */
+ int init_cycle;
/* Default send parameters. */
__u16 default_stream;
@@ -1708,6 +1726,8 @@ void sctp_association_free(struct sctp_association *);
void sctp_association_put(struct sctp_association *);
void sctp_association_hold(struct sctp_association *);
+struct sctp_transport *sctp_assoc_choose_init_transport(
+ struct sctp_association *);
struct sctp_transport *sctp_assoc_choose_shutdown_transport(
struct sctp_association *);
void sctp_assoc_update_retran_path(struct sctp_association *);
@@ -1717,9 +1737,12 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
const union sctp_addr *laddr);
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
const union sctp_addr *address,
- const int gfp);
+ const int gfp,
+ const int peer_state);
void sctp_assoc_del_peer(struct sctp_association *asoc,
const union sctp_addr *addr);
+void sctp_assoc_rm_peer(struct sctp_association *asoc,
+ struct sctp_transport *peer);
void sctp_assoc_control_transport(struct sctp_association *,
struct sctp_transport *,
sctp_transport_cmd_t, sctp_sn_error_t);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 2758e8ce4f25..f6328aeddcce 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -111,6 +111,8 @@ enum sctp_optname {
#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM
SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */
#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
+ SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
+#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX
};
/*
@@ -527,6 +529,7 @@ struct sctp_paddrinfo {
enum sctp_spinfo_state {
SCTP_INACTIVE,
SCTP_ACTIVE,
+ SCTP_UNKNOWN = 0xffff /* Value used for transport state unknown */
};
/*
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0e65e02b7a1d..029522a4ceda 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -204,6 +204,7 @@ struct xfrm_state_afinfo {
rwlock_t lock;
struct list_head *state_bydst;
struct list_head *state_byspi;
+ int (*init_flags)(struct xfrm_state *x);
void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
xfrm_address_t *daddr, xfrm_address_t *saddr);
@@ -225,7 +226,7 @@ struct xfrm_type
struct module *owner;
__u8 proto;
- int (*init_state)(struct xfrm_state *x, void *args);
+ int (*init_state)(struct xfrm_state *x);
void (*destructor)(struct xfrm_state *);
int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
@@ -839,6 +840,7 @@ extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
+extern int xfrm_init_state(struct xfrm_state *x);
extern int xfrm4_rcv(struct sk_buff *skb);
extern int xfrm4_output(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
diff --git a/kernel/params.c b/kernel/params.c
index 5513844bec13..d586c35ef8fc 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -629,7 +629,7 @@ static ssize_t module_attr_show(struct kobject *kobj,
mk = to_module_kobject(kobj);
if (!attribute->show)
- return -EPERM;
+ return -EIO;
if (!try_module_get(mk->mod))
return -ENODEV;
@@ -653,7 +653,7 @@ static ssize_t module_attr_store(struct kobject *kobj,
mk = to_module_kobject(kobj);
if (!attribute->store)
- return -EPERM;
+ return -EIO;
if (!try_module_get(mk->mod))
return -ENODEV;
diff --git a/lib/Makefile b/lib/Makefile
index 7c70db79c0e0..9eccea9429a7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -4,9 +4,10 @@
lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
- kobject.o kref.o idr.o div64.o int_sqrt.o \
- bitmap.o extable.o kobject_uevent.o prio_tree.o sha1.o \
- halfmd4.o
+ idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
+ sha1.o halfmd4.o
+
+lib-y += kobject.o kref.o kobject_uevent.o klist.o
obj-y += sort.o parser.o
diff --git a/lib/klist.c b/lib/klist.c
new file mode 100644
index 000000000000..738ab810160a
--- /dev/null
+++ b/lib/klist.c
@@ -0,0 +1,265 @@
+/*
+ * klist.c - Routines for manipulating klists.
+ *
+ *
+ * This klist interface provides a couple of structures that wrap around
+ * struct list_head to provide explicit list "head" (struct klist) and
+ * list "node" (struct klist_node) objects. For struct klist, a spinlock
+ * is included that protects access to the actual list itself. struct
+ * klist_node provides a pointer to the klist that owns it and a kref
+ * reference count that indicates the number of current users of that node
+ * in the list.
+ *
+ * The entire point is to provide an interface for iterating over a list
+ * that is safe and allows for modification of the list during the
+ * iteration (e.g. insertion and removal), including modification of the
+ * current node on the list.
+ *
+ * It works using a 3rd object type - struct klist_iter - that is declared
+ * and initialized before an iteration. klist_next() is used to acquire the
+ * next element in the list. It returns NULL if there are no more items.
+ * Internally, that routine takes the klist's lock, decrements the reference
+ * count of the previous klist_node and increments the count of the next
+ * klist_node. It then drops the lock and returns.
+ *
+ * There are primitives for adding and removing nodes to/from a klist.
+ * When deleting, klist_del() will simply decrement the reference count.
+ * Only when the count goes to 0 is the node removed from the list.
+ * klist_remove() will try to delete the node from the list and block
+ * until it is actually removed. This is useful for objects (like devices)
+ * that have been removed from the system and must be freed (but must wait
+ * until all accessors have finished).
+ *
+ * Copyright (C) 2005 Patrick Mochel
+ *
+ * This file is released under the GPL v2.
+ */
+
+#include <linux/klist.h>
+#include <linux/module.h>
+
+
+/**
+ * klist_init - Initialize a klist structure.
+ * @k: The klist we're initializing.
+ */
+
+void klist_init(struct klist * k)
+{
+ INIT_LIST_HEAD(&k->k_list);
+ spin_lock_init(&k->k_lock);
+}
+
+EXPORT_SYMBOL_GPL(klist_init);
+
+
+static void add_head(struct klist * k, struct klist_node * n)
+{
+ spin_lock(&k->k_lock);
+ list_add(&n->n_node, &k->k_list);
+ spin_unlock(&k->k_lock);
+}
+
+static void add_tail(struct klist * k, struct klist_node * n)
+{
+ spin_lock(&k->k_lock);
+ list_add_tail(&n->n_node, &k->k_list);
+ spin_unlock(&k->k_lock);
+}
+
+
+static void klist_node_init(struct klist * k, struct klist_node * n)
+{
+ INIT_LIST_HEAD(&n->n_node);
+ init_completion(&n->n_removed);
+ kref_init(&n->n_ref);
+ n->n_klist = k;
+}
+
+
+/**
+ * klist_add_head - Initialize a klist_node and add it to front.
+ * @k: klist it's going on.
+ * @n: node we're adding.
+ */
+
+void klist_add_head(struct klist * k, struct klist_node * n)
+{
+ klist_node_init(k, n);
+ add_head(k, n);
+}
+
+EXPORT_SYMBOL_GPL(klist_add_head);
+
+
+/**
+ * klist_add_tail - Initialize a klist_node and add it to back.
+ * @k: klist it's going on.
+ * @n: node we're adding.
+ */
+
+void klist_add_tail(struct klist * k, struct klist_node * n)
+{
+ klist_node_init(k, n);
+ add_tail(k, n);
+}
+
+EXPORT_SYMBOL_GPL(klist_add_tail);
+
+
+static void klist_release(struct kref * kref)
+{
+ struct klist_node * n = container_of(kref, struct klist_node, n_ref);
+ list_del(&n->n_node);
+ complete(&n->n_removed);
+ n->n_klist = NULL;
+}
+
+static int klist_dec_and_del(struct klist_node * n)
+{
+ return kref_put(&n->n_ref, klist_release);
+}
+
+
+/**
+ * klist_del - Decrement the reference count of node and try to remove.
+ * @n: node we're deleting.
+ */
+
+void klist_del(struct klist_node * n)
+{
+ struct klist * k = n->n_klist;
+
+ spin_lock(&k->k_lock);
+ klist_dec_and_del(n);
+ spin_unlock(&k->k_lock);
+}
+
+EXPORT_SYMBOL_GPL(klist_del);
+
+
+/**
+ * klist_remove - Decrement the refcount of node and wait for it to go away.
+ * @n: node we're removing.
+ */
+
+void klist_remove(struct klist_node * n)
+{
+ struct klist * k = n->n_klist;
+ spin_lock(&k->k_lock);
+ klist_dec_and_del(n);
+ spin_unlock(&k->k_lock);
+ wait_for_completion(&n->n_removed);
+}
+
+EXPORT_SYMBOL_GPL(klist_remove);
+
+
+/**
+ * klist_node_attached - Say whether a node is bound to a list or not.
+ * @n: Node that we're testing.
+ */
+
+int klist_node_attached(struct klist_node * n)
+{
+ return (n->n_klist != NULL);
+}
+
+EXPORT_SYMBOL_GPL(klist_node_attached);
+
+
+/**
+ * klist_iter_init_node - Initialize a klist_iter structure.
+ * @k: klist we're iterating.
+ * @i: klist_iter we're filling.
+ * @n: node to start with.
+ *
+ * Similar to klist_iter_init(), but starts the action off with @n,
+ * instead of with the list head.
+ */
+
+void klist_iter_init_node(struct klist * k, struct klist_iter * i, struct klist_node * n)
+{
+ i->i_klist = k;
+ i->i_head = &k->k_list;
+ i->i_cur = n;
+}
+
+EXPORT_SYMBOL_GPL(klist_iter_init_node);
+
+
+/**
+ * klist_iter_init - Iniitalize a klist_iter structure.
+ * @k: klist we're iterating.
+ * @i: klist_iter structure we're filling.
+ *
+ * Similar to klist_iter_init_node(), but start with the list head.
+ */
+
+void klist_iter_init(struct klist * k, struct klist_iter * i)
+{
+ klist_iter_init_node(k, i, NULL);
+}
+
+EXPORT_SYMBOL_GPL(klist_iter_init);
+
+
+/**
+ * klist_iter_exit - Finish a list iteration.
+ * @i: Iterator structure.
+ *
+ * Must be called when done iterating over list, as it decrements the
+ * refcount of the current node. Necessary in case iteration exited before
+ * the end of the list was reached, and always good form.
+ */
+
+void klist_iter_exit(struct klist_iter * i)
+{
+ if (i->i_cur) {
+ klist_del(i->i_cur);
+ i->i_cur = NULL;
+ }
+}
+
+EXPORT_SYMBOL_GPL(klist_iter_exit);
+
+
+static struct klist_node * to_klist_node(struct list_head * n)
+{
+ return container_of(n, struct klist_node, n_node);
+}
+
+
+/**
+ * klist_next - Ante up next node in list.
+ * @i: Iterator structure.
+ *
+ * First grab list lock. Decrement the reference count of the previous
+ * node, if there was one. Grab the next node, increment its reference
+ * count, drop the lock, and return that next node.
+ */
+
+struct klist_node * klist_next(struct klist_iter * i)
+{
+ struct list_head * next;
+ struct klist_node * knode = NULL;
+
+ spin_lock(&i->i_klist->k_lock);
+ if (i->i_cur) {
+ next = i->i_cur->n_node.next;
+ klist_dec_and_del(i->i_cur);
+ } else
+ next = i->i_head->next;
+
+ if (next != i->i_head) {
+ knode = to_klist_node(next);
+ kref_get(&knode->n_ref);
+ }
+ i->i_cur = knode;
+ spin_unlock(&i->i_klist->k_lock);
+ return knode;
+}
+
+EXPORT_SYMBOL_GPL(klist_next);
+
+
diff --git a/lib/kobject.c b/lib/kobject.c
index 94048826624c..dd0917dd9fa9 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -279,7 +279,7 @@ EXPORT_SYMBOL(kobject_set_name);
* @new_name: object's new name
*/
-int kobject_rename(struct kobject * kobj, char *new_name)
+int kobject_rename(struct kobject * kobj, const char *new_name)
{
int error = 0;
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 2a4e7671eaf4..8e49d21057e4 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -197,7 +197,7 @@ void kobject_hotplug(struct kobject *kobj, enum kobject_action action)
int i = 0;
int retval;
char *kobj_path = NULL;
- char *name = NULL;
+ const char *name = NULL;
char *action_string;
u64 seq;
struct kobject *top_kobj = kobj;
@@ -246,10 +246,10 @@ void kobject_hotplug(struct kobject *kobj, enum kobject_action action)
if (hotplug_ops->name)
name = hotplug_ops->name(kset, kobj);
if (name == NULL)
- name = kset->kobj.name;
+ name = kobject_name(&kset->kobj);
argv [0] = hotplug_path;
- argv [1] = name;
+ argv [1] = (char *)name; /* won't be changed but 'const' has to go */
argv [2] = NULL;
/* minimal command environment */
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index 54640c01b50c..10d040461021 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -565,7 +565,7 @@ int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb,
* numbers we just happen to need. Now put the
* length in the lower two.
*/
- *((__u16 *)skb->data) = htons(skb->len);
+ *((__be16 *)skb->data) = htons(skb->len);
ft = 1;
}
/*
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 876dbac71060..192b529f86a4 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -401,7 +401,7 @@ out_err:
}
/* Find a match for a specific network:node pair */
-static struct atalk_iface *atalk_find_interface(int net, int node)
+static struct atalk_iface *atalk_find_interface(__be16 net, int node)
{
struct atalk_iface *iface;
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index ef9f2095f96e..069253f830c1 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -57,9 +57,6 @@ int br_forward_finish(struct sk_buff *skb)
static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
{
skb->dev = to->dev;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
br_forward_finish);
}
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 8f5f2e730992..9a45e6279c57 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -23,11 +23,7 @@ const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
static int br_pass_frame_up_finish(struct sk_buff *skb)
{
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
netif_receive_skb(skb);
-
return 0;
}
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index be03d3ad2648..03ae4edddac3 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -102,10 +102,6 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
-#endif
-
if (nf_bridge->mask & BRNF_PKT_TYPE) {
skb->pkt_type = PACKET_OTHERHOST;
nf_bridge->mask ^= BRNF_PKT_TYPE;
@@ -182,10 +178,6 @@ static void __br_dnat_complain(void)
* --Bart, 20021007 (updated) */
static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
{
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD);
-#endif
-
if (skb->pkt_type == PACKET_OTHERHOST) {
skb->pkt_type = PACKET_HOST;
skb->nf_bridge->mask |= BRNF_PKT_TYPE;
@@ -207,10 +199,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
struct iphdr *iph = skb->nh.iph;
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
-#endif
-
if (nf_bridge->mask & BRNF_PKT_TYPE) {
skb->pkt_type = PACKET_OTHERHOST;
nf_bridge->mask ^= BRNF_PKT_TYPE;
@@ -382,9 +370,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
goto inhdr_error;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_IP6_PRE_ROUTING);
-#endif
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
return NF_DROP;
setup_pre_routing(skb);
@@ -468,9 +453,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
skb->ip_summed = CHECKSUM_NONE;
}
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING);
-#endif
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
return NF_DROP;
setup_pre_routing(skb);
@@ -517,10 +499,6 @@ static int br_nf_forward_finish(struct sk_buff *skb)
struct net_device *in;
struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_BR_FORWARD);
-#endif
-
if (skb->protocol != __constant_htons(ETH_P_ARP) && !IS_VLAN_ARP) {
in = nf_bridge->physindev;
if (nf_bridge->mask & BRNF_PKT_TYPE) {
@@ -566,9 +544,6 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
(*pskb)->nh.raw += VLAN_HLEN;
}
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_BR_FORWARD);
-#endif
nf_bridge = skb->nf_bridge;
if (skb->pkt_type == PACKET_OTHERHOST) {
skb->pkt_type = PACKET_HOST;
@@ -605,10 +580,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
(*pskb)->nh.raw += VLAN_HLEN;
}
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_BR_FORWARD);
-#endif
-
if (skb->nh.arph->ar_pln != 4) {
if (IS_VLAN_ARP) {
skb_push(*pskb, VLAN_HLEN);
@@ -627,9 +598,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
/* PF_BRIDGE/LOCAL_OUT ***********************************************/
static int br_nf_local_out_finish(struct sk_buff *skb)
{
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT);
-#endif
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
skb_push(skb, VLAN_HLEN);
skb->nh.raw -= VLAN_HLEN;
@@ -731,10 +699,6 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
realoutdev, br_nf_local_out_finish,
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
} else {
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT);
-#endif
-
NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev,
realoutdev, br_nf_local_out_finish,
NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
@@ -779,8 +743,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
printk(KERN_CRIT "br_netfilter: skb->dst == NULL.");
goto print_error;
}
-
- skb->nf_debug ^= (1 << NF_IP_POST_ROUTING);
#endif
/* We assume any code from br_dev_queue_push_xmit onwards doesn't care
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index 22a8f127c4aa..076c156d5eda 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -141,136 +141,6 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
up(&nf_sockopt_mutex);
}
-#ifdef CONFIG_NETFILTER_DEBUG
-#include <net/ip.h>
-#include <net/tcp.h>
-#include <linux/netfilter_ipv4.h>
-
-static void debug_print_hooks_ip(unsigned int nf_debug)
-{
- if (nf_debug & (1 << NF_IP_PRE_ROUTING)) {
- printk("PRE_ROUTING ");
- nf_debug ^= (1 << NF_IP_PRE_ROUTING);
- }
- if (nf_debug & (1 << NF_IP_LOCAL_IN)) {
- printk("LOCAL_IN ");
- nf_debug ^= (1 << NF_IP_LOCAL_IN);
- }
- if (nf_debug & (1 << NF_IP_FORWARD)) {
- printk("FORWARD ");
- nf_debug ^= (1 << NF_IP_FORWARD);
- }
- if (nf_debug & (1 << NF_IP_LOCAL_OUT)) {
- printk("LOCAL_OUT ");
- nf_debug ^= (1 << NF_IP_LOCAL_OUT);
- }
- if (nf_debug & (1 << NF_IP_POST_ROUTING)) {
- printk("POST_ROUTING ");
- nf_debug ^= (1 << NF_IP_POST_ROUTING);
- }
- if (nf_debug)
- printk("Crap bits: 0x%04X", nf_debug);
- printk("\n");
-}
-
-static void nf_dump_skb(int pf, struct sk_buff *skb)
-{
- printk("skb: pf=%i %s dev=%s len=%u\n",
- pf,
- skb->sk ? "(owned)" : "(unowned)",
- skb->dev ? skb->dev->name : "(no dev)",
- skb->len);
- switch (pf) {
- case PF_INET: {
- const struct iphdr *ip = skb->nh.iph;
- __u32 *opt = (__u32 *) (ip + 1);
- int opti;
- __u16 src_port = 0, dst_port = 0;
-
- if (ip->protocol == IPPROTO_TCP
- || ip->protocol == IPPROTO_UDP) {
- struct tcphdr *tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl);
- src_port = ntohs(tcp->source);
- dst_port = ntohs(tcp->dest);
- }
-
- printk("PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
- " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
- ip->protocol, NIPQUAD(ip->saddr),
- src_port, NIPQUAD(ip->daddr),
- dst_port,
- ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
- ntohs(ip->frag_off), ip->ttl);
-
- for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
- printk(" O=0x%8.8X", *opt++);
- printk("\n");
- }
- }
-}
-
-void nf_debug_ip_local_deliver(struct sk_buff *skb)
-{
- /* If it's a loopback packet, it must have come through
- * NF_IP_LOCAL_OUT, NF_IP_RAW_INPUT, NF_IP_PRE_ROUTING and
- * NF_IP_LOCAL_IN. Otherwise, must have gone through
- * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */
- if (!skb->dev) {
- printk("ip_local_deliver: skb->dev is NULL.\n");
- } else {
- if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING)
- | (1<<NF_IP_LOCAL_IN))) {
- printk("ip_local_deliver: bad skb: ");
- debug_print_hooks_ip(skb->nf_debug);
- nf_dump_skb(PF_INET, skb);
- }
- }
-}
-
-void nf_debug_ip_loopback_xmit(struct sk_buff *newskb)
-{
- if (newskb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
- | (1 << NF_IP_POST_ROUTING))) {
- printk("ip_dev_loopback_xmit: bad owned skb = %p: ",
- newskb);
- debug_print_hooks_ip(newskb->nf_debug);
- nf_dump_skb(PF_INET, newskb);
- }
-}
-
-void nf_debug_ip_finish_output2(struct sk_buff *skb)
-{
- /* If it's owned, it must have gone through the
- * NF_IP_LOCAL_OUT and NF_IP_POST_ROUTING.
- * Otherwise, must have gone through
- * NF_IP_PRE_ROUTING, NF_IP_FORWARD and NF_IP_POST_ROUTING.
- */
- if (skb->sk) {
- if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
- | (1 << NF_IP_POST_ROUTING))) {
- printk("ip_finish_output: bad owned skb = %p: ", skb);
- debug_print_hooks_ip(skb->nf_debug);
- nf_dump_skb(PF_INET, skb);
- }
- } else {
- if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING)
- | (1 << NF_IP_FORWARD)
- | (1 << NF_IP_POST_ROUTING))) {
- /* Fragments, entunnelled packets, TCP RSTs
- generated by ipt_REJECT will have no
- owners, but still may be local */
- if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
- | (1 << NF_IP_POST_ROUTING))){
- printk("ip_finish_output:"
- " bad unowned skb = %p: ",skb);
- debug_print_hooks_ip(skb->nf_debug);
- nf_dump_skb(PF_INET, skb);
- }
- }
- }
-}
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
/* Call get/setsockopt() */
static int nf_sockopt(struct sock *sk, int pf, int val,
char __user *opt, int *len, int get)
@@ -488,14 +358,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
/* We may already have this, but read-locks nest anyway */
rcu_read_lock();
-#ifdef CONFIG_NETFILTER_DEBUG
- if (unlikely((*pskb)->nf_debug & (1 << hook))) {
- printk("nf_hook: hook %i already set.\n", hook);
- nf_dump_skb(pf, *pskb);
- }
- (*pskb)->nf_debug |= (1 << hook);
-#endif
-
elem = &nf_hooks[pf][hook];
next_hook:
verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f65b3de590a9..6d68c03bc051 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -365,9 +365,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
C(nfct);
nf_conntrack_get(skb->nfct);
C(nfctinfo);
-#ifdef CONFIG_NETFILTER_DEBUG
- C(nf_debug);
-#endif
#ifdef CONFIG_BRIDGE_NETFILTER
C(nf_bridge);
nf_bridge_get(skb->nf_bridge);
@@ -432,9 +429,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nfct = old->nfct;
nf_conntrack_get(old->nfct);
new->nfctinfo = old->nfctinfo;
-#ifdef CONFIG_NETFILTER_DEBUG
- new->nf_debug = old->nf_debug;
-#endif
#ifdef CONFIG_BRIDGE_NETFILTER
new->nf_bridge = old->nf_bridge;
nf_bridge_get(old->nf_bridge);
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 6d3e8b1bd1f2..05107e0dc145 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -1,6 +1,32 @@
#
# IP configuration
#
+choice
+ prompt "Choose IP: FIB lookup""
+ depends on INET
+ default IP_FIB_HASH
+
+config IP_FIB_HASH
+ bool "FIB_HASH"
+ ---help---
+ Current FIB is very proven and good enough for most users.
+
+config IP_FIB_TRIE
+ bool "FIB_TRIE"
+ ---help---
+ Use new experimental LC-trie as FIB lookup algoritm.
+ This improves lookup performance
+
+ LC-trie is described in:
+
+ IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
+ IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
+ An experimental study of compression methods for dynamic tries
+ Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
+ http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
+
+endchoice
+
config IP_MULTICAST
bool "IP: multicasting"
depends on INET
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 8b379627ebb6..65d57d8e1add 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -7,8 +7,10 @@ obj-y := utils.o route.o inetpeer.o protocol.o \
ip_output.o ip_sockglue.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \
datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
- sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o
+ sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
+obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
+obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
obj-$(CONFIG_IP_MROUTE) += ipmr.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 03942f133944..658e7977924d 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1119,6 +1119,10 @@ module_init(inet_init);
#ifdef CONFIG_PROC_FS
extern int fib_proc_init(void);
extern void fib_proc_exit(void);
+#ifdef CONFIG_IP_FIB_TRIE
+extern int fib_stat_proc_init(void);
+extern void fib_stat_proc_exit(void);
+#endif
extern int ip_misc_proc_init(void);
extern int raw_proc_init(void);
extern void raw_proc_exit(void);
@@ -1139,11 +1143,19 @@ static int __init ipv4_proc_init(void)
goto out_udp;
if (fib_proc_init())
goto out_fib;
+#ifdef CONFIG_IP_FIB_TRIE
+ if (fib_stat_proc_init())
+ goto out_fib_stat;
+ #endif
if (ip_misc_proc_init())
goto out_misc;
out:
return rc;
out_misc:
+#ifdef CONFIG_IP_FIB_TRIE
+ fib_stat_proc_exit();
+out_fib_stat:
+#endif
fib_proc_exit();
out_fib:
udp4_proc_exit();
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 0e98f2235b6e..514c85b2631a 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -200,7 +200,7 @@ static void ah4_err(struct sk_buff *skb, u32 info)
xfrm_state_put(x);
}
-static int ah_init_state(struct xfrm_state *x, void *args)
+static int ah_init_state(struct xfrm_state *x)
{
struct ah_data *ahp = NULL;
struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index eae84cc39d3f..ba57446d5d1f 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -362,7 +362,7 @@ static void esp_destroy(struct xfrm_state *x)
kfree(esp);
}
-static int esp_init_state(struct xfrm_state *x, void *args)
+static int esp_init_state(struct xfrm_state *x)
{
struct esp_data *esp = NULL;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 563e7d612706..cd8e45ab9580 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -516,6 +516,60 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
#undef BRD1_OK
}
+static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
+{
+
+ struct fib_result res;
+ struct flowi fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
+ .fwmark = frn->fl_fwmark,
+ .tos = frn->fl_tos,
+ .scope = frn->fl_scope } } };
+ if (tb) {
+ local_bh_disable();
+
+ frn->tb_id = tb->tb_id;
+ frn->err = tb->tb_lookup(tb, &fl, &res);
+
+ if (!frn->err) {
+ frn->prefixlen = res.prefixlen;
+ frn->nh_sel = res.nh_sel;
+ frn->type = res.type;
+ frn->scope = res.scope;
+ }
+ local_bh_enable();
+ }
+}
+
+static void nl_fib_input(struct sock *sk, int len)
+{
+ struct sk_buff *skb = NULL;
+ struct nlmsghdr *nlh = NULL;
+ struct fib_result_nl *frn;
+ int err;
+ u32 pid;
+ struct fib_table *tb;
+
+ skb = skb_recv_datagram(sk, 0, 0, &err);
+ nlh = (struct nlmsghdr *)skb->data;
+
+ frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
+ tb = fib_get_table(frn->tb_id_in);
+
+ nl_fib_lookup(frn, tb);
+
+ pid = nlh->nlmsg_pid; /*pid of sending process */
+ NETLINK_CB(skb).groups = 0; /* not in mcast group */
+ NETLINK_CB(skb).pid = 0; /* from kernel */
+ NETLINK_CB(skb).dst_pid = pid;
+ NETLINK_CB(skb).dst_groups = 0; /* unicast */
+ netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
+}
+
+static void nl_fib_lookup_init(void)
+{
+ netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input);
+}
+
static void fib_disable_ip(struct net_device *dev, int force)
{
if (fib_sync_down(0, dev, force))
@@ -604,6 +658,7 @@ void __init ip_fib_init(void)
register_netdevice_notifier(&fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
+ nl_fib_lookup_init();
}
EXPORT_SYMBOL(inet_addr_type);
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
new file mode 100644
index 000000000000..0671569ee6f0
--- /dev/null
+++ b/net/ipv4/fib_trie.c
@@ -0,0 +1,2454 @@
+/*
+ * 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.
+ *
+ * Robert Olsson <robert.olsson@its.uu.se> Uppsala Universitet
+ * & Swedish University of Agricultural Sciences.
+ *
+ * Jens Laas <jens.laas@data.slu.se> Swedish University of
+ * Agricultural Sciences.
+ *
+ * Hans Liss <hans.liss@its.uu.se> Uppsala Universitet
+ *
+ * This work is based on the LPC-trie which is originally descibed in:
+ *
+ * An experimental study of compression methods for dynamic tries
+ * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
+ * http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
+ *
+ *
+ * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
+ * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
+ *
+ * Version: $Id: fib_trie.c,v 1.3 2005/06/08 14:20:01 robert Exp $
+ *
+ *
+ * Code from fib_hash has been reused which includes the following header:
+ *
+ *
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * IPv4 FIB: lookup engine and maintenance routines.
+ *
+ *
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *
+ * 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.
+ */
+
+#define VERSION "0.323"
+
+#include <linux/config.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <net/ip.h>
+#include <net/protocol.h>
+#include <net/route.h>
+#include <net/tcp.h>
+#include <net/sock.h>
+#include <net/ip_fib.h>
+#include "fib_lookup.h"
+
+#undef CONFIG_IP_FIB_TRIE_STATS
+#define MAX_CHILDS 16384
+
+#define EXTRACT(p, n, str) ((str)<<(p)>>(32-(n)))
+#define KEYLENGTH (8*sizeof(t_key))
+#define MASK_PFX(k, l) (((l)==0)?0:(k >> (KEYLENGTH-l)) << (KEYLENGTH-l))
+#define TKEY_GET_MASK(offset, bits) (((bits)==0)?0:((t_key)(-1) << (KEYLENGTH - bits) >> offset))
+
+static DEFINE_RWLOCK(fib_lock);
+
+typedef unsigned int t_key;
+
+#define T_TNODE 0
+#define T_LEAF 1
+#define NODE_TYPE_MASK 0x1UL
+#define NODE_PARENT(_node) \
+((struct tnode *)((_node)->_parent & ~NODE_TYPE_MASK))
+#define NODE_SET_PARENT(_node, _ptr) \
+((_node)->_parent = (((unsigned long)(_ptr)) | \
+ ((_node)->_parent & NODE_TYPE_MASK)))
+#define NODE_INIT_PARENT(_node, _type) \
+((_node)->_parent = (_type))
+#define NODE_TYPE(_node) \
+((_node)->_parent & NODE_TYPE_MASK)
+
+#define IS_TNODE(n) (!(n->_parent & T_LEAF))
+#define IS_LEAF(n) (n->_parent & T_LEAF)
+
+struct node {
+ t_key key;
+ unsigned long _parent;
+};
+
+struct leaf {
+ t_key key;
+ unsigned long _parent;
+ struct hlist_head list;
+};
+
+struct leaf_info {
+ struct hlist_node hlist;
+ int plen;
+ struct list_head falh;
+};
+
+struct tnode {
+ t_key key;
+ unsigned long _parent;
+ unsigned short pos:5; /* 2log(KEYLENGTH) bits needed */
+ unsigned short bits:5; /* 2log(KEYLENGTH) bits needed */
+ unsigned short full_children; /* KEYLENGTH bits needed */
+ unsigned short empty_children; /* KEYLENGTH bits needed */
+ struct node *child[0];
+};
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+struct trie_use_stats {
+ unsigned int gets;
+ unsigned int backtrack;
+ unsigned int semantic_match_passed;
+ unsigned int semantic_match_miss;
+ unsigned int null_node_hit;
+};
+#endif
+
+struct trie_stat {
+ unsigned int totdepth;
+ unsigned int maxdepth;
+ unsigned int tnodes;
+ unsigned int leaves;
+ unsigned int nullpointers;
+ unsigned int nodesizes[MAX_CHILDS];
+};
+
+struct trie {
+ struct node *trie;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ struct trie_use_stats stats;
+#endif
+ int size;
+ unsigned int revision;
+};
+
+static int trie_debug = 0;
+
+static int tnode_full(struct tnode *tn, struct node *n);
+static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
+static int tnode_child_length(struct tnode *tn);
+static struct node *resize(struct trie *t, struct tnode *tn);
+static struct tnode *inflate(struct trie *t, struct tnode *tn);
+static struct tnode *halve(struct trie *t, struct tnode *tn);
+static void tnode_free(struct tnode *tn);
+static void trie_dump_seq(struct seq_file *seq, struct trie *t);
+extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio);
+extern int fib_detect_death(struct fib_info *fi, int order,
+ struct fib_info **last_resort, int *last_idx, int *dflt);
+
+extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, int z, int tb_id,
+ struct nlmsghdr *n, struct netlink_skb_parms *req);
+
+static kmem_cache_t *fn_alias_kmem;
+static struct trie *trie_local = NULL, *trie_main = NULL;
+
+static void trie_bug(char *err)
+{
+ printk("Trie Bug: %s\n", err);
+ BUG();
+}
+
+static inline struct node *tnode_get_child(struct tnode *tn, int i)
+{
+ if (i >= 1<<tn->bits)
+ trie_bug("tnode_get_child");
+
+ return tn->child[i];
+}
+
+static inline int tnode_child_length(struct tnode *tn)
+{
+ return 1<<tn->bits;
+}
+
+/*
+ _________________________________________________________________
+ | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C |
+ ----------------------------------------------------------------
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
+ _________________________________________________________________
+ | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u |
+ -----------------------------------------------------------------
+ 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+
+ tp->pos = 7
+ tp->bits = 3
+ n->pos = 15
+ n->bits=4
+ KEYLENGTH=32
+*/
+
+static inline t_key tkey_extract_bits(t_key a, int offset, int bits)
+{
+ if (offset < KEYLENGTH)
+ return ((t_key)(a << offset)) >> (KEYLENGTH - bits);
+ else
+ return 0;
+}
+
+static inline int tkey_equals(t_key a, t_key b)
+{
+ return a == b;
+}
+
+static inline int tkey_sub_equals(t_key a, int offset, int bits, t_key b)
+{
+ if (bits == 0 || offset >= KEYLENGTH)
+ return 1;
+ bits = bits > KEYLENGTH ? KEYLENGTH : bits;
+ return ((a ^ b) << offset) >> (KEYLENGTH - bits) == 0;
+}
+
+static inline int tkey_mismatch(t_key a, int offset, t_key b)
+{
+ t_key diff = a ^ b;
+ int i = offset;
+
+ if(!diff)
+ return 0;
+ while((diff << i) >> (KEYLENGTH-1) == 0)
+ i++;
+ return i;
+}
+
+/* Candiate for fib_semantics */
+
+static void fn_free_alias(struct fib_alias *fa)
+{
+ fib_release_info(fa->fa_info);
+ kmem_cache_free(fn_alias_kmem, fa);
+}
+
+/*
+ To understand this stuff, an understanding of keys and all their bits is
+ necessary. Every node in the trie has a key associated with it, but not
+ all of the bits in that key are significant.
+
+ Consider a node 'n' and its parent 'tp'.
+
+ If n is a leaf, every bit in its key is significant. Its presence is
+ necessitaded by path compression, since during a tree traversal (when
+ searching for a leaf - unless we are doing an insertion) we will completely
+ ignore all skipped bits we encounter. Thus we need to verify, at the end of
+ a potentially successful search, that we have indeed been walking the
+ correct key path.
+
+ Note that we can never "miss" the correct key in the tree if present by
+ following the wrong path. Path compression ensures that segments of the key
+ that are the same for all keys with a given prefix are skipped, but the
+ skipped part *is* identical for each node in the subtrie below the skipped
+ bit! trie_insert() in this implementation takes care of that - note the
+ call to tkey_sub_equals() in trie_insert().
+
+ if n is an internal node - a 'tnode' here, the various parts of its key
+ have many different meanings.
+
+ Example:
+ _________________________________________________________________
+ | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C |
+ -----------------------------------------------------------------
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
+ _________________________________________________________________
+ | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u |
+ -----------------------------------------------------------------
+ 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+
+ tp->pos = 7
+ tp->bits = 3
+ n->pos = 15
+ n->bits=4
+
+ First, let's just ignore the bits that come before the parent tp, that is
+ the bits from 0 to (tp->pos-1). They are *known* but at this point we do
+ not use them for anything.
+
+ The bits from (tp->pos) to (tp->pos + tp->bits - 1) - "N", above - are the
+ index into the parent's child array. That is, they will be used to find
+ 'n' among tp's children.
+
+ The bits from (tp->pos + tp->bits) to (n->pos - 1) - "S" - are skipped bits
+ for the node n.
+
+ All the bits we have seen so far are significant to the node n. The rest
+ of the bits are really not needed or indeed known in n->key.
+
+ The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into
+ n's child array, and will of course be different for each child.
+
+ The rest of the bits, from (n->pos + n->bits) onward, are completely unknown
+ at this point.
+
+*/
+
+static void check_tnode(struct tnode *tn)
+{
+ if(tn && tn->pos+tn->bits > 32) {
+ printk("TNODE ERROR tn=%p, pos=%d, bits=%d\n", tn, tn->pos, tn->bits);
+ }
+}
+
+static int halve_threshold = 25;
+static int inflate_threshold = 50;
+
+static struct leaf *leaf_new(void)
+{
+ struct leaf *l = kmalloc(sizeof(struct leaf), GFP_KERNEL);
+ if(l) {
+ NODE_INIT_PARENT(l, T_LEAF);
+ INIT_HLIST_HEAD(&l->list);
+ }
+ return l;
+}
+
+static struct leaf_info *leaf_info_new(int plen)
+{
+ struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
+ li->plen = plen;
+ INIT_LIST_HEAD(&li->falh);
+ return li;
+}
+
+static inline void free_leaf(struct leaf *l)
+{
+ kfree(l);
+}
+
+static inline void free_leaf_info(struct leaf_info *li)
+{
+ kfree(li);
+}
+
+static struct tnode* tnode_new(t_key key, int pos, int bits)
+{
+ int nchildren = 1<<bits;
+ int sz = sizeof(struct tnode) + nchildren * sizeof(struct node *);
+ struct tnode *tn = kmalloc(sz, GFP_KERNEL);
+
+ if(tn) {
+ memset(tn, 0, sz);
+ NODE_INIT_PARENT(tn, T_TNODE);
+ tn->pos = pos;
+ tn->bits = bits;
+ tn->key = key;
+ tn->full_children = 0;
+ tn->empty_children = 1<<bits;
+ }
+ if(trie_debug > 0)
+ printk("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode),
+ (unsigned int) (sizeof(struct node) * 1<<bits));
+ return tn;
+}
+
+static void tnode_free(struct tnode *tn)
+{
+ if(!tn) {
+ trie_bug("tnode_free\n");
+ }
+ if(IS_LEAF(tn)) {
+ free_leaf((struct leaf *)tn);
+ if(trie_debug > 0 )
+ printk("FL %p \n", tn);
+ }
+ else if(IS_TNODE(tn)) {
+ kfree(tn);
+ if(trie_debug > 0 )
+ printk("FT %p \n", tn);
+ }
+ else {
+ trie_bug("tnode_free\n");
+ }
+}
+
+/*
+ * Check whether a tnode 'n' is "full", i.e. it is an internal node
+ * and no bits are skipped. See discussion in dyntree paper p. 6
+ */
+
+static inline int tnode_full(struct tnode *tn, struct node *n)
+{
+ if(n == NULL || IS_LEAF(n))
+ return 0;
+
+ return ((struct tnode *) n)->pos == tn->pos + tn->bits;
+}
+
+static inline void put_child(struct trie *t, struct tnode *tn, int i, struct node *n)
+{
+ tnode_put_child_reorg(tn, i, n, -1);
+}
+
+ /*
+ * Add a child at position i overwriting the old value.
+ * Update the value of full_children and empty_children.
+ */
+
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull)
+{
+ struct node *chi;
+ int isfull;
+
+ if(i >= 1<<tn->bits) {
+ printk("bits=%d, i=%d\n", tn->bits, i);
+ trie_bug("tnode_put_child_reorg bits");
+ }
+ write_lock_bh(&fib_lock);
+ chi = tn->child[i];
+
+ /* update emptyChildren */
+ if (n == NULL && chi != NULL)
+ tn->empty_children++;
+ else if (n != NULL && chi == NULL)
+ tn->empty_children--;
+
+ /* update fullChildren */
+ if (wasfull == -1)
+ wasfull = tnode_full(tn, chi);
+
+ isfull = tnode_full(tn, n);
+ if (wasfull && !isfull)
+ tn->full_children--;
+
+ else if (!wasfull && isfull)
+ tn->full_children++;
+ if(n)
+ NODE_SET_PARENT(n, tn);
+
+ tn->child[i] = n;
+ write_unlock_bh(&fib_lock);
+}
+
+static struct node *resize(struct trie *t, struct tnode *tn)
+{
+ int i;
+
+ if (!tn)
+ return NULL;
+
+ if(trie_debug)
+ printk("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
+ tn, inflate_threshold, halve_threshold);
+
+ /* No children */
+ if (tn->empty_children == tnode_child_length(tn)) {
+ tnode_free(tn);
+ return NULL;
+ }
+ /* One child */
+ if (tn->empty_children == tnode_child_length(tn) - 1)
+ for (i = 0; i < tnode_child_length(tn); i++) {
+
+ write_lock_bh(&fib_lock);
+ if (tn->child[i] != NULL) {
+
+ /* compress one level */
+ struct node *n = tn->child[i];
+ if(n)
+ NODE_INIT_PARENT(n, NODE_TYPE(n));
+
+ write_unlock_bh(&fib_lock);
+ tnode_free(tn);
+ return n;
+ }
+ write_unlock_bh(&fib_lock);
+ }
+ /*
+ * Double as long as the resulting node has a number of
+ * nonempty nodes that are above the threshold.
+ */
+
+ /*
+ * From "Implementing a dynamic compressed trie" by Stefan Nilsson of
+ * the Helsinki University of Technology and Matti Tikkanen of Nokia
+ * Telecommunications, page 6:
+ * "A node is doubled if the ratio of non-empty children to all
+ * children in the *doubled* node is at least 'high'."
+ *
+ * 'high' in this instance is the variable 'inflate_threshold'. It
+ * is expressed as a percentage, so we multiply it with
+ * tnode_child_length() and instead of multiplying by 2 (since the
+ * child array will be doubled by inflate()) and multiplying
+ * the left-hand side by 100 (to handle the percentage thing) we
+ * multiply the left-hand side by 50.
+ *
+ * The left-hand side may look a bit weird: tnode_child_length(tn)
+ * - tn->empty_children is of course the number of non-null children
+ * in the current node. tn->full_children is the number of "full"
+ * children, that is non-null tnodes with a skip value of 0.
+ * All of those will be doubled in the resulting inflated tnode, so
+ * we just count them one extra time here.
+ *
+ * A clearer way to write this would be:
+ *
+ * to_be_doubled = tn->full_children;
+ * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children -
+ * tn->full_children;
+ *
+ * new_child_length = tnode_child_length(tn) * 2;
+ *
+ * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) /
+ * new_child_length;
+ * if (new_fill_factor >= inflate_threshold)
+ *
+ * ...and so on, tho it would mess up the while() loop.
+ *
+ * anyway,
+ * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >=
+ * inflate_threshold
+ *
+ * avoid a division:
+ * 100 * (not_to_be_doubled + 2*to_be_doubled) >=
+ * inflate_threshold * new_child_length
+ *
+ * expand not_to_be_doubled and to_be_doubled, and shorten:
+ * 100 * (tnode_child_length(tn) - tn->empty_children +
+ * tn->full_children ) >= inflate_threshold * new_child_length
+ *
+ * expand new_child_length:
+ * 100 * (tnode_child_length(tn) - tn->empty_children +
+ * tn->full_children ) >=
+ * inflate_threshold * tnode_child_length(tn) * 2
+ *
+ * shorten again:
+ * 50 * (tn->full_children + tnode_child_length(tn) -
+ * tn->empty_children ) >= inflate_threshold *
+ * tnode_child_length(tn)
+ *
+ */
+
+ check_tnode(tn);
+
+ while ((tn->full_children > 0 &&
+ 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
+ inflate_threshold * tnode_child_length(tn))) {
+
+ tn = inflate(t, tn);
+ }
+
+ check_tnode(tn);
+
+ /*
+ * Halve as long as the number of empty children in this
+ * node is above threshold.
+ */
+ while (tn->bits > 1 &&
+ 100 * (tnode_child_length(tn) - tn->empty_children) <
+ halve_threshold * tnode_child_length(tn))
+
+ tn = halve(t, tn);
+
+ /* Only one child remains */
+
+ if (tn->empty_children == tnode_child_length(tn) - 1)
+ for (i = 0; i < tnode_child_length(tn); i++) {
+
+ write_lock_bh(&fib_lock);
+ if (tn->child[i] != NULL) {
+ /* compress one level */
+ struct node *n = tn->child[i];
+
+ if(n)
+ NODE_INIT_PARENT(n, NODE_TYPE(n));
+
+ write_unlock_bh(&fib_lock);
+ tnode_free(tn);
+ return n;
+ }
+ write_unlock_bh(&fib_lock);
+ }
+
+ return (struct node *) tn;
+}
+
+static struct tnode *inflate(struct trie *t, struct tnode *tn)
+{
+ struct tnode *inode;
+ struct tnode *oldtnode = tn;
+ int olen = tnode_child_length(tn);
+ int i;
+
+ if(trie_debug)
+ printk("In inflate\n");
+
+ tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
+
+ if (!tn)
+ trie_bug("tnode_new failed");
+
+ for(i = 0; i < olen; i++) {
+ struct node *node = tnode_get_child(oldtnode, i);
+
+ /* An empty child */
+ if (node == NULL)
+ continue;
+
+ /* A leaf or an internal node with skipped bits */
+
+ if(IS_LEAF(node) || ((struct tnode *) node)->pos >
+ tn->pos + tn->bits - 1) {
+ if(tkey_extract_bits(node->key, tn->pos + tn->bits - 1,
+ 1) == 0)
+ put_child(t, tn, 2*i, node);
+ else
+ put_child(t, tn, 2*i+1, node);
+ continue;
+ }
+
+ /* An internal node with two children */
+ inode = (struct tnode *) node;
+
+ if (inode->bits == 1) {
+ put_child(t, tn, 2*i, inode->child[0]);
+ put_child(t, tn, 2*i+1, inode->child[1]);
+
+ tnode_free(inode);
+ }
+
+ /* An internal node with more than two children */
+ else {
+ struct tnode *left, *right;
+ int size, j;
+
+ /* We will replace this node 'inode' with two new
+ * ones, 'left' and 'right', each with half of the
+ * original children. The two new nodes will have
+ * a position one bit further down the key and this
+ * means that the "significant" part of their keys
+ * (see the discussion near the top of this file)
+ * will differ by one bit, which will be "0" in
+ * left's key and "1" in right's key. Since we are
+ * moving the key position by one step, the bit that
+ * we are moving away from - the bit at position
+ * (inode->pos) - is the one that will differ between
+ * left and right. So... we synthesize that bit in the
+ * two new keys.
+ * The mask 'm' below will be a single "one" bit at
+ * the position (inode->pos)
+ */
+
+ t_key m = TKEY_GET_MASK(inode->pos, 1);
+
+ /* Use the old key, but set the new significant
+ * bit to zero.
+ */
+ left = tnode_new(inode->key&(~m), inode->pos + 1,
+ inode->bits - 1);
+
+ if(!left)
+ trie_bug("tnode_new failed");
+
+
+ /* Use the old key, but set the new significant
+ * bit to one.
+ */
+ right = tnode_new(inode->key|m, inode->pos + 1,
+ inode->bits - 1);
+
+ if(!right)
+ trie_bug("tnode_new failed");
+
+ size = tnode_child_length(left);
+ for(j = 0; j < size; j++) {
+ put_child(t, left, j, inode->child[j]);
+ put_child(t, right, j, inode->child[j + size]);
+ }
+ put_child(t, tn, 2*i, resize(t, left));
+ put_child(t, tn, 2*i+1, resize(t, right));
+
+ tnode_free(inode);
+ }
+ }
+ tnode_free(oldtnode);
+ return tn;
+}
+
+static struct tnode *halve(struct trie *t, struct tnode *tn)
+{
+ struct tnode *oldtnode = tn;
+ struct node *left, *right;
+ int i;
+ int olen = tnode_child_length(tn);
+
+ if(trie_debug) printk("In halve\n");
+
+ tn=tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
+
+ if(!tn)
+ trie_bug("tnode_new failed");
+
+ for(i = 0; i < olen; i += 2) {
+ left = tnode_get_child(oldtnode, i);
+ right = tnode_get_child(oldtnode, i+1);
+
+ /* At least one of the children is empty */
+ if (left == NULL) {
+ if (right == NULL) /* Both are empty */
+ continue;
+ put_child(t, tn, i/2, right);
+ } else if (right == NULL)
+ put_child(t, tn, i/2, left);
+
+ /* Two nonempty children */
+ else {
+ struct tnode *newBinNode =
+ tnode_new(left->key, tn->pos + tn->bits, 1);
+
+ if(!newBinNode)
+ trie_bug("tnode_new failed");
+
+ put_child(t, newBinNode, 0, left);
+ put_child(t, newBinNode, 1, right);
+ put_child(t, tn, i/2, resize(t, newBinNode));
+ }
+ }
+ tnode_free(oldtnode);
+ return tn;
+}
+
+static void *trie_init(struct trie *t)
+{
+ if(t) {
+ t->size = 0;
+ t->trie = NULL;
+ t->revision = 0;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ memset(&t->stats, 0, sizeof(struct trie_use_stats));
+#endif
+ }
+ return t;
+}
+
+static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
+{
+ struct hlist_node *node;
+ struct leaf_info *li;
+
+ hlist_for_each_entry(li, node, head, hlist) {
+
+ if ( li->plen == plen )
+ return li;
+ }
+ return NULL;
+}
+
+static inline struct list_head * get_fa_head(struct leaf *l, int plen)
+{
+ struct list_head *fa_head=NULL;
+ struct leaf_info *li = find_leaf_info(&l->list, plen);
+
+ if(li)
+ fa_head = &li->falh;
+
+ return fa_head;
+}
+
+static void insert_leaf_info(struct hlist_head *head, struct leaf_info *new)
+{
+ struct leaf_info *li=NULL, *last=NULL;
+ struct hlist_node *node, *tmp;
+
+ write_lock_bh(&fib_lock);
+
+ if(hlist_empty(head))
+ hlist_add_head(&new->hlist, head);
+ else {
+ hlist_for_each_entry_safe(li, node, tmp, head, hlist) {
+
+ if (new->plen > li->plen)
+ break;
+
+ last = li;
+ }
+ if(last)
+ hlist_add_after(&last->hlist, &new->hlist);
+ else
+ hlist_add_before(&new->hlist, &li->hlist);
+ }
+ write_unlock_bh(&fib_lock);
+}
+
+static struct leaf *
+fib_find_node(struct trie *t, u32 key)
+{
+ int pos;
+ struct tnode *tn;
+ struct node *n;
+
+ pos = 0;
+ n=t->trie;
+
+ while (n != NULL && NODE_TYPE(n) == T_TNODE) {
+ tn = (struct tnode *) n;
+
+ check_tnode(tn);
+
+ if(tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
+ pos=tn->pos + tn->bits;
+ n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
+ }
+ else
+ break;
+ }
+ /* Case we have found a leaf. Compare prefixes */
+
+ if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
+ struct leaf *l = (struct leaf *) n;
+ return l;
+ }
+ return NULL;
+}
+
+static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
+{
+ int i = 0;
+ int wasfull;
+ t_key cindex, key;
+ struct tnode *tp = NULL;
+
+ if(!tn)
+ BUG();
+
+ key = tn->key;
+ i = 0;
+
+ while (tn != NULL && NODE_PARENT(tn) != NULL) {
+
+ if( i > 10 ) {
+ printk("Rebalance tn=%p \n", tn);
+ if(tn) printk("tn->parent=%p \n", NODE_PARENT(tn));
+
+ printk("Rebalance tp=%p \n", tp);
+ if(tp) printk("tp->parent=%p \n", NODE_PARENT(tp));
+ }
+
+ if( i > 12 ) BUG();
+ i++;
+
+ tp = NODE_PARENT(tn);
+ cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+ wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
+ tn = (struct tnode *) resize (t, (struct tnode *)tn);
+ tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull);
+
+ if(!NODE_PARENT(tn))
+ break;
+
+ tn = NODE_PARENT(tn);
+ }
+ /* Handle last (top) tnode */
+ if (IS_TNODE(tn))
+ tn = (struct tnode*) resize(t, (struct tnode *)tn);
+
+ return (struct node*) tn;
+}
+
+static struct list_head *
+fib_insert_node(struct trie *t, u32 key, int plen)
+{
+ int pos, newpos;
+ struct tnode *tp = NULL, *tn = NULL;
+ struct node *n;
+ struct leaf *l;
+ int missbit;
+ struct list_head *fa_head=NULL;
+ struct leaf_info *li;
+ t_key cindex;
+
+ pos = 0;
+ n=t->trie;
+
+ /* If we point to NULL, stop. Either the tree is empty and we should
+ * just put a new leaf in if, or we have reached an empty child slot,
+ * and we should just put our new leaf in that.
+ * If we point to a T_TNODE, check if it matches our key. Note that
+ * a T_TNODE might be skipping any number of bits - its 'pos' need
+ * not be the parent's 'pos'+'bits'!
+ *
+ * If it does match the current key, get pos/bits from it, extract
+ * the index from our key, push the T_TNODE and walk the tree.
+ *
+ * If it doesn't, we have to replace it with a new T_TNODE.
+ *
+ * If we point to a T_LEAF, it might or might not have the same key
+ * as we do. If it does, just change the value, update the T_LEAF's
+ * value, and return it.
+ * If it doesn't, we need to replace it with a T_TNODE.
+ */
+
+ while (n != NULL && NODE_TYPE(n) == T_TNODE) {
+ tn = (struct tnode *) n;
+
+ check_tnode(tn);
+
+ if(tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
+ tp = tn;
+ pos=tn->pos + tn->bits;
+ n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
+
+ if(n && NODE_PARENT(n) != tn) {
+ printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n));
+ BUG();
+ }
+ }
+ else
+ break;
+ }
+
+ /*
+ * n ----> NULL, LEAF or TNODE
+ *
+ * tp is n's (parent) ----> NULL or TNODE
+ */
+
+ if(tp && IS_LEAF(tp))
+ BUG();
+
+ t->revision++;
+
+ /* Case 1: n is a leaf. Compare prefixes */
+
+ if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
+ struct leaf *l = ( struct leaf *) n;
+
+ li = leaf_info_new(plen);
+
+ if(! li)
+ BUG();
+
+ fa_head = &li->falh;
+ insert_leaf_info(&l->list, li);
+ goto done;
+ }
+ t->size++;
+ l = leaf_new();
+
+ if(! l)
+ BUG();
+
+ l->key = key;
+ li = leaf_info_new(plen);
+
+ if(! li)
+ BUG();
+
+ fa_head = &li->falh;
+ insert_leaf_info(&l->list, li);
+
+ /* Case 2: n is NULL, and will just insert a new leaf */
+ if (t->trie && n == NULL) {
+
+ NODE_SET_PARENT(l, tp);
+
+ if (!tp)
+ BUG();
+
+ else {
+ cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+ put_child(t, (struct tnode *)tp, cindex, (struct node *)l);
+ }
+ }
+ /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */
+ else {
+ /*
+ * Add a new tnode here
+ * first tnode need some special handling
+ */
+
+ if (tp)
+ pos=tp->pos+tp->bits;
+ else
+ pos=0;
+ if(n) {
+ newpos = tkey_mismatch(key, pos, n->key);
+ tn = tnode_new(n->key, newpos, 1);
+ }
+ else {
+ newpos = 0;
+ tn = tnode_new(key, newpos, 1); /* First tnode */
+ }
+ if(!tn)
+ trie_bug("tnode_pfx_new failed");
+
+ NODE_SET_PARENT(tn, tp);
+
+ missbit=tkey_extract_bits(key, newpos, 1);
+ put_child(t, tn, missbit, (struct node *)l);
+ put_child(t, tn, 1-missbit, n);
+
+ if(tp) {
+ cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+ put_child(t, (struct tnode *)tp, cindex, (struct node *)tn);
+ }
+ else {
+ t->trie = (struct node*) tn; /* First tnode */
+ tp = tn;
+ }
+ }
+ if(tp && tp->pos+tp->bits > 32) {
+ printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
+ tp, tp->pos, tp->bits, key, plen);
+ }
+ /* Rebalance the trie */
+ t->trie = trie_rebalance(t, tp);
+done:;
+ return fa_head;
+}
+
+static int
+fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
+ struct nlmsghdr *nlhdr, struct netlink_skb_parms *req)
+{
+ struct trie *t = (struct trie *) tb->tb_data;
+ struct fib_alias *fa, *new_fa;
+ struct list_head *fa_head=NULL;
+ struct fib_info *fi;
+ int plen = r->rtm_dst_len;
+ int type = r->rtm_type;
+ u8 tos = r->rtm_tos;
+ u32 key, mask;
+ int err;
+ struct leaf *l;
+
+ if (plen > 32)
+ return -EINVAL;
+
+ key = 0;
+ if (rta->rta_dst)
+ memcpy(&key, rta->rta_dst, 4);
+
+ key = ntohl(key);
+
+ if(trie_debug)
+ printk("Insert table=%d %08x/%d\n", tb->tb_id, key, plen);
+
+ mask = ntohl( inet_make_mask(plen) );
+
+ if(key & ~mask)
+ return -EINVAL;
+
+ key = key & mask;
+
+ if ((fi = fib_create_info(r, rta, nlhdr, &err)) == NULL)
+ goto err;
+
+ l = fib_find_node(t, key);
+ fa = NULL;
+
+ if(l) {
+ fa_head = get_fa_head(l, plen);
+ fa = fib_find_alias(fa_head, tos, fi->fib_priority);
+ }
+
+ /* Now fa, if non-NULL, points to the first fib alias
+ * with the same keys [prefix,tos,priority], if such key already
+ * exists or to the node before which we will insert new one.
+ *
+ * If fa is NULL, we will need to allocate a new one and
+ * insert to the head of f.
+ *
+ * If f is NULL, no fib node matched the destination key
+ * and we need to allocate a new one of those as well.
+ */
+
+ if (fa &&
+ fa->fa_info->fib_priority == fi->fib_priority) {
+ struct fib_alias *fa_orig;
+
+ err = -EEXIST;
+ if (nlhdr->nlmsg_flags & NLM_F_EXCL)
+ goto out;
+
+ if (nlhdr->nlmsg_flags & NLM_F_REPLACE) {
+ struct fib_info *fi_drop;
+ u8 state;
+
+ write_lock_bh(&fib_lock);
+
+ fi_drop = fa->fa_info;
+ fa->fa_info = fi;
+ fa->fa_type = type;
+ fa->fa_scope = r->rtm_scope;
+ state = fa->fa_state;
+ fa->fa_state &= ~FA_S_ACCESSED;
+
+ write_unlock_bh(&fib_lock);
+
+ fib_release_info(fi_drop);
+ if (state & FA_S_ACCESSED)
+ rt_cache_flush(-1);
+
+ goto succeeded;
+ }
+ /* Error if we find a perfect match which
+ * uses the same scope, type, and nexthop
+ * information.
+ */
+ fa_orig = fa;
+ list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
+ if (fa->fa_tos != tos)
+ break;
+ if (fa->fa_info->fib_priority != fi->fib_priority)
+ break;
+ if (fa->fa_type == type &&
+ fa->fa_scope == r->rtm_scope &&
+ fa->fa_info == fi) {
+ goto out;
+ }
+ }
+ if (!(nlhdr->nlmsg_flags & NLM_F_APPEND))
+ fa = fa_orig;
+ }
+ err = -ENOENT;
+ if (!(nlhdr->nlmsg_flags&NLM_F_CREATE))
+ goto out;
+
+ err = -ENOBUFS;
+ new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL);
+ if (new_fa == NULL)
+ goto out;
+
+ new_fa->fa_info = fi;
+ new_fa->fa_tos = tos;
+ new_fa->fa_type = type;
+ new_fa->fa_scope = r->rtm_scope;
+ new_fa->fa_state = 0;
+#if 0
+ new_fa->dst = NULL;
+#endif
+ /*
+ * Insert new entry to the list.
+ */
+
+ if(!fa_head)
+ fa_head = fib_insert_node(t, key, plen);
+
+ write_lock_bh(&fib_lock);
+
+ list_add_tail(&new_fa->fa_list,
+ (fa ? &fa->fa_list : fa_head));
+
+ write_unlock_bh(&fib_lock);
+
+ rt_cache_flush(-1);
+ rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
+succeeded:
+ return 0;
+out:
+ fib_release_info(fi);
+err:;
+ return err;
+}
+
+static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *plen, const struct flowi *flp,
+ struct fib_result *res, int *err)
+{
+ int i;
+ t_key mask;
+ struct leaf_info *li;
+ struct hlist_head *hhead = &l->list;
+ struct hlist_node *node;
+
+ hlist_for_each_entry(li, node, hhead, hlist) {
+
+ i = li->plen;
+ mask = ntohl(inet_make_mask(i));
+ if (l->key != (key & mask))
+ continue;
+
+ if (((*err) = fib_semantic_match(&li->falh, flp, res, l->key, mask, i)) == 0) {
+ *plen = i;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ t->stats.semantic_match_passed++;
+#endif
+ return 1;
+ }
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ t->stats.semantic_match_miss++;
+#endif
+ }
+ return 0;
+}
+
+static int
+fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+{
+ struct trie *t = (struct trie *) tb->tb_data;
+ int plen, ret = 0;
+ struct node *n;
+ struct tnode *pn;
+ int pos, bits;
+ t_key key=ntohl(flp->fl4_dst);
+ int chopped_off;
+ t_key cindex = 0;
+ int current_prefix_length = KEYLENGTH;
+ n = t->trie;
+
+ read_lock(&fib_lock);
+ if(!n)
+ goto failed;
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ t->stats.gets++;
+#endif
+
+ /* Just a leaf? */
+ if (IS_LEAF(n)) {
+ if( check_leaf(t, (struct leaf *)n, key, &plen, flp, res, &ret) )
+ goto found;
+ goto failed;
+ }
+ pn = (struct tnode *) n;
+ chopped_off = 0;
+
+ while (pn) {
+
+ pos = pn->pos;
+ bits = pn->bits;
+
+ if(!chopped_off)
+ cindex = tkey_extract_bits(MASK_PFX(key, current_prefix_length), pos, bits);
+
+ n = tnode_get_child(pn, cindex);
+
+ if (n == NULL) {
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ t->stats.null_node_hit++;
+#endif
+ goto backtrace;
+ }
+
+ if (IS_TNODE(n)) {
+#define HL_OPTIMIZE
+#ifdef HL_OPTIMIZE
+ struct tnode *cn = (struct tnode *)n;
+ t_key node_prefix, key_prefix, pref_mismatch;
+ int mp;
+
+ /*
+ * It's a tnode, and we can do some extra checks here if we
+ * like, to avoid descending into a dead-end branch.
+ * This tnode is in the parent's child array at index
+ * key[p_pos..p_pos+p_bits] but potentially with some bits
+ * chopped off, so in reality the index may be just a
+ * subprefix, padded with zero at the end.
+ * We can also take a look at any skipped bits in this
+ * tnode - everything up to p_pos is supposed to be ok,
+ * and the non-chopped bits of the index (se previous
+ * paragraph) are also guaranteed ok, but the rest is
+ * considered unknown.
+ *
+ * The skipped bits are key[pos+bits..cn->pos].
+ */
+
+ /* If current_prefix_length < pos+bits, we are already doing
+ * actual prefix matching, which means everything from
+ * pos+(bits-chopped_off) onward must be zero along some
+ * branch of this subtree - otherwise there is *no* valid
+ * prefix present. Here we can only check the skipped
+ * bits. Remember, since we have already indexed into the
+ * parent's child array, we know that the bits we chopped of
+ * *are* zero.
+ */
+
+ /* NOTA BENE: CHECKING ONLY SKIPPED BITS FOR THE NEW NODE HERE */
+
+ if (current_prefix_length < pos+bits) {
+ if (tkey_extract_bits(cn->key, current_prefix_length,
+ cn->pos - current_prefix_length) != 0 ||
+ !(cn->child[0]))
+ goto backtrace;
+ }
+
+ /*
+ * If chopped_off=0, the index is fully validated and we
+ * only need to look at the skipped bits for this, the new,
+ * tnode. What we actually want to do is to find out if
+ * these skipped bits match our key perfectly, or if we will
+ * have to count on finding a matching prefix further down,
+ * because if we do, we would like to have some way of
+ * verifying the existence of such a prefix at this point.
+ */
+
+ /* The only thing we can do at this point is to verify that
+ * any such matching prefix can indeed be a prefix to our
+ * key, and if the bits in the node we are inspecting that
+ * do not match our key are not ZERO, this cannot be true.
+ * Thus, find out where there is a mismatch (before cn->pos)
+ * and verify that all the mismatching bits are zero in the
+ * new tnode's key.
+ */
+
+ /* Note: We aren't very concerned about the piece of the key
+ * that precede pn->pos+pn->bits, since these have already been
+ * checked. The bits after cn->pos aren't checked since these are
+ * by definition "unknown" at this point. Thus, what we want to
+ * see is if we are about to enter the "prefix matching" state,
+ * and in that case verify that the skipped bits that will prevail
+ * throughout this subtree are zero, as they have to be if we are
+ * to find a matching prefix.
+ */
+
+ node_prefix = MASK_PFX(cn->key, cn->pos);
+ key_prefix = MASK_PFX(key, cn->pos);
+ pref_mismatch = key_prefix^node_prefix;
+ mp = 0;
+
+ /* In short: If skipped bits in this node do not match the search
+ * key, enter the "prefix matching" state.directly.
+ */
+ if (pref_mismatch) {
+ while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) {
+ mp++;
+ pref_mismatch = pref_mismatch <<1;
+ }
+ key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp);
+
+ if (key_prefix != 0)
+ goto backtrace;
+
+ if (current_prefix_length >= cn->pos)
+ current_prefix_length=mp;
+ }
+#endif
+ pn = (struct tnode *)n; /* Descend */
+ chopped_off = 0;
+ continue;
+ }
+ if (IS_LEAF(n)) {
+ if( check_leaf(t, (struct leaf *)n, key, &plen, flp, res, &ret))
+ goto found;
+ }
+backtrace:
+ chopped_off++;
+
+ /* As zero don't change the child key (cindex) */
+ while ((chopped_off <= pn->bits) && !(cindex & (1<<(chopped_off-1)))) {
+ chopped_off++;
+ }
+
+ /* Decrease current_... with bits chopped off */
+ if (current_prefix_length > pn->pos + pn->bits - chopped_off)
+ current_prefix_length = pn->pos + pn->bits - chopped_off;
+
+ /*
+ * Either we do the actual chop off according or if we have
+ * chopped off all bits in this tnode walk up to our parent.
+ */
+
+ if(chopped_off <= pn->bits)
+ cindex &= ~(1 << (chopped_off-1));
+ else {
+ if( NODE_PARENT(pn) == NULL)
+ goto failed;
+
+ /* Get Child's index */
+ cindex = tkey_extract_bits(pn->key, NODE_PARENT(pn)->pos, NODE_PARENT(pn)->bits);
+ pn = NODE_PARENT(pn);
+ chopped_off = 0;
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ t->stats.backtrack++;
+#endif
+ goto backtrace;
+ }
+ }
+failed:
+ ret = 1;
+found:
+ read_unlock(&fib_lock);
+ return ret;
+}
+
+static int trie_leaf_remove(struct trie *t, t_key key)
+{
+ t_key cindex;
+ struct tnode *tp = NULL;
+ struct node *n = t->trie;
+ struct leaf *l;
+
+ if(trie_debug)
+ printk("entering trie_leaf_remove(%p)\n", n);
+
+ /* Note that in the case skipped bits, those bits are *not* checked!
+ * When we finish this, we will have NULL or a T_LEAF, and the
+ * T_LEAF may or may not match our key.
+ */
+
+ while (n != NULL && IS_TNODE(n)) {
+ struct tnode *tn = (struct tnode *) n;
+ check_tnode(tn);
+ n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits));
+
+ if(n && NODE_PARENT(n) != tn) {
+ printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n));
+ BUG();
+ }
+ }
+ l = (struct leaf *) n;
+
+ if(!n || !tkey_equals(l->key, key))
+ return 0;
+
+ /*
+ * Key found.
+ * Remove the leaf and rebalance the tree
+ */
+
+ t->revision++;
+ t->size--;
+
+ tp = NODE_PARENT(n);
+ tnode_free((struct tnode *) n);
+
+ if(tp) {
+ cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+ put_child(t, (struct tnode *)tp, cindex, NULL);
+ t->trie = trie_rebalance(t, tp);
+ }
+ else
+ t->trie = NULL;
+
+ return 1;
+}
+
+static int
+fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
+ struct nlmsghdr *nlhdr, struct netlink_skb_parms *req)
+{
+ struct trie *t = (struct trie *) tb->tb_data;
+ u32 key, mask;
+ int plen = r->rtm_dst_len;
+ u8 tos = r->rtm_tos;
+ struct fib_alias *fa, *fa_to_delete;
+ struct list_head *fa_head;
+ struct leaf *l;
+
+ if (plen > 32)
+ return -EINVAL;
+
+ key = 0;
+ if (rta->rta_dst)
+ memcpy(&key, rta->rta_dst, 4);
+
+ key = ntohl(key);
+ mask = ntohl( inet_make_mask(plen) );
+
+ if(key & ~mask)
+ return -EINVAL;
+
+ key = key & mask;
+ l = fib_find_node(t, key);
+
+ if(!l)
+ return -ESRCH;
+
+ fa_head = get_fa_head(l, plen);
+ fa = fib_find_alias(fa_head, tos, 0);
+
+ if (!fa)
+ return -ESRCH;
+
+ if (trie_debug)
+ printk("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
+
+ fa_to_delete = NULL;
+ fa_head = fa->fa_list.prev;
+ list_for_each_entry(fa, fa_head, fa_list) {
+ struct fib_info *fi = fa->fa_info;
+
+ if (fa->fa_tos != tos)
+ break;
+
+ if ((!r->rtm_type ||
+ fa->fa_type == r->rtm_type) &&
+ (r->rtm_scope == RT_SCOPE_NOWHERE ||
+ fa->fa_scope == r->rtm_scope) &&
+ (!r->rtm_protocol ||
+ fi->fib_protocol == r->rtm_protocol) &&
+ fib_nh_match(r, nlhdr, rta, fi) == 0) {
+ fa_to_delete = fa;
+ break;
+ }
+ }
+
+ if (fa_to_delete) {
+ int kill_li = 0;
+ struct leaf_info *li;
+
+ fa = fa_to_delete;
+ rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);
+
+ l = fib_find_node(t, key);
+ li = find_leaf_info(&l->list, plen);
+
+ write_lock_bh(&fib_lock);
+
+ list_del(&fa->fa_list);
+
+ if(list_empty(fa_head)) {
+ hlist_del(&li->hlist);
+ kill_li = 1;
+ }
+ write_unlock_bh(&fib_lock);
+
+ if(kill_li)
+ free_leaf_info(li);
+
+ if(hlist_empty(&l->list))
+ trie_leaf_remove(t, key);
+
+ if (fa->fa_state & FA_S_ACCESSED)
+ rt_cache_flush(-1);
+
+ fn_free_alias(fa);
+ return 0;
+ }
+ return -ESRCH;
+}
+
+static int trie_flush_list(struct trie *t, struct list_head *head)
+{
+ struct fib_alias *fa, *fa_node;
+ int found = 0;
+
+ list_for_each_entry_safe(fa, fa_node, head, fa_list) {
+ struct fib_info *fi = fa->fa_info;
+
+ if (fi && (fi->fib_flags&RTNH_F_DEAD)) {
+
+ write_lock_bh(&fib_lock);
+ list_del(&fa->fa_list);
+ write_unlock_bh(&fib_lock);
+
+ fn_free_alias(fa);
+ found++;
+ }
+ }
+ return found;
+}
+
+static int trie_flush_leaf(struct trie *t, struct leaf *l)
+{
+ int found = 0;
+ struct hlist_head *lih = &l->list;
+ struct hlist_node *node, *tmp;
+ struct leaf_info *li = NULL;
+
+ hlist_for_each_entry_safe(li, node, tmp, lih, hlist) {
+
+ found += trie_flush_list(t, &li->falh);
+
+ if (list_empty(&li->falh)) {
+
+ write_lock_bh(&fib_lock);
+ hlist_del(&li->hlist);
+ write_unlock_bh(&fib_lock);
+
+ free_leaf_info(li);
+ }
+ }
+ return found;
+}
+
+static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
+{
+ struct node *c = (struct node *) thisleaf;
+ struct tnode *p;
+ int idx;
+
+ if(c == NULL) {
+ if(t->trie == NULL)
+ return NULL;
+
+ if (IS_LEAF(t->trie)) /* trie w. just a leaf */
+ return (struct leaf *) t->trie;
+
+ p = (struct tnode*) t->trie; /* Start */
+ }
+ else
+ p = (struct tnode *) NODE_PARENT(c);
+ while (p) {
+ int pos, last;
+
+ /* Find the next child of the parent */
+ if(c)
+ pos = 1 + tkey_extract_bits(c->key, p->pos, p->bits);
+ else
+ pos = 0;
+
+ last = 1 << p->bits;
+ for(idx = pos; idx < last ; idx++) {
+ if( p->child[idx]) {
+
+ /* Decend if tnode */
+
+ while (IS_TNODE(p->child[idx])) {
+ p = (struct tnode*) p->child[idx];
+ idx = 0;
+
+ /* Rightmost non-NULL branch */
+ if( p && IS_TNODE(p) )
+ while ( p->child[idx] == NULL && idx < (1 << p->bits) ) idx++;
+
+ /* Done with this tnode? */
+ if( idx >= (1 << p->bits) || p->child[idx] == NULL )
+ goto up;
+ }
+ return (struct leaf*) p->child[idx];
+ }
+ }
+up:
+ /* No more children go up one step */
+ c = (struct node*) p;
+ p = (struct tnode *) NODE_PARENT(p);
+ }
+ return NULL; /* Ready. Root of trie */
+}
+
+static int fn_trie_flush(struct fib_table *tb)
+{
+ struct trie *t = (struct trie *) tb->tb_data;
+ struct leaf *ll = NULL, *l = NULL;
+ int found = 0, h;
+
+ t->revision++;
+
+ for (h=0; (l = nextleaf(t, l)) != NULL; h++) {
+ found += trie_flush_leaf(t, l);
+
+ if (ll && hlist_empty(&ll->list))
+ trie_leaf_remove(t, ll->key);
+ ll = l;
+ }
+
+ if (ll && hlist_empty(&ll->list))
+ trie_leaf_remove(t, ll->key);
+
+ if(trie_debug)
+ printk("trie_flush found=%d\n", found);
+ return found;
+}
+
+static int trie_last_dflt=-1;
+
+static void
+fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+{
+ struct trie *t = (struct trie *) tb->tb_data;
+ int order, last_idx;
+ struct fib_info *fi = NULL;
+ struct fib_info *last_resort;
+ struct fib_alias *fa = NULL;
+ struct list_head *fa_head;
+ struct leaf *l;
+
+ last_idx = -1;
+ last_resort = NULL;
+ order = -1;
+
+ read_lock(&fib_lock);
+
+ l = fib_find_node(t, 0);
+ if(!l)
+ goto out;
+
+ fa_head = get_fa_head(l, 0);
+ if(!fa_head)
+ goto out;
+
+ if (list_empty(fa_head))
+ goto out;
+
+ list_for_each_entry(fa, fa_head, fa_list) {
+ struct fib_info *next_fi = fa->fa_info;
+
+ if (fa->fa_scope != res->scope ||
+ fa->fa_type != RTN_UNICAST)
+ continue;
+
+ if (next_fi->fib_priority > res->fi->fib_priority)
+ break;
+ if (!next_fi->fib_nh[0].nh_gw ||
+ next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
+ continue;
+ fa->fa_state |= FA_S_ACCESSED;
+
+ if (fi == NULL) {
+ if (next_fi != res->fi)
+ break;
+ } else if (!fib_detect_death(fi, order, &last_resort,
+ &last_idx, &trie_last_dflt)) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = fi;
+ atomic_inc(&fi->fib_clntref);
+ trie_last_dflt = order;
+ goto out;
+ }
+ fi = next_fi;
+ order++;
+ }
+ if (order <= 0 || fi == NULL) {
+ trie_last_dflt = -1;
+ goto out;
+ }
+
+ if (!fib_detect_death(fi, order, &last_resort, &last_idx, &trie_last_dflt)) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = fi;
+ atomic_inc(&fi->fib_clntref);
+ trie_last_dflt = order;
+ goto out;
+ }
+ if (last_idx >= 0) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = last_resort;
+ if (last_resort)
+ atomic_inc(&last_resort->fib_clntref);
+ }
+ trie_last_dflt = last_idx;
+ out:;
+ read_unlock(&fib_lock);
+}
+
+static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fib_table *tb,
+ struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int i, s_i;
+ struct fib_alias *fa;
+
+ u32 xkey=htonl(key);
+
+ s_i=cb->args[3];
+ i = 0;
+
+ list_for_each_entry(fa, fah, fa_list) {
+ if (i < s_i) {
+ i++;
+ continue;
+ }
+ if (fa->fa_info->fib_nh == NULL) {
+ printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
+ i++;
+ continue;
+ }
+ if (fa->fa_info == NULL) {
+ printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
+ i++;
+ continue;
+ }
+
+ if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq,
+ RTM_NEWROUTE,
+ tb->tb_id,
+ fa->fa_type,
+ fa->fa_scope,
+ &xkey,
+ plen,
+ fa->fa_tos,
+ fa->fa_info, 0) < 0) {
+ cb->args[3] = i;
+ return -1;
+ }
+ i++;
+ }
+ cb->args[3]=i;
+ return skb->len;
+}
+
+static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb, struct sk_buff *skb,
+ struct netlink_callback *cb)
+{
+ int h, s_h;
+ struct list_head *fa_head;
+ struct leaf *l = NULL;
+ s_h=cb->args[2];
+
+ for (h=0; (l = nextleaf(t, l)) != NULL; h++) {
+
+ if (h < s_h)
+ continue;
+ if (h > s_h)
+ memset(&cb->args[3], 0,
+ sizeof(cb->args) - 3*sizeof(cb->args[0]));
+
+ fa_head = get_fa_head(l, plen);
+
+ if(!fa_head)
+ continue;
+
+ if(list_empty(fa_head))
+ continue;
+
+ if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb)<0) {
+ cb->args[2]=h;
+ return -1;
+ }
+ }
+ cb->args[2]=h;
+ return skb->len;
+}
+
+static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb)
+{
+ int m, s_m;
+ struct trie *t = (struct trie *) tb->tb_data;
+
+ s_m = cb->args[1];
+
+ read_lock(&fib_lock);
+ for (m=0; m<=32; m++) {
+
+ if (m < s_m)
+ continue;
+ if (m > s_m)
+ memset(&cb->args[2], 0,
+ sizeof(cb->args) - 2*sizeof(cb->args[0]));
+
+ if (fn_trie_dump_plen(t, 32-m, tb, skb, cb)<0) {
+ cb->args[1] = m;
+ goto out;
+ }
+ }
+ read_unlock(&fib_lock);
+ cb->args[1] = m;
+ return skb->len;
+ out:
+ read_unlock(&fib_lock);
+ return -1;
+}
+
+/* Fix more generic FIB names for init later */
+
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+struct fib_table * fib_hash_init(int id)
+#else
+struct fib_table * __init fib_hash_init(int id)
+#endif
+{
+ struct fib_table *tb;
+ struct trie *t;
+
+ if (fn_alias_kmem == NULL)
+ fn_alias_kmem = kmem_cache_create("ip_fib_alias",
+ sizeof(struct fib_alias),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL, NULL);
+
+ tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie),
+ GFP_KERNEL);
+ if (tb == NULL)
+ return NULL;
+
+ tb->tb_id = id;
+ tb->tb_lookup = fn_trie_lookup;
+ tb->tb_insert = fn_trie_insert;
+ tb->tb_delete = fn_trie_delete;
+ tb->tb_flush = fn_trie_flush;
+ tb->tb_select_default = fn_trie_select_default;
+ tb->tb_dump = fn_trie_dump;
+ memset(tb->tb_data, 0, sizeof(struct trie));
+
+ t = (struct trie *) tb->tb_data;
+
+ trie_init(t);
+
+ if (id == RT_TABLE_LOCAL)
+ trie_local=t;
+ else if (id == RT_TABLE_MAIN)
+ trie_main=t;
+
+ if (id == RT_TABLE_LOCAL)
+ printk("IPv4 FIB: Using LC-trie version %s\n", VERSION);
+
+ return tb;
+}
+
+/* Trie dump functions */
+
+static void putspace_seq(struct seq_file *seq, int n)
+{
+ while (n--) seq_printf(seq, " ");
+}
+
+static void printbin_seq(struct seq_file *seq, unsigned int v, int bits)
+{
+ while (bits--)
+ seq_printf(seq, "%s", (v & (1<<bits))?"1":"0");
+}
+
+static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
+ int pend, int cindex, int bits)
+{
+ putspace_seq(seq, indent);
+ if (IS_LEAF(n))
+ seq_printf(seq, "|");
+ else
+ seq_printf(seq, "+");
+ if (bits) {
+ seq_printf(seq, "%d/", cindex);
+ printbin_seq(seq, cindex, bits);
+ seq_printf(seq, ": ");
+ }
+ else
+ seq_printf(seq, "<root>: ");
+ seq_printf(seq, "%s:%p ", IS_LEAF(n)?"Leaf":"Internal node", n);
+
+ if (IS_LEAF(n))
+ seq_printf(seq, "key=%d.%d.%d.%d\n",
+ n->key >> 24, (n->key >> 16) % 256, (n->key >> 8) % 256, n->key % 256);
+ else {
+ int plen=((struct tnode *)n)->pos;
+ t_key prf=MASK_PFX(n->key, plen);
+ seq_printf(seq, "key=%d.%d.%d.%d/%d\n",
+ prf >> 24, (prf >> 16) % 256, (prf >> 8) % 256, prf % 256, plen);
+ }
+ if (IS_LEAF(n)) {
+ struct leaf *l=(struct leaf *)n;
+ struct fib_alias *fa;
+ int i;
+ for (i=32; i>=0; i--)
+ if(find_leaf_info(&l->list, i)) {
+
+ struct list_head *fa_head = get_fa_head(l, i);
+
+ if(!fa_head)
+ continue;
+
+ if(list_empty(fa_head))
+ continue;
+
+ putspace_seq(seq, indent+2);
+ seq_printf(seq, "{/%d...dumping}\n", i);
+
+
+ list_for_each_entry(fa, fa_head, fa_list) {
+ putspace_seq(seq, indent+2);
+ if (fa->fa_info->fib_nh == NULL) {
+ seq_printf(seq, "Error _fib_nh=NULL\n");
+ continue;
+ }
+ if (fa->fa_info == NULL) {
+ seq_printf(seq, "Error fa_info=NULL\n");
+ continue;
+ }
+
+ seq_printf(seq, "{type=%d scope=%d TOS=%d}\n",
+ fa->fa_type,
+ fa->fa_scope,
+ fa->fa_tos);
+ }
+ }
+ }
+ else if (IS_TNODE(n)) {
+ struct tnode *tn=(struct tnode *)n;
+ putspace_seq(seq, indent); seq_printf(seq, "| ");
+ seq_printf(seq, "{key prefix=%08x/", tn->key&TKEY_GET_MASK(0, tn->pos));
+ printbin_seq(seq, tkey_extract_bits(tn->key, 0, tn->pos), tn->pos);
+ seq_printf(seq, "}\n");
+ putspace_seq(seq, indent); seq_printf(seq, "| ");
+ seq_printf(seq, "{pos=%d", tn->pos);
+ seq_printf(seq, " (skip=%d bits)", tn->pos - pend);
+ seq_printf(seq, " bits=%d (%u children)}\n", tn->bits, (1 << tn->bits));
+ putspace_seq(seq, indent); seq_printf(seq, "| ");
+ seq_printf(seq, "{empty=%d full=%d}\n", tn->empty_children, tn->full_children);
+ }
+}
+
+static void trie_dump_seq(struct seq_file *seq, struct trie *t)
+{
+ struct node *n=t->trie;
+ int cindex=0;
+ int indent=1;
+ int pend=0;
+ int depth = 0;
+
+ read_lock(&fib_lock);
+
+ seq_printf(seq, "------ trie_dump of t=%p ------\n", t);
+ if (n) {
+ printnode_seq(seq, indent, n, pend, cindex, 0);
+ if (IS_TNODE(n)) {
+ struct tnode *tn=(struct tnode *)n;
+ pend = tn->pos+tn->bits;
+ putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
+ indent += 3;
+ depth++;
+
+ while (tn && cindex < (1 << tn->bits)) {
+ if (tn->child[cindex]) {
+
+ /* Got a child */
+
+ printnode_seq(seq, indent, tn->child[cindex], pend, cindex, tn->bits);
+ if (IS_LEAF(tn->child[cindex])) {
+ cindex++;
+
+ }
+ else {
+ /*
+ * New tnode. Decend one level
+ */
+
+ depth++;
+ n=tn->child[cindex];
+ tn=(struct tnode *)n;
+ pend=tn->pos+tn->bits;
+ putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
+ indent+=3;
+ cindex=0;
+ }
+ }
+ else
+ cindex++;
+
+ /*
+ * Test if we are done
+ */
+
+ while (cindex >= (1 << tn->bits)) {
+
+ /*
+ * Move upwards and test for root
+ * pop off all traversed nodes
+ */
+
+ if (NODE_PARENT(tn) == NULL) {
+ tn = NULL;
+ n = NULL;
+ break;
+ }
+ else {
+ cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
+ tn = NODE_PARENT(tn);
+ cindex++;
+ n=(struct node *)tn;
+ pend=tn->pos+tn->bits;
+ indent-=3;
+ depth--;
+ }
+ }
+ }
+ }
+ else n = NULL;
+ }
+ else seq_printf(seq, "------ trie is empty\n");
+
+ read_unlock(&fib_lock);
+}
+
+static struct trie_stat *trie_stat_new(void)
+{
+ struct trie_stat *s = kmalloc(sizeof(struct trie_stat), GFP_KERNEL);
+ int i;
+
+ if(s) {
+ s->totdepth = 0;
+ s->maxdepth = 0;
+ s->tnodes = 0;
+ s->leaves = 0;
+ s->nullpointers = 0;
+
+ for(i=0; i< MAX_CHILDS; i++)
+ s->nodesizes[i] = 0;
+ }
+ return s;
+}
+
+static struct trie_stat *trie_collect_stats(struct trie *t)
+{
+ struct node *n=t->trie;
+ struct trie_stat *s = trie_stat_new();
+ int cindex = 0;
+ int indent = 1;
+ int pend = 0;
+ int depth = 0;
+
+ read_lock(&fib_lock);
+
+ if (s) {
+ if (n) {
+ if (IS_TNODE(n)) {
+ struct tnode *tn = (struct tnode *)n;
+ pend=tn->pos+tn->bits;
+ indent += 3;
+ s->nodesizes[tn->bits]++;
+ depth++;
+
+ while (tn && cindex < (1 << tn->bits)) {
+ if (tn->child[cindex]) {
+ /* Got a child */
+
+ if (IS_LEAF(tn->child[cindex])) {
+ cindex++;
+
+ /* stats */
+ if (depth > s->maxdepth)
+ s->maxdepth = depth;
+ s->totdepth += depth;
+ s->leaves++;
+ }
+
+ else {
+ /*
+ * New tnode. Decend one level
+ */
+
+ s->tnodes++;
+ s->nodesizes[tn->bits]++;
+ depth++;
+
+ n = tn->child[cindex];
+ tn = (struct tnode *)n;
+ pend = tn->pos+tn->bits;
+
+ indent += 3;
+ cindex = 0;
+ }
+ }
+ else {
+ cindex++;
+ s->nullpointers++;
+ }
+
+ /*
+ * Test if we are done
+ */
+
+ while (cindex >= (1 << tn->bits)) {
+
+ /*
+ * Move upwards and test for root
+ * pop off all traversed nodes
+ */
+
+
+ if (NODE_PARENT(tn) == NULL) {
+ tn = NULL;
+ n = NULL;
+ break;
+ }
+ else {
+ cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
+ tn = NODE_PARENT(tn);
+ cindex++;
+ n = (struct node *)tn;
+ pend=tn->pos+tn->bits;
+ indent -= 3;
+ depth--;
+ }
+ }
+ }
+ }
+ else n = NULL;
+ }
+ }
+
+ read_unlock(&fib_lock);
+ return s;
+}
+
+#ifdef CONFIG_PROC_FS
+
+static struct fib_alias *fib_triestat_get_first(struct seq_file *seq)
+{
+ return NULL;
+}
+
+static struct fib_alias *fib_triestat_get_next(struct seq_file *seq)
+{
+ return NULL;
+}
+
+static void *fib_triestat_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ void *v = NULL;
+
+ if (ip_fib_main_table)
+ v = *pos ? fib_triestat_get_next(seq) : SEQ_START_TOKEN;
+ return v;
+}
+
+static void *fib_triestat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ return v == SEQ_START_TOKEN ? fib_triestat_get_first(seq) : fib_triestat_get_next(seq);
+}
+
+static void fib_triestat_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+/*
+ * This outputs /proc/net/fib_triestats
+ *
+ * It always works in backward compatibility mode.
+ * The format of the file is not supposed to be changed.
+ */
+
+static void collect_and_show(struct trie *t, struct seq_file *seq)
+{
+ int bytes = 0; /* How many bytes are used, a ref is 4 bytes */
+ int i, max, pointers;
+ struct trie_stat *stat;
+ int avdepth;
+
+ stat = trie_collect_stats(t);
+
+ bytes=0;
+ seq_printf(seq, "trie=%p\n", t);
+
+ if (stat) {
+ if (stat->leaves)
+ avdepth=stat->totdepth*100 / stat->leaves;
+ else
+ avdepth=0;
+ seq_printf(seq, "Aver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
+ seq_printf(seq, "Max depth: %4d\n", stat->maxdepth);
+
+ seq_printf(seq, "Leaves: %d\n", stat->leaves);
+ bytes += sizeof(struct leaf) * stat->leaves;
+ seq_printf(seq, "Internal nodes: %d\n", stat->tnodes);
+ bytes += sizeof(struct tnode) * stat->tnodes;
+
+ max = MAX_CHILDS-1;
+
+ while (max >= 0 && stat->nodesizes[max] == 0)
+ max--;
+ pointers = 0;
+
+ for (i = 1; i <= max; i++)
+ if (stat->nodesizes[i] != 0) {
+ seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
+ pointers += (1<<i) * stat->nodesizes[i];
+ }
+ seq_printf(seq, "\n");
+ seq_printf(seq, "Pointers: %d\n", pointers);
+ bytes += sizeof(struct node *) * pointers;
+ seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
+ seq_printf(seq, "Total size: %d kB\n", bytes / 1024);
+
+ kfree(stat);
+ }
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ seq_printf(seq, "Counters:\n---------\n");
+ seq_printf(seq,"gets = %d\n", t->stats.gets);
+ seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
+ seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
+ seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
+ seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
+#ifdef CLEAR_STATS
+ memset(&(t->stats), 0, sizeof(t->stats));
+#endif
+#endif /* CONFIG_IP_FIB_TRIE_STATS */
+}
+
+static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+{
+ char bf[128];
+
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+ sizeof(struct leaf), sizeof(struct tnode));
+ if (trie_local)
+ collect_and_show(trie_local, seq);
+
+ if (trie_main)
+ collect_and_show(trie_main, seq);
+ }
+ else {
+ snprintf(bf, sizeof(bf),
+ "*\t%08X\t%08X", 200, 400);
+
+ seq_printf(seq, "%-127s\n", bf);
+ }
+ return 0;
+}
+
+static struct seq_operations fib_triestat_seq_ops = {
+ .start = fib_triestat_seq_start,
+ .next = fib_triestat_seq_next,
+ .stop = fib_triestat_seq_stop,
+ .show = fib_triestat_seq_show,
+};
+
+static int fib_triestat_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+
+ rc = seq_open(file, &fib_triestat_seq_ops);
+ if (rc)
+ goto out_kfree;
+
+ seq = file->private_data;
+out:
+ return rc;
+out_kfree:
+ goto out;
+}
+
+static struct file_operations fib_triestat_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_triestat_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
+int __init fib_stat_proc_init(void)
+{
+ if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops))
+ return -ENOMEM;
+ return 0;
+}
+
+void __init fib_stat_proc_exit(void)
+{
+ proc_net_remove("fib_triestat");
+}
+
+static struct fib_alias *fib_trie_get_first(struct seq_file *seq)
+{
+ return NULL;
+}
+
+static struct fib_alias *fib_trie_get_next(struct seq_file *seq)
+{
+ return NULL;
+}
+
+static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ void *v = NULL;
+
+ if (ip_fib_main_table)
+ v = *pos ? fib_trie_get_next(seq) : SEQ_START_TOKEN;
+ return v;
+}
+
+static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ return v == SEQ_START_TOKEN ? fib_trie_get_first(seq) : fib_trie_get_next(seq);
+}
+
+static void fib_trie_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+/*
+ * This outputs /proc/net/fib_trie.
+ *
+ * It always works in backward compatibility mode.
+ * The format of the file is not supposed to be changed.
+ */
+
+static int fib_trie_seq_show(struct seq_file *seq, void *v)
+{
+ char bf[128];
+
+ if (v == SEQ_START_TOKEN) {
+ if (trie_local)
+ trie_dump_seq(seq, trie_local);
+
+ if (trie_main)
+ trie_dump_seq(seq, trie_main);
+ }
+
+ else {
+ snprintf(bf, sizeof(bf),
+ "*\t%08X\t%08X", 200, 400);
+ seq_printf(seq, "%-127s\n", bf);
+ }
+
+ return 0;
+}
+
+static struct seq_operations fib_trie_seq_ops = {
+ .start = fib_trie_seq_start,
+ .next = fib_trie_seq_next,
+ .stop = fib_trie_seq_stop,
+ .show = fib_trie_seq_show,
+};
+
+static int fib_trie_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+
+ rc = seq_open(file, &fib_trie_seq_ops);
+ if (rc)
+ goto out_kfree;
+
+ seq = file->private_data;
+out:
+ return rc;
+out_kfree:
+ goto out;
+}
+
+static struct file_operations fib_trie_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_trie_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
+int __init fib_proc_init(void)
+{
+ if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_seq_fops))
+ return -ENOMEM;
+ return 0;
+}
+
+void __init fib_proc_exit(void)
+{
+ proc_net_remove("fib_trie");
+}
+
+#endif /* CONFIG_PROC_FS */
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 4e47a2658c7c..af2ec88bbb2f 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -184,6 +184,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
raw_rcv(last, skb2);
}
last = sk;
+ nf_reset(skb);
}
}
@@ -200,10 +201,6 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
{
int ihl = skb->nh.iph->ihl*4;
-#ifdef CONFIG_NETFILTER_DEBUG
- nf_debug_ip_local_deliver(skb);
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
__skb_pull(skb, ihl);
/* Free reference early: we don't need it any more, and it may
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 760dc8238d65..ee07aec215a0 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -107,10 +107,6 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
newskb->pkt_type = PACKET_LOOPBACK;
newskb->ip_summed = CHECKSUM_UNNECESSARY;
BUG_TRAP(newskb->dst);
-
-#ifdef CONFIG_NETFILTER_DEBUG
- nf_debug_ip_loopback_xmit(newskb);
-#endif
nf_reset(newskb);
netif_rx(newskb);
return 0;
@@ -192,10 +188,6 @@ static inline int ip_finish_output2(struct sk_buff *skb)
skb = skb2;
}
-#ifdef CONFIG_NETFILTER_DEBUG
- nf_debug_ip_finish_output2(skb);
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
nf_reset(skb);
if (hh) {
@@ -415,9 +407,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->nf_bridge = from->nf_bridge;
nf_bridge_get(to->nf_bridge);
#endif
-#ifdef CONFIG_NETFILTER_DEBUG
- to->nf_debug = from->nf_debug;
-#endif
#endif
}
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 1a23c5263b99..2065944fd9e5 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -236,15 +236,10 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
-
- t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
- if (t->type == NULL)
- goto error;
-
- if (t->type->init_state(t, NULL))
+
+ if (xfrm_init_state(t))
goto error;
- t->km.state = XFRM_STATE_VALID;
atomic_set(&t->tunnel_users, 1);
out:
return t;
@@ -422,7 +417,7 @@ static void ipcomp_destroy(struct xfrm_state *x)
kfree(ipcd);
}
-static int ipcomp_init_state(struct xfrm_state *x, void *args)
+static int ipcomp_init_state(struct xfrm_state *x)
{
int err;
struct ipcomp_data *ipcd;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index e21c049ec62a..e4f809a93f47 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1350,6 +1350,7 @@ int ip_mr_input(struct sk_buff *skb)
*/
read_lock(&mrt_lock);
if (mroute_socket) {
+ nf_reset(skb);
raw_rcv(mroute_socket, skb);
read_unlock(&mrt_lock);
return 0;
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index de21da00057f..a8512a3fd08a 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -127,7 +127,6 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
#define IP_VS_XMIT(skb, rt) \
do { \
- nf_reset_debug(skb); \
(skb)->nfcache |= NFC_IPVS_PROPERTY; \
(skb)->ip_summed = CHECKSUM_NONE; \
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL, \
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index df79f5ed6a0a..fa1634256680 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -60,7 +60,6 @@ static DECLARE_MUTEX(arpt_mutex);
#define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
#define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/listhelp.h>
struct arpt_table_info {
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index 3dbddd062605..a78a320eee08 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -26,7 +26,6 @@
#include <net/checksum.h>
#include <net/udp.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
@@ -42,7 +41,7 @@ static char *conns[] = { "DATA ", "MESG ", "INDEX " };
/* This is slow, but it's simple. --RR */
static char amanda_buffer[65536];
-static DECLARE_LOCK(amanda_buffer_lock);
+static DEFINE_SPINLOCK(amanda_buffer_lock);
unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
@@ -76,7 +75,7 @@ static int help(struct sk_buff **pskb,
return NF_ACCEPT;
}
- LOCK_BH(&amanda_buffer_lock);
+ spin_lock_bh(&amanda_buffer_lock);
skb_copy_bits(*pskb, dataoff, amanda_buffer, (*pskb)->len - dataoff);
data = amanda_buffer;
data_limit = amanda_buffer + (*pskb)->len - dataoff;
@@ -134,7 +133,7 @@ static int help(struct sk_buff **pskb,
}
out:
- UNLOCK_BH(&amanda_buffer_lock);
+ spin_unlock_bh(&amanda_buffer_lock);
return ret;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 09e824622977..4b78ebeb6635 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -38,10 +38,10 @@
#include <linux/percpu.h>
#include <linux/moduleparam.h>
-/* This rwlock protects the main hash table, protocol/helper/expected
+/* ip_conntrack_lock protects the main hash table, protocol/helper/expected
registrations, conntrack timers*/
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
@@ -57,7 +57,7 @@
#define DEBUGP(format, args...)
#endif
-DECLARE_RWLOCK(ip_conntrack_lock);
+DEFINE_RWLOCK(ip_conntrack_lock);
/* ip_conntrack_standalone needs this */
atomic_t ip_conntrack_count = ATOMIC_INIT(0);
@@ -147,7 +147,7 @@ static void destroy_expect(struct ip_conntrack_expect *exp)
static void unlink_expect(struct ip_conntrack_expect *exp)
{
- MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
+ ASSERT_WRITE_LOCK(&ip_conntrack_lock);
list_del(&exp->list);
/* Logically in destroy_expect, but we hold the lock here. */
exp->master->expecting--;
@@ -157,9 +157,9 @@ static void expectation_timed_out(unsigned long ul_expect)
{
struct ip_conntrack_expect *exp = (void *)ul_expect;
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
unlink_expect(exp);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
destroy_expect(exp);
}
@@ -209,7 +209,7 @@ clean_from_lists(struct ip_conntrack *ct)
unsigned int ho, hr;
DEBUGP("clean_from_lists(%p)\n", ct);
- MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
+ ASSERT_WRITE_LOCK(&ip_conntrack_lock);
ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
@@ -240,7 +240,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
if (ip_conntrack_destroyed)
ip_conntrack_destroyed(ct);
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
/* Expectations will have been removed in clean_from_lists,
* except TFTP can create an expectation on the first packet,
* before connection is in the list, so we need to clean here,
@@ -254,7 +254,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
}
CONNTRACK_STAT_INC(delete);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
if (ct->master)
ip_conntrack_put(ct->master);
@@ -268,12 +268,12 @@ static void death_by_timeout(unsigned long ul_conntrack)
{
struct ip_conntrack *ct = (void *)ul_conntrack;
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
/* Inside lock so preempt is disabled on module removal path.
* Otherwise we can get spurious warnings. */
CONNTRACK_STAT_INC(delete_list);
clean_from_lists(ct);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
ip_conntrack_put(ct);
}
@@ -282,7 +282,7 @@ conntrack_tuple_cmp(const struct ip_conntrack_tuple_hash *i,
const struct ip_conntrack_tuple *tuple,
const struct ip_conntrack *ignored_conntrack)
{
- MUST_BE_READ_LOCKED(&ip_conntrack_lock);
+ ASSERT_READ_LOCK(&ip_conntrack_lock);
return tuplehash_to_ctrack(i) != ignored_conntrack
&& ip_ct_tuple_equal(tuple, &i->tuple);
}
@@ -294,7 +294,7 @@ __ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
struct ip_conntrack_tuple_hash *h;
unsigned int hash = hash_conntrack(tuple);
- MUST_BE_READ_LOCKED(&ip_conntrack_lock);
+ ASSERT_READ_LOCK(&ip_conntrack_lock);
list_for_each_entry(h, &ip_conntrack_hash[hash], list) {
if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) {
CONNTRACK_STAT_INC(found);
@@ -313,11 +313,11 @@ ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
{
struct ip_conntrack_tuple_hash *h;
- READ_LOCK(&ip_conntrack_lock);
+ read_lock_bh(&ip_conntrack_lock);
h = __ip_conntrack_find(tuple, ignored_conntrack);
if (h)
atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
- READ_UNLOCK(&ip_conntrack_lock);
+ read_unlock_bh(&ip_conntrack_lock);
return h;
}
@@ -352,7 +352,7 @@ __ip_conntrack_confirm(struct sk_buff **pskb)
IP_NF_ASSERT(!is_confirmed(ct));
DEBUGP("Confirming conntrack %p\n", ct);
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
/* See if there's one in the list already, including reverse:
NAT could have grabbed it without realizing, since we're
@@ -380,12 +380,12 @@ __ip_conntrack_confirm(struct sk_buff **pskb)
atomic_inc(&ct->ct_general.use);
set_bit(IPS_CONFIRMED_BIT, &ct->status);
CONNTRACK_STAT_INC(insert);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
return NF_ACCEPT;
}
CONNTRACK_STAT_INC(insert_failed);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
return NF_DROP;
}
@@ -398,9 +398,9 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
{
struct ip_conntrack_tuple_hash *h;
- READ_LOCK(&ip_conntrack_lock);
+ read_lock_bh(&ip_conntrack_lock);
h = __ip_conntrack_find(tuple, ignored_conntrack);
- READ_UNLOCK(&ip_conntrack_lock);
+ read_unlock_bh(&ip_conntrack_lock);
return h != NULL;
}
@@ -419,13 +419,13 @@ static int early_drop(struct list_head *chain)
struct ip_conntrack *ct = NULL;
int dropped = 0;
- READ_LOCK(&ip_conntrack_lock);
+ read_lock_bh(&ip_conntrack_lock);
h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *);
if (h) {
ct = tuplehash_to_ctrack(h);
atomic_inc(&ct->ct_general.use);
}
- READ_UNLOCK(&ip_conntrack_lock);
+ read_unlock_bh(&ip_conntrack_lock);
if (!ct)
return dropped;
@@ -508,7 +508,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
conntrack->timeout.data = (unsigned long)conntrack;
conntrack->timeout.function = death_by_timeout;
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
exp = find_expectation(tuple);
if (exp) {
@@ -532,7 +532,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
atomic_inc(&ip_conntrack_count);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
if (exp) {
if (exp->expectfn)
@@ -723,17 +723,17 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
{
struct ip_conntrack_expect *i;
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
/* choose the the oldest expectation to evict */
list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
if (expect_matches(i, exp) && del_timer(&i->timeout)) {
unlink_expect(i);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
destroy_expect(i);
return;
}
}
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
}
struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
@@ -760,15 +760,11 @@ static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
exp->master->expecting++;
list_add(&exp->list, &ip_conntrack_expect_list);
- if (exp->master->helper->timeout) {
- init_timer(&exp->timeout);
- exp->timeout.data = (unsigned long)exp;
- exp->timeout.function = expectation_timed_out;
- exp->timeout.expires
- = jiffies + exp->master->helper->timeout * HZ;
- add_timer(&exp->timeout);
- } else
- exp->timeout.function = NULL;
+ init_timer(&exp->timeout);
+ exp->timeout.data = (unsigned long)exp;
+ exp->timeout.function = expectation_timed_out;
+ exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
+ add_timer(&exp->timeout);
CONNTRACK_STAT_INC(expect_create);
}
@@ -808,7 +804,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
DEBUGP("mask: "); DUMP_TUPLE(&expect->mask);
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
list_for_each_entry(i, &ip_conntrack_expect_list, list) {
if (expect_matches(i, expect)) {
/* Refresh timer: if it's dying, ignore.. */
@@ -832,7 +828,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
ip_conntrack_expect_insert(expect);
ret = 0;
out:
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
return ret;
}
@@ -841,7 +837,7 @@ out:
void ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
const struct ip_conntrack_tuple *newreply)
{
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
/* Should be unconfirmed, so not in hash table yet */
IP_NF_ASSERT(!is_confirmed(conntrack));
@@ -851,15 +847,15 @@ void ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
if (!conntrack->master && conntrack->expecting == 0)
conntrack->helper = ip_ct_find_helper(newreply);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
}
int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
{
BUG_ON(me->timeout == 0);
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
list_prepend(&helpers, me);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
return 0;
}
@@ -878,7 +874,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
struct ip_conntrack_expect *exp, *tmp;
/* Need write lock here, to delete helper. */
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
LIST_DELETE(&helpers, me);
/* Get rid of expectations */
@@ -893,7 +889,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
for (i = 0; i < ip_conntrack_htable_size; i++)
LIST_FIND_W(&ip_conntrack_hash[i], unhelp,
struct ip_conntrack_tuple_hash *, me);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
/* Someone could be still looking at the helper in a bh. */
synchronize_net();
@@ -925,14 +921,14 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct,
ct->timeout.expires = extra_jiffies;
ct_add_counters(ct, ctinfo, skb);
} else {
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
/* Need del_timer for race avoidance (may already be dying). */
if (del_timer(&ct->timeout)) {
ct->timeout.expires = jiffies + extra_jiffies;
add_timer(&ct->timeout);
}
ct_add_counters(ct, ctinfo, skb);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
}
}
@@ -940,10 +936,6 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct,
struct sk_buff *
ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
{
-#ifdef CONFIG_NETFILTER_DEBUG
- unsigned int olddebug = skb->nf_debug;
-#endif
-
skb_orphan(skb);
local_bh_disable();
@@ -953,12 +945,7 @@ ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
if (skb) {
ip_send_check(skb->nh.iph);
skb->nfcache |= NFC_ALTERED;
-#ifdef CONFIG_NETFILTER_DEBUG
- /* Packet path as if nothing had happened. */
- skb->nf_debug = olddebug;
-#endif
}
-
return skb;
}
@@ -997,7 +984,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
{
struct ip_conntrack_tuple_hash *h = NULL;
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
for (; *bucket < ip_conntrack_htable_size; (*bucket)++) {
h = LIST_FIND_W(&ip_conntrack_hash[*bucket], do_iter,
struct ip_conntrack_tuple_hash *, iter, data);
@@ -1009,7 +996,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
struct ip_conntrack_tuple_hash *, iter, data);
if (h)
atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
return h;
}
@@ -1201,14 +1188,14 @@ int __init ip_conntrack_init(void)
}
/* Don't NEED lock here, but good form anyway. */
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
for (i = 0; i < MAX_IP_CT_PROTO; i++)
ip_ct_protos[i] = &ip_conntrack_generic_protocol;
/* Sew in builtin protocols. */
ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp;
ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp;
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
for (i = 0; i < ip_conntrack_htable_size; i++)
INIT_LIST_HEAD(&ip_conntrack_hash[i]);
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index dd86503aa788..fea6dd2a00b6 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -16,7 +16,6 @@
#include <net/checksum.h>
#include <net/tcp.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/moduleparam.h>
@@ -28,7 +27,7 @@ MODULE_DESCRIPTION("ftp connection tracking helper");
/* This is slow, but it's simple. --RR */
static char ftp_buffer[65536];
-static DECLARE_LOCK(ip_ftp_lock);
+static DEFINE_SPINLOCK(ip_ftp_lock);
#define MAX_PORTS 8
static int ports[MAX_PORTS];
@@ -319,7 +318,7 @@ static int help(struct sk_buff **pskb,
}
datalen = (*pskb)->len - dataoff;
- LOCK_BH(&ip_ftp_lock);
+ spin_lock_bh(&ip_ftp_lock);
fb_ptr = skb_header_pointer(*pskb, dataoff,
(*pskb)->len - dataoff, ftp_buffer);
BUG_ON(fb_ptr == NULL);
@@ -442,7 +441,7 @@ out_update_nl:
if (ends_in_nl)
update_nl_seq(seq, ct_ftp_info,dir);
out:
- UNLOCK_BH(&ip_ftp_lock);
+ spin_unlock_bh(&ip_ftp_lock);
return ret;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index 33cc7348b6ee..cd98772cc332 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -29,7 +29,6 @@
#include <net/checksum.h>
#include <net/tcp.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
#include <linux/moduleparam.h>
@@ -41,7 +40,7 @@ static int max_dcc_channels = 8;
static unsigned int dcc_timeout = 300;
/* This is slow, but it's simple. --RR */
static char irc_buffer[65536];
-static DECLARE_LOCK(irc_buffer_lock);
+static DEFINE_SPINLOCK(irc_buffer_lock);
unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
@@ -141,7 +140,7 @@ static int help(struct sk_buff **pskb,
if (dataoff >= (*pskb)->len)
return NF_ACCEPT;
- LOCK_BH(&irc_buffer_lock);
+ spin_lock_bh(&irc_buffer_lock);
ib_ptr = skb_header_pointer(*pskb, dataoff,
(*pskb)->len - dataoff, irc_buffer);
BUG_ON(ib_ptr == NULL);
@@ -237,7 +236,7 @@ static int help(struct sk_buff **pskb,
} /* while data < ... */
out:
- UNLOCK_BH(&irc_buffer_lock);
+ spin_unlock_bh(&irc_buffer_lock);
return ret;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index ff8c34a860ff..31d75390bf12 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -26,7 +26,6 @@
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#if 0
#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
@@ -35,7 +34,7 @@
#endif
/* Protects conntrack->proto.sctp */
-static DECLARE_RWLOCK(sctp_lock);
+static DEFINE_RWLOCK(sctp_lock);
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
closely. They're more complex. --RR
@@ -199,9 +198,9 @@ static int sctp_print_conntrack(struct seq_file *s,
DEBUGP(__FUNCTION__);
DEBUGP("\n");
- READ_LOCK(&sctp_lock);
+ read_lock_bh(&sctp_lock);
state = conntrack->proto.sctp.state;
- READ_UNLOCK(&sctp_lock);
+ read_unlock_bh(&sctp_lock);
return seq_printf(s, "%s ", sctp_conntrack_names[state]);
}
@@ -343,13 +342,13 @@ static int sctp_packet(struct ip_conntrack *conntrack,
oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
for_each_sctp_chunk (skb, sch, _sch, offset, count) {
- WRITE_LOCK(&sctp_lock);
+ write_lock_bh(&sctp_lock);
/* Special cases of Verification tag check (Sec 8.5.1) */
if (sch->type == SCTP_CID_INIT) {
/* Sec 8.5.1 (A) */
if (sh->vtag != 0) {
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
return -1;
}
} else if (sch->type == SCTP_CID_ABORT) {
@@ -357,7 +356,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
&& !(sh->vtag == conntrack->proto.sctp.vtag
[1 - CTINFO2DIR(ctinfo)])) {
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
return -1;
}
} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
@@ -366,13 +365,13 @@ static int sctp_packet(struct ip_conntrack *conntrack,
&& !(sh->vtag == conntrack->proto.sctp.vtag
[1 - CTINFO2DIR(ctinfo)]
&& (sch->flags & 1))) {
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
return -1;
}
} else if (sch->type == SCTP_CID_COOKIE_ECHO) {
/* Sec 8.5.1 (D) */
if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
return -1;
}
}
@@ -384,7 +383,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
if (newconntrack == SCTP_CONNTRACK_MAX) {
DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
return -1;
}
@@ -396,7 +395,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
sizeof(_inithdr), &_inithdr);
if (ih == NULL) {
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
return -1;
}
DEBUGP("Setting vtag %x for dir %d\n",
@@ -405,7 +404,7 @@ static int sctp_packet(struct ip_conntrack *conntrack,
}
conntrack->proto.sctp.state = newconntrack;
- WRITE_UNLOCK(&sctp_lock);
+ write_unlock_bh(&sctp_lock);
}
ip_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 721ddbf522b4..809dfed766d4 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -36,7 +36,6 @@
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#if 0
#define DEBUGP printk
@@ -46,7 +45,7 @@
#endif
/* Protects conntrack->proto.tcp */
-static DECLARE_RWLOCK(tcp_lock);
+static DEFINE_RWLOCK(tcp_lock);
/* "Be conservative in what you do,
be liberal in what you accept from others."
@@ -330,9 +329,9 @@ static int tcp_print_conntrack(struct seq_file *s,
{
enum tcp_conntrack state;
- READ_LOCK(&tcp_lock);
+ read_lock_bh(&tcp_lock);
state = conntrack->proto.tcp.state;
- READ_UNLOCK(&tcp_lock);
+ read_unlock_bh(&tcp_lock);
return seq_printf(s, "%s ", tcp_conntrack_names[state]);
}
@@ -738,14 +737,14 @@ void ip_conntrack_tcp_update(struct sk_buff *skb,
end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, iph, tcph);
- WRITE_LOCK(&tcp_lock);
+ write_lock_bh(&tcp_lock);
/*
* We have to worry for the ack in the reply packet only...
*/
if (after(end, conntrack->proto.tcp.seen[dir].td_end))
conntrack->proto.tcp.seen[dir].td_end = end;
conntrack->proto.tcp.last_end = end;
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -857,7 +856,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
sizeof(_tcph), &_tcph);
BUG_ON(th == NULL);
- WRITE_LOCK(&tcp_lock);
+ write_lock_bh(&tcp_lock);
old_state = conntrack->proto.tcp.state;
dir = CTINFO2DIR(ctinfo);
index = get_conntrack_index(th);
@@ -879,7 +878,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
* that the client cannot but retransmit its SYN and
* thus initiate a clean new session.
*/
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_tcp: killing out of sync session ");
@@ -894,7 +893,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
conntrack->proto.tcp.last_end =
segment_seq_plus_len(ntohl(th->seq), skb->len, iph, th);
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_tcp: invalid packet ignored ");
@@ -904,7 +903,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
DEBUGP("ip_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
dir, get_conntrack_index(th),
old_state);
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_tcp: invalid state ");
@@ -918,13 +917,13 @@ static int tcp_packet(struct ip_conntrack *conntrack,
conntrack->proto.tcp.seen[dir].td_end)) {
/* Attempt to reopen a closed connection.
* Delete this connection and look up again. */
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
if (del_timer(&conntrack->timeout))
conntrack->timeout.function((unsigned long)
conntrack);
return -NF_REPEAT;
} else {
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL,
"ip_ct_tcp: invalid SYN");
@@ -949,7 +948,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
skb, iph, th)) {
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
return -NF_ACCEPT;
}
in_window:
@@ -972,7 +971,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
timeout = conntrack->proto.tcp.retrans >= ip_ct_tcp_max_retrans
&& *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans
? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
- WRITE_UNLOCK(&tcp_lock);
+ write_unlock_bh(&tcp_lock);
if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
/* If only reply is a RST, we can consider ourselves not to
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
index 5bc28a224623..8c1eaba098d4 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -120,6 +120,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
* and moreover root might send raw packets.
* FIXME: Source route IP option packets --RR */
if (hooknum == NF_IP_PRE_ROUTING
+ && skb->ip_summed != CHECKSUM_UNNECESSARY
&& csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
skb->ip_summed == CHECKSUM_HW ? skb->csum
: skb_checksum(skb, iph->ihl*4, udplen, 0))) {
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index bc59f7b39805..42dc95102873 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -28,8 +28,8 @@
#include <net/checksum.h>
#include <net/ip.h>
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
@@ -119,7 +119,7 @@ static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
{
- READ_LOCK(&ip_conntrack_lock);
+ read_lock_bh(&ip_conntrack_lock);
return ct_get_idx(seq, *pos);
}
@@ -131,7 +131,7 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
static void ct_seq_stop(struct seq_file *s, void *v)
{
- READ_UNLOCK(&ip_conntrack_lock);
+ read_unlock_bh(&ip_conntrack_lock);
}
static int ct_seq_show(struct seq_file *s, void *v)
@@ -140,7 +140,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash);
struct ip_conntrack_protocol *proto;
- MUST_BE_READ_LOCKED(&ip_conntrack_lock);
+ ASSERT_READ_LOCK(&ip_conntrack_lock);
IP_NF_ASSERT(conntrack);
/* we only want to print DIR_ORIGINAL */
@@ -239,7 +239,7 @@ static void *exp_seq_start(struct seq_file *s, loff_t *pos)
/* strange seq_file api calls stop even if we fail,
* thus we need to grab lock since stop unlocks */
- READ_LOCK(&ip_conntrack_lock);
+ read_lock_bh(&ip_conntrack_lock);
if (list_empty(e))
return NULL;
@@ -267,7 +267,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
static void exp_seq_stop(struct seq_file *s, void *v)
{
- READ_UNLOCK(&ip_conntrack_lock);
+ read_unlock_bh(&ip_conntrack_lock);
}
static int exp_seq_show(struct seq_file *s, void *v)
@@ -921,22 +921,22 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
{
int ret = 0;
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) {
ret = -EBUSY;
goto out;
}
ip_ct_protos[proto->proto] = proto;
out:
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
return ret;
}
void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
{
- WRITE_LOCK(&ip_conntrack_lock);
+ write_lock_bh(&ip_conntrack_lock);
ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol;
- WRITE_UNLOCK(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
/* Somebody could be still looking at the proto in bh. */
synchronize_net();
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9fc6f93af0dd..739b6dde1c82 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -22,8 +22,8 @@
#include <linux/udp.h>
#include <linux/jhash.h>
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
@@ -41,7 +41,7 @@
#define DEBUGP(format, args...)
#endif
-DECLARE_RWLOCK(ip_nat_lock);
+DEFINE_RWLOCK(ip_nat_lock);
/* Calculated at init based on memory size */
static unsigned int ip_nat_htable_size;
@@ -65,9 +65,9 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn)
if (!(conn->status & IPS_NAT_DONE_MASK))
return;
- WRITE_LOCK(&ip_nat_lock);
+ write_lock_bh(&ip_nat_lock);
list_del(&conn->nat.info.bysource);
- WRITE_UNLOCK(&ip_nat_lock);
+ write_unlock_bh(&ip_nat_lock);
}
/* We do checksum mangling, so if they were wrong before they're still
@@ -142,7 +142,7 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple,
unsigned int h = hash_by_src(tuple);
struct ip_conntrack *ct;
- READ_LOCK(&ip_nat_lock);
+ read_lock_bh(&ip_nat_lock);
list_for_each_entry(ct, &bysource[h], nat.info.bysource) {
if (same_src(ct, tuple)) {
/* Copy source part from reply tuple. */
@@ -151,12 +151,12 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple,
result->dst = tuple->dst;
if (in_range(result, range)) {
- READ_UNLOCK(&ip_nat_lock);
+ read_unlock_bh(&ip_nat_lock);
return 1;
}
}
}
- READ_UNLOCK(&ip_nat_lock);
+ read_unlock_bh(&ip_nat_lock);
return 0;
}
@@ -297,9 +297,9 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
unsigned int srchash
= hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple);
- WRITE_LOCK(&ip_nat_lock);
+ write_lock_bh(&ip_nat_lock);
list_add(&info->bysource, &bysource[srchash]);
- WRITE_UNLOCK(&ip_nat_lock);
+ write_unlock_bh(&ip_nat_lock);
}
/* It's done. */
@@ -474,23 +474,23 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
{
int ret = 0;
- WRITE_LOCK(&ip_nat_lock);
+ write_lock_bh(&ip_nat_lock);
if (ip_nat_protos[proto->protonum] != &ip_nat_unknown_protocol) {
ret = -EBUSY;
goto out;
}
ip_nat_protos[proto->protonum] = proto;
out:
- WRITE_UNLOCK(&ip_nat_lock);
+ write_unlock_bh(&ip_nat_lock);
return ret;
}
/* Noone stores the protocol anywhere; simply delete it. */
void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
{
- WRITE_LOCK(&ip_nat_lock);
+ write_lock_bh(&ip_nat_lock);
ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol;
- WRITE_UNLOCK(&ip_nat_lock);
+ write_unlock_bh(&ip_nat_lock);
/* Someone could be still looking at the proto in a bh. */
synchronize_net();
@@ -509,13 +509,13 @@ int __init ip_nat_init(void)
return -ENOMEM;
/* Sew in builtin protocols. */
- WRITE_LOCK(&ip_nat_lock);
+ write_lock_bh(&ip_nat_lock);
for (i = 0; i < MAX_IP_NAT_PROTO; i++)
ip_nat_protos[i] = &ip_nat_unknown_protocol;
ip_nat_protos[IPPROTO_TCP] = &ip_nat_protocol_tcp;
ip_nat_protos[IPPROTO_UDP] = &ip_nat_protocol_udp;
ip_nat_protos[IPPROTO_ICMP] = &ip_nat_protocol_icmp;
- WRITE_UNLOCK(&ip_nat_lock);
+ write_unlock_bh(&ip_nat_lock);
for (i = 0; i < ip_nat_htable_size; i++) {
INIT_LIST_HEAD(&bysource[i]);
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index 1637b96d8c01..158f34f32c04 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -28,8 +28,8 @@
#include <net/tcp.h>
#include <net/udp.h>
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -47,7 +47,7 @@
#define DUMP_OFFSET(x)
#endif
-static DECLARE_LOCK(ip_nat_seqofs_lock);
+static DEFINE_SPINLOCK(ip_nat_seqofs_lock);
/* Setup TCP sequence correction given this change at this sequence */
static inline void
@@ -70,7 +70,7 @@ adjust_tcp_sequence(u32 seq,
DEBUGP("ip_nat_resize_packet: Seq_offset before: ");
DUMP_OFFSET(this_way);
- LOCK_BH(&ip_nat_seqofs_lock);
+ spin_lock_bh(&ip_nat_seqofs_lock);
/* SYN adjust. If it's uninitialized, or this is after last
* correction, record it: we don't handle more than one
@@ -82,7 +82,7 @@ adjust_tcp_sequence(u32 seq,
this_way->offset_before = this_way->offset_after;
this_way->offset_after += sizediff;
}
- UNLOCK_BH(&ip_nat_seqofs_lock);
+ spin_unlock_bh(&ip_nat_seqofs_lock);
DEBUGP("ip_nat_resize_packet: Seq_offset after: ");
DUMP_OFFSET(this_way);
@@ -142,9 +142,6 @@ static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
/* Transfer socket to new skb. */
if ((*pskb)->sk)
skb_set_owner_w(nskb, (*pskb)->sk);
-#ifdef CONFIG_NETFILTER_DEBUG
- nskb->nf_debug = (*pskb)->nf_debug;
-#endif
kfree_skb(*pskb);
*pskb = nskb;
return 1;
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
index 581f097f5a24..60d70fa41a15 100644
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -19,8 +19,8 @@
#include <net/route.h>
#include <linux/bitops.h>
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_nat.h>
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 79f56f662b33..bc59d0d6e89e 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -31,8 +31,8 @@
#include <net/checksum.h>
#include <linux/spinlock.h>
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_rule.h>
@@ -373,7 +373,6 @@ static int init_or_cleanup(int init)
cleanup_rule_init:
ip_nat_rule_cleanup();
cleanup_nothing:
- MUST_BE_READ_WRITE_UNLOCKED(&ip_nat_lock);
return ret;
}
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 8a54f92b8496..c88dfcd38c56 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -67,7 +67,6 @@ static DECLARE_MUTEX(ipt_mutex);
/* Must have mutex */
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/listhelp.h>
#if 0
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 0f12e3a3dc73..dc4362b57cfa 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -29,7 +29,6 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#define CLUSTERIP_VERSION "0.6"
@@ -41,6 +40,8 @@
#define DEBUGP
#endif
+#define ASSERT_READ_LOCK(x)
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("iptables target for CLUSTERIP");
@@ -67,7 +68,7 @@ static LIST_HEAD(clusterip_configs);
/* clusterip_lock protects the clusterip_configs list _AND_ the configurable
* data within all structurses (num_local_nodes, local_nodes[]) */
-static DECLARE_RWLOCK(clusterip_lock);
+static DEFINE_RWLOCK(clusterip_lock);
#ifdef CONFIG_PROC_FS
static struct file_operations clusterip_proc_fops;
@@ -82,9 +83,9 @@ clusterip_config_get(struct clusterip_config *c) {
static inline void
clusterip_config_put(struct clusterip_config *c) {
if (atomic_dec_and_test(&c->refcount)) {
- WRITE_LOCK(&clusterip_lock);
+ write_lock_bh(&clusterip_lock);
list_del(&c->list);
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0);
dev_put(c->dev);
kfree(c);
@@ -97,7 +98,7 @@ __clusterip_config_find(u_int32_t clusterip)
{
struct list_head *pos;
- MUST_BE_READ_LOCKED(&clusterip_lock);
+ ASSERT_READ_LOCK(&clusterip_lock);
list_for_each(pos, &clusterip_configs) {
struct clusterip_config *c = list_entry(pos,
struct clusterip_config, list);
@@ -114,14 +115,14 @@ clusterip_config_find_get(u_int32_t clusterip)
{
struct clusterip_config *c;
- READ_LOCK(&clusterip_lock);
+ read_lock_bh(&clusterip_lock);
c = __clusterip_config_find(clusterip);
if (!c) {
- READ_UNLOCK(&clusterip_lock);
+ read_unlock_bh(&clusterip_lock);
return NULL;
}
atomic_inc(&c->refcount);
- READ_UNLOCK(&clusterip_lock);
+ read_unlock_bh(&clusterip_lock);
return c;
}
@@ -160,9 +161,9 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
c->pde->data = c;
#endif
- WRITE_LOCK(&clusterip_lock);
+ write_lock_bh(&clusterip_lock);
list_add(&c->list, &clusterip_configs);
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return c;
}
@@ -172,25 +173,25 @@ clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum)
{
int i;
- WRITE_LOCK(&clusterip_lock);
+ write_lock_bh(&clusterip_lock);
if (c->num_local_nodes >= CLUSTERIP_MAX_NODES
|| nodenum > CLUSTERIP_MAX_NODES) {
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return 1;
}
/* check if we alrady have this number in our array */
for (i = 0; i < c->num_local_nodes; i++) {
if (c->local_nodes[i] == nodenum) {
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return 1;
}
}
c->local_nodes[c->num_local_nodes++] = nodenum;
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return 0;
}
@@ -199,10 +200,10 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
{
int i;
- WRITE_LOCK(&clusterip_lock);
+ write_lock_bh(&clusterip_lock);
if (c->num_local_nodes <= 1 || nodenum > CLUSTERIP_MAX_NODES) {
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return 1;
}
@@ -211,12 +212,12 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
int size = sizeof(u_int16_t)*(c->num_local_nodes-(i+1));
memmove(&c->local_nodes[i], &c->local_nodes[i+1], size);
c->num_local_nodes--;
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return 0;
}
}
- WRITE_UNLOCK(&clusterip_lock);
+ write_unlock_bh(&clusterip_lock);
return 1;
}
@@ -286,21 +287,21 @@ clusterip_responsible(struct clusterip_config *config, u_int32_t hash)
{
int i;
- READ_LOCK(&clusterip_lock);
+ read_lock_bh(&clusterip_lock);
if (config->num_local_nodes == 0) {
- READ_UNLOCK(&clusterip_lock);
+ read_unlock_bh(&clusterip_lock);
return 0;
}
for (i = 0; i < config->num_local_nodes; i++) {
if (config->local_nodes[i] == hash) {
- READ_UNLOCK(&clusterip_lock);
+ read_unlock_bh(&clusterip_lock);
return 1;
}
}
- READ_UNLOCK(&clusterip_lock);
+ read_unlock_bh(&clusterip_lock);
return 0;
}
@@ -578,7 +579,7 @@ static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
struct clusterip_config *c = pde->data;
unsigned int *nodeidx;
- READ_LOCK(&clusterip_lock);
+ read_lock_bh(&clusterip_lock);
if (*pos >= c->num_local_nodes)
return NULL;
@@ -608,7 +609,7 @@ static void clusterip_seq_stop(struct seq_file *s, void *v)
{
kfree(v);
- READ_UNLOCK(&clusterip_lock);
+ read_unlock_bh(&clusterip_lock);
}
static int clusterip_seq_show(struct seq_file *s, void *v)
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 57e9f6cf1c36..91e74502c3d3 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables MASQUERADE target module");
#endif
/* Lock protects masq region inside conntrack */
-static DECLARE_RWLOCK(masq_lock);
+static DEFINE_RWLOCK(masq_lock);
/* FIXME: Multiple targets. --RR */
static int
@@ -103,9 +103,9 @@ masquerade_target(struct sk_buff **pskb,
return NF_DROP;
}
- WRITE_LOCK(&masq_lock);
+ write_lock_bh(&masq_lock);
ct->nat.masq_index = out->ifindex;
- WRITE_UNLOCK(&masq_lock);
+ write_unlock_bh(&masq_lock);
/* Transfer from original range. */
newrange = ((struct ip_nat_range)
@@ -122,9 +122,9 @@ device_cmp(struct ip_conntrack *i, void *ifindex)
{
int ret;
- READ_LOCK(&masq_lock);
+ read_lock_bh(&masq_lock);
ret = (i->nat.masq_index == (int)(long)ifindex);
- READ_UNLOCK(&masq_lock);
+ read_unlock_bh(&masq_lock);
return ret;
}
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 266d64979286..915696446020 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -104,10 +104,12 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
static void send_reset(struct sk_buff *oldskb, int hook)
{
struct sk_buff *nskb;
+ struct iphdr *iph = oldskb->nh.iph;
struct tcphdr _otcph, *oth, *tcph;
struct rtable *rt;
u_int16_t tmp_port;
u_int32_t tmp_addr;
+ unsigned int tcplen;
int needs_ack;
int hh_len;
@@ -124,7 +126,16 @@ static void send_reset(struct sk_buff *oldskb, int hook)
if (oth->rst)
return;
- /* FIXME: Check checksum --RR */
+ /* Check checksum */
+ tcplen = oldskb->len - iph->ihl * 4;
+ if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) ||
+ (hook == NF_IP_LOCAL_IN &&
+ oldskb->ip_summed != CHECKSUM_UNNECESSARY)) &&
+ csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
+ oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum :
+ skb_checksum(oldskb, iph->ihl * 4, tcplen, 0)))
+ return;
+
if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
return;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 6f2cefbe16cd..52a0076302a7 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -56,7 +56,6 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_ULOG.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <net/sock.h>
#include <linux/bitops.h>
@@ -99,8 +98,8 @@ typedef struct {
static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS]; /* array of buffers */
-static struct sock *nflognl; /* our socket */
-static DECLARE_LOCK(ulog_lock); /* spinlock */
+static struct sock *nflognl; /* our socket */
+static DEFINE_SPINLOCK(ulog_lock); /* spinlock */
/* send one ulog_buff_t to userspace */
static void ulog_send(unsigned int nlgroupnum)
@@ -135,9 +134,9 @@ static void ulog_timer(unsigned long data)
/* lock to protect against somebody modifying our structure
* from ipt_ulog_target at the same time */
- LOCK_BH(&ulog_lock);
+ spin_lock_bh(&ulog_lock);
ulog_send(data);
- UNLOCK_BH(&ulog_lock);
+ spin_unlock_bh(&ulog_lock);
}
static struct sk_buff *ulog_alloc_skb(unsigned int size)
@@ -193,7 +192,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
ub = &ulog_buffers[groupnum];
- LOCK_BH(&ulog_lock);
+ spin_lock_bh(&ulog_lock);
if (!ub->skb) {
if (!(ub->skb = ulog_alloc_skb(size)))
@@ -278,7 +277,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
ulog_send(groupnum);
}
- UNLOCK_BH(&ulog_lock);
+ spin_unlock_bh(&ulog_lock);
return;
@@ -288,7 +287,7 @@ nlmsg_failure:
alloc_failure:
PRINTR("ipt_ULOG: Error building netlink message\n");
- UNLOCK_BH(&ulog_lock);
+ spin_unlock_bh(&ulog_lock);
}
static unsigned int ipt_ulog_target(struct sk_buff **pskb,
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c
index f1937190cd77..564b49bfebcf 100644
--- a/net/ipv4/netfilter/ipt_hashlimit.c
+++ b/net/ipv4/netfilter/ipt_hashlimit.c
@@ -37,7 +37,6 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_hashlimit.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
/* FIXME: this is just for IP_NF_ASSERRT */
#include <linux/netfilter_ipv4/ip_conntrack.h>
@@ -92,7 +91,7 @@ struct ipt_hashlimit_htable {
struct hlist_head hash[0]; /* hashtable itself */
};
-static DECLARE_LOCK(hashlimit_lock); /* protects htables list */
+static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */
static DECLARE_MUTEX(hlimit_mutex); /* additional checkentry protection */
static HLIST_HEAD(hashlimit_htables);
static kmem_cache_t *hashlimit_cachep;
@@ -233,9 +232,9 @@ static int htable_create(struct ipt_hashlimit_info *minfo)
hinfo->timer.function = htable_gc;
add_timer(&hinfo->timer);
- LOCK_BH(&hashlimit_lock);
+ spin_lock_bh(&hashlimit_lock);
hlist_add_head(&hinfo->node, &hashlimit_htables);
- UNLOCK_BH(&hashlimit_lock);
+ spin_unlock_bh(&hashlimit_lock);
return 0;
}
@@ -301,15 +300,15 @@ static struct ipt_hashlimit_htable *htable_find_get(char *name)
struct ipt_hashlimit_htable *hinfo;
struct hlist_node *pos;
- LOCK_BH(&hashlimit_lock);
+ spin_lock_bh(&hashlimit_lock);
hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) {
if (!strcmp(name, hinfo->pde->name)) {
atomic_inc(&hinfo->use);
- UNLOCK_BH(&hashlimit_lock);
+ spin_unlock_bh(&hashlimit_lock);
return hinfo;
}
}
- UNLOCK_BH(&hashlimit_lock);
+ spin_unlock_bh(&hashlimit_lock);
return NULL;
}
@@ -317,9 +316,9 @@ static struct ipt_hashlimit_htable *htable_find_get(char *name)
static void htable_put(struct ipt_hashlimit_htable *hinfo)
{
if (atomic_dec_and_test(&hinfo->use)) {
- LOCK_BH(&hashlimit_lock);
+ spin_lock_bh(&hashlimit_lock);
hlist_del(&hinfo->node);
- UNLOCK_BH(&hashlimit_lock);
+ spin_unlock_bh(&hashlimit_lock);
htable_destroy(hinfo);
}
}
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
index 33fdf364d3d3..3e7dd014de43 100644
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -53,7 +53,7 @@ match(const struct sk_buff *skb,
return ret;
}
- READ_LOCK(&ip_conntrack_lock);
+ read_lock_bh(&ip_conntrack_lock);
if (!ct->master->helper) {
DEBUGP("ipt_helper: master ct %p has no helper\n",
exp->expectant);
@@ -69,7 +69,7 @@ match(const struct sk_buff *skb,
ret ^= !strncmp(ct->master->helper->name, info->name,
strlen(ct->master->helper->name));
out_unlock:
- READ_UNLOCK(&ip_conntrack_lock);
+ read_unlock_bh(&ip_conntrack_lock);
return ret;
}
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index af2392ae5769..66620a95942a 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -33,6 +33,7 @@ static void xfrm4_encap(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
struct xfrm_state *x = dst->xfrm;
struct iphdr *iph, *top_iph;
+ int flags;
iph = skb->nh.iph;
skb->h.ipiph = iph;
@@ -51,10 +52,13 @@ static void xfrm4_encap(struct sk_buff *skb)
/* DS disclosed */
top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
- if (x->props.flags & XFRM_STATE_NOECN)
+
+ flags = x->props.flags;
+ if (flags & XFRM_STATE_NOECN)
IP_ECN_clear(top_iph);
- top_iph->frag_off = iph->frag_off & htons(IP_DF);
+ top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+ 0 : (iph->frag_off & htons(IP_DF));
if (!top_iph->frag_off)
__ip_select_ident(top_iph, dst, 0);
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 223a2e83853f..050611d7a967 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -7,12 +7,20 @@
*
*/
+#include <net/ip.h>
#include <net/xfrm.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
static struct xfrm_state_afinfo xfrm4_state_afinfo;
+static int xfrm4_init_flags(struct xfrm_state *x)
+{
+ if (ipv4_config.no_pmtu_disc)
+ x->props.flags |= XFRM_STATE_NOPMTUDISC;
+ return 0;
+}
+
static void
__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
@@ -109,6 +117,7 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
static struct xfrm_state_afinfo xfrm4_state_afinfo = {
.family = AF_INET,
.lock = RW_LOCK_UNLOCKED,
+ .init_flags = xfrm4_init_flags,
.init_tempsel = __xfrm4_init_tempsel,
.state_lookup = __xfrm4_state_lookup,
.find_acq = __xfrm4_find_acq,
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 413191f585f6..e1fe360ed27a 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -84,7 +84,7 @@ static void ipip_err(struct sk_buff *skb, u32 info)
handler->err_handler(skb, &arg);
}
-static int ipip_init_state(struct xfrm_state *x, void *args)
+static int ipip_init_state(struct xfrm_state *x)
{
if (!x->props.mode)
return -EINVAL;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 47a30c3188ea..14f5c53235fe 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -695,7 +695,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (onlink == 0) {
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
rt = NULL;
} else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
rt->rt6i_expires = expires;
@@ -1340,7 +1340,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT))
rtmsg.rtmsg_flags |= RTF_NONEXTHOP;
- ip6_route_add(&rtmsg, NULL, NULL);
+ ip6_route_add(&rtmsg, NULL, NULL, NULL);
}
/* Create "default" multicast route to the interface */
@@ -1357,7 +1357,7 @@ static void addrconf_add_mroute(struct net_device *dev)
rtmsg.rtmsg_ifindex = dev->ifindex;
rtmsg.rtmsg_flags = RTF_UP;
rtmsg.rtmsg_type = RTMSG_NEWROUTE;
- ip6_route_add(&rtmsg, NULL, NULL);
+ ip6_route_add(&rtmsg, NULL, NULL, NULL);
}
static void sit_route_add(struct net_device *dev)
@@ -1374,7 +1374,7 @@ static void sit_route_add(struct net_device *dev)
rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP;
rtmsg.rtmsg_ifindex = dev->ifindex;
- ip6_route_add(&rtmsg, NULL, NULL);
+ ip6_route_add(&rtmsg, NULL, NULL, NULL);
}
static void addrconf_add_lroute(struct net_device *dev)
@@ -1467,7 +1467,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (rt->rt6i_flags&RTF_EXPIRES) {
if (valid_lft == 0) {
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
rt = NULL;
} else {
rt->rt6i_expires = rt_expires;
@@ -3094,7 +3094,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
switch (event) {
case RTM_NEWADDR:
dst_hold(&ifp->rt->u.dst);
- if (ip6_ins_rt(ifp->rt, NULL, NULL))
+ if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
dst_release(&ifp->rt->u.dst);
if (ifp->idev->cnf.forwarding)
addrconf_join_anycast(ifp);
@@ -3104,7 +3104,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
addrconf_leave_anycast(ifp);
addrconf_leave_solict(ifp->idev, &ifp->addr);
dst_hold(&ifp->rt->u.dst);
- if (ip6_del_rt(ifp->rt, NULL, NULL))
+ if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
dst_free(&ifp->rt->u.dst);
else
dst_release(&ifp->rt->u.dst);
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index e3ecf626cbf7..986fdfdccbcd 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -339,7 +339,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
xfrm_state_put(x);
}
-static int ah6_init_state(struct xfrm_state *x, void *args)
+static int ah6_init_state(struct xfrm_state *x)
{
struct ah_data *ahp = NULL;
struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 5d22ca3cca2e..6b7294047238 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -337,7 +337,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
write_unlock_bh(&idev->lock);
dst_hold(&rt->u.dst);
- if (ip6_ins_rt(rt, NULL, NULL))
+ if (ip6_ins_rt(rt, NULL, NULL, NULL))
dst_release(&rt->u.dst);
addrconf_join_solict(dev, &aca->aca_addr);
@@ -380,7 +380,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr)
addrconf_leave_solict(idev, &aca->aca_addr);
dst_hold(&aca->aca_rt->u.dst);
- if (ip6_del_rt(aca->aca_rt, NULL, NULL))
+ if (ip6_del_rt(aca->aca_rt, NULL, NULL, NULL))
dst_free(&aca->aca_rt->u.dst);
else
dst_release(&aca->aca_rt->u.dst);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index be7095d6babe..324db62515a2 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -296,7 +296,7 @@ static void esp6_destroy(struct xfrm_state *x)
kfree(esp);
}
-static int esp6_init_state(struct xfrm_state *x, void *args)
+static int esp6_init_state(struct xfrm_state *x)
{
struct esp_data *esp = NULL;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 405740b75abb..1b354aa97934 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -394,7 +394,7 @@ insert_above:
*/
static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
- struct nlmsghdr *nlh)
+ struct nlmsghdr *nlh, struct netlink_skb_parms *req)
{
struct rt6_info *iter = NULL;
struct rt6_info **ins;
@@ -449,7 +449,7 @@ out:
*ins = rt;
rt->rt6i_node = fn;
atomic_inc(&rt->rt6i_ref);
- inet6_rt_notify(RTM_NEWROUTE, rt, nlh);
+ inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req);
rt6_stats.fib_rt_entries++;
if ((fn->fn_flags & RTN_RTINFO) == 0) {
@@ -479,7 +479,8 @@ void fib6_force_start_gc(void)
* with source addr info in sub-trees
*/
-int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int fib6_add(struct fib6_node *root, struct rt6_info *rt,
+ struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
{
struct fib6_node *fn;
int err = -ENOMEM;
@@ -552,7 +553,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh,
}
#endif
- err = fib6_add_rt2node(fn, rt, nlh);
+ err = fib6_add_rt2node(fn, rt, nlh, req);
if (err == 0) {
fib6_start_gc(rt);
@@ -859,7 +860,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
}
static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
- struct nlmsghdr *nlh, void *_rtattr)
+ struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
{
struct fib6_walker_t *w;
struct rt6_info *rt = *rtp;
@@ -915,11 +916,11 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
if (atomic_read(&rt->rt6i_ref) != 1) BUG();
}
- inet6_rt_notify(RTM_DELROUTE, rt, nlh);
+ inet6_rt_notify(RTM_DELROUTE, rt, nlh, req);
rt6_release(rt);
}
-int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
{
struct fib6_node *fn = rt->rt6i_node;
struct rt6_info **rtp;
@@ -944,7 +945,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
if (*rtp == rt) {
- fib6_del_route(fn, rtp, nlh, _rtattr);
+ fib6_del_route(fn, rtp, nlh, _rtattr, req);
return 0;
}
}
@@ -1073,7 +1074,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
res = c->func(rt, c->arg);
if (res < 0) {
w->leaf = rt;
- res = fib6_del(rt, NULL, NULL);
+ res = fib6_del(rt, NULL, NULL, NULL);
if (res) {
#if RT6_DEBUG >= 2
printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index b78a53586804..06e7cdaeedc5 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -484,9 +484,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->nf_bridge = from->nf_bridge;
nf_bridge_get(to->nf_bridge);
#endif
-#ifdef CONFIG_NETFILTER_DEBUG
- to->nf_debug = from->nf_debug;
-#endif
#endif
}
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 6cde5310cd76..423feb46ccc0 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -234,14 +234,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
t->props.mode = 1;
memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
- t->type = xfrm_get_type(IPPROTO_IPV6, t->props.family);
- if (t->type == NULL)
+ if (xfrm_init_state(t))
goto error;
- if (t->type->init_state(t, NULL))
- goto error;
-
- t->km.state = XFRM_STATE_VALID;
atomic_set(&t->tunnel_users, 1);
out:
@@ -420,7 +415,7 @@ static void ipcomp6_destroy(struct xfrm_state *x)
xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
}
-static int ipcomp6_init_state(struct xfrm_state *x, void *args)
+static int ipcomp6_init_state(struct xfrm_state *x)
{
int err;
struct ipcomp_data *ipcd;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 279ab86be662..f3ef4c38d315 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -423,11 +423,12 @@ done:
psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
retv = ipv6_sock_mc_join(sk, greqs.gsr_interface,
&psin6->sin6_addr);
- if (retv)
+ /* prior join w/ different source is ok */
+ if (retv && retv != -EADDRINUSE)
break;
omode = MCAST_INCLUDE;
add = 1;
- } else /*IP_DROP_SOURCE_MEMBERSHIP */ {
+ } else /* MCAST_LEAVE_SOURCE_GROUP */ {
omode = MCAST_INCLUDE;
add = 0;
}
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 393b6e6f50a9..562fcd14fdea 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -188,6 +188,16 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
if (!ipv6_addr_is_multicast(addr))
return -EINVAL;
+ read_lock_bh(&ipv6_sk_mc_lock);
+ for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) {
+ if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
+ ipv6_addr_equal(&mc_lst->addr, addr)) {
+ read_unlock_bh(&ipv6_sk_mc_lock);
+ return -EADDRINUSE;
+ }
+ }
+ read_unlock_bh(&ipv6_sk_mc_lock);
+
mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
if (mc_lst == NULL)
@@ -349,6 +359,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
struct ipv6_pinfo *inet6 = inet6_sk(sk);
struct ip6_sf_socklist *psl;
int i, j, rv;
+ int leavegroup = 0;
int err;
if (pgsr->gsr_group.ss_family != AF_INET6 ||
@@ -368,6 +379,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
err = -EADDRNOTAVAIL;
+ read_lock_bh(&ipv6_sk_mc_lock);
for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
continue;
@@ -401,6 +413,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
if (rv) /* source not found */
goto done;
+ /* special case - (INCLUDE, empty) == LEAVE_GROUP */
+ if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
+ leavegroup = 1;
+ goto done;
+ }
+
/* update the interface filter */
ip6_mc_del_src(idev, group, omode, 1, source, 1);
@@ -453,9 +471,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
/* update the interface list */
ip6_mc_add_src(idev, group, omode, 1, source, 1);
done:
+ read_unlock_bh(&ipv6_sk_mc_lock);
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
dev_put(dev);
+ if (leavegroup)
+ return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
return err;
}
@@ -1280,15 +1301,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
return NULL;
skb_reserve(skb, LL_RESERVED_SPACE(dev));
- if (dev->hard_header) {
- unsigned char ha[MAX_ADDR_LEN];
-
- ndisc_mc_map(&mld2_all_mcr, ha, dev, 1);
- if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) {
- kfree_skb(skb);
- return NULL;
- }
- }
if (ipv6_get_lladdr(dev, &addr_buf)) {
/* <draft-ietf-magma-mld-source-05.txt>:
@@ -1312,6 +1324,30 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
return skb;
}
+static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
+{
+ struct net_device *dev = skb->dev;
+
+ if (dev->hard_header) {
+ unsigned char ha[MAX_ADDR_LEN];
+ int err;
+
+ ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1);
+ err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len);
+ if (err < 0) {
+ kfree_skb(skb);
+ return err;
+ }
+ }
+ return dev_queue_xmit(skb);
+}
+
+static inline int mld_dev_queue_xmit(struct sk_buff *skb)
+{
+ return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev,
+ mld_dev_queue_xmit2);
+}
+
static void mld_sendpack(struct sk_buff *skb)
{
struct ipv6hdr *pip6 = skb->nh.ipv6h;
@@ -1329,7 +1365,7 @@ static void mld_sendpack(struct sk_buff *skb)
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
- dev_queue_xmit);
+ mld_dev_queue_xmit);
if (!err) {
ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS);
@@ -1635,12 +1671,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
}
skb_reserve(skb, LL_RESERVED_SPACE(dev));
- if (dev->hard_header) {
- unsigned char ha[MAX_ADDR_LEN];
- ndisc_mc_map(snd_addr, ha, dev, 1);
- if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
- goto out;
- }
if (ipv6_get_lladdr(dev, &addr_buf)) {
/* <draft-ietf-magma-mld-source-05.txt>:
@@ -1668,7 +1698,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
idev = in6_dev_get(skb->dev);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
- dev_queue_xmit);
+ mld_dev_queue_xmit);
if (!err) {
if (type == ICMPV6_MGM_REDUCTION)
ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
@@ -1682,10 +1712,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
if (likely(idev != NULL))
in6_dev_put(idev);
return;
-
-out:
- IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
- kfree_skb(skb);
}
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 7c291f4e9edc..7ae72d4c9bd2 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -955,7 +955,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
struct rt6_info *rt;
rt = rt6_get_dflt_router(saddr, dev);
if (rt)
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
}
out:
@@ -1096,7 +1096,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if (rt && lifetime == 0) {
neigh_clone(neigh);
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
rt = NULL;
}
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index c735276fdd5f..73034511c8db 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -71,7 +71,6 @@ static DECLARE_MUTEX(ip6t_mutex);
/* Must have mutex */
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
-#include <linux/netfilter_ipv4/lockhelp.h>
#include <linux/netfilter_ipv4/listhelp.h>
#if 0
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index bfc3d0185d19..c44685e391b7 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -366,8 +366,6 @@ ip6t_log_packet(unsigned int hooknum,
const char *level_string,
const char *prefix)
{
- struct ipv6hdr *ipv6h = skb->nh.ipv6h;
-
spin_lock_bh(&log_lock);
printk(level_string);
printk("%sIN=%s OUT=%s ",
@@ -377,39 +375,25 @@ ip6t_log_packet(unsigned int hooknum,
if (in && !out) {
/* MAC logging for input chain only. */
printk("MAC=");
- if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
- if (skb->dev->type != ARPHRD_SIT){
- int i;
- unsigned char *p = skb->mac.raw;
- for (i = 0; i < skb->dev->hard_header_len; i++,p++)
- printk("%02x%c", *p,
- i==skb->dev->hard_header_len - 1
- ? ' ':':');
- } else {
- int i;
- unsigned char *p = skb->mac.raw;
- if ( p - (ETH_ALEN*2+2) > skb->head ){
- p -= (ETH_ALEN+2);
- for (i = 0; i < (ETH_ALEN); i++,p++)
- printk("%02x%s", *p,
- i == ETH_ALEN-1 ? "->" : ":");
- p -= (ETH_ALEN*2);
- for (i = 0; i < (ETH_ALEN); i++,p++)
- printk("%02x%c", *p,
- i == ETH_ALEN-1 ? ' ' : ':');
- }
-
- if ((skb->dev->addr_len == 4) &&
- skb->dev->hard_header_len > 20){
- printk("TUNNEL=");
- p = skb->mac.raw + 12;
- for (i = 0; i < 4; i++,p++)
- printk("%3d%s", *p,
- i == 3 ? "->" : ".");
- for (i = 0; i < 4; i++,p++)
- printk("%3d%c", *p,
- i == 3 ? ' ' : '.');
- }
+ if (skb->dev && skb->dev->hard_header_len &&
+ skb->mac.raw != skb->nh.raw) {
+ unsigned char *p = skb->mac.raw;
+ int i;
+
+ if (skb->dev->type == ARPHRD_SIT &&
+ (p -= ETH_HLEN) < skb->head)
+ p = NULL;
+
+ if (p != NULL)
+ for (i = 0; i < skb->dev->hard_header_len; i++)
+ printk("%02x", p[i]);
+ printk(" ");
+
+ if (skb->dev->type == ARPHRD_SIT) {
+ struct iphdr *iph = (struct iphdr *)skb->mac.raw;
+ printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ",
+ NIPQUAD(iph->saddr),
+ NIPQUAD(iph->daddr));
}
} else
printk(" ");
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 71407beaf790..c2982efd14af 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -129,13 +129,15 @@ static struct nf_hook_ops ip6t_ops[] = {
.hook = ip6t_hook,
.pf = PF_INET6,
.hooknum = NF_IP6_PRE_ROUTING,
- .priority = NF_IP6_PRI_FIRST
+ .priority = NF_IP6_PRI_FIRST,
+ .owner = THIS_MODULE,
},
{
.hook = ip6t_hook,
.pf = PF_INET6,
.hooknum = NF_IP6_LOCAL_OUT,
- .priority = NF_IP6_PRI_FIRST
+ .priority = NF_IP6_PRI_FIRST,
+ .owner = THIS_MODULE,
},
};
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1f5b226c3573..878789b3122d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -384,12 +384,13 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
be destroyed.
*/
-int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh,
+ void *_rtattr, struct netlink_skb_parms *req)
{
int err;
write_lock_bh(&rt6_lock);
- err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr);
+ err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req);
write_unlock_bh(&rt6_lock);
return err;
@@ -400,7 +401,7 @@ int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
*/
static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
- struct in6_addr *saddr)
+ struct in6_addr *saddr, struct netlink_skb_parms *req)
{
int err;
struct rt6_info *rt;
@@ -432,7 +433,7 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
dst_hold(&rt->u.dst);
- err = ip6_ins_rt(rt, NULL, NULL);
+ err = ip6_ins_rt(rt, NULL, NULL, req);
if (err == 0)
return rt;
@@ -491,7 +492,8 @@ restart:
read_unlock_bh(&rt6_lock);
nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr,
- &skb->nh.ipv6h->saddr);
+ &skb->nh.ipv6h->saddr,
+ &NETLINK_CB(skb));
dst_release(&rt->u.dst);
rt = nrt;
@@ -551,7 +553,7 @@ restart:
dst_hold(&rt->u.dst);
read_unlock_bh(&rt6_lock);
- nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src);
+ nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL);
dst_release(&rt->u.dst);
rt = nrt;
@@ -598,7 +600,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
if (rt) {
if (rt->rt6i_flags & RTF_CACHE)
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
else
dst_release(dst);
}
@@ -787,7 +789,8 @@ int ipv6_get_hoplimit(struct net_device *dev)
*
*/
-int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
+int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
+ void *_rtattr, struct netlink_skb_parms *req)
{
int err;
struct rtmsg *r;
@@ -974,7 +977,7 @@ install_route:
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
rt->u.dst.dev = dev;
rt->rt6i_idev = idev;
- return ip6_ins_rt(rt, nlh, _rtattr);
+ return ip6_ins_rt(rt, nlh, _rtattr, req);
out:
if (dev)
@@ -986,7 +989,7 @@ out:
return err;
}
-int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
{
int err;
@@ -994,7 +997,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
rt6_reset_dflt_pointer(NULL);
- err = fib6_del(rt, nlh, _rtattr);
+ err = fib6_del(rt, nlh, _rtattr, req);
dst_release(&rt->u.dst);
write_unlock_bh(&rt6_lock);
@@ -1002,7 +1005,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
return err;
}
-static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
+static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
{
struct fib6_node *fn;
struct rt6_info *rt;
@@ -1029,7 +1032,7 @@ static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_r
dst_hold(&rt->u.dst);
read_unlock_bh(&rt6_lock);
- return ip6_del_rt(rt, nlh, _rtattr);
+ return ip6_del_rt(rt, nlh, _rtattr, req);
}
}
read_unlock_bh(&rt6_lock);
@@ -1136,11 +1139,11 @@ source_ok:
nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst));
- if (ip6_ins_rt(nrt, NULL, NULL))
+ if (ip6_ins_rt(nrt, NULL, NULL, NULL))
goto out;
if (rt->rt6i_flags&RTF_CACHE) {
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
return;
}
@@ -1204,7 +1207,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
2. It is gatewayed route or NONEXTHOP route. Action: clone it.
*/
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) {
- nrt = rt6_cow(rt, daddr, saddr);
+ nrt = rt6_cow(rt, daddr, saddr, NULL);
if (!nrt->u.dst.error) {
nrt->u.dst.metrics[RTAX_MTU-1] = pmtu;
if (allfrag)
@@ -1232,7 +1235,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
nrt->u.dst.metrics[RTAX_MTU-1] = pmtu;
if (allfrag)
nrt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
- ip6_ins_rt(nrt, NULL, NULL);
+ ip6_ins_rt(nrt, NULL, NULL, NULL);
}
out:
@@ -1305,7 +1308,7 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
rtmsg.rtmsg_ifindex = dev->ifindex;
- ip6_route_add(&rtmsg, NULL, NULL);
+ ip6_route_add(&rtmsg, NULL, NULL, NULL);
return rt6_get_dflt_router(gwaddr, dev);
}
@@ -1323,7 +1326,7 @@ restart:
read_unlock_bh(&rt6_lock);
- ip6_del_rt(rt, NULL, NULL);
+ ip6_del_rt(rt, NULL, NULL, NULL);
goto restart;
}
@@ -1349,10 +1352,10 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
rtnl_lock();
switch (cmd) {
case SIOCADDRT:
- err = ip6_route_add(&rtmsg, NULL, NULL);
+ err = ip6_route_add(&rtmsg, NULL, NULL, NULL);
break;
case SIOCDELRT:
- err = ip6_route_del(&rtmsg, NULL, NULL);
+ err = ip6_route_del(&rtmsg, NULL, NULL, NULL);
break;
default:
err = -EINVAL;
@@ -1546,7 +1549,7 @@ int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
return -EINVAL;
- return ip6_route_del(&rtmsg, nlh, arg);
+ return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb));
}
int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
@@ -1556,7 +1559,7 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
return -EINVAL;
- return ip6_route_add(&rtmsg, nlh, arg);
+ return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb));
}
struct rt6_rtnl_dump_arg
@@ -1566,12 +1569,9 @@ struct rt6_rtnl_dump_arg
};
static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
- struct in6_addr *dst,
- struct in6_addr *src,
- int iif,
- int type, u32 pid, u32 seq,
- struct nlmsghdr *in_nlh, int prefix,
- unsigned int flags)
+ struct in6_addr *dst, struct in6_addr *src,
+ int iif, int type, u32 pid, u32 seq,
+ int prefix, unsigned int flags)
{
struct rtmsg *rtm;
struct nlmsghdr *nlh;
@@ -1585,10 +1585,6 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
}
}
- if (!pid && in_nlh) {
- pid = in_nlh->nlmsg_pid;
- }
-
nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags);
rtm = NLMSG_DATA(nlh);
rtm->rtm_family = AF_INET6;
@@ -1675,7 +1671,7 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg)
return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
- NULL, prefix, NLM_F_MULTI);
+ prefix, NLM_F_MULTI);
}
static int fib6_dump_node(struct fib6_walker_t *w)
@@ -1823,7 +1819,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
&fl.fl6_dst, &fl.fl6_src,
iif,
RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
- nlh->nlmsg_seq, nlh, 0, 0);
+ nlh->nlmsg_seq, 0, 0);
if (err < 0) {
err = -EMSGSIZE;
goto out_free;
@@ -1839,17 +1835,25 @@ out_free:
goto out;
}
-void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh)
+void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh,
+ struct netlink_skb_parms *req)
{
struct sk_buff *skb;
int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
+ u32 pid = current->pid;
+ u32 seq = 0;
+ if (req)
+ pid = req->pid;
+ if (nlh)
+ seq = nlh->nlmsg_seq;
+
skb = alloc_skb(size, gfp_any());
if (!skb) {
netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS);
return;
}
- if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0, 0) < 0) {
+ if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) {
kfree_skb(skb);
netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL);
return;
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index ffcadd68b951..60c26c87277e 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -466,7 +466,7 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return;
}
-static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args)
+static int xfrm6_tunnel_init_state(struct xfrm_state *x)
{
if (!x->props.mode)
return -EINVAL;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 98b72f2024ff..4879743b945a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -690,6 +690,8 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
if (x->props.flags & XFRM_STATE_DECAP_DSCP)
sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
+ if (x->props.flags & XFRM_STATE_NOPMTUDISC)
+ sa->sadb_sa_flags |= SADB_SAFLAGS_NOPMTUDISC;
/* hard time */
if (hsc & 2) {
@@ -974,6 +976,8 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
x->props.flags |= XFRM_STATE_NOECN;
if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
x->props.flags |= XFRM_STATE_DECAP_DSCP;
+ if (sa->sadb_sa_flags & SADB_SAFLAGS_NOPMTUDISC)
+ x->props.flags |= XFRM_STATE_NOPMTUDISC;
lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
if (lifetime != NULL) {
@@ -1096,17 +1100,11 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
}
}
- x->type = xfrm_get_type(proto, x->props.family);
- if (x->type == NULL) {
- err = -ENOPROTOOPT;
- goto out;
- }
- if (x->type->init_state(x, NULL)) {
- err = -EINVAL;
+ err = xfrm_init_state(x);
+ if (err)
goto out;
- }
+
x->km.seq = hdr->sadb_msg_seq;
- x->km.state = XFRM_STATE_VALID;
return x;
out:
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 663843d97a92..7ae6aa772dab 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -191,10 +191,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc->last_cwr_tsn = asoc->ctsn_ack_point;
asoc->unack_data = 0;
- SCTP_DEBUG_PRINTK("myctsnap for %s INIT as 0x%x.\n",
- asoc->ep->debug_name,
- asoc->ctsn_ack_point);
-
/* ADDIP Section 4.1 Asconf Chunk Procedures
*
* When an endpoint has an ASCONF signaled change to be sent to the
@@ -211,6 +207,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
/* Make an empty list of remote transport addresses. */
INIT_LIST_HEAD(&asoc->peer.transport_addr_list);
+ asoc->peer.transport_count = 0;
/* RFC 2960 5.1 Normal Establishment of an Association
*
@@ -288,6 +285,7 @@ struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
asoc->base.malloced = 1;
SCTP_DBG_OBJCNT_INC(assoc);
+ SCTP_DEBUG_PRINTK("Created asoc %p\n", asoc);
return asoc;
@@ -356,6 +354,8 @@ void sctp_association_free(struct sctp_association *asoc)
sctp_transport_free(transport);
}
+ asoc->peer.transport_count = 0;
+
/* Free any cached ASCONF_ACK chunk. */
if (asoc->addip_last_asconf_ack)
sctp_chunk_free(asoc->addip_last_asconf_ack);
@@ -400,7 +400,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
/* If the primary path is changing, assume that the
* user wants to use this new path.
*/
- if (transport->active)
+ if (transport->state != SCTP_INACTIVE)
asoc->peer.active_path = transport;
/*
@@ -428,10 +428,58 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
transport->cacc.next_tsn_at_change = asoc->next_tsn;
}
+/* Remove a transport from an association. */
+void sctp_assoc_rm_peer(struct sctp_association *asoc,
+ struct sctp_transport *peer)
+{
+ struct list_head *pos;
+ struct sctp_transport *transport;
+
+ SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_rm_peer:association %p addr: ",
+ " port: %d\n",
+ asoc,
+ (&peer->ipaddr),
+ peer->ipaddr.v4.sin_port);
+
+ /* If we are to remove the current retran_path, update it
+ * to the next peer before removing this peer from the list.
+ */
+ if (asoc->peer.retran_path == peer)
+ sctp_assoc_update_retran_path(asoc);
+
+ /* Remove this peer from the list. */
+ list_del(&peer->transports);
+
+ /* Get the first transport of asoc. */
+ pos = asoc->peer.transport_addr_list.next;
+ transport = list_entry(pos, struct sctp_transport, transports);
+
+ /* Update any entries that match the peer to be deleted. */
+ if (asoc->peer.primary_path == peer)
+ sctp_assoc_set_primary(asoc, transport);
+ if (asoc->peer.active_path == peer)
+ asoc->peer.active_path = transport;
+ if (asoc->peer.last_data_from == peer)
+ asoc->peer.last_data_from = transport;
+
+ /* If we remove the transport an INIT was last sent to, set it to
+ * NULL. Combined with the update of the retran path above, this
+ * will cause the next INIT to be sent to the next available
+ * transport, maintaining the cycle.
+ */
+ if (asoc->init_last_sent_to == peer)
+ asoc->init_last_sent_to = NULL;
+
+ asoc->peer.transport_count--;
+
+ sctp_transport_free(peer);
+}
+
/* Add a transport address to an association. */
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
const union sctp_addr *addr,
- int gfp)
+ const int gfp,
+ const int peer_state)
{
struct sctp_transport *peer;
struct sctp_sock *sp;
@@ -442,14 +490,25 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* AF_INET and AF_INET6 share common port field. */
port = addr->v4.sin_port;
+ SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ",
+ " port: %d state:%s\n",
+ asoc,
+ addr,
+ addr->v4.sin_port,
+ peer_state == SCTP_UNKNOWN?"UNKNOWN":"ACTIVE");
+
/* Set the port if it has not been set yet. */
if (0 == asoc->peer.port)
asoc->peer.port = port;
/* Check to see if this is a duplicate. */
peer = sctp_assoc_lookup_paddr(asoc, addr);
- if (peer)
+ if (peer) {
+ if (peer_state == SCTP_ACTIVE &&
+ peer->state == SCTP_UNKNOWN)
+ peer->state = SCTP_ACTIVE;
return peer;
+ }
peer = sctp_transport_new(addr, gfp);
if (!peer)
@@ -516,8 +575,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* Set the transport's RTO.initial value */
peer->rto = asoc->rto_initial;
+ /* Set the peer's active state. */
+ peer->state = peer_state;
+
/* Attach the remote transport to our asoc. */
list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
+ asoc->peer.transport_count++;
/* If we do not yet have a primary path, set one. */
if (!asoc->peer.primary_path) {
@@ -525,8 +588,9 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
asoc->peer.retran_path = peer;
}
- if (asoc->peer.active_path == asoc->peer.retran_path)
+ if (asoc->peer.active_path == asoc->peer.retran_path) {
asoc->peer.retran_path = peer;
+ }
return peer;
}
@@ -537,37 +601,16 @@ void sctp_assoc_del_peer(struct sctp_association *asoc,
{
struct list_head *pos;
struct list_head *temp;
- struct sctp_transport *peer = NULL;
struct sctp_transport *transport;
list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
transport = list_entry(pos, struct sctp_transport, transports);
if (sctp_cmp_addr_exact(addr, &transport->ipaddr)) {
- peer = transport;
- list_del(pos);
+ /* Do book keeping for removing the peer and free it. */
+ sctp_assoc_rm_peer(asoc, transport);
break;
}
}
-
- /* The address we want delete is not in the association. */
- if (!peer)
- return;
-
- /* Get the first transport of asoc. */
- pos = asoc->peer.transport_addr_list.next;
- transport = list_entry(pos, struct sctp_transport, transports);
-
- /* Update any entries that match the peer to be deleted. */
- if (asoc->peer.primary_path == peer)
- sctp_assoc_set_primary(asoc, transport);
- if (asoc->peer.active_path == peer)
- asoc->peer.active_path = transport;
- if (asoc->peer.retran_path == peer)
- asoc->peer.retran_path = transport;
- if (asoc->peer.last_data_from == peer)
- asoc->peer.last_data_from = transport;
-
- sctp_transport_free(peer);
}
/* Lookup a transport by address. */
@@ -608,12 +651,12 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
/* Record the transition on the transport. */
switch (command) {
case SCTP_TRANSPORT_UP:
- transport->active = SCTP_ACTIVE;
+ transport->state = SCTP_ACTIVE;
spc_state = SCTP_ADDR_AVAILABLE;
break;
case SCTP_TRANSPORT_DOWN:
- transport->active = SCTP_INACTIVE;
+ transport->state = SCTP_INACTIVE;
spc_state = SCTP_ADDR_UNREACHABLE;
break;
@@ -643,7 +686,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, struct sctp_transport, transports);
- if (!t->active)
+ if (t->state == SCTP_INACTIVE)
continue;
if (!first || t->last_time_heard > first->last_time_heard) {
second = first;
@@ -663,7 +706,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
* [If the primary is active but not most recent, bump the most
* recently used transport.]
*/
- if (asoc->peer.primary_path->active &&
+ if (asoc->peer.primary_path->state != SCTP_INACTIVE &&
first != asoc->peer.primary_path) {
second = first;
first = asoc->peer.primary_path;
@@ -958,7 +1001,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
transports);
if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr))
sctp_assoc_add_peer(asoc, &trans->ipaddr,
- GFP_ATOMIC);
+ GFP_ATOMIC, SCTP_ACTIVE);
}
asoc->ctsn_ack_point = asoc->next_tsn - 1;
@@ -998,7 +1041,7 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
/* Try to find an active transport. */
- if (t->active) {
+ if (t->state != SCTP_INACTIVE) {
break;
} else {
/* Keep track of the next transport in case
@@ -1019,6 +1062,40 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
}
asoc->peer.retran_path = t;
+
+ SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
+ " %p addr: ",
+ " port: %d\n",
+ asoc,
+ (&t->ipaddr),
+ t->ipaddr.v4.sin_port);
+}
+
+/* Choose the transport for sending a INIT packet. */
+struct sctp_transport *sctp_assoc_choose_init_transport(
+ struct sctp_association *asoc)
+{
+ struct sctp_transport *t;
+
+ /* Use the retran path. If the last INIT was sent over the
+ * retran path, update the retran path and use it.
+ */
+ if (!asoc->init_last_sent_to) {
+ t = asoc->peer.active_path;
+ } else {
+ if (asoc->init_last_sent_to == asoc->peer.retran_path)
+ sctp_assoc_update_retran_path(asoc);
+ t = asoc->peer.retran_path;
+ }
+
+ SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
+ " %p addr: ",
+ " port: %d\n",
+ asoc,
+ (&t->ipaddr),
+ t->ipaddr.v4.sin_port);
+
+ return t;
}
/* Choose the transport for sending a SHUTDOWN packet. */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 334f61773e6d..2ec0320fac3b 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -134,7 +134,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
ep->last_key = ep->current_key = 0;
ep->key_changed_at = jiffies;
- ep->debug_name = "unnamedEndpoint";
return ep;
}
diff --git a/net/sctp/input.c b/net/sctp/input.c
index fffc880a646d..339f7acfdb64 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -353,7 +353,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
sctp_do_sm(SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
- asoc->state, asoc->ep, asoc, NULL,
+ asoc->state, asoc->ep, asoc, t,
GFP_ATOMIC);
}
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1b2d4adc4ddb..4eb81a1407b7 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -682,9 +682,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
if (!new_transport) {
new_transport = asoc->peer.active_path;
- } else if (!new_transport->active) {
- /* If the chunk is Heartbeat or Heartbeat Ack,
- * send it to chunk->transport, even if it's
+ } else if (new_transport->state == SCTP_INACTIVE) {
+ /* If the chunk is Heartbeat or Heartbeat Ack,
+ * send it to chunk->transport, even if it's
* inactive.
*
* 3.3.6 Heartbeat Acknowledgement:
@@ -840,7 +840,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
* Otherwise, we want to use the active path.
*/
new_transport = chunk->transport;
- if (!new_transport || !new_transport->active)
+ if (!new_transport ||
+ new_transport->state == SCTP_INACTIVE)
new_transport = asoc->peer.active_path;
/* Change packets if necessary. */
@@ -1454,7 +1455,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
/* Mark the destination transport address as
* active if it is not so marked.
*/
- if (!transport->active) {
+ if (transport->state == SCTP_INACTIVE) {
sctp_assoc_control_transport(
transport->asoc,
transport,
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 33ac8bf47b0e..5baed9bb7de5 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1830,7 +1830,7 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* be a a better choice than any of the embedded addresses.
*/
if (peer_addr)
- if(!sctp_assoc_add_peer(asoc, peer_addr, gfp))
+ if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
goto nomem;
/* Process the initialization parameters. */
@@ -1841,6 +1841,14 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
goto clean_up;
}
+ /* Walk list of transports, removing transports in the UNKNOWN state. */
+ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
+ transport = list_entry(pos, struct sctp_transport, transports);
+ if (transport->state == SCTP_UNKNOWN) {
+ sctp_assoc_rm_peer(asoc, transport);
+ }
+ }
+
/* The fixed INIT headers are always in network byte
* order.
*/
@@ -1906,7 +1914,8 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* stream sequence number shall be set to 0.
*/
- /* Allocate storage for the negotiated streams if it is not a temporary * association.
+ /* Allocate storage for the negotiated streams if it is not a temporary
+ * association.
*/
if (!asoc->temp) {
int assoc_id;
@@ -1952,6 +1961,9 @@ clean_up:
list_del_init(pos);
sctp_transport_free(transport);
}
+
+ asoc->peer.transport_count = 0;
+
nomem:
return 0;
}
@@ -1995,7 +2007,7 @@ static int sctp_process_param(struct sctp_association *asoc,
af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
scope = sctp_scope(peer_addr);
if (sctp_in_scope(&addr, scope))
- if (!sctp_assoc_add_peer(asoc, &addr, gfp))
+ if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_ACTIVE))
return 0;
break;
@@ -2396,7 +2408,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
* Due to Resource Shortage'.
*/
- peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC);
+ peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_ACTIVE);
if (!peer)
return SCTP_ERROR_RSRC_LOW;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index f65fa441952f..778639db125a 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -414,11 +414,13 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
*/
asoc->overall_error_count++;
- if (transport->active &&
+ if (transport->state != SCTP_INACTIVE &&
(transport->error_count++ >= transport->max_retrans)) {
- SCTP_DEBUG_PRINTK("transport_strike: transport "
- "IP:%d.%d.%d.%d failed.\n",
- NIPQUAD(transport->ipaddr.v4.sin_addr));
+ SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
+ " transport IP: port:%d failed.\n",
+ asoc,
+ (&transport->ipaddr),
+ transport->ipaddr.v4.sin_port);
sctp_assoc_control_transport(asoc, transport,
SCTP_TRANSPORT_DOWN,
SCTP_FAILED_THRESHOLD);
@@ -593,7 +595,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
/* Mark the destination transport address as active if it is not so
* marked.
*/
- if (!t->active)
+ if (t->state == SCTP_INACTIVE)
sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
SCTP_HEARTBEAT_SUCCESS);
@@ -665,8 +667,11 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
asoc->state = state;
+ SCTP_DEBUG_PRINTK("sctp_cmd_new_state: asoc %p[%s]\n",
+ asoc, sctp_state_tbl[state]);
+
if (sctp_style(sk, TCP)) {
- /* Change the sk->sk_state of a TCP-style socket that has
+ /* Change the sk->sk_state of a TCP-style socket that has
* sucessfully completed a connect() call.
*/
if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
@@ -678,6 +683,16 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
sk->sk_shutdown |= RCV_SHUTDOWN;
}
+ if (sctp_state(asoc, COOKIE_WAIT)) {
+ /* Reset init timeouts since they may have been
+ * increased due to timer expirations.
+ */
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
+ asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT];
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
+ asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE];
+ }
+
if (sctp_state(asoc, ESTABLISHED) ||
sctp_state(asoc, CLOSED) ||
sctp_state(asoc, SHUTDOWN_RECEIVED)) {
@@ -1120,10 +1135,10 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
* to be executed only during failed attempts of
* association establishment.
*/
- if ((asoc->peer.retran_path !=
- asoc->peer.primary_path) &&
- (asoc->counters[SCTP_COUNTER_INIT_ERROR] > 0)) {
- sctp_add_cmd_sf(commands,
+ if ((asoc->peer.retran_path !=
+ asoc->peer.primary_path) &&
+ (asoc->init_err_counter > 0)) {
+ sctp_add_cmd_sf(commands,
SCTP_CMD_FORCE_PRIM_RETRAN,
SCTP_NULL());
}
@@ -1237,18 +1252,67 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_association_put(asoc);
break;
+ case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
+ chunk = cmd->obj.ptr;
+ t = sctp_assoc_choose_init_transport(asoc);
+ asoc->init_last_sent_to = t;
+ chunk->transport = t;
+ t->init_sent_count++;
+ break;
+
case SCTP_CMD_INIT_RESTART:
/* Do the needed accounting and updates
* associated with restarting an initialization
- * timer.
+ * timer. Only multiply the timeout by two if
+ * all transports have been tried at the current
+ * timeout.
+ */
+ t = asoc->init_last_sent_to;
+ asoc->init_err_counter++;
+
+ if (t->init_sent_count > (asoc->init_cycle + 1)) {
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
+ if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
+ asoc->max_init_timeo) {
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
+ asoc->max_init_timeo;
+ }
+ asoc->init_cycle++;
+ SCTP_DEBUG_PRINTK(
+ "T1 INIT Timeout adjustment"
+ " init_err_counter: %d"
+ " cycle: %d"
+ " timeout: %d\n",
+ asoc->init_err_counter,
+ asoc->init_cycle,
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
+ }
+
+ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+ break;
+
+ case SCTP_CMD_COOKIEECHO_RESTART:
+ /* Do the needed accounting and updates
+ * associated with restarting an initialization
+ * timer. Only multiply the timeout by two if
+ * all transports have been tried at the current
+ * timeout.
*/
- asoc->counters[SCTP_COUNTER_INIT_ERROR]++;
- asoc->timeouts[cmd->obj.to] *= 2;
- if (asoc->timeouts[cmd->obj.to] >
+ asoc->init_err_counter++;
+
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2;
+ if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
asoc->max_init_timeo) {
- asoc->timeouts[cmd->obj.to] =
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
asoc->max_init_timeo;
}
+ SCTP_DEBUG_PRINTK(
+ "T1 COOKIE Timeout adjustment"
+ " init_err_counter: %d"
+ " timeout: %d\n",
+ asoc->init_err_counter,
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
/* If we've sent any data bundled with
* COOKIE-ECHO we need to resend.
@@ -1261,7 +1325,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_add_cmd_sf(commands,
SCTP_CMD_TIMER_RESTART,
- SCTP_TO(cmd->obj.to));
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
break;
case SCTP_CMD_INIT_FAILED:
@@ -1273,12 +1337,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
subtype, chunk, cmd->obj.u32);
break;
- case SCTP_CMD_COUNTER_INC:
- asoc->counters[cmd->obj.counter]++;
+ case SCTP_CMD_INIT_COUNTER_INC:
+ asoc->init_err_counter++;
break;
- case SCTP_CMD_COUNTER_RESET:
- asoc->counters[cmd->obj.counter] = 0;
+ case SCTP_CMD_INIT_COUNTER_RESET:
+ asoc->init_err_counter = 0;
+ asoc->init_cycle = 0;
break;
case SCTP_CMD_REPORT_DUP:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8e01b8f09ac2..058189684c7c 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -533,6 +533,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
SCTP_PEER_INIT(initchunk));
+ /* Reset init error count upon receipt of INIT-ACK. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
+
/* 5.1 C) "A" shall stop the T1-init timer and leave
* COOKIE-WAIT state. "A" shall then ... start the T1-cookie
* timer, and enter the COOKIE-ECHOED state.
@@ -775,8 +778,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
* from the COOKIE-ECHOED state to the COOKIE-WAIT
* state is performed.
*/
- sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET,
- SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
/* RFC 2960 5.1 Normal Establishment of an Association
*
@@ -1019,10 +1021,22 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
link = sctp_assoc_lookup_paddr(asoc, &from_addr);
/* This should never happen, but lets log it if so. */
- if (!link) {
- printk(KERN_WARNING
- "%s: Could not find address %d.%d.%d.%d\n",
- __FUNCTION__, NIPQUAD(from_addr.v4.sin_addr));
+ if (unlikely(!link)) {
+ if (from_addr.sa.sa_family == AF_INET6) {
+ printk(KERN_WARNING
+ "%s association %p could not find address "
+ "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+ __FUNCTION__,
+ asoc,
+ NIP6(from_addr.v6.sin6_addr));
+ } else {
+ printk(KERN_WARNING
+ "%s association %p could not find address "
+ "%u.%u.%u.%u\n",
+ __FUNCTION__,
+ asoc,
+ NIPQUAD(from_addr.v4.sin_addr.s_addr));
+ }
return SCTP_DISPOSITION_DISCARD;
}
@@ -2095,9 +2109,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
sctp_errhdr_t *err;
struct sctp_chunk *reply;
struct sctp_bind_addr *bp;
- int attempts;
-
- attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
+ int attempts = asoc->init_err_counter + 1;
if (attempts >= asoc->max_init_attempts) {
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
@@ -2157,8 +2169,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
/* Cast away the const modifier, as we want to just
* rerun it through as a sideffect.
*/
- sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC,
- SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_INC, SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
@@ -2281,8 +2292,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
- sctp_stop_t1_and_abort(commands, error);
- return SCTP_DISPOSITION_ABORT;
+ return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport);
}
/*
@@ -2294,8 +2304,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
void *arg,
sctp_cmd_seq_t *commands)
{
- sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR);
- return SCTP_DISPOSITION_ABORT;
+ return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc,
+ (struct sctp_transport *)arg);
}
/*
@@ -2318,8 +2328,12 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
*
* This is common code called by several sctp_sf_*_abort() functions above.
*/
-void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error)
+sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
+ __u16 error,
+ const struct sctp_association *asoc,
+ struct sctp_transport *transport)
{
+ SCTP_DEBUG_PRINTK("ABORT received (INIT).\n");
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2328,6 +2342,7 @@ void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error)
/* CMD_INIT_FAILED will DELETE_TCB. */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
SCTP_U32(error));
+ return SCTP_DISPOSITION_ABORT;
}
/*
@@ -3805,6 +3820,10 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC,
SCTP_ASOC((struct sctp_association *) asoc));
+ /* Choose transport for INIT. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
+ SCTP_CHUNK(repl));
+
/* After sending the INIT, "A" starts the T1-init timer and
* enters the COOKIE-WAIT state.
*/
@@ -4589,7 +4608,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
}
/*
- * sctp_sf_t1_timer_expire
+ * sctp_sf_t1_init_timer_expire
*
* Section: 4 Note: 2
* Verification Tag:
@@ -4603,7 +4622,59 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
* endpoint MUST abort the initialization process and report the
* error to SCTP user.
*
- * 3) If the T1-cookie timer expires, the endpoint MUST retransmit
+ * Outputs
+ * (timers, events)
+ *
+ */
+sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc,
+ const sctp_subtype_t type,
+ void *arg,
+ sctp_cmd_seq_t *commands)
+{
+ struct sctp_chunk *repl = NULL;
+ struct sctp_bind_addr *bp;
+ int attempts = asoc->init_err_counter + 1;
+
+ SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n");
+
+ if (attempts < asoc->max_init_attempts) {
+ bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
+ repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
+ if (!repl)
+ return SCTP_DISPOSITION_NOMEM;
+
+ /* Choose transport for INIT. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
+ SCTP_CHUNK(repl));
+
+ /* Issue a sideeffect to do the needed accounting. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
+ } else {
+ SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
+ " max_init_attempts: %d\n",
+ attempts, asoc->max_init_attempts);
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+ SCTP_U32(SCTP_ERROR_NO_ERROR));
+ return SCTP_DISPOSITION_DELETE_TCB;
+ }
+
+ return SCTP_DISPOSITION_CONSUME;
+}
+
+/*
+ * sctp_sf_t1_cookie_timer_expire
+ *
+ * Section: 4 Note: 2
+ * Verification Tag:
+ * Inputs
+ * (endpoint, asoc)
+ *
+ * RFC 2960 Section 4 Notes
+ * 3) If the T1-cookie timer expires, the endpoint MUST retransmit
* COOKIE ECHO and re-start the T1-cookie timer without changing
* state. This MUST be repeated up to 'Max.Init.Retransmits' times.
* After that, the endpoint MUST abort the initialization process and
@@ -4613,46 +4684,26 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
* (timers, events)
*
*/
-sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
- struct sctp_chunk *repl;
- struct sctp_bind_addr *bp;
- sctp_event_timeout_t timer = (sctp_event_timeout_t) arg;
- int timeout;
- int attempts;
-
- timeout = asoc->timeouts[timer];
- attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
- repl = NULL;
+ struct sctp_chunk *repl = NULL;
+ int attempts = asoc->init_err_counter + 1;
- SCTP_DEBUG_PRINTK("Timer T1 expired.\n");
+ SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n");
if (attempts < asoc->max_init_attempts) {
- switch (timer) {
- case SCTP_EVENT_TIMEOUT_T1_INIT:
- bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
- repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
- break;
-
- case SCTP_EVENT_TIMEOUT_T1_COOKIE:
- repl = sctp_make_cookie_echo(asoc, NULL);
- break;
-
- default:
- BUG();
- break;
- };
-
+ repl = sctp_make_cookie_echo(asoc, NULL);
if (!repl)
- goto nomem;
+ return SCTP_DISPOSITION_NOMEM;
/* Issue a sideeffect to do the needed accounting. */
- sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
- SCTP_TO(timer));
+ sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
+
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
} else {
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
@@ -4661,9 +4712,6 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
}
return SCTP_DISPOSITION_CONSUME;
-
-nomem:
- return SCTP_DISPOSITION_NOMEM;
}
/* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 8967846f69e8..75ef10408764 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -783,7 +783,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
/* SCTP_STATE_COOKIE_WAIT */ \
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \
- {.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
+ {.fn = sctp_sf_t1_cookie_timer_expire, \
+ .name = "sctp_sf_t1_cookie_timer_expire"}, \
/* SCTP_STATE_ESTABLISHED */ \
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \
@@ -802,7 +803,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
/* SCTP_STATE_CLOSED */ \
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \
- {.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
+ {.fn = sctp_sf_t1_init_timer_expire, \
+ .name = "sctp_sf_t1_init_timer_expire"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e6926cb19420..aad55dc3792b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -262,18 +262,18 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
* sockaddr_in6 [RFC 2553]),
* addr_len - the size of the address structure.
*/
-SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
{
int retval = 0;
sctp_lock_sock(sk);
- SCTP_DEBUG_PRINTK("sctp_bind(sk: %p, uaddr: %p, addr_len: %d)\n",
- sk, uaddr, addr_len);
+ SCTP_DEBUG_PRINTK("sctp_bind(sk: %p, addr: %p, addr_len: %d)\n",
+ sk, addr, addr_len);
/* Disallow binding twice. */
if (!sctp_sk(sk)->ep->base.bind_addr.port)
- retval = sctp_do_bind(sk, (union sctp_addr *)uaddr,
+ retval = sctp_do_bind(sk, (union sctp_addr *)addr,
addr_len);
else
retval = -EINVAL;
@@ -318,23 +318,27 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
unsigned short snum;
int ret = 0;
- SCTP_DEBUG_PRINTK("sctp_do_bind(sk: %p, newaddr: %p, len: %d)\n",
- sk, addr, len);
-
/* Common sockaddr verification. */
af = sctp_sockaddr_af(sp, addr, len);
- if (!af)
+ if (!af) {
+ SCTP_DEBUG_PRINTK("sctp_do_bind(sk: %p, newaddr: %p, len: %d) EINVAL\n",
+ sk, addr, len);
return -EINVAL;
+ }
+
+ snum = ntohs(addr->v4.sin_port);
+
+ SCTP_DEBUG_PRINTK_IPADDR("sctp_do_bind(sk: %p, new addr: ",
+ ", port: %d, new port: %d, len: %d)\n",
+ sk,
+ addr,
+ bp->port, snum,
+ len);
/* PF specific bind() address verification. */
if (!sp->pf->bind_verify(sp, addr))
return -EADDRNOTAVAIL;
- snum= ntohs(addr->v4.sin_port);
-
- SCTP_DEBUG_PRINTK("sctp_do_bind: port: %d, new port: %d\n",
- bp->port, snum);
-
/* We must either be unbound, or bind to the same port. */
if (bp->port && (snum != bp->port)) {
SCTP_DEBUG_PRINTK("sctp_do_bind:"
@@ -816,7 +820,8 @@ out:
*
* Basically do nothing but copying the addresses from user to kernel
* land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk.
- * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() * from userspace.
+ * This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
+ * from userspace.
*
* We don't use copy_from_user() for optimization: we first do the
* sanity checks (buffer size -fast- and access check-healthy
@@ -913,6 +918,243 @@ out:
return err;
}
+/* __sctp_connect(struct sock* sk, struct sockaddr *kaddrs, int addrs_size)
+ *
+ * Common routine for handling connect() and sctp_connectx().
+ * Connect will come in with just a single address.
+ */
+static int __sctp_connect(struct sock* sk,
+ struct sockaddr *kaddrs,
+ int addrs_size)
+{
+ struct sctp_sock *sp;
+ struct sctp_endpoint *ep;
+ struct sctp_association *asoc = NULL;
+ struct sctp_association *asoc2;
+ struct sctp_transport *transport;
+ union sctp_addr to;
+ struct sctp_af *af;
+ sctp_scope_t scope;
+ long timeo;
+ int err = 0;
+ int addrcnt = 0;
+ int walk_size = 0;
+ struct sockaddr *sa_addr;
+ void *addr_buf;
+
+ sp = sctp_sk(sk);
+ ep = sp->ep;
+
+ /* connect() cannot be done on a socket that is already in ESTABLISHED
+ * state - UDP-style peeled off socket or a TCP-style socket that
+ * is already connected.
+ * It cannot be done even on a TCP-style listening socket.
+ */
+ if (sctp_sstate(sk, ESTABLISHED) ||
+ (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))) {
+ err = -EISCONN;
+ goto out_free;
+ }
+
+ /* Walk through the addrs buffer and count the number of addresses. */
+ addr_buf = kaddrs;
+ while (walk_size < addrs_size) {
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+
+ /* If the address family is not supported or if this address
+ * causes the address buffer to overflow return EINVAL.
+ */
+ if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ err = sctp_verify_addr(sk, (union sctp_addr *)sa_addr,
+ af->sockaddr_len);
+ if (err)
+ goto out_free;
+
+ memcpy(&to, sa_addr, af->sockaddr_len);
+ to.v4.sin_port = ntohs(to.v4.sin_port);
+
+ /* Check if there already is a matching association on the
+ * endpoint (other than the one created here).
+ */
+ asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport);
+ if (asoc2 && asoc2 != asoc) {
+ if (asoc2->state >= SCTP_STATE_ESTABLISHED)
+ err = -EISCONN;
+ else
+ err = -EALREADY;
+ goto out_free;
+ }
+
+ /* If we could not find a matching association on the endpoint,
+ * make sure that there is no peeled-off association matching
+ * the peer address even on another socket.
+ */
+ if (sctp_endpoint_is_peeled_off(ep, &to)) {
+ err = -EADDRNOTAVAIL;
+ goto out_free;
+ }
+
+ if (!asoc) {
+ /* If a bind() or sctp_bindx() is not called prior to
+ * an sctp_connectx() call, the system picks an
+ * ephemeral port and will choose an address set
+ * equivalent to binding with a wildcard address.
+ */
+ if (!ep->base.bind_addr.port) {
+ if (sctp_autobind(sk)) {
+ err = -EAGAIN;
+ goto out_free;
+ }
+ }
+
+ scope = sctp_scope(&to);
+ asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
+ if (!asoc) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+ }
+
+ /* Prime the peer's transport structures. */
+ transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL,
+ SCTP_UNKNOWN);
+ if (!transport) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ addrcnt++;
+ addr_buf += af->sockaddr_len;
+ walk_size += af->sockaddr_len;
+ }
+
+ err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
+ if (err < 0) {
+ goto out_free;
+ }
+
+ err = sctp_primitive_ASSOCIATE(asoc, NULL);
+ if (err < 0) {
+ goto out_free;
+ }
+
+ /* Initialize sk's dport and daddr for getpeername() */
+ inet_sk(sk)->dport = htons(asoc->peer.port);
+ af = sctp_get_af_specific(to.sa.sa_family);
+ af->to_sk_daddr(&to, sk);
+
+ timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
+ err = sctp_wait_for_connect(asoc, &timeo);
+
+ /* Don't free association on exit. */
+ asoc = NULL;
+
+out_free:
+
+ SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p"
+ " kaddrs: %p err: %d\n",
+ asoc, kaddrs, err);
+ if (asoc)
+ sctp_association_free(asoc);
+ return err;
+}
+
+/* Helper for tunneling sctp_connectx() requests through sctp_setsockopt()
+ *
+ * API 8.9
+ * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt);
+ *
+ * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
+ * If the sd is an IPv6 socket, the addresses passed can either be IPv4
+ * or IPv6 addresses.
+ *
+ * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see
+ * Section 3.1.2 for this usage.
+ *
+ * addrs is a pointer to an array of one or more socket addresses. Each
+ * address is contained in its appropriate structure (i.e. struct
+ * sockaddr_in or struct sockaddr_in6) the family of the address type
+ * must be used to distengish the address length (note that this
+ * representation is termed a "packed array" of addresses). The caller
+ * specifies the number of addresses in the array with addrcnt.
+ *
+ * On success, sctp_connectx() returns 0. On failure, sctp_connectx() returns
+ * -1, and sets errno to the appropriate error code.
+ *
+ * For SCTP, the port given in each socket address must be the same, or
+ * sctp_connectx() will fail, setting errno to EINVAL.
+ *
+ * An application can use sctp_connectx to initiate an association with
+ * an endpoint that is multi-homed. Much like sctp_bindx() this call
+ * allows a caller to specify multiple addresses at which a peer can be
+ * reached. The way the SCTP stack uses the list of addresses to set up
+ * the association is implementation dependant. This function only
+ * specifies that the stack will try to make use of all the addresses in
+ * the list when needed.
+ *
+ * Note that the list of addresses passed in is only used for setting up
+ * the association. It does not necessarily equal the set of addresses
+ * the peer uses for the resulting association. If the caller wants to
+ * find out the set of peer addresses, it must use sctp_getpaddrs() to
+ * retrieve them after the association has been set up.
+ *
+ * Basically do nothing but copying the addresses from user to kernel
+ * land and invoking either sctp_connectx(). This is used for tunneling
+ * the sctp_connectx() request through sctp_setsockopt() from userspace.
+ *
+ * We don't use copy_from_user() for optimization: we first do the
+ * sanity checks (buffer size -fast- and access check-healthy
+ * pointer); if all of those succeed, then we can alloc the memory
+ * (expensive operation) needed to copy the data to kernel. Then we do
+ * the copying without checking the user space area
+ * (__copy_from_user()).
+ *
+ * On exit there is no need to do sockfd_put(), sys_setsockopt() does
+ * it.
+ *
+ * sk The sk of the socket
+ * addrs The pointer to the addresses in user land
+ * addrssize Size of the addrs buffer
+ *
+ * Returns 0 if ok, <0 errno code on error.
+ */
+SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
+ struct sockaddr __user *addrs,
+ int addrs_size)
+{
+ int err = 0;
+ struct sockaddr *kaddrs;
+
+ SCTP_DEBUG_PRINTK("%s - sk %p addrs %p addrs_size %d\n",
+ __FUNCTION__, sk, addrs, addrs_size);
+
+ if (unlikely(addrs_size <= 0))
+ return -EINVAL;
+
+ /* Check the user passed a healthy pointer. */
+ if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
+ return -EFAULT;
+
+ /* Alloc space for the address array in kernel memory. */
+ kaddrs = (struct sockaddr *)kmalloc(addrs_size, GFP_KERNEL);
+ if (unlikely(!kaddrs))
+ return -ENOMEM;
+
+ if (__copy_from_user(kaddrs, addrs, addrs_size)) {
+ err = -EFAULT;
+ } else {
+ err = __sctp_connect(sk, kaddrs, addrs_size);
+ }
+
+ kfree(kaddrs);
+ return err;
+}
+
/* API 3.1.4 close() - UDP Style Syntax
* Applications use close() to perform graceful shutdown (as described in
* Section 10.1 of [SCTP]) on ALL the associations currently represented
@@ -1095,7 +1337,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
sp = sctp_sk(sk);
ep = sp->ep;
- SCTP_DEBUG_PRINTK("Using endpoint: %s.\n", ep->debug_name);
+ SCTP_DEBUG_PRINTK("Using endpoint: %p.\n", ep);
/* We cannot send a message over a TCP-style listening socket. */
if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) {
@@ -1306,7 +1548,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
/* Prime the peer's transport structures. */
- transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL);
+ transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, SCTP_UNKNOWN);
if (!transport) {
err = -ENOMEM;
goto out_free;
@@ -2208,6 +2450,12 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
optlen, SCTP_BINDX_REM_ADDR);
break;
+ case SCTP_SOCKOPT_CONNECTX:
+ /* 'optlen' is the size of the addresses buffer. */
+ retval = sctp_setsockopt_connectx(sk, (struct sockaddr __user *)optval,
+ optlen);
+ break;
+
case SCTP_DISABLE_FRAGMENTS:
retval = sctp_setsockopt_disable_fragments(sk, optval, optlen);
break;
@@ -2283,112 +2531,29 @@ out_nounlock:
*
* len: the size of the address.
*/
-SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr,
+SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *addr,
int addr_len)
{
- struct sctp_sock *sp;
- struct sctp_endpoint *ep;
- struct sctp_association *asoc;
- struct sctp_transport *transport;
- union sctp_addr to;
- struct sctp_af *af;
- sctp_scope_t scope;
- long timeo;
int err = 0;
+ struct sctp_af *af;
sctp_lock_sock(sk);
- SCTP_DEBUG_PRINTK("%s - sk: %p, sockaddr: %p, addr_len: %d)\n",
- __FUNCTION__, sk, uaddr, addr_len);
-
- sp = sctp_sk(sk);
- ep = sp->ep;
-
- /* connect() cannot be done on a socket that is already in ESTABLISHED
- * state - UDP-style peeled off socket or a TCP-style socket that
- * is already connected.
- * It cannot be done even on a TCP-style listening socket.
- */
- if (sctp_sstate(sk, ESTABLISHED) ||
- (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))) {
- err = -EISCONN;
- goto out_unlock;
- }
-
- err = sctp_verify_addr(sk, (union sctp_addr *)uaddr, addr_len);
- if (err)
- goto out_unlock;
-
- if (addr_len > sizeof(to))
- addr_len = sizeof(to);
- memcpy(&to, uaddr, addr_len);
- to.v4.sin_port = ntohs(to.v4.sin_port);
-
- asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
- if (asoc) {
- if (asoc->state >= SCTP_STATE_ESTABLISHED)
- err = -EISCONN;
- else
- err = -EALREADY;
- goto out_unlock;
- }
-
- /* If we could not find a matching association on the endpoint,
- * make sure that there is no peeled-off association matching the
- * peer address even on another socket.
- */
- if (sctp_endpoint_is_peeled_off(ep, &to)) {
- err = -EADDRNOTAVAIL;
- goto out_unlock;
- }
-
- /* If a bind() or sctp_bindx() is not called prior to a connect()
- * call, the system picks an ephemeral port and will choose an address
- * set equivalent to binding with a wildcard address.
- */
- if (!ep->base.bind_addr.port) {
- if (sctp_autobind(sk)) {
- err = -EAGAIN;
- goto out_unlock;
- }
- }
-
- scope = sctp_scope(&to);
- asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
- if (!asoc) {
- err = -ENOMEM;
- goto out_unlock;
- }
+ SCTP_DEBUG_PRINTK("%s - sk: %p, sockaddr: %p, addr_len: %d\n",
+ __FUNCTION__, sk, addr, addr_len);
- /* Prime the peer's transport structures. */
- transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL);
- if (!transport) {
- sctp_association_free(asoc);
- goto out_unlock;
- }
- err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
- if (err < 0) {
- sctp_association_free(asoc);
- goto out_unlock;
- }
-
- err = sctp_primitive_ASSOCIATE(asoc, NULL);
- if (err < 0) {
- sctp_association_free(asoc);
- goto out_unlock;
+ /* Validate addr_len before calling common connect/connectx routine. */
+ af = sctp_get_af_specific(addr->sa_family);
+ if (!af || addr_len < af->sockaddr_len) {
+ err = -EINVAL;
+ } else {
+ /* Pass correct addr len to common routine (so it knows there
+ * is only one address being passed.
+ */
+ err = __sctp_connect(sk, addr, af->sockaddr_len);
}
- /* Initialize sk's dport and daddr for getpeername() */
- inet_sk(sk)->dport = htons(asoc->peer.port);
- af = sctp_get_af_specific(to.sa.sa_family);
- af->to_sk_daddr(&to, sk);
-
- timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
- err = sctp_wait_for_connect(asoc, &timeo);
-
-out_unlock:
sctp_release_sock(sk);
-
return err;
}
@@ -2677,12 +2842,15 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
/* Map ipv4 address into v4-mapped-on-v6 address. */
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
(union sctp_addr *)&status.sstat_primary.spinfo_address);
- status.sstat_primary.spinfo_state = transport->active;
+ status.sstat_primary.spinfo_state = transport->state;
status.sstat_primary.spinfo_cwnd = transport->cwnd;
status.sstat_primary.spinfo_srtt = transport->srtt;
status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto);
status.sstat_primary.spinfo_mtu = transport->pmtu;
+ if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN)
+ status.sstat_primary.spinfo_state = SCTP_ACTIVE;
+
if (put_user(len, optlen)) {
retval = -EFAULT;
goto out;
@@ -2733,12 +2901,15 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
return -EINVAL;
pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc);
- pinfo.spinfo_state = transport->active;
+ pinfo.spinfo_state = transport->state;
pinfo.spinfo_cwnd = transport->cwnd;
pinfo.spinfo_srtt = transport->srtt;
pinfo.spinfo_rto = jiffies_to_msecs(transport->rto);
pinfo.spinfo_mtu = transport->pmtu;
+ if (pinfo.spinfo_state == SCTP_UNKNOWN)
+ pinfo.spinfo_state = SCTP_ACTIVE;
+
if (put_user(len, optlen)) {
retval = -EFAULT;
goto out;
@@ -3591,7 +3762,8 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
int retval = 0;
int len;
- SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p, ...)\n", sk);
+ SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p... optname: %d)\n",
+ sk, optname);
/* I can hardly begin to describe how wrong this is. This is
* so broken as to be worse than useless. The API draft
@@ -4596,8 +4768,7 @@ out:
return err;
do_error:
- if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >=
- asoc->max_init_attempts)
+ if (asoc->init_err_counter + 1 >= asoc->max_init_attempts)
err = -ETIMEDOUT;
else
err = -ECONNREFUSED;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index f30882e1e96a..0ec0fde6e6c5 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -83,7 +83,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
peer->last_time_used = jiffies;
peer->last_time_ecne_reduced = jiffies;
- peer->active = SCTP_ACTIVE;
+ peer->init_sent_count = 0;
+
+ peer->state = SCTP_ACTIVE;
peer->hb_allowed = 0;
/* Initialize the default path max_retrans. */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 0a4260719a12..d65ed8684fc1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -118,7 +118,6 @@ retry:
xfrm_policy_put_afinfo(afinfo);
return type;
}
-EXPORT_SYMBOL(xfrm_get_type);
int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
unsigned short family)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 2537f26f097c..9d206c282cf1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1055,6 +1055,43 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
}
EXPORT_SYMBOL(xfrm_state_mtu);
+
+int xfrm_init_state(struct xfrm_state *x)
+{
+ struct xfrm_state_afinfo *afinfo;
+ int family = x->props.family;
+ int err;
+
+ err = -EAFNOSUPPORT;
+ afinfo = xfrm_state_get_afinfo(family);
+ if (!afinfo)
+ goto error;
+
+ err = 0;
+ if (afinfo->init_flags)
+ err = afinfo->init_flags(x);
+
+ xfrm_state_put_afinfo(afinfo);
+
+ if (err)
+ goto error;
+
+ err = -EPROTONOSUPPORT;
+ x->type = xfrm_get_type(x->id.proto, family);
+ if (x->type == NULL)
+ goto error;
+
+ err = x->type->init_state(x);
+ if (err)
+ goto error;
+
+ x->km.state = XFRM_STATE_VALID;
+
+error:
+ return err;
+}
+
+EXPORT_SYMBOL(xfrm_init_state);
void __init xfrm_state_init(void)
{
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 5ce8558eac91..ecade4893a13 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -249,17 +249,10 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
goto error;
- err = -ENOENT;
- x->type = xfrm_get_type(x->id.proto, x->props.family);
- if (x->type == NULL)
- goto error;
-
- err = x->type->init_state(x, NULL);
+ err = xfrm_init_state(x);
if (err)
goto error;
- x->curlft.add_time = (unsigned long) xtime.tv_sec;
- x->km.state = XFRM_STATE_VALID;
x->km.seq = p->seq;
return x;
diff --git a/security/seclvl.c b/security/seclvl.c
index 8a0ab0d7949e..c8e87b22c9bd 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -155,7 +155,7 @@ seclvl_attr_store(struct kobject *kobj,
struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
struct seclvl_attribute *attribute =
container_of(attr, struct seclvl_attribute, attr);
- return (attribute->store ? attribute->store(obj, buf, len) : 0);
+ return attribute->store ? attribute->store(obj, buf, len) : -EIO;
}
static ssize_t
@@ -164,7 +164,7 @@ seclvl_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
struct seclvl_attribute *attribute =
container_of(attr, struct seclvl_attribute, attr);
- return (attribute->show ? attribute->show(obj, buf) : 0);
+ return attribute->show ? attribute->show(obj, buf) : -EIO;
}
/**
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 88e052079f85..33eaa5e5d284 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -64,7 +64,7 @@ static struct list_head snd_minors_hash[SNDRV_CARDS];
static DECLARE_MUTEX(sound_mutex);
-extern struct class_simple *sound_class;
+extern struct class *sound_class;
#ifdef CONFIG_KMOD
@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg,
devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
if (card)
device = card->dev;
- class_simple_device_add(sound_class, MKDEV(major, minor), device, name);
+ class_device_create(sound_class, MKDEV(major, minor), device, "%s", name);
up(&sound_mutex);
return 0;
@@ -263,7 +263,7 @@ int snd_unregister_device(int type, snd_card_t * card, int dev)
if (strncmp(mptr->name, "controlC", 8) || card->number >= cards_limit) /* created in sound.c */
devfs_remove("snd/%s", mptr->name);
- class_simple_device_remove(MKDEV(major, minor));
+ class_device_destroy(sound_class, MKDEV(major, minor));
list_del(&mptr->list);
up(&sound_mutex);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index de91c90a0112..a686be936aff 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -73,7 +73,7 @@ static char dma_alloc_map[MAX_DMA_CHANNELS];
unsigned long seq_time = 0; /* Time for /dev/sequencer */
-extern struct class_simple *sound_class;
+extern struct class *sound_class;
/*
* Table for configurable mixer volume handling
@@ -567,9 +567,9 @@ static int __init oss_init(void)
devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
S_IFCHR | dev_list[i].mode,
"sound/%s", dev_list[i].name);
- class_simple_device_add(sound_class,
- MKDEV(SOUND_MAJOR, dev_list[i].minor),
- NULL, "%s", dev_list[i].name);
+ class_device_create(sound_class,
+ MKDEV(SOUND_MAJOR, dev_list[i].minor),
+ NULL, "%s", dev_list[i].name);
if (!dev_list[i].num)
continue;
@@ -579,10 +579,9 @@ static int __init oss_init(void)
dev_list[i].minor + (j*0x10)),
S_IFCHR | dev_list[i].mode,
"sound/%s%d", dev_list[i].name, j);
- class_simple_device_add(sound_class,
- MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
- NULL,
- "%s%d", dev_list[i].name, j);
+ class_device_create(sound_class,
+ MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
+ NULL, "%s%d", dev_list[i].name, j);
}
}
@@ -598,12 +597,12 @@ static void __exit oss_cleanup(void)
for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
devfs_remove("sound/%s", dev_list[i].name);
- class_simple_device_remove(MKDEV(SOUND_MAJOR, dev_list[i].minor));
+ class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor));
if (!dev_list[i].num)
continue;
for (j = 1; j < *dev_list[i].num; j++) {
devfs_remove("sound/%s%d", dev_list[i].name, j);
- class_simple_device_remove(MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
+ class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
}
}
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 30f75c9288cb..21a69e096225 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -65,7 +65,7 @@ extern int msnd_classic_init(void);
extern int msnd_pinnacle_init(void);
#endif
-struct class_simple *sound_class;
+struct class *sound_class;
EXPORT_SYMBOL(sound_class);
/*
@@ -174,7 +174,7 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f
devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
S_IFCHR | mode, s->name);
- class_simple_device_add(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
+ class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
NULL, s->name+6);
return r;
@@ -198,7 +198,7 @@ static void sound_remove_unit(struct sound_unit **list, int unit)
spin_unlock(&sound_loader_lock);
if (p) {
devfs_remove(p->name);
- class_simple_device_remove(MKDEV(SOUND_MAJOR, p->unit_minor));
+ class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor));
kfree(p);
}
}
@@ -562,7 +562,7 @@ static void __exit cleanup_soundcore(void)
empty */
unregister_chrdev(SOUND_MAJOR, "sound");
devfs_remove("sound");
- class_simple_destroy(sound_class);
+ class_destroy(sound_class);
}
static int __init init_soundcore(void)
@@ -572,7 +572,7 @@ static int __init init_soundcore(void)
return -EBUSY;
}
devfs_mk_dir ("sound");
- sound_class = class_simple_create(THIS_MODULE, "sound");
+ sound_class = class_create(THIS_MODULE, "sound");
if (IS_ERR(sound_class))
return PTR_ERR(sound_class);