]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'vfree' into for-next
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 1 May 2013 21:31:27 +0000 (17:31 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 1 May 2013 21:31:27 +0000 (17:31 -0400)
1354 files changed:
CREDITS
Documentation/SubmittingPatches
Documentation/device-mapper/dm-raid.txt
Documentation/devicetree/bindings/mfd/ab8500.txt
Documentation/devicetree/bindings/tty/serial/of-serial.txt
Documentation/hwmon/adm1275
Documentation/hwmon/adt7410
Documentation/hwmon/jc42
Documentation/hwmon/lineage-pem
Documentation/hwmon/lm25066
Documentation/hwmon/lm75
Documentation/hwmon/ltc2978
Documentation/hwmon/ltc4261
Documentation/hwmon/max16064
Documentation/hwmon/max16065
Documentation/hwmon/max34440
Documentation/hwmon/max8688
Documentation/hwmon/pmbus
Documentation/hwmon/smm665
Documentation/hwmon/ucd9000
Documentation/hwmon/ucd9200
Documentation/hwmon/zl6100
Documentation/i2c/busses/i2c-diolan-u2c
Documentation/input/alps.txt
Documentation/networking/ipvs-sysctl.txt
Documentation/networking/tuntap.txt
Documentation/power/opp.txt
Documentation/printk-formats.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/seq_oss.html
Documentation/trace/ftrace.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/boot/head.S
arch/alpha/kernel/srm_env.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/dts/armada-370-rd.dts
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/dbx5x0.dtsi
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos5440.dtsi
arch/arm/boot/dts/href.dtsi
arch/arm/boot/dts/hrefv60plus.dts
arch/arm/boot/dts/imx53-mba53.dts
arch/arm/boot/dts/kirkwood-dns320.dts
arch/arm/boot/dts/kirkwood-dns325.dts
arch/arm/boot/dts/kirkwood-dockstar.dts
arch/arm/boot/dts/kirkwood-dreamplug.dts
arch/arm/boot/dts/kirkwood-goflexnet.dts
arch/arm/boot/dts/kirkwood-ib62x0.dts
arch/arm/boot/dts/kirkwood-iconnect.dts
arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
arch/arm/boot/dts/kirkwood-km_kirkwood.dts
arch/arm/boot/dts/kirkwood-lschlv2.dts
arch/arm/boot/dts/kirkwood-lsxhl.dts
arch/arm/boot/dts/kirkwood-mplcec4.dts
arch/arm/boot/dts/kirkwood-ns2-common.dtsi
arch/arm/boot/dts/kirkwood-nsa310.dts
arch/arm/boot/dts/kirkwood-openblocks_a6.dts
arch/arm/boot/dts/kirkwood-topkick.dts
arch/arm/boot/dts/kirkwood.dtsi
arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
arch/arm/boot/dts/snowball.dts
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/configs/mxs_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/include/asm/mmu.h
arch/arm/include/asm/mmu_context.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/asm/xen/events.h
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/atags_proc.c
arch/arm/kernel/calls.S
arch/arm/kernel/head.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/smp.c
arch/arm/kernel/smp_tlb.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/suspend.c
arch/arm/kernel/swp_emulate.c
arch/arm/lib/memset.S
arch/arm/mach-at91/board-foxg20.c
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-at91/include/mach/gpio.h
arch/arm/mach-at91/irq.c
arch/arm/mach-at91/pm.c
arch/arm/mach-davinci/dma.c
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-imx/clk-imx35.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/headsmp.S
arch/arm/mach-imx/imx25-dt.c
arch/arm/mach-imx/pm-imx6q.c
arch/arm/mach-ixp4xx/vulcan-setup.c
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-mmp/gplugd.c
arch/arm/mach-msm/last_radio_log.c
arch/arm/mach-mxs/icoll.c
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-mxs/mm.c
arch/arm/mach-mxs/ocotp.c
arch/arm/mach-netx/generic.c
arch/arm/mach-netx/include/mach/irqs.h
arch/arm/mach-omap1/common.h
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-spear3xx/spear3xx.c
arch/arm/mm/context.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/idmap.c
arch/arm/mm/proc-v7-3level.S
arch/arm/net/bpf_jit_32.c
arch/arm/plat-orion/addr-map.c
arch/arm/plat-spear/Kconfig
arch/arm64/Kconfig
arch/arm64/Kconfig.debug
arch/arm64/configs/defconfig
arch/arm64/include/asm/ucontext.h
arch/arm64/kernel/arm64ksyms.c
arch/arm64/kernel/signal32.c
arch/avr32/Kconfig
arch/blackfin/Kconfig
arch/blackfin/kernel/cplbinfo.c
arch/cris/Kconfig
arch/cris/arch-v10/kernel/fasttimer.c
arch/cris/arch-v32/kernel/fasttimer.c
arch/frv/Kconfig
arch/h8300/Kconfig
arch/h8300/kernel/gpio.c
arch/ia64/Kconfig
arch/ia64/kernel/palinfo.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/salinfo.c
arch/ia64/sn/kernel/sn2/prominfo_proc.c
arch/m32r/Kconfig
arch/m32r/include/uapi/asm/stat.h
arch/m68k/Kconfig
arch/m68k/Kconfig.machine
arch/m68k/include/asm/MC68328.h
arch/m68k/kernel/setup_no.c
arch/m68k/mm/init.c
arch/m68k/platform/coldfire/m528x.c
arch/metag/include/asm/elf.h
arch/metag/mm/Kconfig
arch/microblaze/Kconfig
arch/mips/Kconfig
arch/mips/kernel/smtc-proc.c
arch/mips/lasat/picvue_proc.c
arch/mips/mm/init.c
arch/mips/pci/ops-pmcmsp.c
arch/mips/sibyte/sb1250/bus_watcher.c
arch/mn10300/Kconfig
arch/openrisc/Kconfig
arch/parisc/Kconfig
arch/parisc/kernel/pdc_chassis.c
arch/powerpc/Kconfig
arch/powerpc/crypto/sha1-powerpc-asm.S
arch/powerpc/include/asm/bitops.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/include/uapi/asm/unistd.h
arch/powerpc/kernel/cpu_setup_power.S
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/proc_powerpc.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kvm/book3s_64_mmu_host.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_64_vio.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/mmu_context_hash64.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/slb_low.S
arch/powerpc/mm/tlb_hash64.c
arch/powerpc/perf/power7-pmu.c
arch/powerpc/platforms/85xx/sgy_cts1000.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/pseries/hvcserver.c
arch/powerpc/platforms/pseries/reconfig.c
arch/powerpc/platforms/pseries/scanlog.c
arch/s390/Kconfig
arch/s390/hypfs/inode.c
arch/s390/include/asm/cpu_mf.h
arch/s390/include/asm/eadm.h
arch/s390/include/asm/tlbflush.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/irq.c
arch/s390/kernel/os_info.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscalls.S
arch/score/Kconfig
arch/score/mm/init.c
arch/sh/drivers/dma/dma-api.c
arch/sh/mm/alignment.c
arch/sparc/Kconfig
arch/sparc/include/asm/spitfire.h
arch/sparc/kernel/cpu.c
arch/sparc/kernel/head_64.S
arch/sparc/kernel/ioport.c
arch/sparc/kernel/leon_pci_grpci2.c
arch/sparc/kernel/sun4d_irq.c
arch/tile/Kconfig
arch/tile/configs/tilegx_defconfig
arch/tile/configs/tilepro_defconfig
arch/tile/include/asm/compat.h
arch/tile/kernel/compat.c
arch/tile/kernel/hardwall.c
arch/um/drivers/chan.h
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_user.c
arch/um/drivers/chan_user.h
arch/um/drivers/line.c
arch/um/drivers/mconsole_kern.c
arch/um/drivers/net_kern.c
arch/um/drivers/ssl.c
arch/um/drivers/stdio_console.c
arch/um/os-Linux/signal.c
arch/um/os-Linux/start_up.c
arch/unicore32/Kconfig
arch/x86/Kconfig
arch/x86/ia32/ia32_aout.c
arch/x86/include/asm/bootparam_utils.h
arch/x86/include/asm/kprobes.h
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/microcode_intel_early.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/x86.c
arch/x86/lib/usercopy_64.c
arch/x86/mm/init.c
arch/x86/mm/init_64.c
arch/x86/mm/pat.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_64.c
arch/x86/power/cpu.c
arch/xtensa/Kconfig
arch/xtensa/platforms/iss/simdisk.c
drivers/acpi/ac.c
drivers/acpi/battery.c
drivers/acpi/button.c
drivers/acpi/glue.c
drivers/acpi/proc.c
drivers/acpi/processor_core.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_perflib.c
drivers/acpi/sbs.c
drivers/acpi/sleep.c
drivers/amba/tegra-ahb.c
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-acpi.c
drivers/ata/pata_samsung_cf.c
drivers/ata/sata_fsl.c
drivers/ata/sata_svw.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/base/power/qos.c
drivers/base/power/sysfs.c
drivers/base/regmap/regmap-irq.c
drivers/bcma/driver_pci_host.c
drivers/block/DAC960.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/cpqarray.c
drivers/block/drbd/drbd_proc.c
drivers/block/loop.c
drivers/block/nvme.c
drivers/block/pktcdvd.c
drivers/block/ps3vram.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/char/ds1620.c
drivers/char/efirtc.c
drivers/char/genrtc.c
drivers/char/hw_random/core.c
drivers/char/hw_random/virtio-rng.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/random.c
drivers/clk/clk-vt8500.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra30.c
drivers/connector/cn_proc.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/highbank-cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/edac/amd64_edac.c
drivers/edac/edac_mc.c
drivers/edac/edac_mc_sysfs.c
drivers/firmware/Kconfig
drivers/firmware/dmi_scan.c
drivers/firmware/efivars.c
drivers/gpio/gpio-ich.c
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_proc.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_i2c.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/core/core/object.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
drivers/gpu/drm/nouveau/core/include/subdev/therm.h
drivers/gpu/drm/nouveau/core/subdev/bios/init.c
drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
drivers/gpu/drm/nouveau/core/subdev/therm/base.c
drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_agp.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_pm.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_benchmark.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/tegra/Kconfig
drivers/hid/hid-logitech-dj.c
drivers/hwmon/lineage-pem.c
drivers/hwmon/lm75.h
drivers/hwmon/pmbus/ltc2978.c
drivers/hwmon/pmbus/pmbus_core.c
drivers/hwmon/sht15.c
drivers/i2c/Kconfig
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk_proc.c
drivers/ide/ide-floppy_proc.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/ad5064.c
drivers/iio/imu/inv_mpu6050/Kconfig
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/mlx4/cm.c
drivers/infiniband/hw/qib/Kconfig
drivers/infiniband/hw/qib/qib_driver.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_init.c
drivers/infiniband/hw/qib/qib_sd7220.c
drivers/infiniband/hw/qib/qib_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/input/joystick/analog.c
drivers/input/keyboard/tc3589x-keypad.c
drivers/input/misc/hp_sdc_rtc.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/cypress_ps2.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/mms114.c
drivers/iommu/dmar.c
drivers/irqchip/irq-gic.c
drivers/isdn/gigaset/capi.c
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/eicon/divasproc.c
drivers/isdn/hisax/Kconfig
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/hysdn/hycapi.c
drivers/isdn/hysdn/hysdn_procconf.c
drivers/isdn/hysdn/hysdn_proclog.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/mISDN/timerdev.c
drivers/macintosh/via-pmu.c
drivers/mailbox/pl320-ipc.c
drivers/md/Kconfig
drivers/md/dm-bufio.c
drivers/md/dm-cache-metadata.c
drivers/md/dm-cache-metadata.h
drivers/md/dm-cache-policy-cleaner.c
drivers/md/dm-cache-policy-internal.h
drivers/md/dm-cache-policy-mq.c
drivers/md/dm-cache-policy.c
drivers/md/dm-cache-policy.h
drivers/md/dm-cache-target.c
drivers/md/dm-raid.c
drivers/md/dm-thin.c
drivers/md/dm-verity.c
drivers/md/md.c
drivers/md/md.h
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid10.h
drivers/md/raid5.c
drivers/md/raid5.h
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvb_net.c
drivers/media/pci/cx25821/cx25821-audio-upstream.c
drivers/media/pci/ttpci/av7110_ir.c
drivers/media/pci/zoran/zoran_procfs.c
drivers/media/rc/ir-lirc-codec.c
drivers/media/rc/lirc_dev.c
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/message/fusion/mptspi.c
drivers/message/i2o/i2o_proc.c
drivers/mfd/Kconfig
drivers/mfd/ab8500-gpadc.c
drivers/mfd/omap-usb-host.c
drivers/mfd/palmas.c
drivers/mfd/tps65912-core.c
drivers/mfd/twl4030-audio.c
drivers/mfd/twl4030-madc.c
drivers/misc/ibmasm/ibmasmfs.c
drivers/misc/lis3lv02d/lis3lv02d.c
drivers/misc/sgi-gru/gruprocfs.c
drivers/mtd/bcm47xxpart.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdcore.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_ids.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_procfs.c
drivers/net/bonding/bond_sysfs.c
drivers/net/ethernet/broadcom/bgmac.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/dec/tulip/Kconfig
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_ptp.c
drivers/net/ethernet/intel/e1000e/ethtool.c
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/ich8lan.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/e1000e/regs.h
drivers/net/ethernet/intel/igb/e1000_82575.c
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_hwmon.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igb/igb_ptp.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/pd.c
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx4/srq.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/nic.c
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/hippi/rrunner.c
drivers/net/irda/vlsi_ir.c
drivers/net/macvlan.c
drivers/net/netconsole.c
drivers/net/phy/micrel.c
drivers/net/phy/phy_device.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/asix_devices.c
drivers/net/usb/ax88179_178a.c [new file with mode: 0644]
drivers/net/usb/cdc_mbim.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/vxlan.c
drivers/net/wireless/airo.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/common.h
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/atmel.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_download.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_proc.c
drivers/net/wireless/hostap/hostap_wlan.h
drivers/net/wireless/iwlegacy/3945-mac.c
drivers/net/wireless/iwlwifi/dvm/sta.c
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-modparams.h
drivers/net/wireless/iwlwifi/iwl-phy-db.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/usb.c
drivers/nubus/nubus.c
drivers/nubus/proc.c
drivers/of/base.c
drivers/oprofile/oprofilefs.c
drivers/parisc/led.c
drivers/pci/pci-acpi.c
drivers/pci/proc.c
drivers/pci/rom.c
drivers/pinctrl/mvebu/pinctrl-mvebu.c
drivers/pinctrl/pinconf.c
drivers/pinctrl/pinconf.h
drivers/pinctrl/pinctrl-abx500.c
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinmux.c
drivers/platform/x86/chromeos_laptop.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/pnp/isapnp/proc.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpbios/proc.c
drivers/pps/clients/pps_parport.c
drivers/regulator/core.c
drivers/regulator/db8500-prcmu.c
drivers/regulator/palmas-regulator.c
drivers/regulator/twl-regulator.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-at91rm9200.h
drivers/rtc/rtc-da9052.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-proc.c
drivers/s390/block/scm_blk.c
drivers/s390/block/scm_blk.h
drivers/s390/block/scm_drv.c
drivers/s390/char/sclp_cmd.c
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/scm.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/net/qeth_l3_sys.c
drivers/scsi/BusLogic.c
drivers/scsi/BusLogic.h
drivers/scsi/NCR5380.c
drivers/scsi/NCR5380.h
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/advansys.c
drivers/scsi/aha152x.c
drivers/scsi/aha1740.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.h
drivers/scsi/aic7xxx/aic79xx_proc.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.h
drivers/scsi/aic7xxx/aic7xxx_proc.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/aic7xxx_old/aic7xxx_proc.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/arxescsi.c
drivers/scsi/arm/cumana_1.c
drivers/scsi/arm/cumana_2.c
drivers/scsi/arm/eesox.c
drivers/scsi/arm/fas216.c
drivers/scsi/arm/fas216.h
drivers/scsi/arm/oak.c
drivers/scsi/arm/powertec.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/atari_scsi.h
drivers/scsi/atp870u.c
drivers/scsi/dc395x.c
drivers/scsi/dpt_i2o.c
drivers/scsi/dtc.c
drivers/scsi/dtc.h
drivers/scsi/eata_pio.c
drivers/scsi/g_NCR5380.c
drivers/scsi/gdth.c
drivers/scsi/gdth.h
drivers/scsi/gdth_proc.c
drivers/scsi/gdth_proc.h
drivers/scsi/gvp11.c
drivers/scsi/imm.c
drivers/scsi/in2000.c
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/mac_scsi.c
drivers/scsi/mac_scsi.h
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/mpt2sas/mpt2sas_ctl.c
drivers/scsi/mpt3sas/mpt3sas_ctl.c
drivers/scsi/mvme147.c
drivers/scsi/nsp32.c
drivers/scsi/pas16.c
drivers/scsi/pas16.h
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pmcraid.c
drivers/scsi/ppa.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_proc.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/t128.c
drivers/scsi/t128.h
drivers/scsi/wd33c93.c
drivers/scsi/wd33c93.h
drivers/scsi/wd7000.c
drivers/staging/ccg/f_fs.c
drivers/staging/ccg/rndis.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxfast.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/comedi/proc.c
drivers/staging/csr/csr_wifi_hip_udi.c
drivers/staging/csr/csr_wifi_hip_unifi_udi.h
drivers/staging/csr/drv.c
drivers/staging/csr/io.c
drivers/staging/cxt1e1/Makefile
drivers/staging/cxt1e1/sbeproc.c
drivers/staging/cxt1e1/sbeproc.h
drivers/staging/dgrp/dgrp_common.c
drivers/staging/dgrp/dgrp_common.h
drivers/staging/dgrp/dgrp_dpa_ops.c
drivers/staging/dgrp/dgrp_mon_ops.c
drivers/staging/dgrp/dgrp_net_ops.c
drivers/staging/dgrp/dgrp_ports_ops.c
drivers/staging/dgrp/dgrp_specproc.c
drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
drivers/staging/imx-drm/ipuv3-crtc.c
drivers/staging/keucr/scsiglue.c
drivers/staging/rtl8187se/r8180.h
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8192e/rtl8192e/Makefile
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.h
drivers/staging/rtl8192e/rtl8192e/rtl_debug.c [deleted file]
drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
drivers/staging/rtl8192e/rtllib_crypt_tkip.c
drivers/staging/rtl8192e/rtllib_crypt_wep.c
drivers/staging/rtl8192e/rtllib_module.c
drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
drivers/staging/rtl8192u/ieee80211/proc.c
drivers/staging/rtl8192u/r8192U.h
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rts5139/rts51x_scsi.c
drivers/staging/rts5139/rts51x_scsi.h
drivers/staging/silicom/Makefile
drivers/staging/silicom/bp_proc.c [deleted file]
drivers/staging/silicom/bpctl_mod.c [moved from drivers/staging/silicom/bp_mod.c with 84% similarity]
drivers/staging/tidspbridge/rmgr/drv.c
drivers/staging/vt6655/device_main.c
drivers/staging/vt6656/card.c
drivers/staging/vt6656/main_usb.c
drivers/staging/wlags49_h2/wl_main.c
drivers/staging/zcache/ramster/tcp.c
drivers/target/iscsi/iscsi_target_auth.c
drivers/target/loopback/tcm_loop.c
drivers/target/target_core_file.h
drivers/target/target_core_pscsi.c
drivers/target/target_core_sbc.c
drivers/target/target_core_tpg.c
drivers/thermal/dove_thermal.c
drivers/thermal/exynos_thermal.c
drivers/thermal/kirkwood_thermal.c
drivers/thermal/rcar_thermal.c
drivers/tty/hvc/hvcs.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/8250_pnp.c
drivers/tty/serial/Kconfig
drivers/tty/serial/bcm63xx_uart.c
drivers/tty/serial/mpc52xx_uart.c
drivers/tty/serial/of_serial.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sunsu.c
drivers/tty/serial/vt8500_serial.c
drivers/tty/tty_buffer.c
drivers/tty/vt/vc_screen.c
drivers/usb/Makefile
drivers/usb/c67x00/c67x00-sched.c
drivers/usb/chipidea/udc.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/usb-acpi.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/dwc3/dwc3-omap.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/Makefile
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_rndis.c
drivers/usb/gadget/f_uac1.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/g_ffs.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/lpc32xx_udc.c
drivers/usb/gadget/net2272.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/gadget/u_serial.c
drivers/usb/gadget/u_uac1.c
drivers/usb/gadget/udc-core.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-timer.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/yurex.c
drivers/usb/musb/Kconfig
drivers/usb/musb/da8xx.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/omap2430.c
drivers/usb/otg/otg.c
drivers/usb/phy/omap-control-usb.c
drivers/usb/phy/omap-usb3.c
drivers/usb/phy/samsung-usbphy.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/ch341.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/f81232.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/oti6858.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/qcaux.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/quatech2.c
drivers/usb/serial/spcp8x5.c
drivers/usb/serial/ssu100.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/initializers.c
drivers/usb/storage/initializers.h
drivers/usb/storage/scsiglue.c
drivers/usb/storage/unusual_devs.h
drivers/vfio/pci/vfio_pci_config.c
drivers/vfio/pci/vfio_pci_intrs.c
drivers/vhost/net.c
drivers/vhost/tcm_vhost.c
drivers/video/atmel_lcdfb.c
drivers/video/bfin_adv7393fb.c
drivers/video/ep93xx-fb.c
drivers/video/mxsfb.c
drivers/video/omap/lcd_ams_delta.c
drivers/video/omap/lcd_osk.c
drivers/video/pxa3xx-gcu.c
drivers/w1/masters/w1-gpio.c
drivers/w1/w1.c
drivers/watchdog/sp5100_tco.c
drivers/watchdog/sp5100_tco.h
drivers/xen/xen-acpi-processor.c
drivers/xen/xen-pciback/pciback_ops.c
drivers/xen/xen-stub.c
drivers/xen/xenfs/super.c
drivers/zorro/proc.c
firmware/Makefile
firmware/intel/sd7220.fw.ihex [moved from firmware/qlogic/sd7220.fw.ihex with 100% similarity]
fs/9p/vfs_super.c
fs/Makefile
fs/adfs/super.c
fs/affs/super.c
fs/afs/proc.c
fs/afs/super.c
fs/aio.c
fs/autofs4/init.c
fs/befs/linuxvfs.c
fs/bfs/inode.c
fs/binfmt_aout.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/binfmt_misc.c
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-inode.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/locking.h
fs/btrfs/qgroup.c
fs/btrfs/relocation.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/cachefiles/rdwr.c
fs/ceph/super.c
fs/cifs/asn1.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/netmisc.c
fs/cifs/smb2ops.c
fs/coda/file.c
fs/coda/inode.c
fs/compat.c
fs/configfs/mount.c
fs/coredump.c
fs/cramfs/inode.c
fs/dcache.c
fs/debugfs/inode.c
fs/ecryptfs/Kconfig
fs/ecryptfs/Makefile
fs/ecryptfs/crypto.c
fs/ecryptfs/dentry.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/messaging.c
fs/ecryptfs/miscdev.c
fs/efs/super.c
fs/exec.c
fs/exofs/super.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/extents_status.c
fs/ext4/extents_status.h
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/move_extent.c
fs/ext4/page-io.c
fs/ext4/resize.c
fs/ext4/super.c
fs/f2fs/acl.c
fs/f2fs/dir.c
fs/f2fs/file.c
fs/f2fs/super.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/fifo.c [deleted file]
fs/filesystems.c
fs/freevxfs/vxfs_super.c
fs/fuse/control.c
fs/fuse/dev.c
fs/fuse/file.c
fs/fuse/inode.c
fs/gfs2/ops_fstype.c
fs/hfs/super.c
fs/hfsplus/super.c
fs/hostfs/hostfs_kern.c
fs/hpfs/file.c
fs/hpfs/super.c
fs/hppfs/hppfs.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/internal.h
fs/isofs/inode.c
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/jffs2/super.c
fs/jfs/super.c
fs/logfs/super.c
fs/minix/inode.c
fs/mount.h
fs/namei.c
fs/namespace.c
fs/ncpfs/inode.c
fs/nfs/blocklayout/blocklayoutdm.c
fs/nfs/idmap.c
fs/nfs/nfs4filelayout.c
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h
fs/nfs/super.c
fs/nfsd/nfs4state.c
fs/nfsd/nfscache.c
fs/nfsd/nfsctl.c
fs/nfsd/vfs.c
fs/nilfs2/super.c
fs/notify/inotify/inotify_user.c
fs/ntfs/file.c
fs/ntfs/super.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/file.c
fs/ocfs2/super.c
fs/omfs/inode.c
fs/openpromfs/inode.c
fs/pipe.c
fs/pnode.c
fs/pnode.h
fs/proc/base.c
fs/proc/fd.h
fs/proc/generic.c
fs/proc/inode.c
fs/proc/internal.h
fs/proc/kcore.c
fs/proc/namespaces.c
fs/proc/proc_devtree.c
fs/proc/proc_net.c
fs/proc/root.c
fs/proc/self.c
fs/proc/vmcore.c
fs/qnx4/inode.c
fs/qnx6/inode.c
fs/quota/dquot.c
fs/read_write.c
fs/read_write.h
fs/reiserfs/file.c
fs/reiserfs/procfs.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/seq_file.c
fs/splice.c
fs/squashfs/super.c
fs/sysv/super.c
fs/ubifs/super.c
fs/udf/super.c
fs/ufs/super.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_file.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_super.c
include/acpi/acpi_bus.h
include/acpi/processor.h
include/asm-generic/atomic.h
include/asm-generic/cmpxchg.h
include/drm/drmP.h
include/drm/drm_crtc.h
include/drm/drm_pciids.h
include/linux/binfmts.h
include/linux/cgroup.h
include/linux/cpuset.h
include/linux/ecryptfs.h
include/linux/edac.h
include/linux/fs.h
include/linux/hardirq.h
include/linux/hash.h
include/linux/i2c/atmel_mxt_ts.h
include/linux/idr.h
include/linux/iio/common/st_sensors.h
include/linux/irq_work.h
include/linux/kcore.h [new file with mode: 0644]
include/linux/kernel.h
include/linux/list.h
include/linux/mfd/palmas.h
include/linux/mfd/tps65912.h
include/linux/mfd/wm831x/auxadc.h
include/linux/mfd/wm831x/core.h
include/linux/mmzone.h
include/linux/mtd/nand.h
include/linux/mxsfb.h
include/linux/netfilter/ipset/ip_set_ahash.h
include/linux/nubus.h
include/linux/nvme.h
include/linux/of.h
include/linux/perf_event.h
include/linux/pid_namespace.h
include/linux/pipe_fs_i.h
include/linux/printk.h
include/linux/proc_fs.h
include/linux/proc_ns.h [new file with mode: 0644]
include/linux/profile.h
include/linux/regulator/driver.h
include/linux/res_counter.h
include/linux/seq_file.h
include/linux/signal.h
include/linux/skbuff.h
include/linux/smpboot.h
include/linux/thermal.h
include/linux/tty.h
include/linux/udp.h
include/linux/usb/cdc_ncm.h
include/linux/usb/composite.h
include/linux/usb/serial.h
include/linux/usb/ulpi.h
include/net/bluetooth/bluetooth.h
include/net/dst.h
include/net/flow_keys.h
include/net/inet_frag.h
include/net/ip_fib.h
include/net/ip_vs.h
include/net/ipip.h
include/net/lib80211.h
include/net/tcp.h
include/scsi/scsi_host.h
include/uapi/linux/acct.h
include/uapi/linux/aio_abi.h
include/uapi/linux/packet_diag.h
include/uapi/linux/raid/md_p.h
include/uapi/linux/serial_core.h
include/uapi/linux/unix_diag.h
include/video/atmel_lcdc.h
init/Kconfig
init/version.c
ipc/mqueue.c
ipc/msg.c
ipc/msgutil.c
ipc/namespace.c
ipc/util.c
kernel/acct.c
kernel/cgroup.c
kernel/configs.c
kernel/cpuset.c
kernel/events/core.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/irq/proc.c
kernel/nsproxy.c
kernel/pid.c
kernel/pid_namespace.c
kernel/printk.c
kernel/profile.c
kernel/sched/stats.c
kernel/signal.c
kernel/smpboot.c
kernel/softirq.c
kernel/stop_machine.c
kernel/sys.c
kernel/time/tick-broadcast.c
kernel/trace/Kconfig
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_irqsoff.c
kernel/trace/trace_sched_wakeup.c
kernel/user.c
kernel/user_namespace.c
kernel/utsname.c
kernel/workqueue.c
lib/bust_spinlocks.c
lib/dma-debug.c
lib/idr.c
lib/notifier-error-inject.c
lib/xz/Kconfig
mm/Kconfig
mm/filemap.c
mm/filemap_xip.c
mm/fremap.c
mm/hugetlb.c
mm/ksm.c
mm/memcontrol.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/process_vm_access.c
net/8021q/vlan.c
net/8021q/vlanproc.c
net/9p/trans_virtio.c
net/atm/proc.c
net/batman-adv/bat_iv_ogm.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/capi.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bridge/br_device.c
net/bridge/br_fdb.c
net/bridge/br_input.c
net/bridge/br_mdb.c
net/bridge/br_multicast.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/caif/caif_dev.c
net/caif/caif_usb.c
net/can/bcm.c
net/can/proc.c
net/ceph/osdmap.c
net/core/dev.c
net/core/flow_dissector.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/pktgen.c
net/core/rtnetlink.c
net/dcb/dcbnl.c
net/ieee802154/6lowpan.h
net/ipv4/af_inet.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_fragment.c
net/ipv4/ip_fragment.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ipconfig.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/ip6_input.c
net/ipv6/netfilter/ip6t_NPT.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/proc.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/irda/af_irda.c
net/irda/ircomm/ircomm_tty.c
net/irda/iriap.c
net/key/af_key.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_debugfs.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/l2tp/l2tp_netlink.c
net/l2tp/l2tp_ppp.c
net/mac80211/cfg.c
net/mac80211/iface.c
net/mac80211/mlme.c
net/mac80211/tx.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_proto_sctp.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_udplite.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_queue_core.c
net/netfilter/x_tables.c
net/netfilter/xt_AUDIT.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_recent.c
net/netlabel/netlabel_unlabeled.c
net/netlink/genetlink.c
net/nfc/llcp/llcp.c
net/nfc/llcp/sock.c
net/openvswitch/actions.c
net/openvswitch/datapath.c
net/openvswitch/flow.c
net/openvswitch/vport-netdev.c
net/openvswitch/vport.c
net/rds/message.c
net/rds/stats.c
net/sched/sch_qfq.c
net/sctp/associola.c
net/sctp/endpointola.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/ssnmap.c
net/sctp/tsnmap.c
net/sctp/ulpqueue.c
net/socket.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/rpc_pipe.c
net/sunrpc/sched.c
net/sunrpc/stats.c
net/sunrpc/xprtsock.c
net/unix/af_unix.c
net/wireless/core.c
net/wireless/lib80211_crypt_ccmp.c
net/wireless/lib80211_crypt_tkip.c
net/wireless/lib80211_crypt_wep.c
net/wireless/nl80211.c
net/x25/x25_proc.c
scripts/Makefile.headersinst
security/keys/compat.c
security/keys/process_keys.c
security/selinux/xfrm.c
security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/securityfs_if.c
sound/core/info.c
sound/core/seq/oss/seq_oss_event.c
sound/core/seq/seq_timer.c
sound/core/vmaster.c
sound/oss/dmasound/dmasound_core.c
sound/oss/sequencer.c
sound/pci/asihpi/asihpi.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/ice1712/ice1712.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8960.c
sound/soc/tegra/tegra20_i2s.h
sound/soc/tegra/tegra30_i2s.h
sound/sound_firmware.c
sound/usb/card.c
sound/usb/mixer.c
tools/lib/traceevent/Makefile
tools/perf/Makefile
tools/perf/bench/bench.h
tools/perf/builtin-record.c
tools/perf/util/hist.h
tools/perf/util/strlist.c
tools/testing/selftests/efivarfs/efivarfs.sh
tools/usb/ffs-test.c
virt/kvm/ioapic.c

diff --git a/CREDITS b/CREDITS
index 948e0fb9a70e570c383dd9ec016118f8ff128568..afaa7cec6ea5126198d5220389f66d9678ed8949 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -953,11 +953,11 @@ S: Blacksburg, Virginia 24061
 S: USA
 
 N: Randy Dunlap
-E: rdunlap@xenotime.net
-W: http://www.xenotime.net/linux/linux.html
-W: http://www.linux-usb.org
+E: rdunlap@infradead.org
+W: http://www.infradead.org/~rdunlap/
 D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
 D: x86 SMP, ACPI, bootflag hacking
+D: documentation, builds
 S: (ask for current address)
 S: USA
 
@@ -1510,6 +1510,14 @@ D: Natsemi ethernet
 D: Cobalt Networks (x86) support
 D: This-and-That
 
+N: Mark M. Hoffman
+E: mhoffman@lightlink.com
+D: asb100, lm93 and smsc47b397 hardware monitoring drivers
+D: hwmon subsystem core
+D: hwmon subsystem maintainer
+D: i2c-sis96x and i2c-stub SMBus drivers
+S: USA
+
 N: Dirk Hohndel
 E: hohndel@suse.de
 D: The XFree86[tm] Project
index c379a2a6949f1c1cac04fb6f185c633512f37061..aa0c1e63f05028e7e0e5ee2054bb5353c29be196 100644 (file)
@@ -60,8 +60,7 @@ own source tree.  For example:
 "dontdiff" is a list of files which are generated by the kernel during
 the build process, and should be ignored in any diff(1)-generated
 patch.  The "dontdiff" file is included in the kernel tree in
-2.6.12 and later.  For earlier kernel versions, you can get it
-from <http://www.xenotime.net/linux/doc/dontdiff>.
+2.6.12 and later.
 
 Make sure your patch does not include any extra files which do not
 belong in a patch submission.  Make sure to review your patch -after-
index 56fb62b09fc59ad757fc81de6ad6e478b3b0184b..b428556197c99a0eea19d3b040bfbe3c0ffcf06e 100644 (file)
@@ -30,6 +30,7 @@ The target is named "raid" and it accepts the following parameters:
   raid10        Various RAID10 inspired algorithms chosen by additional params
                - RAID10: Striped Mirrors (aka 'Striping on top of mirrors')
                - RAID1E: Integrated Adjacent Stripe Mirroring
+               - RAID1E: Integrated Offset Stripe Mirroring
                -  and other similar RAID10 variants
 
   Reference: Chapter 4 of
@@ -64,15 +65,15 @@ The target is named "raid" and it accepts the following parameters:
                synchronisation state for each region.
 
         [raid10_copies   <# copies>]
-        [raid10_format   near]
+        [raid10_format   <near|far|offset>]
                These two options are used to alter the default layout of
                a RAID10 configuration.  The number of copies is can be
-               specified, but the default is 2.  There are other variations
-               to how the copies are laid down - the default and only current
-               option is "near".  Near copies are what most people think of
-               with respect to mirroring.  If these options are left
-               unspecified, or 'raid10_copies 2' and/or 'raid10_format near'
-               are given, then the layouts for 2, 3 and 4 devices are:
+               specified, but the default is 2.  There are also three
+               variations to how the copies are laid down - the default
+               is "near".  Near copies are what most people think of with
+               respect to mirroring.  If these options are left unspecified,
+               or 'raid10_copies 2' and/or 'raid10_format near' are given,
+               then the layouts for 2, 3 and 4 devices are:
                2 drives         3 drives          4 drives
                --------         ----------        --------------
                A1  A1           A1  A1  A2        A1  A1  A2  A2
@@ -85,6 +86,33 @@ The target is named "raid" and it accepts the following parameters:
                3-device layout is what might be called a 'RAID1E - Integrated
                Adjacent Stripe Mirroring'.
 
+               If 'raid10_copies 2' and 'raid10_format far', then the layouts
+               for 2, 3 and 4 devices are:
+               2 drives             3 drives             4 drives
+               --------             --------------       --------------------
+               A1  A2               A1   A2   A3         A1   A2   A3   A4
+               A3  A4               A4   A5   A6         A5   A6   A7   A8
+               A5  A6               A7   A8   A9         A9   A10  A11  A12
+               ..  ..               ..   ..   ..         ..   ..   ..   ..
+               A2  A1               A3   A1   A2         A2   A1   A4   A3
+               A4  A3               A6   A4   A5         A6   A5   A8   A7
+               A6  A5               A9   A7   A8         A10  A9   A12  A11
+               ..  ..               ..   ..   ..         ..   ..   ..   ..
+
+               If 'raid10_copies 2' and 'raid10_format offset', then the
+               layouts for 2, 3 and 4 devices are:
+               2 drives       3 drives           4 drives
+               --------       ------------       -----------------
+               A1  A2         A1  A2  A3         A1  A2  A3  A4
+               A2  A1         A3  A1  A2         A2  A1  A4  A3
+               A3  A4         A4  A5  A6         A5  A6  A7  A8
+               A4  A3         A6  A4  A5         A6  A5  A8  A7
+               A5  A6         A7  A8  A9         A9  A10 A11 A12
+               A6  A5         A9  A7  A8         A10 A9  A12 A11
+               ..  ..         ..  ..  ..         ..  ..  ..  ..
+               Here we see layouts closely akin to 'RAID1E - Integrated
+               Offset Stripe Mirroring'.
+
 <#raid_devs>: The number of devices composing the array.
        Each device consists of two entries.  The first is the device
        containing the metadata (if any); the second is the one containing the
@@ -142,3 +170,5 @@ Version History
 1.3.0  Added support for RAID 10
 1.3.1  Allow device replacement/rebuild for RAID 10
 1.3.2   Fix/improve redundancy checking for RAID10
+1.4.0  Non-functional change.  Removes arg from mapping function.
+1.4.1   Add RAID10 "far" and "offset" algorithm support.
index 13b707b7355c005e9c877e860c93d4e9ca6baf12..c3a14e0ad0addf57715902618482a5593344f8da 100644 (file)
@@ -13,9 +13,6 @@ Required parent device properties:
                                   4 = active high level-sensitive
                                   8 = active low level-sensitive
 
-Optional parent device properties:
-- reg                    : contains the PRCMU mailbox address for the AB8500 i2c port
-
 The AB8500 consists of a large and varied group of sub-devices:
 
 Device                     IRQ Names              Supply Names   Description
@@ -86,9 +83,8 @@ Non-standard child device properties:
    - stericsson,amic2-bias-vamic1           : Analoge Mic wishes to use a non-standard Vamic
    - stericsson,earpeice-cmv                : Earpeice voltage (only: 950 | 1100 | 1270 | 1580)
 
-ab8500@5 {
+ab8500 {
          compatible = "stericsson,ab8500";
-         reg = <5>; /* mailbox 5 is i2c */
          interrupts = <0 40 0x4>;
          interrupt-controller;
          #interrupt-cells = <2>;
index 1e1145ca4f3c2cb192f7e4bf5ce95f6c73ba0801..8f01cb190f25686747873ab54eaa53652c9b35bc 100644 (file)
@@ -11,6 +11,9 @@ Required properties:
        - "nvidia,tegra20-uart"
        - "nxp,lpc3220-uart"
        - "ibm,qpace-nwp-serial"
+       - "altr,16550-FIFO32"
+       - "altr,16550-FIFO64"
+       - "altr,16550-FIFO128"
        - "serial" if the port type is unknown.
 - reg : offset and length of the register set for the device.
 - interrupts : should contain uart interrupt.
index 2cfa256671235745f3433bec2e0c0a18e93041bf..15b4a20d5062f4e3872135557f6740da6c9408cf 100644 (file)
@@ -15,7 +15,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1276.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 96004000dc2a3ef0d622cbccb6c48aa422a0ed9f..58150c480e5694668c32f6348dab6ae1bcd168bf 100644 (file)
@@ -4,9 +4,14 @@ Kernel driver adt7410
 Supported chips:
   * Analog Devices ADT7410
     Prefix: 'adt7410'
-    Addresses scanned: I2C 0x48 - 0x4B
+    Addresses scanned: None
     Datasheet: Publicly available at the Analog Devices website
                http://www.analog.com/static/imported-files/data_sheets/ADT7410.pdf
+  * Analog Devices ADT7420
+    Prefix: 'adt7420'
+    Addresses scanned: None
+    Datasheet: Publicly available at the Analog Devices website
+               http://www.analog.com/static/imported-files/data_sheets/ADT7420.pdf
 
 Author: Hartmut Knaack <knaack.h@gmx.de>
 
@@ -27,6 +32,10 @@ value per second or even justget one sample on demand for power saving.
 Besides, it can completely power down its ADC, if power management is
 required.
 
+The ADT7420 is register compatible, the only differences being the package,
+a slightly narrower operating temperature range (-40°C to +150°C), and a
+better accuracy (0.25°C instead of 0.50°C.)
+
 Configuration Notes
 -------------------
 
index 1650771212382296f6a63b321fce6b322dcba27e..868d74d6b773bfcf902b5d45d0827f3f3482197f 100644 (file)
@@ -49,7 +49,7 @@ Supported chips:
     Addresses scanned: I2C 0x18 - 0x1f
 
 Author:
-       Guenter Roeck <guenter.roeck@ericsson.com>
+       Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 2ba5ed126858e467b46380319a0b5876ecc91d18..83b2ddc160c898714ce967aaa90098950db95059 100644 (file)
@@ -8,7 +8,7 @@ Supported devices:
     Documentation:
         http://www.lineagepower.com/oem/pdf/CPLI2C.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index a21db81c4591fa48212e08d08ac88c0e24bbe3e2..26025e419d357c5e078e96a3f831be67f5b4e289 100644 (file)
@@ -19,7 +19,7 @@ Supported chips:
     Datasheet:
        http://www.national.com/pf/LM/LM5066.html
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index c91a1d15fa28ae62aca3796ab89e15de3fdd0f5a..69af1c7db6b7437ca797c61baaeb74086d264c5c 100644 (file)
@@ -23,7 +23,7 @@ Supported chips:
     Datasheet: Publicly available at the Maxim website
                http://www.maxim-ic.com/
   * Microchip (TelCom) TCN75
-    Prefix: 'lm75'
+    Prefix: 'tcn75'
     Addresses scanned: none
     Datasheet: Publicly available at the Microchip website
                http://www.microchip.com/
index c365f9beb5dd6a1657fbcbbb38f2298aba204b73..e4d75c606c97e88f9a45c2dfd956931b568b28e7 100644 (file)
@@ -5,13 +5,13 @@ Supported chips:
   * Linear Technology LTC2978
     Prefix: 'ltc2978'
     Addresses scanned: -
-    Datasheet: http://cds.linear.com/docs/Datasheet/2978fa.pdf
+    Datasheet: http://www.linear.com/product/ltc2978
   * Linear Technology LTC3880
     Prefix: 'ltc3880'
     Addresses scanned: -
-    Datasheet: http://cds.linear.com/docs/Datasheet/3880f.pdf
+    Datasheet: http://www.linear.com/product/ltc3880
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index eba2e2c4b94d89e2f3eb06006ab763ce874233ff..9378a75c61340850b4d0cb47273252e6a3a41be6 100644 (file)
@@ -8,7 +8,7 @@ Supported chips:
     Datasheet:
         http://cds.linear.com/docs/Datasheet/42612fb.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index f8b478076f6dfda9e2fdbd47e2a4b843ca13bc51..d59cc7829bec1b223a8e3b577741624d9cc4ee6a 100644 (file)
@@ -7,7 +7,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX16064.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index c11f64a1f2adb61077f5910215981d589503aa0f..208a29e430105fa78fd86f2e548e19690d91fbb2 100644 (file)
@@ -24,7 +24,7 @@ Supported chips:
        http://datasheets.maxim-ic.com/en/ds/MAX16070-MAX16071.pdf
 
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 47651ff341aed4cc7ad95d20c052c57250e5c827..37cbf472a19d19aef7aea0217d008943eb28909f 100644 (file)
@@ -27,7 +27,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34461.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index fe849871df32dbe81af61fca76c300794047a1fe..e78078638b9142906b8308c4700f25d2f8a2ef88 100644 (file)
@@ -7,7 +7,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8688.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 3d3a0f97f966f677e76a5d9685036edc43022ca6..cf756ed48ff9458d7cc6f8137d239f376ef2a154 100644 (file)
@@ -34,7 +34,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: n.a.
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 59e316140542017517be09171448fc4e6e16d28e..a341eeedab75f5b10e12991d1927652d8c52dc5e 100644 (file)
@@ -29,7 +29,7 @@ Supported chips:
       http://www.summitmicro.com/prod_select/summary/SMM766/SMM766_2086.pdf
       http://www.summitmicro.com/prod_select/summary/SMM766B/SMM766B_2122.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Module Parameters
index 0df5f276505b6470e28f00c86c6bd1d76aad5b4d..805e33edb978b7f21c92f2d1ee001431a8ee9ac0 100644 (file)
@@ -11,7 +11,7 @@ Supported chips:
        http://focus.ti.com/lit/ds/symlink/ucd9090.pdf
        http://focus.ti.com/lit/ds/symlink/ucd90910.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index fd7d07b1908a9d0c5dfd3c38f3bb73c6cf980210..1e8060e631bdcd4f6126f35243a2ad96d23959c7 100644 (file)
@@ -15,7 +15,7 @@ Supported chips:
        http://focus.ti.com/lit/ds/symlink/ucd9246.pdf
        http://focus.ti.com/lit/ds/symlink/ucd9248.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 3d924b6b59e915ff043e933209d7d449b6f889ce..756b57c6b73e8683308641aaad38887d7c4797d0 100644 (file)
@@ -54,7 +54,7 @@ http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146401
 http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146256
 
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 30fe4bb9a069b13f5979b7debd8a5ec0c0302eab..0d6018c316c741f9cc0cf3b0391457b880b58234 100644 (file)
@@ -5,7 +5,7 @@ Supported adapters:
     Documentation:
        http://www.diolan.com/i2c/u2c12.html
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 Description
 -----------
index 3262b6e4d686ac944f7e767642228f4d4cc2f8f6..e544c7ff8cfa5c6c60697aae738eb4b029e86d23 100644 (file)
@@ -3,10 +3,26 @@ ALPS Touchpad Protocol
 
 Introduction
 ------------
-
-Currently the ALPS touchpad driver supports four protocol versions in use by
-ALPS touchpads, called versions 1, 2, 3, and 4. Information about the various
-protocol versions is contained in the following sections.
+Currently the ALPS touchpad driver supports five protocol versions in use by
+ALPS touchpads, called versions 1, 2, 3, 4 and 5.
+
+Since roughly mid-2010 several new ALPS touchpads have been released and
+integrated into a variety of laptops and netbooks.  These new touchpads
+have enough behavior differences that the alps_model_data definition
+table, describing the properties of the different versions, is no longer
+adequate.  The design choices were to re-define the alps_model_data
+table, with the risk of regression testing existing devices, or isolate
+the new devices outside of the alps_model_data table.  The latter design
+choice was made.  The new touchpad signatures are named: "Rushmore",
+"Pinnacle", and "Dolphin", which you will see in the alps.c code.
+For the purposes of this document, this group of ALPS touchpads will
+generically be called "new ALPS touchpads".
+
+We experimented with probing the ACPI interface _HID (Hardware ID)/_CID
+(Compatibility ID) definition as a way to uniquely identify the
+different ALPS variants but there did not appear to be a 1:1 mapping.
+In fact, it appeared to be an m:n mapping between the _HID and actual
+hardware type.
 
 Detection
 ---------
@@ -20,9 +36,13 @@ If the E6 report is successful, the touchpad model is identified using the "E7
 report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
 matched against known models in the alps_model_data_array.
 
-With protocol versions 3 and 4, the E7 report model signature is always
-73-02-64. To differentiate between these versions, the response from the
-"Enter Command Mode" sequence must be inspected as described below.
+For older touchpads supporting protocol versions 3 and 4, the E7 report
+model signature is always 73-02-64. To differentiate between these
+versions, the response from the "Enter Command Mode" sequence must be
+inspected as described below.
+
+The new ALPS touchpads have an E7 signature of 73-03-50 or 73-03-0A but
+seem to be better differentiated by the EC Command Mode response.
 
 Command Mode
 ------------
@@ -47,6 +67,14 @@ address of the register being read, and the third contains the value of the
 register. Registers are written by writing the value one nibble at a time
 using the same encoding used for addresses.
 
+For the new ALPS touchpads, the EC command is used to enter command
+mode. The response in the new ALPS touchpads is significantly different,
+and more important in determining the behavior.  This code has been
+separated from the original alps_model_data table and put in the
+alps_identify function.  For example, there seem to be two hardware init
+sequences for the "Dolphin" touchpads as determined by the second byte
+of the EC response.
+
 Packet Format
 -------------
 
@@ -187,3 +215,28 @@ There are several things worth noting here.
     well.
 
 So far no v4 devices with tracksticks have been encountered.
+
+ALPS Absolute Mode - Protocol Version 5
+---------------------------------------
+This is basically Protocol Version 3 but with different logic for packet
+decode.  It uses the same alps_process_touchpad_packet_v3 call with a
+specialized decode_fields function pointer to correctly interpret the
+packets.  This appears to only be used by the Dolphin devices.
+
+For single-touch, the 6-byte packet format is:
+
+ byte 0:    1    1    0    0    1    0    0    0
+ byte 1:    0   x6   x5   x4   x3   x2   x1   x0
+ byte 2:    0   y6   y5   y4   y3   y2   y1   y0
+ byte 3:    0    M    R    L    1    m    r    l
+ byte 4:   y10  y9   y8   y7  x10   x9   x8   x7
+ byte 5:    0   z6   z5   z4   z3   z2   z1   z0
+
+For mt, the format is:
+
+ byte 0:    1    1    1    n3   1   n2   n1   x24
+ byte 1:    1   y7   y6    y5  y4   y3   y2    y1
+ byte 2:    ?   x2   x1   y12 y11  y10   y9    y8
+ byte 3:    0  x23  x22   x21 x20  x19  x18   x17
+ byte 4:    0   x9   x8    x7  x6   x5   x4    x3
+ byte 5:    0  x16  x15   x14 x13  x12  x11   x10
index f2a2488f1bf33d8290384c4823fccee2b39afe36..9573d0c48c6ea882099edd94ed2dcda94e4fe3dd 100644 (file)
@@ -15,6 +15,13 @@ amemthresh - INTEGER
         enabled and the variable is automatically set to 2, otherwise
         the strategy is disabled and the variable is  set  to 1.
 
+backup_only - BOOLEAN
+       0 - disabled (default)
+       not 0 - enabled
+
+       If set, disable the director function while the server is
+       in backup mode to avoid packet loops for DR/TUN methods.
+
 conntrack - BOOLEAN
        0 - disabled (default)
        not 0 - enabled
index c0aab985bad9ac4a159ea9f96e837bee28475291..949d5dcdd9a348fd646f89c62f604d9d29433d2c 100644 (file)
@@ -105,6 +105,83 @@ Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
      Proto [2 bytes]
      Raw protocol(IP, IPv6, etc) frame.
 
+  3.3 Multiqueue tuntap interface:
+
+  From version 3.8, Linux supports multiqueue tuntap which can uses multiple
+  file descriptors (queues) to parallelize packets sending or receiving. The
+  device allocation is the same as before, and if user wants to create multiple
+  queues, TUNSETIFF with the same device name must be called many times with
+  IFF_MULTI_QUEUE flag.
+
+  char *dev should be the name of the device, queues is the number of queues to
+  be created, fds is used to store and return the file descriptors (queues)
+  created to the caller. Each file descriptor were served as the interface of a
+  queue which could be accessed by userspace.
+
+  #include <linux/if.h>
+  #include <linux/if_tun.h>
+
+  int tun_alloc_mq(char *dev, int queues, int *fds)
+  {
+      struct ifreq ifr;
+      int fd, err, i;
+
+      if (!dev)
+          return -1;
+
+      memset(&ifr, 0, sizeof(ifr));
+      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
+       *        IFF_TAP   - TAP device
+       *
+       *        IFF_NO_PI - Do not provide packet information
+       *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
+       */
+      ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
+      strcpy(ifr.ifr_name, dev);
+
+      for (i = 0; i < queues; i++) {
+          if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+             goto err;
+          err = ioctl(fd, TUNSETIFF, (void *)&ifr);
+          if (err) {
+             close(fd);
+             goto err;
+          }
+          fds[i] = fd;
+      }
+
+      return 0;
+  err:
+      for (--i; i >= 0; i--)
+          close(fds[i]);
+      return err;
+  }
+
+  A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
+  calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
+  calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
+  enabled by default after it was created through TUNSETIFF.
+
+  fd is the file descriptor (queue) that we want to enable or disable, when
+  enable is true we enable it, otherwise we disable it
+
+  #include <linux/if.h>
+  #include <linux/if_tun.h>
+
+  int tun_set_queue(int fd, int enable)
+  {
+      struct ifreq ifr;
+
+      memset(&ifr, 0, sizeof(ifr));
+
+      if (enable)
+         ifr.ifr_flags = IFF_ATTACH_QUEUE;
+      else
+         ifr.ifr_flags = IFF_DETACH_QUEUE;
+
+      return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
+  }
+
 Universal TUN/TAP device driver Frequently Asked Question.
    
 1. What platforms are supported by TUN/TAP driver ?
index 3035d00757ad53d857418a3d6196866b7460f357..425c51d56aefb8b991b3d97b5d3f01564f9baaf6 100644 (file)
@@ -1,6 +1,5 @@
-*=============*
-* OPP Library *
-*=============*
+Operating Performance Points (OPP) Library
+==========================================
 
 (C) 2009-2010 Nishanth Menon <nm@ti.com>, Texas Instruments Incorporated
 
@@ -16,15 +15,31 @@ Contents
 
 1. Introduction
 ===============
+1.1 What is an Operating Performance Point (OPP)?
+
 Complex SoCs of today consists of a multiple sub-modules working in conjunction.
 In an operational system executing varied use cases, not all modules in the SoC
 need to function at their highest performing frequency all the time. To
 facilitate this, sub-modules in a SoC are grouped into domains, allowing some
-domains to run at lower voltage and frequency while other domains are loaded
-more. The set of discrete tuples consisting of frequency and voltage pairs that
+domains to run at lower voltage and frequency while other domains run at
+voltage/frequency pairs that are higher.
+
+The set of discrete tuples consisting of frequency and voltage pairs that
 the device will support per domain are called Operating Performance Points or
 OPPs.
 
+As an example:
+Let us consider an MPU device which supports the following:
+{300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V},
+{1GHz at minimum voltage of 1.3V}
+
+We can represent these as three OPPs as the following {Hz, uV} tuples:
+{300000000, 1000000}
+{800000000, 1200000}
+{1000000000, 1300000}
+
+1.2 Operating Performance Points Library
+
 OPP library provides a set of helper functions to organize and query the OPP
 information. The library is located in drivers/base/power/opp.c and the header
 is located in include/linux/opp.h. OPP library can be enabled by enabling
index e8a6aa473babbedc1df224c250cd0f28f8ecb061..6e953564de03013d5059d7dc7616c91d3aea0b43 100644 (file)
@@ -170,5 +170,5 @@ Reminder: sizeof() result is of type size_t.
 Thank you for your cooperation and attention.
 
 
-By Randy Dunlap <rdunlap@xenotime.net> and
+By Randy Dunlap <rdunlap@infradead.org> and
 Andrew Murray <amurray@mpc-data.co.uk>
index ce6581c8ca26915c1a00f31a9b7605c0cb6c3413..4499bd948860cebe52e7db8aae65b2a16fd1a897 100644 (file)
@@ -912,7 +912,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     models depending on the codec chip.  The list of available models
     is found in HD-Audio-Models.txt
 
-    The model name "genric" is treated as a special case.  When this
+    The model name "generic" is treated as a special case.  When this
     model is given, the driver uses the generic codec parser without
     "codec-patch".  It's sometimes good for testing and debugging.
 
index d9776cf60c07a9b62445174cd6eed64e1e69cb83..9663b45f6fde66ba5d2bb4abdd4b9bf9e651a32b 100644 (file)
@@ -285,7 +285,7 @@ sample data.
 <H4>
 7.2.4 Close Callback</H4>
 The <TT>close</TT> callback is called when this device is closed by the
-applicaion. If any private data was allocated in open callback, it must
+application. If any private data was allocated in open callback, it must
 be released in the close callback. The deletion of ALSA port should be
 done here, too. This callback must not be NULL.
 <H4>
index 53d6a3c51d875771fc2966c9917aec13b17f53c6..a372304aef10a378bc00440053c0fe4028eac566 100644 (file)
@@ -1873,7 +1873,7 @@ feature:
 
        status\input  |     0      |     1      |    else    |
        --------------+------------+------------+------------+
-       not allocated |(do nothing)| alloc+swap |   EINVAL   |
+       not allocated |(do nothing)| alloc+swap |(do nothing)|
        --------------+------------+------------+------------+
        allocated     |    free    |    swap    |   clear    |
        --------------+------------+------------+------------+
index e95b1e944eb7d26e19b712af2ffa3788d47be2ec..72b08438d536bc04fc6211acf29cd762d53c5245 100644 (file)
@@ -114,12 +114,6 @@ Maintainers List (try to look for most precise areas first)
 
                -----------------------------------
 
-3C505 NETWORK DRIVER
-M:     Philip Blundell <philb@gnu.org>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/ethernet/i825xx/3c505*
-
 3C59X NETWORK DRIVER
 M:     Steffen Klassert <klassert@mathematik.tu-chemnitz.de>
 L:     netdev@vger.kernel.org
@@ -1344,12 +1338,6 @@ S:       Maintained
 F:     drivers/platform/x86/asus*.c
 F:     drivers/platform/x86/eeepc*.c
 
-ASUS ASB100 HARDWARE MONITOR DRIVER
-M:     "Mark M. Hoffman" <mhoffman@lightlink.com>
-L:     lm-sensors@lm-sensors.org
-S:     Maintained
-F:     drivers/hwmon/asb100.c
-
 ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API
 M:     Dan Williams <djbw@fb.com>
 W:     http://sourceforge.net/projects/xscaleiop
@@ -1473,6 +1461,12 @@ F:       drivers/dma/at_hdmac.c
 F:     drivers/dma/at_hdmac_regs.h
 F:     include/linux/platform_data/dma-atmel.h
 
+ATMEL I2C DRIVER
+M:     Ludovic Desroches <ludovic.desroches@atmel.com>
+L:     linux-i2c@vger.kernel.org
+S:     Supported
+F:     drivers/i2c/busses/i2c-at91.c
+
 ATMEL ISI DRIVER
 M:     Josh Wu <josh.wu@atmel.com>
 L:     linux-media@vger.kernel.org
@@ -2361,12 +2355,6 @@ W:       http://www.arm.linux.org.uk/
 S:     Maintained
 F:     drivers/video/cyber2000fb.*
 
-CYCLADES 2X SYNC CARD DRIVER
-M:     Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
-W:     http://oops.ghostprotocols.net:81/blog
-S:     Maintained
-F:     drivers/net/wan/cycx*
-
 CYCLADES ASYNC MUX DRIVER
 W:     http://www.cyclades.com/
 S:     Orphan
@@ -2641,7 +2629,7 @@ F:        include/uapi/drm/
 
 INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
 M:     Daniel Vetter <daniel.vetter@ffwll.ch>
-L:     intel-gfx@lists.freedesktop.org (subscribers-only)
+L:     intel-gfx@lists.freedesktop.org
 L:     dri-devel@lists.freedesktop.org
 T:     git git://people.freedesktop.org/~danvet/drm-intel
 S:     Supported
@@ -3067,12 +3055,6 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
 F:     drivers/video/s1d13xxxfb.c
 F:     include/video/s1d13xxxfb.h
 
-ETHEREXPRESS-16 NETWORK DRIVER
-M:     Philip Blundell <philb@gnu.org>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/ethernet/i825xx/eexpress.*
-
 ETHERNET BRIDGE
 M:     Stephen Hemminger <stephen@networkplumber.org>
 L:     bridge@lists.linux-foundation.org
@@ -3869,7 +3851,7 @@ F:        drivers/i2c/busses/i2c-ismt.c
 F:     Documentation/i2c/busses/i2c-ismt
 
 I2C/SMBUS STUB DRIVER
-M:     "Mark M. Hoffman" <mhoffman@lightlink.com>
+M:     Jean Delvare <khali@linux-fr.org>
 L:     linux-i2c@vger.kernel.org
 S:     Maintained
 F:     drivers/i2c/i2c-stub.c
@@ -4023,6 +4005,22 @@ M:       Stanislaw Gruszka <stf_xl@wp.pl>
 S:     Maintained
 F:     drivers/usb/atm/ueagle-atm.c
 
+INA209 HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/ina209
+F:     Documentation/devicetree/bindings/i2c/ina209.txt
+F:     drivers/hwmon/ina209.c
+
+INA2XX HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/ina2xx
+F:     drivers/hwmon/ina2xx.c
+F:     include/linux/platform_data/ina2xx.h
+
 INDUSTRY PACK SUBSYSTEM (IPACK)
 M:     Samuel Iglesias Gonsalvez <siglesias@igalia.com>
 M:     Jens Taprogge <jens.taprogge@taprogge.org>
@@ -5116,6 +5114,15 @@ S:       Maintained
 F:     Documentation/hwmon/max6650
 F:     drivers/hwmon/max6650.c
 
+MAX6697 HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/max6697
+F:     Documentation/devicetree/bindings/i2c/max6697.txt
+F:     drivers/hwmon/max6697.c
+F:     include/linux/platform_data/max6697.h
+
 MAXIRADIO FM RADIO RECEIVER DRIVER
 M:     Hans Verkuil <hverkuil@xs4all.nl>
 L:     linux-media@vger.kernel.org
@@ -5640,6 +5647,14 @@ S:       Maintained
 F:     drivers/video/riva/
 F:     drivers/video/nvidia/
 
+NVM EXPRESS DRIVER
+M:     Matthew Wilcox <willy@linux.intel.com>
+L:     linux-nvme@lists.infradead.org
+T:     git git://git.infradead.org/users/willy/linux-nvme.git
+S:     Supported
+F:     drivers/block/nvme.c
+F:     include/linux/nvme.h
+
 OMAP SUPPORT
 M:     Tony Lindgren <tony@atomide.com>
 L:     linux-omap@vger.kernel.org
@@ -5668,7 +5683,7 @@ S:        Maintained
 F:     arch/arm/*omap*/*clock*
 
 OMAP POWER MANAGEMENT SUPPORT
-M:     Kevin Hilman <khilman@ti.com>
+M:     Kevin Hilman <khilman@deeprootsystems.com>
 L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     arch/arm/*omap*/*pm*
@@ -5762,7 +5777,7 @@ F:        arch/arm/*omap*/usb*
 
 OMAP GPIO DRIVER
 M:     Santosh Shilimkar <santosh.shilimkar@ti.com>
-M:     Kevin Hilman <khilman@ti.com>
+M:     Kevin Hilman <khilman@deeprootsystems.com>
 L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     drivers/gpio/gpio-omap.c
@@ -6430,6 +6445,8 @@ F:        Documentation/networking/LICENSE.qla3xxx
 F:     drivers/net/ethernet/qlogic/qla3xxx.*
 
 QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
+M:     Rajesh Borundia <rajesh.borundia@qlogic.com>
+M:     Shahed Shaikh <shahed.shaikh@qlogic.com>
 M:     Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
 M:     Sony Chacko <sony.chacko@qlogic.com>
 M:     linux-driver@qlogic.com
@@ -7156,7 +7173,7 @@ F:        arch/arm/mach-s3c2410/bast-irq.c
 
 TI DAVINCI MACHINE SUPPORT
 M:     Sekhar Nori <nsekhar@ti.com>
-M:     Kevin Hilman <khilman@ti.com>
+M:     Kevin Hilman <khilman@deeprootsystems.com>
 L:     davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
 T:     git git://gitorious.org/linux-davinci/linux-davinci.git
 Q:     http://patchwork.kernel.org/project/linux-davinci/list/
@@ -7189,13 +7206,6 @@ L:       netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/sis/sis900.*
 
-SIS 96X I2C/SMBUS DRIVER
-M:     "Mark M. Hoffman" <mhoffman@lightlink.com>
-L:     linux-i2c@vger.kernel.org
-S:     Maintained
-F:     Documentation/i2c/busses/i2c-sis96x
-F:     drivers/i2c/busses/i2c-sis96x.c
-
 SIS FRAMEBUFFER DRIVER
 M:     Thomas Winischhofer <thomas@winischhofer.net>
 W:     http://www.winischhofer.net/linuxsisvga.shtml
@@ -7273,7 +7283,7 @@ F:        Documentation/hwmon/sch5627
 F:     drivers/hwmon/sch5627.c
 
 SMSC47B397 HARDWARE MONITOR DRIVER
-M:     "Mark M. Hoffman" <mhoffman@lightlink.com>
+M:     Jean Delvare <khali@linux-fr.org>
 L:     lm-sensors@lm-sensors.org
 S:     Maintained
 F:     Documentation/hwmon/smsc47b397
index 5bd9f7700eb9582a59cc7d75bf6e55a82ce587b3..54d2b2a0fef0e2a1dba259b8f97ac0f7e8341225 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc4
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index 5a1779c93940153b30ba84a561b75aaec1e109ea..1455579791ec02514a5d616a4b6749cbec3185b0 100644 (file)
@@ -319,13 +319,6 @@ config ARCH_WANT_OLD_COMPAT_IPC
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
        bool
 
-config HAVE_VIRT_TO_BUS
-       bool
-       help
-         An architecture should select this if it implements the
-         deprecated interface virt_to_bus().  All new architectures
-         should probably not select this.
-
 config HAVE_ARCH_SECCOMP_FILTER
        bool
        help
index 5833aa4414816526dd23be127ef718a1900d4b7f..8a33ba01301ff5cb4966455699a164c27feb1484 100644 (file)
@@ -9,7 +9,7 @@ config ALPHA
        select HAVE_PERF_EVENTS
        select HAVE_DMA_ATTRS
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select AUTO_IRQ_AFFINITY if SMP
        select GENERIC_IRQ_SHOW
index b06812bcac83b911cf43613cba8f1d6619fd380d..8efb26686d4789e2afbfc910921b2327e8fbe2c1 100644 (file)
@@ -4,6 +4,7 @@
  * initial bootloader stuff..
  */
 
+#include <asm/pal.h>
 
        .set noreorder
        .globl  __start
index e64559f0a82dfd1599f803742ba6f474e0c665ba..ffe996a54fadb3db9e0ed8b10dd0f0f1deb6bea5 100644 (file)
@@ -51,13 +51,11 @@ MODULE_LICENSE("GPL");
 typedef struct _srm_env {
        char                    *name;
        unsigned long           id;
-       struct proc_dir_entry   *proc_entry;
 } srm_env_t;
 
 static struct proc_dir_entry   *base_dir;
 static struct proc_dir_entry   *named_dir;
 static struct proc_dir_entry   *numbered_dir;
-static char                    number[256][4];
 
 static srm_env_t       srm_named_entries[] = {
        { "auto_action",        ENV_AUTO_ACTION         },
@@ -77,21 +75,18 @@ static srm_env_t    srm_named_entries[] = {
        { "tty_dev",            ENV_TTY_DEV             },
        { NULL,                 0                       },
 };
-static srm_env_t       srm_numbered_entries[256];
-
 
 static int srm_env_proc_show(struct seq_file *m, void *v)
 {
        unsigned long   ret;
-       srm_env_t       *entry;
+       unsigned long   id = (unsigned long)m->private;
        char            *page;
 
-       entry = m->private;
        page = (char *)__get_free_page(GFP_USER);
        if (!page)
                return -ENOMEM;
 
-       ret = callback_getenv(entry->id, page, PAGE_SIZE);
+       ret = callback_getenv(id, page, PAGE_SIZE);
 
        if ((ret >> 61) == 0) {
                seq_write(m, page, ret);
@@ -104,14 +99,14 @@ static int srm_env_proc_show(struct seq_file *m, void *v)
 
 static int srm_env_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, srm_env_proc_show, PDE(inode)->data);
+       return single_open(file, srm_env_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
                                  size_t count, loff_t *pos)
 {
        int res;
-       srm_env_t       *entry = PDE(file_inode(file))->data;
+       unsigned long   id = (unsigned long)PDE_DATA(file_inode(file));
        char            *buf = (char *) __get_free_page(GFP_USER);
        unsigned long   ret1, ret2;
 
@@ -127,7 +122,7 @@ static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
                goto out;
        buf[count] = '\0';
 
-       ret1 = callback_setenv(entry->id, buf, count);
+       ret1 = callback_setenv(id, buf, count);
        if ((ret1 >> 61) == 0) {
                do
                        ret2 = callback_save_env();
@@ -149,52 +144,6 @@ static const struct file_operations srm_env_proc_fops = {
        .write          = srm_env_proc_write,
 };
 
-static void
-srm_env_cleanup(void)
-{
-       srm_env_t       *entry;
-       unsigned long   var_num;
-
-       if (base_dir) {
-               /*
-                * Remove named entries
-                */
-               if (named_dir) {
-                       entry = srm_named_entries;
-                       while (entry->name != NULL && entry->id != 0) {
-                               if (entry->proc_entry) {
-                                       remove_proc_entry(entry->name,
-                                                       named_dir);
-                                       entry->proc_entry = NULL;
-                               }
-                               entry++;
-                       }
-                       remove_proc_entry(NAMED_DIR, base_dir);
-               }
-
-               /*
-                * Remove numbered entries
-                */
-               if (numbered_dir) {
-                       for (var_num = 0; var_num <= 255; var_num++) {
-                               entry = &srm_numbered_entries[var_num];
-
-                               if (entry->proc_entry) {
-                                       remove_proc_entry(entry->name,
-                                                       numbered_dir);
-                                       entry->proc_entry       = NULL;
-                                       entry->name             = NULL;
-                               }
-                       }
-                       remove_proc_entry(NUMBERED_DIR, base_dir);
-               }
-
-               remove_proc_entry(BASE_DIR, NULL);
-       }
-
-       return;
-}
-
 static int __init
 srm_env_init(void)
 {
@@ -212,12 +161,6 @@ srm_env_init(void)
                return -ENODEV;
        }
 
-       /*
-        * Init numbers
-        */
-       for (var_num = 0; var_num <= 255; var_num++)
-               sprintf(number[var_num], "%ld", var_num);
-
        /*
         * Create base directory
         */
@@ -225,7 +168,7 @@ srm_env_init(void)
        if (!base_dir) {
                printk(KERN_ERR "Couldn't create base dir /proc/%s\n",
                                BASE_DIR);
-               goto cleanup;
+               return -ENOMEM;
        }
 
        /*
@@ -254,9 +197,8 @@ srm_env_init(void)
         */
        entry = srm_named_entries;
        while (entry->name && entry->id) {
-               entry->proc_entry = proc_create_data(entry->name, 0644, named_dir,
-                                                    &srm_env_proc_fops, entry);
-               if (!entry->proc_entry)
+               if (!proc_create_data(entry->name, 0644, named_dir,
+                            &srm_env_proc_fops, (void *)entry->id))
                        goto cleanup;
                entry++;
        }
@@ -265,15 +207,11 @@ srm_env_init(void)
         * Create all numbered nodes
         */
        for (var_num = 0; var_num <= 255; var_num++) {
-               entry = &srm_numbered_entries[var_num];
-               entry->name = number[var_num];
-
-               entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir,
-                                                    &srm_env_proc_fops, entry);
-               if (!entry->proc_entry)
+               char name[4];
+               sprintf(name, "%ld", var_num);
+               if (!proc_create_data(name, 0644, numbered_dir,
+                            &srm_env_proc_fops, (void *)var_num))
                        goto cleanup;
-
-               entry->id                       = var_num;
        }
 
        printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
@@ -282,18 +220,15 @@ srm_env_init(void)
        return 0;
 
 cleanup:
-       srm_env_cleanup();
-
+       remove_proc_subtree(BASE_DIR, NULL);
        return -ENOMEM;
 }
 
 static void __exit
 srm_env_exit(void)
 {
-       srm_env_cleanup();
+       remove_proc_subtree(BASE_DIR, NULL);
        printk(KERN_INFO "%s: unloaded successfully\n", NAME);
-
-       return;
 }
 
 module_init(srm_env_init);
index 5b714695b01bb9db0455ad2f5c959a714aa00064..13b739469c515cb93a8dff1cdf686583a3941c54 100644 (file)
@@ -49,7 +49,6 @@ config ARM
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
        select KTIME_SCALAR
        select PERF_USE_VMALLOC
        select RTC_LIB
@@ -556,7 +555,6 @@ config ARCH_IXP4XX
 config ARCH_DOVE
        bool "Marvell Dove"
        select ARCH_REQUIRE_GPIOLIB
-       select COMMON_CLK_DOVE
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select MIGHT_HAVE_PCI
@@ -744,6 +742,7 @@ config ARCH_RPC
        select NEED_MACH_IO_H
        select NEED_MACH_MEMORY_H
        select NO_IOPORT
+       select VIRT_TO_BUS
        help
          On the Acorn Risc-PC, Linux can support the internal IDE disk and
          CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -879,6 +878,7 @@ config ARCH_SHARK
        select ISA_DMA
        select NEED_MACH_MEMORY_H
        select PCI
+       select VIRT_TO_BUS
        select ZONE_DMA
        help
          Support for the StrongARM based Digital DNARD machine, also known
@@ -1006,12 +1006,12 @@ config ARCH_MULTI_V4_V5
        bool
 
 config ARCH_MULTI_V6
-       bool "ARMv6 based platforms (ARM11, Scorpion, ...)"
+       bool "ARMv6 based platforms (ARM11)"
        select ARCH_MULTI_V6_V7
        select CPU_V6
 
 config ARCH_MULTI_V7
-       bool "ARMv7 based platforms (Cortex-A, PJ4, Krait)"
+       bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)"
        default y
        select ARCH_MULTI_V6_V7
        select ARCH_VEXPRESS
@@ -1462,10 +1462,6 @@ config ISA_DMA
        bool
        select ISA_DMA_API
 
-config ARCH_NO_VIRT_TO_BUS
-       def_bool y
-       depends on !ARCH_RPC && !ARCH_NETWINDER && !ARCH_SHARK
-
 # Select ISA DMA interface
 config ISA_DMA_API
        bool
@@ -1657,13 +1653,16 @@ config LOCAL_TIMERS
          accounting to be spread across the timer interval, preventing a
          "thundering herd" at every timer tick.
 
+# The GPIO number here must be sorted by descending number. In case of
+# a multiplatform kernel, we just want the highest value required by the
+# selected platforms.
 config ARCH_NR_GPIO
        int
        default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
-       default 355 if ARCH_U8500
-       default 264 if MACH_H4700
        default 512 if SOC_OMAP5
+       default 355 if ARCH_U8500
        default 288 if ARCH_VT8500 || ARCH_SUNXI
+       default 264 if MACH_H4700
        default 0
        help
          Maximum number of GPIOs in the system.
@@ -1887,8 +1886,9 @@ config XEN_DOM0
 
 config XEN
        bool "Xen guest support on ARM (EXPERIMENTAL)"
-       depends on ARM && OF
+       depends on ARM && AEABI && OF
        depends on CPU_V7 && !CPU_V6
+       depends on !GENERIC_ATOMIC64
        help
          Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
 
index acddddac7ee46fb961e8ba1fe86d038276d0a632..9b31f4311ea2717818d8a387d3e0131d335195d0 100644 (file)
@@ -492,9 +492,10 @@ config DEBUG_IMX_UART_PORT
                                                DEBUG_IMX31_UART || \
                                                DEBUG_IMX35_UART || \
                                                DEBUG_IMX51_UART || \
-                                               DEBUG_IMX50_IMX53_UART || \
+                                               DEBUG_IMX53_UART || \
                                                DEBUG_IMX6Q_UART
        default 1
+       depends on ARCH_MXC
        help
          Choose UART port on which kernel low-level debug messages
          should be output.
index 71768b8a1ab91b7d7afe8241b11fc571cc30b516..84aa2caf07ed203fb810220258401a1b51f7cab3 100644 (file)
@@ -115,4 +115,4 @@ i:
        $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
        $(obj)/Image System.map "$(INSTALL_PATH)"
 
-subdir-            := bootp compressed
+subdir-            := bootp compressed dts
index 5cad8a6dadb021fd2aef0a4ef1a77c40173041e7..afed28e37ea5776073c9bace41d644b4bd6dda44 100644 (file)
@@ -120,7 +120,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 
-ccflags-y := -fpic -fno-builtin -I$(obj)
+ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
 asflags-y := -Wa,-march=all -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
index f8e4855bc9a536b34405dca9a8ff64a268542879..070bba4f25853be236d7b7cd26790283432b5364 100644 (file)
                        status = "okay";
                        /* No CD or WP GPIOs */
                };
+
+               usb@d0050000 {
+                       status = "okay";
+               };
+
+               usb@d0051000 {
+                       status = "okay";
+               };
        };
 };
index 6f1acc75e1559ca109066c7ad68c6e11f50087a0..5b708208b607b4b1eeaf7411040c56784fd93df5 100644 (file)
@@ -31,7 +31,6 @@
        mpic: interrupt-controller@d0020000 {
              compatible = "marvell,mpic";
              #interrupt-cells = <1>;
-             #address-cells = <1>;
              #size-cells = <1>;
              interrupt-controller;
        };
@@ -54,7 +53,7 @@
                                reg = <0xd0012000 0x100>;
                                reg-shift = <2>;
                                interrupts = <41>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
                serial@d0012100 {
@@ -62,7 +61,7 @@
                                reg = <0xd0012100 0x100>;
                                reg-shift = <2>;
                                interrupts = <42>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
 
index 1443949c165ea8fa787fe798f687a63a116f2626..ca00d8326c8746cd127e7c35f3c8e7d3da697c15 100644 (file)
@@ -46,7 +46,7 @@
                                reg = <0xd0012200 0x100>;
                                reg-shift = <2>;
                                interrupts = <43>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
                serial@d0012300 {
@@ -54,7 +54,7 @@
                                reg = <0xd0012300 0x100>;
                                reg-shift = <2>;
                                interrupts = <44>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
 
index aa98e641931fa21ed76c627229da576289005d12..a98c0d50fbbe1ed80e6c29d5228716155f3399f5 100644 (file)
                                nand {
                                        pinctrl_nand: nand-0 {
                                                atmel,pins =
-                                                       <3 4 0x0 0x1    /* PD5 gpio RDY pin pull_up */
-                                                        3 5 0x0 0x1>;  /* PD4 gpio enable pin pull_up */
+                                                       <3 0 0x1 0x0    /* PD0 periph A Read Enable */
+                                                        3 1 0x1 0x0    /* PD1 periph A Write Enable */
+                                                        3 2 0x1 0x0    /* PD2 periph A Address Latch Enable */
+                                                        3 3 0x1 0x0    /* PD3 periph A Command Latch Enable */
+                                                        3 4 0x0 0x1    /* PD4 gpio Chip Enable pin pull_up */
+                                                        3 5 0x0 0x1    /* PD5 gpio RDY/BUSY pin pull_up */
+                                                        3 6 0x1 0x0    /* PD6 periph A Data bit 0 */
+                                                        3 7 0x1 0x0    /* PD7 periph A Data bit 1 */
+                                                        3 8 0x1 0x0    /* PD8 periph A Data bit 2 */
+                                                        3 9 0x1 0x0    /* PD9 periph A Data bit 3 */
+                                                        3 10 0x1 0x0   /* PD10 periph A Data bit 4 */
+                                                        3 11 0x1 0x0   /* PD11 periph A Data bit 5 */
+                                                        3 12 0x1 0x0   /* PD12 periph A Data bit 6 */
+                                                        3 13 0x1 0x0>; /* PD13 periph A Data bit 7 */
+                                       };
+
+                                       pinctrl_nand_16bits: nand_16bits-0 {
+                                               atmel,pins =
+                                                       <3 14 0x1 0x0   /* PD14 periph A Data bit 8 */
+                                                        3 15 0x1 0x0   /* PD15 periph A Data bit 9 */
+                                                        3 16 0x1 0x0   /* PD16 periph A Data bit 10 */
+                                                        3 17 0x1 0x0   /* PD17 periph A Data bit 11 */
+                                                        3 18 0x1 0x0   /* PD18 periph A Data bit 12 */
+                                                        3 19 0x1 0x0   /* PD19 periph A Data bit 13 */
+                                                        3 20 0x1 0x0   /* PD20 periph A Data bit 14 */
+                                                        3 21 0x1 0x0>; /* PD21 periph A Data bit 15 */
                                        };
                                };
 
index 4bf2a8774aa76ab53889c51208f5fa0cf6841c11..7e0481e2441ac49b96d33ec1491414562a3d9935 100644 (file)
                        compatible = "fixed-clock";
                        reg = <1>;
                        #clock-cells = <0>;
-                       clock-frequency = <150000000>;
+                       clock-frequency = <250000000>;
                };
        };
 };
index 69140ba99f465ea357980c84cc232924a69071c0..9de93096601a2d1d526c37faf332a5510a4fc5d1 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                compatible = "stericsson,ab8500";
-                               reg = <5>; /* mailbox 5 is i2c */
                                interrupt-parent = <&intc>;
                                interrupts = <0 40 0x4>;
                                interrupt-controller;
index 67dbe20868a2746638ef2e20c380633a1e6fbcfa..f7509cafc377a14dc38aa5d77232c264a8d8a301 100644 (file)
                        status = "disabled";
                };
 
+               rtc@d8500 {
+                       compatible = "marvell,orion-rtc";
+                       reg = <0xd8500 0x20>;
+               };
+
                crypto: crypto@30000 {
                        compatible = "marvell,orion-crypto";
                        reg = <0x30000 0x10000>,
index e1347fceb5bc44c269e62d85c97a36249a76a073..1a62bcf18aa3cb942b4808d02fd007c7b995850b 100644 (file)
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12680000 0x1000>;
                        interrupts = <0 35 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <32>;
                };
 
                pdma1: pdma@12690000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12690000 0x1000>;
                        interrupts = <0 36 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <32>;
                };
 
                mdma1: mdma@12850000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12850000 0x1000>;
                        interrupts = <0 34 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <1>;
                };
        };
 };
index 5f3562ad67463a89a2bac80a81b1ac01c46907af..9a99755920c04e52f58b29bb5ca684606d6d55e6 100644 (file)
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x120000 0x1000>;
                        interrupts = <0 34 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <32>;
                };
 
                pdma1: pdma@121B0000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121000 0x1000>;
                        interrupts = <0 35 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <32>;
                };
        };
 
index 592fb9dc35bdcd355293e923b5a07bb79d11b1b9..379128eb9d981fc8f38b69cd8420652f48d1f91a 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
index 55f4191a626ede9b0f74d27752ede38d7a547b2b..2b587a74b8136f9d396deedffd9bd43c9bd28f54 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
index e54fffd483690300c2a89e6719a2621b03aa75bb..468c0a1d48d93a0804737cc78494a21234887f3b 100644 (file)
                        fsl,pins = <689 0x10000         /* DISP1_DRDY   */
                                    482 0x10000         /* DISP1_HSYNC  */
                                    489 0x10000         /* DISP1_VSYNC  */
-                                   684 0x10000         /* DISP1_DAT_0  */
                                    515 0x10000         /* DISP1_DAT_22 */
                                    523 0x10000         /* DISP1_DAT_23 */
-                                   543 0x10000         /* DISP1_DAT_21 */
+                                   545 0x10000         /* DISP1_DAT_21 */
                                    553 0x10000         /* DISP1_DAT_20 */
                                    558 0x10000         /* DISP1_DAT_19 */
                                    564 0x10000         /* DISP1_DAT_18 */
index 5bb0bf39d3b88483ffd16828b57fdd8aceca7612..c9c44b2f62d7b6a4248a7f2d84125e14ce4b1284 100644 (file)
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
 
                serial@12100 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
        };
index d430713ea9b93c3fd746df1e3f4a92cf31796026..e4e4930dc5cf78b9318e9f7015980ab5bd5b90da 100644 (file)
@@ -50,7 +50,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "okay";
                };
        };
index 2e3dd34e21a554298a029dc1bdf563c26f19ea59..0196cf6b0ef29c302e2628767d3284893cc851b9 100644 (file)
@@ -37,7 +37,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index ef2d8c7057093b8ef609488fe56ae45d9991c7b3..289e51d86372895ff6428892fe199cbefa255520 100644 (file)
@@ -38,7 +38,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 1b133e0c566e80b4c4e47ab1cd2531772065489d..bd83b8fc7c83f01304397ac17e75be5a6438128e 100644 (file)
@@ -73,7 +73,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 71902da33d6383583659adf35b16d7b3a1684c85..5335b1aa8601309f1ce9dc1a75a21243be1364f0 100644 (file)
@@ -51,7 +51,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "okay";
                };
 
index 504f16be8b54bf682a4c45413a354a48fd27c35e..12ccf74ac3c417e6de31fa5c33a2ab731f136220 100644 (file)
@@ -78,7 +78,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 6cae4599c4b3e620974dbfa318119db952a56136..93c3afbef9eeecc4b0b3741c2bc2360717da81b9 100644 (file)
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 8db3123ac80f49d0bef30aa4c6c79dcf68690a51..5bbd0542cdd3b97848515a64fd55b49adfd0eaec 100644 (file)
@@ -34,7 +34,6 @@
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 9510c9ea666cc15dad8b512ac6c84d2b2cd8a0d5..9f55d95f35f5806ca126cb23120abbcf0d692a94 100644 (file)
@@ -13,7 +13,6 @@
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
        };
index 739019c4cba9c0806ca09da9b2c8cb2fffca2762..5c84c118ed8d6f81e490c9b7924c3aecd2fb845d 100644 (file)
@@ -13,7 +13,6 @@
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "okay";
                };
        };
index 662dfd81b1cee275358db30328259529928d99f1..758824118a9a8e22041817183449839f1c9c072e 100644 (file)
@@ -90,7 +90,6 @@
                 };
 
                 serial@12000 {
-                        clock-frequency = <200000000>;
                         status = "ok";
                 };
 
index e8e7ecef1650e3bb9ad6b73d43382a0946a4abff..6affd924fe11c48df75653970cb92cbac7954591 100644 (file)
@@ -23,7 +23,6 @@
                };
 
                serial@12000 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
 
index 3a178cf708d729885c78d81926349e9c15fc4f56..a7412b937a8add0c3f0ccfbc165c0a5c3325f50d 100644 (file)
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index ede7fe0d7a87d872f9a108f25c479d6fc0c1349d..d27f7245f8e71a07539b041121b66cb06e2402a7 100644 (file)
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
                serial@12100 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 842ff95d60df1f392347abb9b5a1d44981a309be..66eb45b00b25218476c372a5bb1dfc20f3046fb0 100644 (file)
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 2c738d9dc82a17143b1578c3867dbf87e304cef0..fada7e6d24d8543fd956ef18d7981aa12b9b9ee6 100644 (file)
@@ -38,6 +38,7 @@
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        interrupts = <35>, <36>, <37>, <38>;
+                       clocks = <&gate_clk 7>;
                };
 
                gpio1: gpio@10140 {
@@ -49,6 +50,7 @@
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        interrupts = <39>, <40>, <41>;
+                       clocks = <&gate_clk 7>;
                };
 
                serial@12000 {
@@ -57,7 +59,6 @@
                        reg-shift = <2>;
                        interrupts = <33>;
                        clocks = <&gate_clk 7>;
-                       /* set clock-frequency in board dts */
                        status = "disabled";
                };
 
@@ -67,7 +68,6 @@
                        reg-shift = <2>;
                        interrupts = <34>;
                        clocks = <&gate_clk 7>;
-                       /* set clock-frequency in board dts */
                        status = "disabled";
                };
 
@@ -75,6 +75,7 @@
                        compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
                        reg = <0x10300 0x20>;
                        interrupts = <53>;
+                       clocks = <&gate_clk 7>;
                };
 
                spi@10600 {
index 5a3a58b7e18fa134d71094ea27b5138b5ca5abc3..0077fc8510b78d5b92b03a5f3a7951ee5e9d5753 100644 (file)
@@ -11,7 +11,7 @@
 
 / {
        model = "LaCie Ethernet Disk mini V2";
-       compatible = "lacie,ethernet-disk-mini-v2", "marvell-orion5x-88f5182", "marvell,orion5x";
+       compatible = "lacie,ethernet-disk-mini-v2", "marvell,orion5x-88f5182", "marvell,orion5x";
 
        memory {
                reg = <0x00000000 0x4000000>; /* 64 MB */
index 27f31a5fa4947aa530d74cfa4c0260fc406ace7e..d3ec32f6b79073fc7171f966f47257cac86aabfb 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
index 936d2306e7e12e9e46fd09294b6af54e41f0ccb3..7e8769bd59774334ce330c27b91e96d5783ee93e 100644 (file)
@@ -75,6 +75,9 @@
                                compatible = "arm,pl330", "arm,primecell";
                                reg = <0xffe01000 0x1000>;
                                interrupts = <0 180 4>;
+                               #dma-cells = <1>;
+                               #dma-channels = <8>;
+                               #dma-requests = <32>;
                        };
                };
 
index 9a428931d0429d2befef3d6d3084b7499eeb3a02..3d3f64d2111a33fb415979c2a1b911c2f7b37a66 100644 (file)
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x50040600 0x20>;
                interrupts = <1 13 0x304>;
+               clocks = <&tegra_car 132>;
        };
 
        intc: interrupt-controller {
 
        spi@7000d800 {
                compatible = "nvidia,tegra20-slink";
-               reg = <0x7000d480 0x200>;
+               reg = <0x7000d800 0x200>;
                interrupts = <0 83 0x04>;
                nvidia,dma-request-selector = <&apbdma 17>;
                #address-cells = <1>;
index 767803e1fd55f2d6e75053527e47a26d536e4f77..dbf46c27256255fd35ffaf6501a314f50668af3c 100644 (file)
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x50040600 0x20>;
                interrupts = <1 13 0xf04>;
+               clocks = <&tegra_car 214>;
        };
 
        intc: interrupt-controller {
 
        spi@7000d800 {
                compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
-               reg = <0x7000d480 0x200>;
+               reg = <0x7000d800 0x200>;
                interrupts = <0 83 0x04>;
                nvidia,dma-request-selector = <&apbdma 17>;
                #address-cells = <1>;
index fbbc5bb022d56ad6f6244405cc0e0911eccfdfe0..6a99e30f81d2ac992da503ba5338571c2d2731ba 100644 (file)
@@ -116,6 +116,7 @@ CONFIG_SND_SOC=y
 CONFIG_SND_MXS_SOC=y
 CONFIG_SND_SOC_MXS_SGTL5000=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_USB_STORAGE=y
index b16bae2c9a600f504c442c1c9f5513179e8d710a..bd07864f14a00b0fd9608139cb607ae9f021a154 100644 (file)
@@ -126,6 +126,8 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_TWL4030_PWRBUTTON=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
index 9f77e7804f3b66e7c08e7ece91780b2df178c9ca..e3d55547e75592a9eb98fa1704ee8df9e872c2c5 100644 (file)
@@ -5,15 +5,15 @@
 
 typedef struct {
 #ifdef CONFIG_CPU_HAS_ASID
-       u64 id;
+       atomic64_t      id;
 #endif
-       unsigned int vmalloc_seq;
+       unsigned int    vmalloc_seq;
 } mm_context_t;
 
 #ifdef CONFIG_CPU_HAS_ASID
 #define ASID_BITS      8
 #define ASID_MASK      ((~0ULL) << ASID_BITS)
-#define ASID(mm)       ((mm)->context.id & ~ASID_MASK)
+#define ASID(mm)       ((mm)->context.id.counter & ~ASID_MASK)
 #else
 #define ASID(mm)       (0)
 #endif
@@ -26,7 +26,7 @@ typedef struct {
  *  modified for 2.6 by Hyok S. Choi <hyok.choi@samsung.com>
  */
 typedef struct {
-       unsigned long           end_brk;
+       unsigned long   end_brk;
 } mm_context_t;
 
 #endif
index e1f644bc7cc504412613a08489dffbfc4ecc63bd..863a6611323c70077a9428b198a10d59758ff919 100644 (file)
@@ -25,7 +25,7 @@ void __check_vmalloc_seq(struct mm_struct *mm);
 #ifdef CONFIG_CPU_HAS_ASID
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
-#define init_new_context(tsk,mm)       ({ mm->context.id = 0; })
+#define init_new_context(tsk,mm)       ({ atomic64_set(&mm->context.id, 0); 0; })
 
 #else  /* !CONFIG_CPU_HAS_ASID */
 
index 6e924d3a77ebc168cb8359e7cf79f21b8890146d..4db8c8820f0d1c832bf9efd5e81a69d32b4fc7d7 100644 (file)
 #define TLB_V6_D_ASID  (1 << 17)
 #define TLB_V6_I_ASID  (1 << 18)
 
+#define TLB_V6_BP      (1 << 19)
+
 /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
-#define TLB_V7_UIS_PAGE        (1 << 19)
-#define TLB_V7_UIS_FULL (1 << 20)
-#define TLB_V7_UIS_ASID (1 << 21)
+#define TLB_V7_UIS_PAGE        (1 << 20)
+#define TLB_V7_UIS_FULL (1 << 21)
+#define TLB_V7_UIS_ASID (1 << 22)
+#define TLB_V7_UIS_BP  (1 << 23)
 
 #define TLB_BARRIER    (1 << 28)
 #define TLB_L2CLEAN_FR (1 << 29)               /* Feroceon */
 #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
                         TLB_V6_I_FULL | TLB_V6_D_FULL | \
                         TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
-                        TLB_V6_I_ASID | TLB_V6_D_ASID)
+                        TLB_V6_I_ASID | TLB_V6_D_ASID | \
+                        TLB_V6_BP)
 
 #ifdef CONFIG_CPU_TLB_V6
 # define v6wbi_possible_flags  v6wbi_tlb_flags
 #endif
 
 #define v7wbi_tlb_flags_smp    (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
-                        TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
+                                TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | \
+                                TLB_V7_UIS_ASID | TLB_V7_UIS_BP)
 #define v7wbi_tlb_flags_up     (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
-                        TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
+                                TLB_V6_U_FULL | TLB_V6_U_PAGE | \
+                                TLB_V6_U_ASID | TLB_V6_BP)
 
 #ifdef CONFIG_CPU_TLB_V7
 
@@ -430,6 +436,20 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        }
 }
 
+static inline void local_flush_bp_all(void)
+{
+       const int zero = 0;
+       const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+       if (tlb_flag(TLB_V7_UIS_BP))
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero));
+       else if (tlb_flag(TLB_V6_BP))
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero));
+
+       if (tlb_flag(TLB_BARRIER))
+               isb();
+}
+
 /*
  *     flush_pmd_entry
  *
@@ -480,6 +500,7 @@ static inline void clean_pmd_entry(void *pmd)
 #define flush_tlb_kernel_page  local_flush_tlb_kernel_page
 #define flush_tlb_range                local_flush_tlb_range
 #define flush_tlb_kernel_range local_flush_tlb_kernel_range
+#define flush_bp_all           local_flush_bp_all
 #else
 extern void flush_tlb_all(void);
 extern void flush_tlb_mm(struct mm_struct *mm);
@@ -487,6 +508,7 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
 extern void flush_tlb_kernel_page(unsigned long kaddr);
 extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_bp_all(void);
 #endif
 
 /*
index 5c27696de14fda11bf6866138387f1149128e485..8b1f37bfeeecf3c2d8af09ed15bcbc4cc8fa991f 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_ARM_XEN_EVENTS_H
 
 #include <asm/ptrace.h>
+#include <asm/atomic.h>
 
 enum ipi_vector {
        XEN_PLACEHOLDER_VECTOR,
@@ -15,26 +16,8 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
        return raw_irqs_disabled_flags(regs->ARM_cpsr);
 }
 
-/*
- * We cannot use xchg because it does not support 8-byte
- * values. However it is safe to use {ldr,dtd}exd directly because all
- * platforms which Xen can run on support those instructions.
- */
-static inline xen_ulong_t xchg_xen_ulong(xen_ulong_t *ptr, xen_ulong_t val)
-{
-       xen_ulong_t oldval;
-       unsigned int tmp;
-
-       wmb();
-       asm volatile("@ xchg_xen_ulong\n"
-               "1:     ldrexd  %0, %H0, [%3]\n"
-               "       strexd  %1, %2, %H2, [%3]\n"
-               "       teq     %1, #0\n"
-               "       bne     1b"
-               : "=&r" (oldval), "=&r" (tmp)
-               : "r" (val), "r" (ptr)
-               : "memory", "cc");
-       return oldval;
-}
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr),     \
+                                                           atomic64_t, \
+                                                           counter), (val))
 
 #endif /* _ASM_ARM_XEN_EVENTS_H */
index 4da7cde70b5d3fac435bdbf13b3dcc9c298be4c7..af33b44990ed4a395662f0c5e7021049e5755a78 100644 (file)
 #define __NR_setns                     (__NR_SYSCALL_BASE+375)
 #define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
-                                       /* 378 for kcmp */
+#define __NR_kcmp                      (__NR_SYSCALL_BASE+378)
 #define __NR_finit_module              (__NR_SYSCALL_BASE+379)
 
 /*
index 5ce738b435081254652ed3abdcbdfa2dcf5c88c2..923eec7105cff3cbb5f1eccd7e044a25e4cfdbf3 100644 (file)
@@ -110,7 +110,7 @@ int main(void)
   BLANK();
 #endif
 #ifdef CONFIG_CPU_HAS_ASID
-  DEFINE(MM_CONTEXT_ID,                offsetof(struct mm_struct, context.id));
+  DEFINE(MM_CONTEXT_ID,                offsetof(struct mm_struct, context.id.counter));
   BLANK();
 #endif
   DEFINE(VMA_VM_MM,            offsetof(struct vm_area_struct, vm_mm));
index 42a1a1415fa6c37ee96b742d4bb3c1bdc9a6542d..c7ff8073416fb0fc4619f597d17cc738985c0a0f 100644 (file)
@@ -9,24 +9,18 @@ struct buffer {
        char data[];
 };
 
-static int
-read_buffer(char* page, char** start, off_t off, int count,
-       int* eof, void* data)
+static ssize_t atags_read(struct file *file, char __user *buf,
+                         size_t count, loff_t *ppos)
 {
-       struct buffer *buffer = (struct buffer *)data;
-
-       if (off >= buffer->size) {
-               *eof = 1;
-               return 0;
-       }
-
-       count = min((int) (buffer->size - off), count);
-
-       memcpy(page, &buffer->data[off], count);
-
-       return count;
+       struct buffer *b = PDE_DATA(file_inode(file));
+       return simple_read_from_buffer(buf, count, ppos, b->data, b->size);
 }
 
+static const struct file_operations atags_fops = {
+       .read = atags_read,
+       .llseek = default_llseek,
+};
+
 #define BOOT_PARAMS_SIZE 1536
 static char __initdata atags_copy[BOOT_PARAMS_SIZE];
 
@@ -66,9 +60,7 @@ static int __init init_atags_procfs(void)
        b->size = size;
        memcpy(b->data, atags_copy, size);
 
-       tags_entry = create_proc_read_entry("atags", 0400,
-                       NULL, read_buffer, b);
-
+       tags_entry = proc_create_data("atags", 0400, NULL, &atags_fops, b);
        if (!tags_entry)
                goto nomem;
 
index 0cc57611fc4f379b1e6087d4f8d6492dede8156f..c6ca7e376773fcc73ef619e1c5a97793d97b41b4 100644 (file)
 /* 375 */      CALL(sys_setns)
                CALL(sys_process_vm_readv)
                CALL(sys_process_vm_writev)
-               CALL(sys_ni_syscall)    /* reserved for sys_kcmp */
+               CALL(sys_kcmp)
                CALL(sys_finit_module)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
index 486a15ae901192fa3e26539b3d2b7003a1528e0f..e0eb9a1cae774fc714548c3e11ad5141cc82190e 100644 (file)
@@ -184,13 +184,22 @@ __create_page_tables:
        orr     r3, r3, #3                      @ PGD block type
        mov     r6, #4                          @ PTRS_PER_PGD
        mov     r7, #1 << (55 - 32)             @ L_PGD_SWAPPER
-1:     str     r3, [r0], #4                    @ set bottom PGD entry bits
+1:
+#ifdef CONFIG_CPU_ENDIAN_BE8
        str     r7, [r0], #4                    @ set top PGD entry bits
+       str     r3, [r0], #4                    @ set bottom PGD entry bits
+#else
+       str     r3, [r0], #4                    @ set bottom PGD entry bits
+       str     r7, [r0], #4                    @ set top PGD entry bits
+#endif
        add     r3, r3, #0x1000                 @ next PMD table
        subs    r6, r6, #1
        bne     1b
 
        add     r4, r4, #0x1000                 @ point to the PMD tables
+#ifdef CONFIG_CPU_ENDIAN_BE8
+       add     r4, r4, #4                      @ we only write the bottom word
+#endif
 #endif
 
        ldr     r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
@@ -258,6 +267,11 @@ __create_page_tables:
        addne   r6, r6, #1 << SECTION_SHIFT
        strne   r6, [r3]
 
+#if defined(CONFIG_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8)
+       sub     r4, r4, #4                      @ Fixup page table pointer
+                                               @ for 64-bit descriptors
+#endif
+
 #ifdef CONFIG_DEBUG_LL
 #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING)
        /*
@@ -276,13 +290,17 @@ __create_page_tables:
        orr     r3, r7, r3, lsl #SECTION_SHIFT
 #ifdef CONFIG_ARM_LPAE
        mov     r7, #1 << (54 - 32)             @ XN
+#ifdef CONFIG_CPU_ENDIAN_BE8
+       str     r7, [r0], #4
+       str     r3, [r0], #4
 #else
-       orr     r3, r3, #PMD_SECT_XN
-#endif
        str     r3, [r0], #4
-#ifdef CONFIG_ARM_LPAE
        str     r7, [r0], #4
 #endif
+#else
+       orr     r3, r3, #PMD_SECT_XN
+       str     r3, [r0], #4
+#endif
 
 #else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
        /* we don't need any serial debugging mappings */
index 5eae53e7a2e1619c5d128b20b5337e727fc43864..96093b75ab90dc134d7232e3f6a1e3c5f41e7902 100644 (file)
@@ -1023,7 +1023,7 @@ out_mdbgen:
 static int __cpuinit dbg_reset_notify(struct notifier_block *self,
                                      unsigned long action, void *cpu)
 {
-       if (action == CPU_ONLINE)
+       if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
                smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
 
        return NOTIFY_OK;
index 31e0eb353cd80a1bf3c02dfe6c4b7c5b1112bec4..146157dfe27c6c991b8507c2c3f248d810754cc0 100644 (file)
@@ -400,7 +400,7 @@ __hw_perf_event_init(struct perf_event *event)
        }
 
        if (event->group_leader != event) {
-               if (validate_group(event) != 0);
+               if (validate_group(event) != 0)
                        return -EINVAL;
        }
 
@@ -484,7 +484,7 @@ const struct dev_pm_ops armpmu_dev_pm_ops = {
        SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
 };
 
-static void __init armpmu_init(struct arm_pmu *armpmu)
+static void armpmu_init(struct arm_pmu *armpmu)
 {
        atomic_set(&armpmu->active_events, 0);
        mutex_init(&armpmu->reserve_mutex);
index 8c79a9e70b83d1dd31afdca93addae57c7c9c0cb..039cffb053a7ec017a552013fc6eff5c17ca1d50 100644 (file)
@@ -774,7 +774,7 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 /*
  * PMXEVTYPER: Event selection reg
  */
-#define        ARMV7_EVTYPE_MASK       0xc00000ff      /* Mask for writable bits */
+#define        ARMV7_EVTYPE_MASK       0xc80000ff      /* Mask for writable bits */
 #define        ARMV7_EVTYPE_EVENT      0xff            /* Mask for EVENT bits */
 
 /*
index 1bdfd87c8e41d026bcaf9fe1893c2645e6dce6dd..79078edbb9bc12d38bb144a88754b83390429c95 100644 (file)
@@ -285,6 +285,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
         * switch away from it before attempting any exclusive accesses.
         */
        cpu_switch_mm(mm->pgd, mm);
+       local_flush_bp_all();
        enter_lazy_tlb(mm, current);
        local_flush_tlb_all();
 
@@ -479,7 +480,7 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
        evt->features   = CLOCK_EVT_FEAT_ONESHOT |
                          CLOCK_EVT_FEAT_PERIODIC |
                          CLOCK_EVT_FEAT_DUMMY;
-       evt->rating     = 400;
+       evt->rating     = 100;
        evt->mult       = 1;
        evt->set_mode   = broadcast_timer_set_mode;
 
index 02c5d2ce23bf121f17479bba2b52460419481930..bd0300531399e5eeb066a45f3c29b0d897c23b42 100644 (file)
@@ -64,6 +64,11 @@ static inline void ipi_flush_tlb_kernel_range(void *arg)
        local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
 }
 
+static inline void ipi_flush_bp_all(void *ignored)
+{
+       local_flush_bp_all();
+}
+
 void flush_tlb_all(void)
 {
        if (tlb_ops_need_broadcast())
@@ -127,3 +132,10 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
                local_flush_tlb_kernel_range(start, end);
 }
 
+void flush_bp_all(void)
+{
+       if (tlb_ops_need_broadcast())
+               on_each_cpu(ipi_flush_bp_all, NULL, 1);
+       else
+               local_flush_bp_all();
+}
index c092115d903a8ad4e4c789398a7c444064ff273a..3f256503748005346d5f1388aa1ed30978433b03 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 
+#include <asm/smp_plat.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 
@@ -373,6 +374,9 @@ void __init twd_local_timer_of_register(void)
        struct device_node *np;
        int err;
 
+       if (!is_smp() || !setup_max_cpus)
+               return;
+
        np = of_find_matching_node(NULL, twd_of_match);
        if (!np)
                return;
index 358bca3a995ed37ec66da93ec40841abd99fa804..c59c97ea8268b461b45b8d46066b2f4208f9afe5 100644 (file)
@@ -68,6 +68,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
        ret = __cpu_suspend(arg, fn);
        if (ret == 0) {
                cpu_switch_mm(mm->pgd, mm);
+               local_flush_bp_all();
                local_flush_tlb_all();
        }
 
index ab1017bd1667d9772e01a903099aa665b3f86b7d..087fc321e9e5e52d37f1b61e4b0bc461b43f8442 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/perf_event.h>
@@ -79,27 +80,27 @@ static unsigned long abtcounter;
 static pid_t         previous_pid;
 
 #ifdef CONFIG_PROC_FS
-static int proc_read_status(char *page, char **start, off_t off, int count,
-                           int *eof, void *data)
+static int proc_status_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       int len;
-
-       p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
-       p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
-       p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
+       seq_printf(m, "Emulated SWP:\t\t%lu\n", swpcounter);
+       seq_printf(m, "Emulated SWPB:\t\t%lu\n", swpbcounter);
+       seq_printf(m, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
        if (previous_pid != 0)
-               p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
-
-       len = (p - page) - off;
-       if (len < 0)
-               len = 0;
-
-       *eof = (len <= count) ? 1 : 0;
-       *start = page + off;
+               seq_printf(m, "Last process:\t\t%d\n", previous_pid);
+       return 0;
+}
 
-       return len;
+static int proc_status_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_status_show, PDE_DATA(inode));
 }
+
+static const struct file_operations proc_status_fops = {
+       .open           = proc_status_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif
 
 /*
@@ -266,14 +267,8 @@ static struct undef_hook swp_hook = {
 static int __init swp_emulation_init(void)
 {
 #ifdef CONFIG_PROC_FS
-       struct proc_dir_entry *res;
-
-       res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
-
-       if (!res)
+       if (!proc_create("cpu/swp_emulation", S_IRUGO, NULL, &proc_status_fops))
                return -ENOMEM;
-
-       res->read_proc = proc_read_status;
 #endif /* CONFIG_PROC_FS */
 
        printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
index 650d5923ab83cd849c38db3a64c55fccf36a631a..94b0650ea98fd42492c280d20c7610382a2f4a81 100644 (file)
 
        .text
        .align  5
-       .word   0
-
-1:     subs    r2, r2, #4              @ 1 do we have enough
-       blt     5f                      @ 1 bytes to align with?
-       cmp     r3, #2                  @ 1
-       strltb  r1, [r0], #1            @ 1
-       strleb  r1, [r0], #1            @ 1
-       strb    r1, [r0], #1            @ 1
-       add     r2, r2, r3              @ 1 (r2 = r2 - (4 - r3))
-/*
- * The pointer is now aligned and the length is adjusted.  Try doing the
- * memset again.
- */
 
 ENTRY(memset)
        ands    r3, r0, #3              @ 1 unaligned?
-       bne     1b                      @ 1
+       mov     ip, r0                  @ preserve r0 as return value
+       bne     6f                      @ 1
 /*
- * we know that the pointer in r0 is aligned to a word boundary.
+ * we know that the pointer in ip is aligned to a word boundary.
  */
-       orr     r1, r1, r1, lsl #8
+1:     orr     r1, r1, r1, lsl #8
        orr     r1, r1, r1, lsl #16
        mov     r3, r1
        cmp     r2, #16
@@ -43,29 +31,28 @@ ENTRY(memset)
 #if ! CALGN(1)+0
 
 /*
- * We need an extra register for this loop - save the return address and
- * use the LR
+ * We need 2 extra registers for this loop - use r8 and the LR
  */
-       str     lr, [sp, #-4]!
-       mov     ip, r1
+       stmfd   sp!, {r8, lr}
+       mov     r8, r1
        mov     lr, r1
 
 2:     subs    r2, r2, #64
-       stmgeia r0!, {r1, r3, ip, lr}   @ 64 bytes at a time.
-       stmgeia r0!, {r1, r3, ip, lr}
-       stmgeia r0!, {r1, r3, ip, lr}
-       stmgeia r0!, {r1, r3, ip, lr}
+       stmgeia ip!, {r1, r3, r8, lr}   @ 64 bytes at a time.
+       stmgeia ip!, {r1, r3, r8, lr}
+       stmgeia ip!, {r1, r3, r8, lr}
+       stmgeia ip!, {r1, r3, r8, lr}
        bgt     2b
-       ldmeqfd sp!, {pc}               @ Now <64 bytes to go.
+       ldmeqfd sp!, {r8, pc}           @ Now <64 bytes to go.
 /*
  * No need to correct the count; we're only testing bits from now on
  */
        tst     r2, #32
-       stmneia r0!, {r1, r3, ip, lr}
-       stmneia r0!, {r1, r3, ip, lr}
+       stmneia ip!, {r1, r3, r8, lr}
+       stmneia ip!, {r1, r3, r8, lr}
        tst     r2, #16
-       stmneia r0!, {r1, r3, ip, lr}
-       ldr     lr, [sp], #4
+       stmneia ip!, {r1, r3, r8, lr}
+       ldmfd   sp!, {r8, lr}
 
 #else
 
@@ -74,54 +61,63 @@ ENTRY(memset)
  * whole cache lines at once.
  */
 
-       stmfd   sp!, {r4-r7, lr}
+       stmfd   sp!, {r4-r8, lr}
        mov     r4, r1
        mov     r5, r1
        mov     r6, r1
        mov     r7, r1
-       mov     ip, r1
+       mov     r8, r1
        mov     lr, r1
 
        cmp     r2, #96
-       tstgt   r0, #31
+       tstgt   ip, #31
        ble     3f
 
-       and     ip, r0, #31
-       rsb     ip, ip, #32
-       sub     r2, r2, ip
-       movs    ip, ip, lsl #(32 - 4)
-       stmcsia r0!, {r4, r5, r6, r7}
-       stmmiia r0!, {r4, r5}
-       tst     ip, #(1 << 30)
-       mov     ip, r1
-       strne   r1, [r0], #4
+       and     r8, ip, #31
+       rsb     r8, r8, #32
+       sub     r2, r2, r8
+       movs    r8, r8, lsl #(32 - 4)
+       stmcsia ip!, {r4, r5, r6, r7}
+       stmmiia ip!, {r4, r5}
+       tst     r8, #(1 << 30)
+       mov     r8, r1
+       strne   r1, [ip], #4
 
 3:     subs    r2, r2, #64
-       stmgeia r0!, {r1, r3-r7, ip, lr}
-       stmgeia r0!, {r1, r3-r7, ip, lr}
+       stmgeia ip!, {r1, r3-r8, lr}
+       stmgeia ip!, {r1, r3-r8, lr}
        bgt     3b
-       ldmeqfd sp!, {r4-r7, pc}
+       ldmeqfd sp!, {r4-r8, pc}
 
        tst     r2, #32
-       stmneia r0!, {r1, r3-r7, ip, lr}
+       stmneia ip!, {r1, r3-r8, lr}
        tst     r2, #16
-       stmneia r0!, {r4-r7}
-       ldmfd   sp!, {r4-r7, lr}
+       stmneia ip!, {r4-r7}
+       ldmfd   sp!, {r4-r8, lr}
 
 #endif
 
 4:     tst     r2, #8
-       stmneia r0!, {r1, r3}
+       stmneia ip!, {r1, r3}
        tst     r2, #4
-       strne   r1, [r0], #4
+       strne   r1, [ip], #4
 /*
  * When we get here, we've got less than 4 bytes to zero.  We
  * may have an unaligned pointer as well.
  */
 5:     tst     r2, #2
-       strneb  r1, [r0], #1
-       strneb  r1, [r0], #1
+       strneb  r1, [ip], #1
+       strneb  r1, [ip], #1
        tst     r2, #1
-       strneb  r1, [r0], #1
+       strneb  r1, [ip], #1
        mov     pc, lr
+
+6:     subs    r2, r2, #4              @ 1 do we have enough
+       blt     5b                      @ 1 bytes to align with?
+       cmp     r3, #2                  @ 1
+       strltb  r1, [ip], #1            @ 1
+       strleb  r1, [ip], #1            @ 1
+       strb    r1, [ip], #1            @ 1
+       add     r2, r2, r3              @ 1 (r2 = r2 - (4 - r3))
+       b       1b
 ENDPROC(memset)
index 2ea7059b840bfedc5a156d009c943ee4246340ac..c20a870ea9c9295e01eda9842650a3aa593533fd 100644 (file)
@@ -176,6 +176,7 @@ static struct w1_gpio_platform_data w1_gpio_pdata = {
        /* If you choose to use a pin other than PB16 it needs to be 3.3V */
        .pin            = AT91_PIN_PB16,
        .is_open_drain  = 1,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 static struct platform_device w1_device = {
index a033b8df9fb2b147965c95a7393958c832180983..869cbecf00b7eee51c78b4621019ac40ea2edacf 100644 (file)
@@ -188,6 +188,7 @@ static struct spi_board_info portuxg20_spi_devices[] = {
 static struct w1_gpio_platform_data w1_gpio_pdata = {
        .pin            = AT91_PIN_PA29,
        .is_open_drain  = 1,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 static struct platform_device w1_device = {
index eed465ab0dd7d14c589880f4a242ce74138e7030..5fc23771c15455a4874211ba49ae2b012ffe6566 100644 (file)
@@ -209,6 +209,14 @@ extern int at91_get_gpio_value(unsigned pin);
 extern void at91_gpio_suspend(void);
 extern void at91_gpio_resume(void);
 
+#ifdef CONFIG_PINCTRL_AT91
+extern void at91_pinctrl_gpio_suspend(void);
+extern void at91_pinctrl_gpio_resume(void);
+#else
+static inline void at91_pinctrl_gpio_suspend(void) {}
+static inline void at91_pinctrl_gpio_resume(void) {}
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif
index 8e210262aeee59c3aef9ea13ab2a8d4e5d0af120..e0ca59171022fb8f2cee7a488cc2ee622c238384 100644 (file)
@@ -92,23 +92,21 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
 
 void at91_irq_suspend(void)
 {
-       int i = 0, bit;
+       int bit = -1;
 
        if (has_aic5()) {
                /* disable enabled irqs */
-               while ((bit = find_next_bit(backups, n_irqs, i)) < n_irqs) {
+               while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
                        at91_aic_write(AT91_AIC5_SSR,
                                       bit & AT91_AIC5_INTSEL_MSK);
                        at91_aic_write(AT91_AIC5_IDCR, 1);
-                       i = bit;
                }
                /* enable wakeup irqs */
-               i = 0;
-               while ((bit = find_next_bit(wakeups, n_irqs, i)) < n_irqs) {
+               bit = -1;
+               while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
                        at91_aic_write(AT91_AIC5_SSR,
                                       bit & AT91_AIC5_INTSEL_MSK);
                        at91_aic_write(AT91_AIC5_IECR, 1);
-                       i = bit;
                }
        } else {
                at91_aic_write(AT91_AIC_IDCR, *backups);
@@ -118,23 +116,21 @@ void at91_irq_suspend(void)
 
 void at91_irq_resume(void)
 {
-       int i = 0, bit;
+       int bit = -1;
 
        if (has_aic5()) {
                /* disable wakeup irqs */
-               while ((bit = find_next_bit(wakeups, n_irqs, i)) < n_irqs) {
+               while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
                        at91_aic_write(AT91_AIC5_SSR,
                                       bit & AT91_AIC5_INTSEL_MSK);
                        at91_aic_write(AT91_AIC5_IDCR, 1);
-                       i = bit;
                }
                /* enable irqs disabled for suspend */
-               i = 0;
-               while ((bit = find_next_bit(backups, n_irqs, i)) < n_irqs) {
+               bit = -1;
+               while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
                        at91_aic_write(AT91_AIC5_SSR,
                                       bit & AT91_AIC5_INTSEL_MSK);
                        at91_aic_write(AT91_AIC5_IECR, 1);
-                       i = bit;
                }
        } else {
                at91_aic_write(AT91_AIC_IDCR, *wakeups);
index adb6db888a1f1ebda8a088e9ae1e5780ba4b4555..73f1f250403a68575b78e02a8e8d72078ca42375 100644 (file)
@@ -201,7 +201,10 @@ extern u32 at91_slow_clock_sz;
 
 static int at91_pm_enter(suspend_state_t state)
 {
-       at91_gpio_suspend();
+       if (of_have_populated_dt())
+               at91_pinctrl_gpio_suspend();
+       else
+               at91_gpio_suspend();
        at91_irq_suspend();
 
        pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
@@ -286,7 +289,10 @@ static int at91_pm_enter(suspend_state_t state)
 error:
        target_state = PM_SUSPEND_ON;
        at91_irq_resume();
-       at91_gpio_resume();
+       if (of_have_populated_dt())
+               at91_pinctrl_gpio_resume();
+       else
+               at91_gpio_resume();
        return 0;
 }
 
index a685e9706b7ba305b462b103899398b3521f2917..45b7c71d9cc1966bb514862364b5180cdd307060 100644 (file)
@@ -743,6 +743,9 @@ EXPORT_SYMBOL(edma_free_channel);
  */
 int edma_alloc_slot(unsigned ctlr, int slot)
 {
+       if (!edma_cc[ctlr])
+               return -EINVAL;
+
        if (slot >= 0)
                slot = EDMA_CHAN_SLOT(slot);
 
index abda5a18a664734a5d29a015cfabfbe7d0a5c26a..0f2111a11315853a046284b71b290890f3ae8fdd 100644 (file)
@@ -67,6 +67,7 @@ config ARCH_NETWINDER
        select ISA
        select ISA_DMA
        select PCI
+       select VIRT_TO_BUS
        help
          Say Y here if you intend to run this kernel on the Rebel.COM
          NetWinder.  Information about this machine can be found at:
index 74e3a34d78b80a25be2edeb9afcc2f027f610368..e13a8fa5e62c5aa4f04b0aba66f4e77df0ac24ce 100644 (file)
@@ -264,6 +264,7 @@ int __init mx35_clocks_init(void)
        clk_prepare_enable(clk[gpio3_gate]);
        clk_prepare_enable(clk[iim_gate]);
        clk_prepare_enable(clk[emi_gate]);
+       clk_prepare_enable(clk[max_gate]);
 
        /*
         * SCC is needed to boot via mmc after a watchdog reset. The clock code
index 7b025ee528a517bdb7d584e90cebefc40fb56a48..2f9ff93a4e6134773befacb68c4dd4ec5c14bb90 100644 (file)
@@ -172,7 +172,7 @@ static struct clk *clk[clk_max];
 static struct clk_onecell_data clk_data;
 
 static enum mx6q_clks const clks_init_on[] __initconst = {
-       mmdc_ch0_axi, rom,
+       mmdc_ch0_axi, rom, pll1_sys,
 };
 
 static struct clk_div_table clk_enet_ref_table[] = {
index 921fc15558549093f0ff0bbcc9b9de946d520152..a58c8b0527ccb3aad1f542b83a159c868a61655d 100644 (file)
@@ -26,16 +26,16 @@ ENDPROC(v7_secondary_startup)
 
 #ifdef CONFIG_PM
 /*
- * The following code is located into the .data section.  This is to
- * allow phys_l2x0_saved_regs to be accessed with a relative load
- * as we are running on physical address here.
+ * The following code must assume it is running from physical address
+ * where absolute virtual addresses to the data section have to be
+ * turned into relative ones.
  */
-       .data
-       .align
 
 #ifdef CONFIG_CACHE_L2X0
        .macro  pl310_resume
-       ldr     r2, phys_l2x0_saved_regs
+       adr     r0, l2x0_saved_regs_offset
+       ldr     r2, [r0]
+       add     r2, r2, r0
        ldr     r0, [r2, #L2X0_R_PHY_BASE]      @ get physical base of l2x0
        ldr     r1, [r2, #L2X0_R_AUX_CTRL]      @ get aux_ctrl value
        str     r1, [r0, #L2X0_AUX_CTRL]        @ restore aux_ctrl
@@ -43,9 +43,9 @@ ENDPROC(v7_secondary_startup)
        str     r1, [r0, #L2X0_CTRL]            @ re-enable L2
        .endm
 
-       .globl  phys_l2x0_saved_regs
-phys_l2x0_saved_regs:
-        .long   0
+l2x0_saved_regs_offset:
+       .word   l2x0_saved_regs - .
+
 #else
        .macro  pl310_resume
        .endm
index 03b65e5ea541613a062ea5719b32ab045b9e723f..82348391582a0944108a8d3ab06a4abb81771e20 100644 (file)
@@ -27,6 +27,11 @@ static const char * const imx25_dt_board_compat[] __initconst = {
        NULL
 };
 
+static void __init imx25_timer_init(void)
+{
+       mx25_clocks_init_dt();
+}
+
 DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
        .map_io         = mx25_map_io,
        .init_early     = imx25_init_early,
index ee42d20cba19f022d4a9ece8616e27b443d7e82e..5faba7a3c95f6e74393699045aa0635331459d46 100644 (file)
@@ -22,8 +22,6 @@
 #include "common.h"
 #include "hardware.h"
 
-extern unsigned long phys_l2x0_saved_regs;
-
 static int imx6q_suspend_finish(unsigned long val)
 {
        cpu_do_idle();
@@ -57,18 +55,5 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
 
 void __init imx6q_pm_init(void)
 {
-       /*
-        * The l2x0 core code provides an infrastucture to save and restore
-        * l2x0 registers across suspend/resume cycle.  But because imx6q
-        * retains L2 content during suspend and needs to resume L2 before
-        * MMU is enabled, it can only utilize register saving support and
-        * have to take care of restoring on its own.  So we save physical
-        * address of the data structure used by l2x0 core to save registers,
-        * and later restore the necessary ones in imx6q resume entry.
-        */
-#ifdef CONFIG_CACHE_L2X0
-       phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
-#endif
-
        suspend_set_ops(&imx6q_pm_ops);
 }
index d42730a1d4abf5b85ccb193c6e9c297a140485c0..d599e354ca57fd6511db36fb8660636e6d152c81 100644 (file)
@@ -163,6 +163,7 @@ static struct platform_device vulcan_max6369 = {
 
 static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = {
        .pin                    = 14,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 static struct platform_device vulcan_w1_gpio = {
index 2e73e9d53f705775246a057bb7cfbdf8219f44a2..d367aa6b47bbf8a11df36fd856e620e81b65d0c1 100644 (file)
@@ -41,16 +41,12 @@ static void __init kirkwood_legacy_clk_init(void)
 
        struct device_node *np = of_find_compatible_node(
                NULL, NULL, "marvell,kirkwood-gating-clock");
-
        struct of_phandle_args clkspec;
+       struct clk *clk;
 
        clkspec.np = np;
        clkspec.args_count = 1;
 
-       clkspec.args[0] = CGC_BIT_GE0;
-       orion_clkdev_add(NULL, "mv643xx_eth_port.0",
-                        of_clk_get_from_provider(&clkspec));
-
        clkspec.args[0] = CGC_BIT_PEX0;
        orion_clkdev_add("0", "pcie",
                         of_clk_get_from_provider(&clkspec));
@@ -59,9 +55,24 @@ static void __init kirkwood_legacy_clk_init(void)
        orion_clkdev_add("1", "pcie",
                         of_clk_get_from_provider(&clkspec));
 
-       clkspec.args[0] = CGC_BIT_GE1;
-       orion_clkdev_add(NULL, "mv643xx_eth_port.1",
+       clkspec.args[0] = CGC_BIT_SDIO;
+       orion_clkdev_add(NULL, "mvsdio",
                         of_clk_get_from_provider(&clkspec));
+
+       /*
+        * The ethernet interfaces forget the MAC address assigned by
+        * u-boot if the clocks are turned off. Until proper DT support
+        * is available we always enable them for now.
+        */
+       clkspec.args[0] = CGC_BIT_GE0;
+       clk = of_clk_get_from_provider(&clkspec);
+       orion_clkdev_add(NULL, "mv643xx_eth_port.0", clk);
+       clk_prepare_enable(clk);
+
+       clkspec.args[0] = CGC_BIT_GE1;
+       clk = of_clk_get_from_provider(&clkspec);
+       orion_clkdev_add(NULL, "mv643xx_eth_port.1", clk);
+       clk_prepare_enable(clk);
 }
 
 static void __init kirkwood_of_clk_init(void)
index d1e2d595e79cafd44b737d49904b07b65042d3fa..f62b68d926f4237bf70911ba43487d27c98d4e97 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <linux/gpio.h>
 
 #include <asm/mach/arch.h>
index 1e243f46a9699341b9e35310632fcd6ed25fa3b4..7777767ee89ae0aecf390cf4396574e76b02517b 100644 (file)
@@ -31,20 +31,8 @@ extern void *smem_item(unsigned id, unsigned *size);
 static ssize_t last_radio_log_read(struct file *file, char __user *buf,
                        size_t len, loff_t *offset)
 {
-       loff_t pos = *offset;
-       ssize_t count;
-
-       if (pos >= radio_log_size)
-               return 0;
-
-       count = min(len, (size_t)(radio_log_size - pos));
-       if (copy_to_user(buf, radio_log_base + pos, count)) {
-               pr_err("%s: copy to user failed\n", __func__);
-               return -EFAULT;
-       }
-
-       *offset += count;
-       return count;
+       return simple_read_from_buffer(buf, len, offset,
+                               radio_log_base, radio_log_size);
 }
 
 static struct file_operations last_radio_log_fops = {
@@ -67,7 +55,8 @@ void msm_init_last_radio_log(struct module *owner)
                return;
        }
 
-       entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL);
+       entry = proc_create("last_radio_log", S_IRUGO, NULL,
+                               &last_radio_log_fops);
        if (!entry) {
                pr_err("%s: could not create proc entry for radio log\n",
                                __func__);
@@ -77,7 +66,6 @@ void msm_init_last_radio_log(struct module *owner)
        pr_err("%s: last radio log is %d bytes long\n", __func__,
                radio_log_size);
        last_radio_log_fops.owner = owner;
-       entry->proc_fops = &last_radio_log_fops;
        entry->size = radio_log_size;
 }
 EXPORT_SYMBOL(msm_init_last_radio_log);
index 8fb23af154b391957da0c03b16ed1d046fca6d2e..e26eeba46598356be29a31fc1e1caeac1c07a9c3 100644 (file)
@@ -100,7 +100,7 @@ static struct irq_domain_ops icoll_irq_domain_ops = {
        .xlate = irq_domain_xlate_onecell,
 };
 
-void __init icoll_of_init(struct device_node *np,
+static void __init icoll_of_init(struct device_node *np,
                          struct device_node *interrupt_parent)
 {
        /*
index 052186713347c5b4ed1a17c503825f4b9894f316..e7b781d3788f2c9a9e896ef75b502f789fd15d64 100644 (file)
@@ -41,8 +41,6 @@ static struct fb_videomode mx23evk_video_modes[] = {
                .lower_margin   = 4,
                .hsync_len      = 1,
                .vsync_len      = 1,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                                 FB_SYNC_DOTCLK_FAILING_ACT,
        },
 };
 
@@ -59,8 +57,6 @@ static struct fb_videomode mx28evk_video_modes[] = {
                .lower_margin   = 10,
                .hsync_len      = 10,
                .vsync_len      = 10,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                                 FB_SYNC_DOTCLK_FAILING_ACT,
        },
 };
 
@@ -77,7 +73,6 @@ static struct fb_videomode m28evk_video_modes[] = {
                .lower_margin   = 45,
                .hsync_len      = 1,
                .vsync_len      = 1,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT,
        },
 };
 
@@ -94,9 +89,7 @@ static struct fb_videomode apx4devkit_video_modes[] = {
                .lower_margin   = 13,
                .hsync_len      = 48,
                .vsync_len      = 3,
-               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
-                                 FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                                 FB_SYNC_DOTCLK_FAILING_ACT,
+               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        },
 };
 
@@ -113,9 +106,7 @@ static struct fb_videomode apf28dev_video_modes[] = {
                .lower_margin = 0x15,
                .hsync_len = 64,
                .vsync_len = 4,
-               .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
-                               FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                               FB_SYNC_DOTCLK_FAILING_ACT,
+               .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        },
 };
 
@@ -132,7 +123,6 @@ static struct fb_videomode cfa10049_video_modes[] = {
                .lower_margin   = 2,
                .hsync_len      = 15,
                .vsync_len      = 15,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT
        },
 };
 
@@ -259,6 +249,8 @@ static void __init imx23_evk_init(void)
        mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes);
        mxsfb_pdata.default_bpp = 32;
        mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
+       mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
+                               MXSFB_SYNC_DOTCLK_FAILING_ACT;
 }
 
 static inline void enable_clk_enet_out(void)
@@ -278,6 +270,8 @@ static void __init imx28_evk_init(void)
        mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes);
        mxsfb_pdata.default_bpp = 32;
        mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
+       mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
+                               MXSFB_SYNC_DOTCLK_FAILING_ACT;
 
        mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
 }
@@ -297,6 +291,7 @@ static void __init m28evk_init(void)
        mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes);
        mxsfb_pdata.default_bpp = 16;
        mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
+       mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
 }
 
 static void __init sc_sps1_init(void)
@@ -322,6 +317,8 @@ static void __init apx4devkit_init(void)
        mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes);
        mxsfb_pdata.default_bpp = 32;
        mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
+       mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
+                               MXSFB_SYNC_DOTCLK_FAILING_ACT;
 }
 
 #define ENET0_MDC__GPIO_4_0    MXS_GPIO_NR(4, 0)
@@ -402,17 +399,18 @@ static void __init cfa10049_init(void)
 {
        enable_clk_enet_out();
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
+
+       mxsfb_pdata.mode_list = cfa10049_video_modes;
+       mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
+       mxsfb_pdata.default_bpp = 32;
+       mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
+       mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
 }
 
 static void __init cfa10037_init(void)
 {
        enable_clk_enet_out();
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
-
-       mxsfb_pdata.mode_list = cfa10049_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
-       mxsfb_pdata.default_bpp = 32;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
 }
 
 static void __init apf28_init(void)
@@ -423,6 +421,8 @@ static void __init apf28_init(void)
        mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes);
        mxsfb_pdata.default_bpp = 16;
        mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT;
+       mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
+                               MXSFB_SYNC_DOTCLK_FAILING_ACT;
 }
 
 static void __init mxs_machine_init(void)
index a4294aa9f301f93c6166c1902fe8577753bc3961..e63b7d87acbda14b1c422113e8198e58c245c999 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <mach/mx23.h>
 #include <mach/mx28.h>
+#include <mach/common.h>
 
 /*
  * Define the MX23 memory map.
index 54add60f94c98c5d8d15c119e996395a13b6fc86..1dff46703753f67e96a3efd2a62a29966aba8b71 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/processor.h>     /* for cpu_relax() */
 
 #include <mach/mxs.h>
+#include <mach/common.h>
 
 #define OCOTP_WORD_OFFSET              0x20
 #define OCOTP_WORD_COUNT               0x20
index 27c2cb7ab8130bc606b82d25c5c457bb8a3959e8..1504b68f4c6672d132628307d97ee0aab534800f 100644 (file)
@@ -168,7 +168,7 @@ void __init netx_init_irq(void)
 {
        int irq;
 
-       vic_init(io_p2v(NETX_PA_VIC), 0, ~0, 0);
+       vic_init(io_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, ~0, 0);
 
        for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
                irq_set_chip_and_handler(irq, &netx_hif_chip,
index 6ce914d54a30f922034074a2e8d487ea27f014d7..8f74a844a775568edd1a22ea423e6f705c3f6e9b 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define NETX_IRQ_VIC_START   0
-#define NETX_IRQ_SOFTINT     0
-#define NETX_IRQ_TIMER0      1
-#define NETX_IRQ_TIMER1      2
-#define NETX_IRQ_TIMER2      3
-#define NETX_IRQ_SYSTIME_NS  4
-#define NETX_IRQ_SYSTIME_S   5
-#define NETX_IRQ_GPIO_15     6
-#define NETX_IRQ_WATCHDOG    7
-#define NETX_IRQ_UART0       8
-#define NETX_IRQ_UART1       9
-#define NETX_IRQ_UART2      10
-#define NETX_IRQ_USB        11
-#define NETX_IRQ_SPI        12
-#define NETX_IRQ_I2C        13
-#define NETX_IRQ_LCD        14
-#define NETX_IRQ_HIF        15
-#define NETX_IRQ_GPIO_0_14  16
-#define NETX_IRQ_XPEC0      17
-#define NETX_IRQ_XPEC1      18
-#define NETX_IRQ_XPEC2      19
-#define NETX_IRQ_XPEC3      20
-#define NETX_IRQ_XPEC(no)   (17 + (no))
-#define NETX_IRQ_MSYNC0     21
-#define NETX_IRQ_MSYNC1     22
-#define NETX_IRQ_MSYNC2     23
-#define NETX_IRQ_MSYNC3     24
-#define NETX_IRQ_IRQ_PHY    25
-#define NETX_IRQ_ISO_AREA   26
+#define NETX_IRQ_VIC_START     64
+#define NETX_IRQ_SOFTINT       (NETX_IRQ_VIC_START + 0)
+#define NETX_IRQ_TIMER0                (NETX_IRQ_VIC_START + 1)
+#define NETX_IRQ_TIMER1                (NETX_IRQ_VIC_START + 2)
+#define NETX_IRQ_TIMER2                (NETX_IRQ_VIC_START + 3)
+#define NETX_IRQ_SYSTIME_NS    (NETX_IRQ_VIC_START + 4)
+#define NETX_IRQ_SYSTIME_S     (NETX_IRQ_VIC_START + 5)
+#define NETX_IRQ_GPIO_15       (NETX_IRQ_VIC_START + 6)
+#define NETX_IRQ_WATCHDOG      (NETX_IRQ_VIC_START + 7)
+#define NETX_IRQ_UART0         (NETX_IRQ_VIC_START + 8)
+#define NETX_IRQ_UART1         (NETX_IRQ_VIC_START + 9)
+#define NETX_IRQ_UART2         (NETX_IRQ_VIC_START + 10)
+#define NETX_IRQ_USB           (NETX_IRQ_VIC_START + 11)
+#define NETX_IRQ_SPI           (NETX_IRQ_VIC_START + 12)
+#define NETX_IRQ_I2C           (NETX_IRQ_VIC_START + 13)
+#define NETX_IRQ_LCD           (NETX_IRQ_VIC_START + 14)
+#define NETX_IRQ_HIF           (NETX_IRQ_VIC_START + 15)
+#define NETX_IRQ_GPIO_0_14     (NETX_IRQ_VIC_START + 16)
+#define NETX_IRQ_XPEC0         (NETX_IRQ_VIC_START + 17)
+#define NETX_IRQ_XPEC1         (NETX_IRQ_VIC_START + 18)
+#define NETX_IRQ_XPEC2         (NETX_IRQ_VIC_START + 19)
+#define NETX_IRQ_XPEC3         (NETX_IRQ_VIC_START + 20)
+#define NETX_IRQ_XPEC(no)      (NETX_IRQ_VIC_START + 17 + (no))
+#define NETX_IRQ_MSYNC0                (NETX_IRQ_VIC_START + 21)
+#define NETX_IRQ_MSYNC1                (NETX_IRQ_VIC_START + 22)
+#define NETX_IRQ_MSYNC2                (NETX_IRQ_VIC_START + 23)
+#define NETX_IRQ_MSYNC3                (NETX_IRQ_VIC_START + 24)
+#define NETX_IRQ_IRQ_PHY       (NETX_IRQ_VIC_START + 25)
+#define NETX_IRQ_ISO_AREA      (NETX_IRQ_VIC_START + 26)
 /* int 27 is reserved */
 /* int 28 is reserved */
-#define NETX_IRQ_TIMER3     29
-#define NETX_IRQ_TIMER4     30
+#define NETX_IRQ_TIMER3                (NETX_IRQ_VIC_START + 29)
+#define NETX_IRQ_TIMER4                (NETX_IRQ_VIC_START + 30)
 /* int 31 is reserved */
 
-#define NETX_IRQS 32
+#define NETX_IRQS              (NETX_IRQ_VIC_START + 32)
 
 /* for multiplexed irqs on gpio 0..14 */
 #define NETX_IRQ_GPIO(x) (NETX_IRQS + (x))
index fb18831e88aa5009fd8d1b546bba39d9397697d3..14f7e99204798dc5cfff4fc14be33c683751a405 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <plat/i2c.h>
 
+#include <mach/irqs.h>
+
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 void omap7xx_map_io(void);
 #else
index 7a7690ab6cb8a8e76c279b4955fe5ada77586801..ff72d297a172550a83faaba10502ff49f495f3c6 100644 (file)
@@ -37,7 +37,8 @@
 
 #include <linux/suspend.h>
 #include <linux/sched.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -422,23 +423,12 @@ void omap1_pm_suspend(void)
                omap_rev());
 }
 
-#if defined(DEBUG) && defined(CONFIG_PROC_FS)
-static int g_read_completed;
-
+#ifdef CONFIG_DEBUG_FS
 /*
  * Read system PM registers for debugging
  */
-static int omap_pm_read_proc(
-       char *page_buffer,
-       char **my_first_byte,
-       off_t virtual_start,
-       int length,
-       int *eof,
-       void *data)
+static int omap_pm_debug_show(struct seq_file *m, void *v)
 {
-       int my_buffer_offset = 0;
-       char * const my_base = page_buffer;
-
        ARM_SAVE(ARM_CKCTL);
        ARM_SAVE(ARM_IDLECT1);
        ARM_SAVE(ARM_IDLECT2);
@@ -479,10 +469,7 @@ static int omap_pm_read_proc(
                MPUI1610_SAVE(EMIFS_CONFIG);
        }
 
-       if (virtual_start == 0) {
-               g_read_completed = 0;
-
-               my_buffer_offset += sprintf(my_base + my_buffer_offset,
+       seq_printf(m,
                   "ARM_CKCTL_REG:            0x%-8x     \n"
                   "ARM_IDLECT1_REG:          0x%-8x     \n"
                   "ARM_IDLECT2_REG:          0x%-8x     \n"
@@ -512,8 +499,8 @@ static int omap_pm_read_proc(
                   ULPD_SHOW(ULPD_STATUS_REQ),
                   ULPD_SHOW(ULPD_POWER_CTRL));
 
-               if (cpu_is_omap7xx()) {
-                       my_buffer_offset += sprintf(my_base + my_buffer_offset,
+       if (cpu_is_omap7xx()) {
+               seq_printf(m,
                           "MPUI7XX_CTRL_REG         0x%-8x \n"
                           "MPUI7XX_DSP_STATUS_REG:      0x%-8x \n"
                           "MPUI7XX_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
@@ -526,8 +513,8 @@ static int omap_pm_read_proc(
                           MPUI7XX_SHOW(MPUI_DSP_API_CONFIG),
                           MPUI7XX_SHOW(EMIFF_SDRAM_CONFIG),
                           MPUI7XX_SHOW(EMIFS_CONFIG));
-               } else if (cpu_is_omap15xx()) {
-                       my_buffer_offset += sprintf(my_base + my_buffer_offset,
+       } else if (cpu_is_omap15xx()) {
+               seq_printf(m,
                           "MPUI1510_CTRL_REG             0x%-8x \n"
                           "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
                           "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
@@ -540,8 +527,8 @@ static int omap_pm_read_proc(
                           MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
                           MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
                           MPUI1510_SHOW(EMIFS_CONFIG));
-               } else if (cpu_is_omap16xx()) {
-                       my_buffer_offset += sprintf(my_base + my_buffer_offset,
+       } else if (cpu_is_omap16xx()) {
+               seq_printf(m,
                           "MPUI1610_CTRL_REG             0x%-8x \n"
                           "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
                           "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
@@ -554,28 +541,37 @@ static int omap_pm_read_proc(
                           MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
                           MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
                           MPUI1610_SHOW(EMIFS_CONFIG));
-               }
-
-               g_read_completed++;
-       } else if (g_read_completed >= 1) {
-                *eof = 1;
-                return 0;
        }
-       g_read_completed++;
 
-       *my_first_byte = page_buffer;
-       return  my_buffer_offset;
+       return 0;
+}
+
+static int omap_pm_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, omap_pm_debug_show,
+                               &inode->i_private);
 }
 
-static void omap_pm_init_proc(void)
+static const struct file_operations omap_pm_debug_fops = {
+       .open           = omap_pm_debug_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static void omap_pm_init_debugfs(void)
 {
-       /* XXX Appears to leak memory */
-       create_proc_read_entry("driver/omap_pm",
-                              S_IWUSR | S_IRUGO, NULL,
-                              omap_pm_read_proc, NULL);
+       struct dentry *d;
+
+       d = debugfs_create_dir("pm_debug", NULL);
+       if (!d)
+               return;
+
+       (void) debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO,
+                                       d, NULL, &omap_pm_debug_fops);
 }
 
-#endif /* DEBUG && CONFIG_PROC_FS */
+#endif /* CONFIG_DEBUG_FS */
 
 /*
  *     omap_pm_prepare - Do preliminary suspend work.
@@ -701,8 +697,8 @@ static int __init omap_pm_init(void)
 
        suspend_set_ops(&omap_pm_ops);
 
-#if defined(DEBUG) && defined(CONFIG_PROC_FS)
-       omap_pm_init_proc();
+#ifdef CONFIG_DEBUG_FS
+       omap_pm_init_debugfs();
 #endif
 
 #ifdef CONFIG_OMAP_32K_TIMER
index 49ac3dfebef90b15d7d1da6e15f06e2807bc9cc1..8111cd9ff3e5201d9c92a66a90a24e30823d7074 100644 (file)
@@ -311,9 +311,6 @@ config MACH_OMAP_ZOOM2
        default y
        select OMAP_PACKAGE_CBB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select SERIAL_8250
-       select SERIAL_8250_CONSOLE
-       select SERIAL_CORE_CONSOLE
 
 config MACH_OMAP_ZOOM3
        bool "OMAP3630 Zoom3 board"
@@ -321,9 +318,6 @@ config MACH_OMAP_ZOOM3
        default y
        select OMAP_PACKAGE_CBP
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select SERIAL_8250
-       select SERIAL_8250_CONSOLE
-       select SERIAL_CORE_CONSOLE
 
 config MACH_CM_T35
        bool "CompuLab CM-T35/CM-T3730 modules"
index 0274ff7a2a2b1c33dcdcf5e6aaac541f15a86c84..e54a480601988402e4b43fe54e4ac287fbed51d4 100644 (file)
@@ -102,6 +102,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
        .init_irq       = omap_intc_of_init,
        .handle_irq     = omap3_intc_handle_irq,
        .init_machine   = omap_generic_init,
+       .init_late      = omap3_init_late,
        .init_time      = omap3_sync32k_timer_init,
        .dt_compat      = omap3_boards_compat,
        .restart        = omap3xxx_restart,
@@ -119,6 +120,7 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
        .init_irq       = omap_intc_of_init,
        .handle_irq     = omap3_intc_handle_irq,
        .init_machine   = omap_generic_init,
+       .init_late      = omap3_init_late,
        .init_time      = omap3_secure_sync32k_timer_init,
        .dt_compat      = omap3_gp_boards_compat,
        .restart        = omap3xxx_restart,
index f7c4616cbb60a7e90f45e1fdc8a686e3cd47857f..d2ea68ea678af901715aa609b4c5f41175641ddf 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
+#include <linux/usb/phy.h>
 #include <linux/usb/musb.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
@@ -98,6 +99,7 @@ static void __init rx51_init(void)
        sdrc_params = nokia_get_sdram_timings();
        omap_sdrc_init(sdrc_params, sdrc_params);
 
+       usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(&musb_board_data);
        rx51_peripherals_init();
 
index 0a6b9c7a63da494f6596f702cc3763fe1a25a3d2..40f4a03d728fc9a7278b722ce809bd57f47c64f4 100644 (file)
@@ -108,7 +108,6 @@ void omap35xx_init_late(void);
 void omap3630_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
-void omap4430_init_late(void);
 int omap2_common_pm_late_init(void);
 
 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
index e4b16c8efe8b05d8296f6431f253f1dd5e0e49be..410e1bac781531e35fb4aa3b58b77a9a2a01111d 100644 (file)
@@ -1122,9 +1122,6 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
        /* TODO: remove, see function definition */
        gpmc_convert_ps_to_ns(gpmc_t);
 
-       /* Now the GPMC is initialised, unreserve the chip-selects */
-       gpmc_cs_map = 0;
-
        return 0;
 }
 
@@ -1383,6 +1380,9 @@ static int gpmc_probe(struct platform_device *pdev)
        if (IS_ERR_VALUE(gpmc_setup_irq()))
                dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
 
+       /* Now the GPMC is initialised, unreserve the chip-selects */
+       gpmc_cs_map = 0;
+
        rc = gpmc_probe_dt(pdev);
        if (rc < 0) {
                clk_disable_unprepare(gpmc_l3_clk);
index 6a217c98db5484a2560d08ff343219557ee75fb9..f82cf878d6af41da87b8bb444acd609105af72a9 100644 (file)
@@ -211,8 +211,6 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
                return -EINVAL;
        }
 
-       pr_err("%s: Could not find signal %s\n", __func__, muxname);
-
        return -ENODEV;
 }
 
@@ -234,6 +232,8 @@ int __init omap_mux_get_by_name(const char *muxname,
                return mux_mode;
        }
 
+       pr_err("%s: Could not find signal %s\n", __func__, muxname);
+
        return -ENODEV;
 }
 
@@ -739,8 +739,9 @@ static void __init omap_mux_dbg_create_entry(
        list_for_each_entry(e, &partition->muxmodes, node) {
                struct omap_mux *m = &e->mux;
 
-               (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir,
-                                         m, &omap_mux_dbg_signal_fops);
+               (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO,
+                                         mux_dbg_dir, m,
+                                         &omap_mux_dbg_signal_fops);
        }
 }
 
index af41888acbd674db746f194475b4ad077150b070..969b0ba7fa703a688a7078250c2118a3e19fe4b3 100644 (file)
@@ -505,6 +505,7 @@ static struct w1_gpio_platform_data w1_gpio_platform_data = {
        .pin                    = GPIO_ONE_WIRE,
        .is_open_drain          = 0,
        .enable_external_pullup = w1_enable_external_pullup,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 struct platform_device raumfeld_w1_gpio_device = {
index fcdf52dbcc49f9bb8525790bc77953db7f452b73..f051f53e35b7bcb3d2ec85af45d2e4d8071fa821 100644 (file)
@@ -214,11 +214,6 @@ static struct clk clk_pcmcdclk2 = {
        .name           = "pcmcdclk",
 };
 
-static struct clk dummy_apb_pclk = {
-       .name           = "apb_pclk",
-       .id             = -1,
-};
-
 static struct clk *clkset_vpllsrc_list[] = {
        [0] = &clk_fin_vpll,
        [1] = &clk_sclk_hdmi27m,
@@ -305,18 +300,6 @@ static struct clk_ops clk_fout_apll_ops = {
 
 static struct clk init_clocks_off[] = {
        {
-               .name           = "dma",
-               .devname        = "dma-pl330.0",
-               .parent         = &clk_hclk_psys.clk,
-               .enable         = s5pv210_clk_ip0_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "dma",
-               .devname        = "dma-pl330.1",
-               .parent         = &clk_hclk_psys.clk,
-               .enable         = s5pv210_clk_ip0_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
                .name           = "rot",
                .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
@@ -573,6 +556,20 @@ static struct clk clk_hsmmc3 = {
        .ctrlbit        = (1<<19),
 };
 
+static struct clk clk_pdma0 = {
+       .name           = "pdma0",
+       .parent         = &clk_hclk_psys.clk,
+       .enable         = s5pv210_clk_ip0_ctrl,
+       .ctrlbit        = (1 << 3),
+};
+
+static struct clk clk_pdma1 = {
+       .name           = "pdma1",
+       .parent         = &clk_hclk_psys.clk,
+       .enable         = s5pv210_clk_ip0_ctrl,
+       .ctrlbit        = (1 << 4),
+};
+
 static struct clk *clkset_uart_list[] = {
        [6] = &clk_mout_mpll.clk,
        [7] = &clk_mout_epll.clk,
@@ -1075,6 +1072,8 @@ static struct clk *clk_cdev[] = {
        &clk_hsmmc1,
        &clk_hsmmc2,
        &clk_hsmmc3,
+       &clk_pdma0,
+       &clk_pdma1,
 };
 
 /* Clock initialisation code */
@@ -1333,6 +1332,8 @@ static struct clk_lookup s5pv210_clk_lookup[] = {
        CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
        CLKDEV_INIT("s5pv210-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
        CLKDEV_INIT("s5pv210-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
+       CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
+       CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
 };
 
 void __init s5pv210_register_clocks(void)
@@ -1361,6 +1362,5 @@ void __init s5pv210_register_clocks(void)
        for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
                s3c_disable_clocks(clk_cdev[ptr], 1);
 
-       s3c24xx_register_clock(&dummy_apb_pclk);
        s3c_pwmclk_init();
 }
index 3a38f7b34b9400e52293456729a0b51c8cd29051..e373de44a8b6f473672e1f10cd1d0a95287182aa 100644 (file)
@@ -845,7 +845,7 @@ static struct fimc_source_info goni_camera_sensors[] = {
                .mux_id         = 0,
                .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
                                  V4L2_MBUS_VSYNC_ACTIVE_LOW,
-               .bus_type       = FIMC_BUS_TYPE_ITU_601,
+               .fimc_bus_type  = FIMC_BUS_TYPE_ITU_601,
                .board_info     = &noon010pc30_board_info,
                .i2c_bus_num    = 0,
                .clk_frequency  = 16000000UL,
index cdcb799e802f0e2e5bcdaeaf42e50107a18b0197..fec49ebc359a56497b1aa7cf819177edd0293728 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/smsc911x.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/sh_hspi.h>
+#include <linux/mmc/host.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/mfd/tmio.h>
 #include <linux/usb/otg.h>
index f9d754f90c5991e6bce11371fa5702f9a8d81c16..d2b3937c4014c1cc737d737d1800f0fb58de36ea 100644 (file)
@@ -14,7 +14,7 @@
 #define pr_fmt(fmt) "SPEAr3xx: " fmt
 
 #include <linux/amba/pl022.h>
-#include <linux/amba/pl08x.h>
+#include <linux/amba/pl080.h>
 #include <linux/io.h>
 #include <plat/pl080.h>
 #include <mach/generic.h>
index 7a0511191f6bb0c3d6bf8c8148db973ce48c973d..a5a4b2bc42ba353e7e0ae94461cf4d8691b2b68a 100644 (file)
@@ -152,9 +152,9 @@ static int is_reserved_asid(u64 asid)
        return 0;
 }
 
-static void new_context(struct mm_struct *mm, unsigned int cpu)
+static u64 new_context(struct mm_struct *mm, unsigned int cpu)
 {
-       u64 asid = mm->context.id;
+       u64 asid = atomic64_read(&mm->context.id);
        u64 generation = atomic64_read(&asid_generation);
 
        if (asid != 0 && is_reserved_asid(asid)) {
@@ -181,13 +181,14 @@ static void new_context(struct mm_struct *mm, unsigned int cpu)
                cpumask_clear(mm_cpumask(mm));
        }
 
-       mm->context.id = asid;
+       return asid;
 }
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
 {
        unsigned long flags;
        unsigned int cpu = smp_processor_id();
+       u64 asid;
 
        if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
                __check_vmalloc_seq(mm);
@@ -198,20 +199,26 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
         */
        cpu_set_reserved_ttbr0();
 
-       if (!((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
-           && atomic64_xchg(&per_cpu(active_asids, cpu), mm->context.id))
+       asid = atomic64_read(&mm->context.id);
+       if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+           && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
                goto switch_mm_fastpath;
 
        raw_spin_lock_irqsave(&cpu_asid_lock, flags);
        /* Check that our ASID belongs to the current generation. */
-       if ((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
-               new_context(mm, cpu);
-
-       atomic64_set(&per_cpu(active_asids, cpu), mm->context.id);
-       cpumask_set_cpu(cpu, mm_cpumask(mm));
+       asid = atomic64_read(&mm->context.id);
+       if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
+               asid = new_context(mm, cpu);
+               atomic64_set(&mm->context.id, asid);
+       }
 
-       if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending))
+       if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
+               local_flush_bp_all();
                local_flush_tlb_all();
+       }
+
+       atomic64_set(&per_cpu(active_asids, cpu), asid);
+       cpumask_set_cpu(cpu, mm_cpumask(mm));
        raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
 
 switch_mm_fastpath:
index c7e3759f16d303c8c989af0a903f768f358c0e4f..e9db6b4bf65a158adf54bd4a799dbc7fee754c36 100644 (file)
@@ -342,6 +342,7 @@ static int __init atomic_pool_init(void)
 {
        struct dma_pool *pool = &atomic_pool;
        pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
+       gfp_t gfp = GFP_KERNEL | GFP_DMA;
        unsigned long nr_pages = pool->size >> PAGE_SHIFT;
        unsigned long *bitmap;
        struct page *page;
@@ -361,8 +362,8 @@ static int __init atomic_pool_init(void)
                ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
                                              atomic_pool_init);
        else
-               ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
-                                          &page, atomic_pool_init);
+               ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page,
+                                          atomic_pool_init);
        if (ptr) {
                int i;
 
index 2dffc010cc41b930f28a07f1dfb2b88045fc3049..5ee505c937d171902839369f3cd98c13b93b11ca 100644 (file)
@@ -141,6 +141,7 @@ void setup_mm_for_reboot(void)
 {
        /* Switch to the identity mapping. */
        cpu_switch_mm(idmap_pgd, &init_mm);
+       local_flush_bp_all();
 
 #ifdef CONFIG_CPU_HAS_ASID
        /*
index 50bf1dafc9eafca49cf80a32ffbf5b529cb0cf40..6ffd78c0f9abeeacf0295dd888a9b537e9249604 100644 (file)
@@ -48,7 +48,7 @@
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
        mmid    r1, r1                          @ get mm->context.id
-       and     r3, r1, #0xff
+       asid    r3, r1
        mov     r3, r3, lsl #(48 - 32)          @ ASID
        mcrr    p15, 0, r0, r3, c2              @ set TTB 0
        isb
index 6828ef6ce80e69c5ce360190917abd75a3028041..a0bd8a755bdfc9616c0515116d37dc41bc16e812 100644 (file)
@@ -576,7 +576,7 @@ load_ind:
                        /* x = ((*(frame + k)) & 0xf) << 2; */
                        ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
                        /* the interpreter should deal with the negative K */
-                       if (k < 0)
+                       if ((int)k < 0)
                                return -1;
                        /* offset in r1: we might have to take the slow path */
                        emit_mov_i(r_off, k, ctx);
index febe3862873ca2238aaaccf3265991c97fe5384c..807ac8e5cbc062ed7e5dbb17869a163e58b15ce7 100644 (file)
@@ -157,9 +157,12 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
                u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
 
                /*
-                * Chip select enabled?
+                * We only take care of entries for which the chip
+                * select is enabled, and that don't have high base
+                * address bits set (devices can only access the first
+                * 32 bits of the memory).
                 */
-               if (size & 1) {
+               if ((size & 1) && !(base & 0xF)) {
                        struct mbus_dram_window *w;
 
                        w = &orion_mbus_dram_info.cs[cs++];
index 739d016eb273faf8a22859856767901ce7e8beef..8a08c31b5e20a950052901f6549dccc09f1d871a 100644 (file)
@@ -10,7 +10,7 @@ choice
 
 config ARCH_SPEAR13XX
        bool "ST SPEAr13xx with Device Tree"
-       select ARCH_HAVE_CPUFREQ
+       select ARCH_HAS_CPUFREQ
        select ARM_GIC
        select CPU_V7
        select GPIO_SPEAR_SPICS
index fd70a68387ebe5d3baeec3b18adf93f5523e4661..9b6d19f74078e0a2118e6fbd1c517e5f4f82203c 100644 (file)
@@ -9,7 +9,6 @@ config ARM64
        select CLONE_BACKWARDS
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IOMAP
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
index 51493430f142d8c1cce428826bb8371d98250916..1a6bfe954d4926de3a8dcee10fdbe0b0698279b3 100644 (file)
@@ -6,17 +6,6 @@ config FRAME_POINTER
        bool
        default y
 
-config DEBUG_ERRORS
-       bool "Verbose kernel error messages"
-       depends on DEBUG_KERNEL
-       help
-         This option controls verbose debugging information which can be
-         printed when the kernel detects an internal error. This debugging
-         information is useful to kernel hackers when tracking down problems,
-         but mostly meaningless to other people. It's safe to say Y unless
-         you are concerned with the code size or don't want to see these
-         messages.
-
 config DEBUG_STACK_USAGE
        bool "Enable stack utilization instrumentation"
        depends on DEBUG_KERNEL
index 9212c7880da742e54e0bebbe3709ef941aa6282d..09bef29f3a09aa02a9441df34773670649cd19c2 100644 (file)
@@ -82,4 +82,3 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_FTRACE is not set
 CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_DEBUG_ERRORS=y
index bde960720892a694bda151a3288c9ecd30c8954d..42e04c87742837e1e204492a3a675dfae29fea4f 100644 (file)
@@ -22,7 +22,7 @@ struct ucontext {
        stack_t           uc_stack;
        sigset_t          uc_sigmask;
        /* glibc uses a 1024-bit sigset_t */
-       __u8              __unused[(1024 - sizeof(sigset_t)) / 8];
+       __u8              __unused[1024 / 8 - sizeof(sigset_t)];
        /* last for future expansion */
        struct sigcontext uc_mcontext;
 };
index cef3925eaf60d3367c610df3db9769d87dfe918d..aa3e948f78857bb1e64278c79e57916abbb2e5a4 100644 (file)
@@ -40,7 +40,9 @@ EXPORT_SYMBOL(__copy_to_user);
 EXPORT_SYMBOL(__clear_user);
 
        /* bitops */
+#ifdef CONFIG_SMP
 EXPORT_SYMBOL(__atomic_hash);
+#endif
 
        /* physical memory */
 EXPORT_SYMBOL(memstart_addr);
index 7f4f3673f2bc0e1ad4f1d0dd5f978cbb1b7f4255..e393174fe859721e7f6538bc377577cb69bb68aa 100644 (file)
@@ -549,7 +549,6 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
                          sigset_t *set, struct pt_regs *regs)
 {
        struct compat_rt_sigframe __user *frame;
-       compat_stack_t stack;
        int err = 0;
 
        frame = compat_get_sigframe(ka, regs, sizeof(*frame));
index 9b89257b2cfdc348746e0145ea428afdfc97c273..c1a868d398bd284f6c7552d31279e24215792f51 100644 (file)
@@ -7,7 +7,7 @@ config AVR32
        select HAVE_OPROFILE
        select HAVE_KPROBES
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_ATOMIC64
        select HARDIRQS_SW_RESEND
index 600494c70e96e2d26728cc2967a31053a470f667..c3f2e0bc644aed0b64e86b7a801424d5cb239b9a 100644 (file)
@@ -33,7 +33,7 @@ config BLACKFIN
        select ARCH_HAVE_CUSTOM_GPIO_H
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_ATOMIC64
index e1d0b24c60708378b894d3a7cabd9a6f2ebef65e..404045dcc5e4bc321c30ddf0eecc1a259e5312ce 100644 (file)
@@ -116,14 +116,12 @@ static const struct seq_operations cplbinfo_sops = {
 
 static int cplbinfo_open(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *pde = PDE(file_inode(file));
        char cplb_type;
-       unsigned int cpu;
+       unsigned int cpu = (unsigned long)PDE_DATA(file_inode(file));
        int ret;
        struct seq_file *m;
        struct cplbinfo_data *cdata;
 
-       cpu = (unsigned int)pde->data;
        cplb_type = cpu & CPLBINFO_DCPLB_FLAG ? 'D' : 'I';
        cpu &= ~CPLBINFO_DCPLB_FLAG;
 
index bb0ac66cf5336aab4e240e32ad44d6fd8ea10679..06dd026533e3b758b68091bc0a8c754b3084f0da 100644 (file)
@@ -43,7 +43,7 @@ config CRIS
        select GENERIC_ATOMIC64
        select HAVE_GENERIC_HARDIRQS
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select GENERIC_IRQ_SHOW
        select GENERIC_IOMAP
index 082f1890bacbea4808917912fa1602e14d4f8e82..ce6f512968a4dd3457c84fd8305351a012611fc1 100644 (file)
@@ -25,6 +25,7 @@
 #include <arch/svinto.h>
 #include <asm/fasttimer.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 
 #define DEBUG_LOG_INCLUDED
@@ -489,197 +490,162 @@ void schedule_usleep(unsigned long us)
 }
 
 #ifdef CONFIG_PROC_FS
-static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-                       ,int *eof, void *data_unused);
-static struct proc_dir_entry *fasttimer_proc_entry;
-#endif /* CONFIG_PROC_FS */
-
-#ifdef CONFIG_PROC_FS
-
 /* This value is very much based on testing */
 #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
 
-static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-                       ,int *eof, void *data_unused)
+static int proc_fasttimer_show(struct seq_file *m, void *v)
 {
-  unsigned long flags;
-  int i = 0;
-  int num_to_show;
+       unsigned long flags;
+       int i = 0;
+       int num_to_show;
        struct fasttime_t tv;
-  struct fast_timer *t, *nextt;
-  static char *bigbuf = NULL;
-  static unsigned long used;
-
-  if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
-  {
-    used = 0;
-       if (buf)
-               buf[0] = '\0';
-    return 0;
-  }
-
-  if (!offset || !used)
-  {
-    do_gettimeofday_fast(&tv);
-
-    used = 0;
-    used += sprintf(bigbuf + used, "Fast timers added:     %i\n",
-                    fast_timers_added);
-    used += sprintf(bigbuf + used, "Fast timers started:   %i\n",
-                    fast_timers_started);
-    used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
-                    fast_timer_ints);
-    used += sprintf(bigbuf + used, "Fast timers expired:   %i\n",
-                    fast_timers_expired);
-    used += sprintf(bigbuf + used, "Fast timers deleted:   %i\n",
-                    fast_timers_deleted);
-    used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
-                    fast_timer_running ? "yes" : "no");
-    used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
-                       (unsigned long)tv.tv_jiff,
-                    (unsigned long)tv.tv_usec);
+       struct fast_timer *t, *nextt;
+
+       do_gettimeofday_fast(&tv);
+
+       seq_printf(m, "Fast timers added:     %i\n", fast_timers_added);
+       seq_printf(m, "Fast timers started:   %i\n", fast_timers_started);
+       seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints);
+       seq_printf(m, "Fast timers expired:   %i\n", fast_timers_expired);
+       seq_printf(m, "Fast timers deleted:   %i\n", fast_timers_deleted);
+       seq_printf(m, "Fast timer running:    %s\n",
+                  fast_timer_running ? "yes" : "no");
+       seq_printf(m, "Current time:          %lu.%06lu\n",
+                  (unsigned long)tv.tv_jiff,
+                  (unsigned long)tv.tv_usec);
 #ifdef FAST_TIMER_SANITY_CHECKS
-    used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
-                    sanity_failed);
+       seq_printf(m, "Sanity failed:         %i\n", sanity_failed);
 #endif
-    used += sprintf(bigbuf + used, "\n");
+       seq_putc(m, '\n');
 
 #ifdef DEBUG_LOG_INCLUDED
-    {
-      int end_i = debug_log_cnt;
-      i = 0;
-
-      if (debug_log_cnt_wrapped)
-      {
-        i = debug_log_cnt;
-      }
-
-      while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
-             used+100 < BIG_BUF_SIZE)
-      {
-        used += sprintf(bigbuf + used, debug_log_string[i],
-                        debug_log_value[i]);
-        i = (i+1) % DEBUG_LOG_MAX;
-      }
-    }
-    used += sprintf(bigbuf + used, "\n");
+       {
+               int end_i = debug_log_cnt;
+               i = 0;
+
+               if (debug_log_cnt_wrapped)
+                       i = debug_log_cnt;
+
+               while (i != end_i || debug_log_cnt_wrapped) {
+                       if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0)
+                               return 0;
+                       i = (i+1) % DEBUG_LOG_MAX;
+               }
+       }
+       seq_putc(m, '\n');
 #endif
 
-    num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
-                   NUM_TIMER_STATS);
-    used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
-    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
-    {
-      int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
+       num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
+                      NUM_TIMER_STATS);
+       seq_printf(m, "Timers started: %i\n", fast_timers_started);
+       for (i = 0; i < num_to_show; i++) {
+               int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
 
 #if 1 //ndef FAST_TIMER_LOG
-      used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i"
-                      "\n",
-                      timer_div_settings[cur],
-                      timer_freq_settings[cur],
-                      timer_delay_settings[cur]
-                      );
+               seq_printf(m, "div: %i freq: %i delay: %i"
+                          "\n",
+                          timer_div_settings[cur],
+                          timer_freq_settings[cur],
+                          timer_delay_settings[cur]);
 #endif
 #ifdef FAST_TIMER_LOG
-      t = &timer_started_log[cur];
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
-                      "\n",
-                      t->name,
-                       (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                       (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
-                      );
+               t = &timer_started_log[cur];
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data) < 0)
+                       return 0;
 #endif
-    }
-    used += sprintf(bigbuf + used, "\n");
+       }
+       seq_putc(m, '\n');
 
 #ifdef FAST_TIMER_LOG
-    num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
-                   NUM_TIMER_STATS);
-    used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
-    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
-    {
-      t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
-                      "\n",
-                      t->name,
-                       (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                       (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
-                      );
-    }
-    used += sprintf(bigbuf + used, "\n");
-
-    num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
-                   NUM_TIMER_STATS);
-    used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
-    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
-    {
-      t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
-                      "\n",
-                      t->name,
-                       (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                       (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
-                      );
-    }
-    used += sprintf(bigbuf + used, "\n");
+       num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
+                      NUM_TIMER_STATS);
+       seq_printf(m, "Timers added: %i\n", fast_timers_added);
+       for (i = 0; i < num_to_show; i++) {
+               t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data) < 0)
+                       return 0;
+       }
+       seq_putc(m, '\n');
+
+       num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
+                      NUM_TIMER_STATS);
+       seq_printf(m, "Timers expired: %i\n", fast_timers_expired);
+       for (i = 0; i < num_to_show; i++) {
+               t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data) < 0)
+                       return 0;
+       }
+       seq_putc(m, '\n');
 #endif
 
-    used += sprintf(bigbuf + used, "Active timers:\n");
-    local_irq_save(flags);
-    t = fast_timer_list;
-    while (t != NULL && (used+100 < BIG_BUF_SIZE))
-    {
-      nextt = t->next;
-      local_irq_restore(flags);
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
+       seq_puts(m, "Active timers:\n");
+       local_irq_save(flags);
+       t = fast_timer_list;
+       while (t) {
+               nextt = t->next;
+               local_irq_restore(flags);
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
 /*                      " func: 0x%08lX" */
-                      "\n",
-                      t->name,
-                       (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                       (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data
 /*                      , t->function */
-                      );
-       local_irq_save(flags);
-      if (t->next != nextt)
-      {
-        printk(KERN_WARNING "timer removed!\n");
-      }
-      t = nextt;
-    }
-    local_irq_restore(flags);
-  }
-
-  if (used - offset < len)
-  {
-    len = used - offset;
-  }
+                              ) < 0)
+                       return 0;
+               local_irq_save(flags);
+               if (t->next != nextt)
+                       printk(KERN_WARNING "timer removed!\n");
+               t = nextt;
+       }
+       local_irq_restore(flags);
 
-  memcpy(buf, bigbuf + offset, len);
-  *start = buf;
-  *eof = 1;
+       return 0;
+}
 
-  return len;
+static int proc_fasttimer_open(struct inode *inode, struct file *file)
+{
+       return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE);
 }
+
+static const struct file_operations proc_fasttimer_fops = {
+       .open           = proc_fasttimer_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif /* PROC_FS */
 
 #ifdef FAST_TIMER_TEST
@@ -857,8 +823,7 @@ int fast_timer_init(void)
     }
 #endif
 #ifdef CONFIG_PROC_FS
-   if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
-     fasttimer_proc_entry->read_proc = proc_fasttimer_read;
+   proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops);
 #endif /* PROC_FS */
     if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0,
                    "fast timer int", NULL))
index ab1551ee43c53c9c9c7aedbfe2e9d85a09600a1d..e43dd70acd96325071b8b333aae616cf0cf6eac3 100644 (file)
@@ -23,6 +23,7 @@
 #include <hwregs/timer_defs.h>
 #include <asm/fasttimer.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 /*
  * timer0 is running at 100MHz and generating jiffies timer ticks
@@ -463,195 +464,161 @@ void schedule_usleep(unsigned long us)
 }
 
 #ifdef CONFIG_PROC_FS
-static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-                       ,int *eof, void *data_unused);
-static struct proc_dir_entry *fasttimer_proc_entry;
-#endif /* CONFIG_PROC_FS */
-
-#ifdef CONFIG_PROC_FS
-
 /* This value is very much based on testing */
 #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
 
-static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-                       ,int *eof, void *data_unused)
+static int proc_fasttimer_show(struct seq_file *m, void *v)
 {
-  unsigned long flags;
-  int i = 0;
-  int num_to_show;
+       unsigned long flags;
+       int i = 0;
+       int num_to_show;
        struct fasttime_t tv;
-  struct fast_timer *t, *nextt;
-  static char *bigbuf = NULL;
-  static unsigned long used;
-
-       if (!bigbuf) {
-               bigbuf = vmalloc(BIG_BUF_SIZE);
-               if (!bigbuf) {
-                       used = 0;
-                       if (buf)
-                               buf[0] = '\0';
-                       return 0;
-               }
-       }
-
-       if (!offset || !used) {
-    do_gettimeofday_fast(&tv);
-
-    used = 0;
-    used += sprintf(bigbuf + used, "Fast timers added:     %i\n",
-                    fast_timers_added);
-    used += sprintf(bigbuf + used, "Fast timers started:   %i\n",
-                    fast_timers_started);
-    used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
-                    fast_timer_ints);
-    used += sprintf(bigbuf + used, "Fast timers expired:   %i\n",
-                    fast_timers_expired);
-    used += sprintf(bigbuf + used, "Fast timers deleted:   %i\n",
-                    fast_timers_deleted);
-    used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
-                    fast_timer_running ? "yes" : "no");
-    used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
-                       (unsigned long)tv.tv_jiff,
-                    (unsigned long)tv.tv_usec);
+       struct fast_timer *t, *nextt;
+
+       do_gettimeofday_fast(&tv);
+
+       seq_printf(m, "Fast timers added:     %i\n", fast_timers_added);
+       seq_printf(m, "Fast timers started:   %i\n", fast_timers_started);
+       seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints);
+       seq_printf(m, "Fast timers expired:   %i\n", fast_timers_expired);
+       seq_printf(m, "Fast timers deleted:   %i\n", fast_timers_deleted);
+       seq_printf(m, "Fast timer running:    %s\n",
+                  fast_timer_running ? "yes" : "no");
+       seq_printf(m, "Current time:          %lu.%06lu\n",
+                  (unsigned long)tv.tv_jiff,
+                  (unsigned long)tv.tv_usec);
 #ifdef FAST_TIMER_SANITY_CHECKS
-    used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
-                    sanity_failed);
+       seq_printf(m, "Sanity failed:         %i\n", sanity_failed);
 #endif
-    used += sprintf(bigbuf + used, "\n");
+       seq_putc(m, '\n');
 
 #ifdef DEBUG_LOG_INCLUDED
-    {
-      int end_i = debug_log_cnt;
-      i = 0;
-
-                       if (debug_log_cnt_wrapped)
-        i = debug_log_cnt;
-
-      while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
-             used+100 < BIG_BUF_SIZE)
-      {
-        used += sprintf(bigbuf + used, debug_log_string[i],
-                        debug_log_value[i]);
-        i = (i+1) % DEBUG_LOG_MAX;
-      }
-    }
-    used += sprintf(bigbuf + used, "\n");
+       {
+               int end_i = debug_log_cnt;
+               i = 0;
+
+               if (debug_log_cnt_wrapped)
+                       i = debug_log_cnt;
+
+               while ((i != end_i || debug_log_cnt_wrapped)) {
+                       if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0)
+                               return 0;
+                       i = (i+1) % DEBUG_LOG_MAX;
+               }
+       }
+       seq_putc(m, '\n');
 #endif
 
-    num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
-                   NUM_TIMER_STATS);
-    used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
-    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
-    {
-      int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
+       num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
+                      NUM_TIMER_STATS);
+       seq_printf(m, "Timers started: %i\n", fast_timers_started);
+       for (i = 0; i < num_to_show; i++) {
+               int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
 
 #if 1 //ndef FAST_TIMER_LOG
-      used += sprintf(bigbuf + used, "div: %i delay: %i"
-                      "\n",
-                      timer_div_settings[cur],
-                      timer_delay_settings[cur]
-                      );
+               seq_printf(m, "div: %i delay: %i"
+                          "\n",
+                          timer_div_settings[cur],
+                          timer_delay_settings[cur]);
 #endif
 #ifdef FAST_TIMER_LOG
-      t = &timer_started_log[cur];
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
-                      "\n",
-                      t->name,
-                               (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                               (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
-                      );
+               t = &timer_started_log[cur];
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data) < 0)
+                       return 0;
 #endif
-    }
-    used += sprintf(bigbuf + used, "\n");
+       }
+       seq_putc(m, '\n');
 
 #ifdef FAST_TIMER_LOG
-    num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
-                   NUM_TIMER_STATS);
-    used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
-    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
-    {
-      t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
-                      "\n",
-                      t->name,
-                               (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                               (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
-                      );
-    }
-    used += sprintf(bigbuf + used, "\n");
-
-    num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
-                   NUM_TIMER_STATS);
-    used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
-    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
-    {
-      t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                      "d: %6li us data: 0x%08lX"
-                      "\n",
-                      t->name,
-                               (unsigned long)t->tv_set.tv_jiff,
-                      (unsigned long)t->tv_set.tv_usec,
-                               (unsigned long)t->tv_expires.tv_jiff,
-                      (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
-                      );
-    }
-    used += sprintf(bigbuf + used, "\n");
+       num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
+                      NUM_TIMER_STATS);
+       seq_printf(m, "Timers added: %i\n", fast_timers_added);
+       for (i = 0; i < num_to_show; i++) {
+               t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data) < 0)
+                       return 0;
+       }
+       seq_putc(m, '\n');
+
+       num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
+                      NUM_TIMER_STATS);
+       seq_printf(m, "Timers expired: %i\n", fast_timers_expired);
+       for (i = 0; i < num_to_show; i++){
+               t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data) < 0)
+                       return 0;
+       }
+       seq_putc(m, '\n');
 #endif
 
-    used += sprintf(bigbuf + used, "Active timers:\n");
-    local_irq_save(flags);
-    t = fast_timer_list;
-    while (t != NULL && (used+100 < BIG_BUF_SIZE))
-    {
-      nextt = t->next;
-      local_irq_restore(flags);
-      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
-                       "d: %6li us data: 0x%08lX"
+       seq_puts(m, "Active timers:\n");
+       local_irq_save(flags);
+       t = fast_timer_list;
+       while (t != NULL){
+               nextt = t->next;
+               local_irq_restore(flags);
+               if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                              "d: %6li us data: 0x%08lX"
 /*                     " func: 0x%08lX" */
-                       "\n",
-                       t->name,
-                       (unsigned long)t->tv_set.tv_jiff,
-                       (unsigned long)t->tv_set.tv_usec,
-                       (unsigned long)t->tv_expires.tv_jiff,
-                       (unsigned long)t->tv_expires.tv_usec,
-                      t->delay_us,
-                      t->data
+                              "\n",
+                              t->name,
+                              (unsigned long)t->tv_set.tv_jiff,
+                              (unsigned long)t->tv_set.tv_usec,
+                              (unsigned long)t->tv_expires.tv_jiff,
+                              (unsigned long)t->tv_expires.tv_usec,
+                              t->delay_us,
+                              t->data
 /*                      , t->function */
-                      );
-                       local_irq_save(flags);
-      if (t->next != nextt)
-      {
-        printk("timer removed!\n");
-      }
-      t = nextt;
-    }
-    local_irq_restore(flags);
-  }
+                              ) < 0)
+                       return 0;
+               local_irq_save(flags);
+               if (t->next != nextt)
+                       printk("timer removed!\n");
+               t = nextt;
+       }
+       local_irq_restore(flags);
+       return 0;
+}
 
-  if (used - offset < len)
-  {
-    len = used - offset;
-  }
+static int proc_fasttimer_open(struct inode *inode, struct file *file)
+{
+       return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE);
+}
 
-  memcpy(buf, bigbuf + offset, len);
-  *start = buf;
-  *eof = 1;
+static const struct file_operations proc_fasttimer_fops = {
+       .open           = proc_fasttimer_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-  return len;
-}
 #endif /* PROC_FS */
 
 #ifdef FAST_TIMER_TEST
@@ -816,9 +783,7 @@ int fast_timer_init(void)
     printk("fast_timer_init()\n");
 
 #ifdef CONFIG_PROC_FS
-    fasttimer_proc_entry = create_proc_entry("fasttimer", 0, 0);
-    if (fasttimer_proc_entry)
-      fasttimer_proc_entry->read_proc = proc_fasttimer_read;
+    proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops);
 #endif /* PROC_FS */
                if (request_irq(TIMER0_INTR_VECT, timer_trig_interrupt,
                                IRQF_SHARED | IRQF_DISABLED,
index 12369b194c7b2e98a9fa00b688882809f3000c36..2ce731f9aa4d522abfc7d2fbcfff33483a2b2154 100644 (file)
@@ -6,7 +6,7 @@ config FRV
        select HAVE_PERF_EVENTS
        select HAVE_UID16
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_SHOW
        select HAVE_DEBUG_BUGVERBOSE
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
index ae8551eb3736ae201bd2decbf1fc34feb23f9c75..79250de1b12a434f7b0d945cb6b4b42559a9d101 100644 (file)
@@ -5,7 +5,7 @@ config H8300
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_ATOMIC64
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
index 6a25dd5530e70cd48477f18b7487415b818648f3..b02c752cd3265996cb1bf878174cf3d8f5138255 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/stddef.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fs.h>
@@ -138,30 +139,34 @@ static char *port_status(int portno)
        return result;
 }
 
-static int gpio_proc_read(char *buf, char **start, off_t offset, 
-                          int len, int *unused_i, void *unused_v)
+static int gpio_proc_show(struct seq_file *m, void *v)
 {
-       int c,outlen;
        static const char port_name[]="123456789ABCDEFGH";
-       outlen = 0;
+       int c;
+
        for (c = 0; c < MAX_PORT; c++) {
                if (ddrs[c] == NULL)
-                       continue ;
-               len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c));
-               buf += len;
-               outlen += len;
+                       continue;
+               seq_printf(m, "P%c: %s\n", port_name[c], port_status(c));
        }
-       return outlen;
+       return 0;
 }
 
-static __init int register_proc(void)
+static int gpio_proc_open(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *proc_gpio;
+       return single_open(file, gpio_proc_show, PDE_DATA(inode));
+}
 
-       proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
-       if (proc_gpio) 
-               proc_gpio->read_proc = gpio_proc_read;
-       return proc_gpio != NULL;
+static const struct file_operations gpio_proc_fops = {
+       .open           = gpio_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static __init int register_proc(void)
+{
+       return proc_create("gpio", S_IRUGO, NULL, &gpio_proc_fops) != NULL;
 }
 
 __initcall(register_proc);
index 33f3fdc0b214e93350b95d8ec8fcc935df2b56d9..9a02f71c6b1f7cb5e8339e55f77bb82ad9b8d8d3 100644 (file)
@@ -26,7 +26,7 @@ config IA64
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_VIRT_CPU_ACCOUNTING
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_DISCARD_MEMBLOCK
        select GENERIC_IRQ_PROBE
        select GENERIC_PENDING_IRQ if SMP
index 77597e5ea60aca9429f29c26ec7973bf89a19683..b17129e3b7c83a0d07587c506ef8ada1c009e08f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/efi.h>
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL");
 
 #define PALINFO_VERSION "0.5"
 
-typedef int (*palinfo_func_t)(char*);
+typedef int (*palinfo_func_t)(struct seq_file *);
 
 typedef struct {
        const char              *name;          /* name of the proc entry */
@@ -54,7 +55,7 @@ typedef struct {
  *  A bunch of string array to get pretty printing
  */
 
-static char *cache_types[] = {
+static const char *cache_types[] = {
        "",                     /* not used */
        "Instruction",
        "Data",
@@ -122,19 +123,16 @@ static const char *mem_attrib[]={
  *     - a pointer to the end of the buffer
  *
  */
-static char *
-bitvector_process(char *p, u64 vector)
+static void bitvector_process(struct seq_file *m, u64 vector)
 {
        int i,j;
-       const char *units[]={ "", "K", "M", "G", "T" };
+       static const char *units[]={ "", "K", "M", "G", "T" };
 
        for (i=0, j=0; i < 64; i++ , j=i/10) {
-               if (vector & 0x1) {
-                       p += sprintf(p, "%d%s ", 1 << (i-j*10), units[j]);
-               }
+               if (vector & 0x1)
+                       seq_printf(m, "%d%s ", 1 << (i-j*10), units[j]);
                vector >>= 1;
        }
-       return p;
 }
 
 /*
@@ -149,8 +147,7 @@ bitvector_process(char *p, u64 vector)
  *     - a pointer to the end of the buffer
  *
  */
-static char *
-bitregister_process(char *p, u64 *reg_info, int max)
+static void bitregister_process(struct seq_file *m, u64 *reg_info, int max)
 {
        int i, begin, skip = 0;
        u64 value = reg_info[0];
@@ -163,9 +160,9 @@ bitregister_process(char *p, u64 *reg_info, int max)
 
                if ((value & 0x1) == 0 && skip == 0) {
                        if (begin  <= i - 2)
-                               p += sprintf(p, "%d-%d ", begin, i-1);
+                               seq_printf(m, "%d-%d ", begin, i-1);
                        else
-                               p += sprintf(p, "%d ", i-1);
+                               seq_printf(m, "%d ", i-1);
                        skip  = 1;
                        begin = -1;
                } else if ((value & 0x1) && skip == 1) {
@@ -176,19 +173,15 @@ bitregister_process(char *p, u64 *reg_info, int max)
        }
        if (begin > -1) {
                if (begin < 127)
-                       p += sprintf(p, "%d-127", begin);
+                       seq_printf(m, "%d-127", begin);
                else
-                       p += sprintf(p, "127");
+                       seq_puts(m, "127");
        }
-
-       return p;
 }
 
-static int
-power_info(char *page)
+static int power_info(struct seq_file *m)
 {
        s64 status;
-       char *p = page;
        u64 halt_info_buffer[8];
        pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer;
        int i;
@@ -198,26 +191,25 @@ power_info(char *page)
 
        for (i=0; i < 8 ; i++ ) {
                if (halt_info[i].pal_power_mgmt_info_s.im == 1) {
-                       p += sprintf(p, "Power level %d:\n"
-                                    "\tentry_latency       : %d cycles\n"
-                                    "\texit_latency        : %d cycles\n"
-                                    "\tpower consumption   : %d mW\n"
-                                    "\tCache+TLB coherency : %s\n", i,
-                                    halt_info[i].pal_power_mgmt_info_s.entry_latency,
-                                    halt_info[i].pal_power_mgmt_info_s.exit_latency,
-                                    halt_info[i].pal_power_mgmt_info_s.power_consumption,
-                                    halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No");
+                       seq_printf(m,
+                                  "Power level %d:\n"
+                                  "\tentry_latency       : %d cycles\n"
+                                  "\texit_latency        : %d cycles\n"
+                                  "\tpower consumption   : %d mW\n"
+                                  "\tCache+TLB coherency : %s\n", i,
+                                  halt_info[i].pal_power_mgmt_info_s.entry_latency,
+                                  halt_info[i].pal_power_mgmt_info_s.exit_latency,
+                                  halt_info[i].pal_power_mgmt_info_s.power_consumption,
+                                  halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No");
                } else {
-                       p += sprintf(p,"Power level %d: not implemented\n",i);
+                       seq_printf(m,"Power level %d: not implemented\n", i);
                }
        }
-       return p - page;
+       return 0;
 }
 
-static int
-cache_info(char *page)
+static int cache_info(struct seq_file *m)
 {
-       char *p = page;
        unsigned long i, levels, unique_caches;
        pal_cache_config_info_t cci;
        int j, k;
@@ -228,73 +220,74 @@ cache_info(char *page)
                return 0;
        }
 
-       p += sprintf(p, "Cache levels  : %ld\nUnique caches : %ld\n\n", levels, unique_caches);
+       seq_printf(m, "Cache levels  : %ld\nUnique caches : %ld\n\n",
+                  levels, unique_caches);
 
        for (i=0; i < levels; i++) {
-
                for (j=2; j >0 ; j--) {
-
                        /* even without unification some level may not be present */
-                       if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) {
+                       if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0)
                                continue;
-                       }
-                       p += sprintf(p,
-                                    "%s Cache level %lu:\n"
-                                    "\tSize           : %u bytes\n"
-                                    "\tAttributes     : ",
-                                    cache_types[j+cci.pcci_unified], i+1,
-                                    cci.pcci_cache_size);
-
-                       if (cci.pcci_unified) p += sprintf(p, "Unified ");
-
-                       p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]);
-
-                       p += sprintf(p,
-                                    "\tAssociativity  : %d\n"
-                                    "\tLine size      : %d bytes\n"
-                                    "\tStride         : %d bytes\n",
-                                    cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride);
+
+                       seq_printf(m,
+                                  "%s Cache level %lu:\n"
+                                  "\tSize           : %u bytes\n"
+                                  "\tAttributes     : ",
+                                  cache_types[j+cci.pcci_unified], i+1,
+                                  cci.pcci_cache_size);
+
+                       if (cci.pcci_unified)
+                               seq_puts(m, "Unified ");
+
+                       seq_printf(m, "%s\n", cache_mattrib[cci.pcci_cache_attr]);
+
+                       seq_printf(m,
+                                  "\tAssociativity  : %d\n"
+                                  "\tLine size      : %d bytes\n"
+                                  "\tStride         : %d bytes\n",
+                                  cci.pcci_assoc,
+                                  1<<cci.pcci_line_size,
+                                  1<<cci.pcci_stride);
                        if (j == 1)
-                               p += sprintf(p, "\tStore latency  : N/A\n");
+                               seq_puts(m, "\tStore latency  : N/A\n");
                        else
-                               p += sprintf(p, "\tStore latency  : %d cycle(s)\n",
-                                               cci.pcci_st_latency);
+                               seq_printf(m, "\tStore latency  : %d cycle(s)\n",
+                                          cci.pcci_st_latency);
 
-                       p += sprintf(p,
-                                    "\tLoad latency   : %d cycle(s)\n"
-                                    "\tStore hints    : ", cci.pcci_ld_latency);
+                       seq_printf(m,
+                                  "\tLoad latency   : %d cycle(s)\n"
+                                  "\tStore hints    : ", cci.pcci_ld_latency);
 
                        for(k=0; k < 8; k++ ) {
                                if ( cci.pcci_st_hints & 0x1)
-                                       p += sprintf(p, "[%s]", cache_st_hints[k]);
+                                       seq_printf(m, "[%s]", cache_st_hints[k]);
                                cci.pcci_st_hints >>=1;
                        }
-                       p += sprintf(p, "\n\tLoad hints     : ");
+                       seq_puts(m, "\n\tLoad hints     : ");
 
                        for(k=0; k < 8; k++ ) {
                                if (cci.pcci_ld_hints & 0x1)
-                                       p += sprintf(p, "[%s]", cache_ld_hints[k]);
+                                       seq_printf(m, "[%s]", cache_ld_hints[k]);
                                cci.pcci_ld_hints >>=1;
                        }
-                       p += sprintf(p,
-                                    "\n\tAlias boundary : %d byte(s)\n"
-                                    "\tTag LSB        : %d\n"
-                                    "\tTag MSB        : %d\n",
-                                    1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb,
-                                    cci.pcci_tag_msb);
+                       seq_printf(m,
+                                  "\n\tAlias boundary : %d byte(s)\n"
+                                  "\tTag LSB        : %d\n"
+                                  "\tTag MSB        : %d\n",
+                                  1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb,
+                                  cci.pcci_tag_msb);
 
                        /* when unified, data(j=2) is enough */
-                       if (cci.pcci_unified) break;
+                       if (cci.pcci_unified)
+                               break;
                }
        }
-       return p - page;
+       return 0;
 }
 
 
-static int
-vm_info(char *page)
+static int vm_info(struct seq_file *m)
 {
-       char *p = page;
        u64 tr_pages =0, vw_pages=0, tc_pages;
        u64 attrib;
        pal_vm_info_1_u_t vm_info_1;
@@ -309,7 +302,7 @@ vm_info(char *page)
                printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
        } else {
 
-               p += sprintf(p,
+               seq_printf(m,
                     "Physical Address Space         : %d bits\n"
                     "Virtual Address Space          : %d bits\n"
                     "Protection Key Registers(PKR)  : %d\n"
@@ -324,49 +317,49 @@ vm_info(char *page)
                     vm_info_1.pal_vm_info_1_s.hash_tag_id,
                     vm_info_2.pal_vm_info_2_s.rid_size);
                if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES)
-                       p += sprintf(p, "unlimited\n");
+                       seq_puts(m, "unlimited\n");
                else
-                       p += sprintf(p, "%d\n",
+                       seq_printf(m, "%d\n",
                                vm_info_2.pal_vm_info_2_s.max_purges ?
                                vm_info_2.pal_vm_info_2_s.max_purges : 1);
        }
 
        if (ia64_pal_mem_attrib(&attrib) == 0) {
-               p += sprintf(p, "Supported memory attributes    : ");
+               seq_puts(m, "Supported memory attributes    : ");
                sep = "";
                for (i = 0; i < 8; i++) {
                        if (attrib & (1 << i)) {
-                               p += sprintf(p, "%s%s", sep, mem_attrib[i]);
+                               seq_printf(m, "%s%s", sep, mem_attrib[i]);
                                sep = ", ";
                        }
                }
-               p += sprintf(p, "\n");
+               seq_putc(m, '\n');
        }
 
        if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
                printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status);
        } else {
 
-               p += sprintf(p,
-                            "\nTLB walker                     : %simplemented\n"
-                            "Number of DTR                  : %d\n"
-                            "Number of ITR                  : %d\n"
-                            "TLB insertable page sizes      : ",
-                            vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
-                            vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
-                            vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
-
+               seq_printf(m,
+                          "\nTLB walker                     : %simplemented\n"
+                          "Number of DTR                  : %d\n"
+                          "Number of ITR                  : %d\n"
+                          "TLB insertable page sizes      : ",
+                          vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
+                          vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
+                          vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
 
-               p = bitvector_process(p, tr_pages);
+               bitvector_process(m, tr_pages);
 
-               p += sprintf(p, "\nTLB purgeable page sizes       : ");
+               seq_puts(m, "\nTLB purgeable page sizes       : ");
 
-               p = bitvector_process(p, vw_pages);
+               bitvector_process(m, vw_pages);
        }
-       if ((status=ia64_get_ptce(&ptce)) != 0) {
+
+       if ((status = ia64_get_ptce(&ptce)) != 0) {
                printk(KERN_ERR "ia64_get_ptce=%ld\n", status);
        } else {
-               p += sprintf(p,
+               seq_printf(m,
                     "\nPurge base address             : 0x%016lx\n"
                     "Purge outer loop count         : %d\n"
                     "Purge inner loop count         : %d\n"
@@ -375,7 +368,7 @@ vm_info(char *page)
                     ptce.base, ptce.count[0], ptce.count[1],
                     ptce.stride[0], ptce.stride[1]);
 
-               p += sprintf(p,
+               seq_printf(m,
                     "TC Levels                      : %d\n"
                     "Unique TC(s)                   : %d\n",
                     vm_info_1.pal_vm_info_1_s.num_tc_levels,
@@ -385,13 +378,11 @@ vm_info(char *page)
                        for (j=2; j>0 ; j--) {
                                tc_pages = 0; /* just in case */
 
-
                                /* even without unification, some levels may not be present */
-                               if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) {
+                               if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0)
                                        continue;
-                               }
 
-                               p += sprintf(p,
+                               seq_printf(m,
                                     "\n%s Translation Cache Level %d:\n"
                                     "\tHash sets           : %d\n"
                                     "\tAssociativity       : %d\n"
@@ -403,15 +394,15 @@ vm_info(char *page)
                                     tc_info.tc_num_entries);
 
                                if (tc_info.tc_pf)
-                                       p += sprintf(p, "PreferredPageSizeOptimized ");
+                                       seq_puts(m, "PreferredPageSizeOptimized ");
                                if (tc_info.tc_unified)
-                                       p += sprintf(p, "Unified ");
+                                       seq_puts(m, "Unified ");
                                if (tc_info.tc_reduce_tr)
-                                       p += sprintf(p, "TCReduction");
+                                       seq_puts(m, "TCReduction");
 
-                               p += sprintf(p, "\n\tSupported page sizes: ");
+                               seq_puts(m, "\n\tSupported page sizes: ");
 
-                               p = bitvector_process(p, tc_pages);
+                               bitvector_process(m, tc_pages);
 
                                /* when unified date (j=2) is enough */
                                if (tc_info.tc_unified)
@@ -419,16 +410,14 @@ vm_info(char *page)
                        }
                }
        }
-       p += sprintf(p, "\n");
 
-       return p - page;
+       seq_putc(m, '\n');
+       return 0;
 }
 
 
-static int
-register_info(char *page)
+static int register_info(struct seq_file *m)
 {
-       char *p = page;
        u64 reg_info[2];
        u64 info;
        unsigned long phys_stacked;
@@ -442,35 +431,31 @@ register_info(char *page)
        };
 
        for(info=0; info < 4; info++) {
-
-               if (ia64_pal_register_info(info, &reg_info[0], &reg_info[1]) != 0) return 0;
-
-               p += sprintf(p, "%-32s : ", info_type[info]);
-
-               p = bitregister_process(p, reg_info, 128);
-
-               p += sprintf(p, "\n");
+               if (ia64_pal_register_info(info, &reg_info[0], &reg_info[1]) != 0)
+                       return 0;
+               seq_printf(m, "%-32s : ", info_type[info]);
+               bitregister_process(m, reg_info, 128);
+               seq_putc(m, '\n');
        }
 
-       if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) {
+       if (ia64_pal_rse_info(&phys_stacked, &hints) == 0)
+               seq_printf(m,
+                          "RSE stacked physical registers   : %ld\n"
+                          "RSE load/store hints             : %ld (%s)\n",
+                          phys_stacked, hints.ph_data,
+                          hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)");
 
-       p += sprintf(p,
-                    "RSE stacked physical registers   : %ld\n"
-                    "RSE load/store hints             : %ld (%s)\n",
-                    phys_stacked, hints.ph_data,
-                    hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)");
-       }
        if (ia64_pal_debug_info(&iregs, &dregs))
                return 0;
 
-       p += sprintf(p,
-                    "Instruction debug register pairs : %ld\n"
-                    "Data debug register pairs        : %ld\n", iregs, dregs);
+       seq_printf(m,
+                  "Instruction debug register pairs : %ld\n"
+                  "Data debug register pairs        : %ld\n", iregs, dregs);
 
-       return p - page;
+       return 0;
 }
 
-static char *proc_features_0[]={               /* Feature set 0 */
+static const char *const proc_features_0[]={           /* Feature set 0 */
        NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
        NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,
        NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
@@ -502,7 +487,7 @@ static char *proc_features_0[]={            /* Feature set 0 */
        "Enable BERR promotion"
 };
 
-static char *proc_features_16[]={              /* Feature set 16 */
+static const char *const proc_features_16[]={          /* Feature set 16 */
        "Disable ETM",
        "Enable ETM",
        "Enable MCA on half-way timer",
@@ -522,7 +507,7 @@ static char *proc_features_16[]={           /* Feature set 16 */
        NULL, NULL, NULL, NULL, NULL
 };
 
-static char **proc_features[]={
+static const char *const *const proc_features[]={
        proc_features_0,
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        NULL, NULL, NULL, NULL,
@@ -530,11 +515,10 @@ static char **proc_features[]={
        NULL, NULL, NULL, NULL,
 };
 
-static char * feature_set_info(char *page, u64 avail, u64 status, u64 control,
-                                                       unsigned long set)
+static void feature_set_info(struct seq_file *m, u64 avail, u64 status, u64 control,
+                            unsigned long set)
 {
-       char *p = page;
-       char **vf, **v;
+       const char *const *vf, *const *v;
        int i;
 
        vf = v = proc_features[set];
@@ -547,13 +531,13 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control,
                if (vf)
                        v = vf + i;
                if ( v && *v ) {
-                       p += sprintf(p, "%-40s : %s %s\n", *v,
+                       seq_printf(m, "%-40s : %s %s\n", *v,
                                avail & 0x1 ? (status & 0x1 ?
-                                               "On " : "Off"): "",
+                                             "On " : "Off"): "",
                                avail & 0x1 ? (control & 0x1 ?
                                                "Ctrl" : "NoCtrl"): "");
                } else {
-                       p += sprintf(p, "Feature set %2ld bit %2d\t\t\t"
+                       seq_printf(m, "Feature set %2ld bit %2d\t\t\t"
                                        " : %s %s\n",
                                set, i,
                                avail & 0x1 ? (status & 0x1 ?
@@ -562,36 +546,32 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control,
                                                "Ctrl" : "NoCtrl"): "");
                }
        }
-       return p;
 }
 
-static int
-processor_info(char *page)
+static int processor_info(struct seq_file *m)
 {
-       char *p = page;
        u64 avail=1, status=1, control=1, feature_set=0;
        s64 ret;
 
        do {
                ret = ia64_pal_proc_get_features(&avail, &status, &control,
                                                feature_set);
-               if (ret < 0) {
-                       return p - page;
-               }
+               if (ret < 0)
+                       return 0;
+
                if (ret == 1) {
                        feature_set++;
                        continue;
                }
 
-               p = feature_set_info(p, avail, status, control, feature_set);
-
+               feature_set_info(m, avail, status, control, feature_set);
                feature_set++;
        } while(1);
 
-       return p - page;
+       return 0;
 }
 
-static const char *bus_features[]={
+static const char *const bus_features[]={
        NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
        NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,
        NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
@@ -617,125 +597,118 @@ static const char *bus_features[]={
 };
 
 
-static int
-bus_info(char *page)
+static int bus_info(struct seq_file *m)
 {
-       char *p = page;
-       const char **v = bus_features;
+       const char *const *v = bus_features;
        pal_bus_features_u_t av, st, ct;
        u64 avail, status, control;
        int i;
        s64 ret;
 
-       if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) return 0;
+       if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0)
+               return 0;
 
        avail   = av.pal_bus_features_val;
        status  = st.pal_bus_features_val;
        control = ct.pal_bus_features_val;
 
        for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) {
-               if ( ! *v ) continue;
-               p += sprintf(p, "%-48s : %s%s %s\n", *v,
-                               avail & 0x1 ? "" : "NotImpl",
-                               avail & 0x1 ? (status  & 0x1 ? "On" : "Off"): "",
-                               avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
+               if ( ! *v )
+                       continue;
+               seq_printf(m, "%-48s : %s%s %s\n", *v,
+                          avail & 0x1 ? "" : "NotImpl",
+                          avail & 0x1 ? (status  & 0x1 ? "On" : "Off"): "",
+                          avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
        }
-       return p - page;
+       return 0;
 }
 
-static int
-version_info(char *page)
+static int version_info(struct seq_file *m)
 {
        pal_version_u_t min_ver, cur_ver;
-       char *p = page;
 
        if (ia64_pal_version(&min_ver, &cur_ver) != 0)
                return 0;
 
-       p += sprintf(p,
-                    "PAL_vendor : 0x%02x (min=0x%02x)\n"
-                    "PAL_A      : %02x.%02x (min=%02x.%02x)\n"
-                    "PAL_B      : %02x.%02x (min=%02x.%02x)\n",
-                    cur_ver.pal_version_s.pv_pal_vendor,
-                    min_ver.pal_version_s.pv_pal_vendor,
-                    cur_ver.pal_version_s.pv_pal_a_model,
-                    cur_ver.pal_version_s.pv_pal_a_rev,
-                    min_ver.pal_version_s.pv_pal_a_model,
-                    min_ver.pal_version_s.pv_pal_a_rev,
-                    cur_ver.pal_version_s.pv_pal_b_model,
-                    cur_ver.pal_version_s.pv_pal_b_rev,
-                    min_ver.pal_version_s.pv_pal_b_model,
-                    min_ver.pal_version_s.pv_pal_b_rev);
-       return p - page;
+       seq_printf(m,
+                  "PAL_vendor : 0x%02x (min=0x%02x)\n"
+                  "PAL_A      : %02x.%02x (min=%02x.%02x)\n"
+                  "PAL_B      : %02x.%02x (min=%02x.%02x)\n",
+                  cur_ver.pal_version_s.pv_pal_vendor,
+                  min_ver.pal_version_s.pv_pal_vendor,
+                  cur_ver.pal_version_s.pv_pal_a_model,
+                  cur_ver.pal_version_s.pv_pal_a_rev,
+                  min_ver.pal_version_s.pv_pal_a_model,
+                  min_ver.pal_version_s.pv_pal_a_rev,
+                  cur_ver.pal_version_s.pv_pal_b_model,
+                  cur_ver.pal_version_s.pv_pal_b_rev,
+                  min_ver.pal_version_s.pv_pal_b_model,
+                  min_ver.pal_version_s.pv_pal_b_rev);
+       return 0;
 }
 
-static int
-perfmon_info(char *page)
+static int perfmon_info(struct seq_file *m)
 {
-       char *p = page;
        u64 pm_buffer[16];
        pal_perf_mon_info_u_t pm_info;
 
-       if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0;
-
-       p += sprintf(p,
-                    "PMC/PMD pairs                 : %d\n"
-                    "Counter width                 : %d bits\n"
-                    "Cycle event number            : %d\n"
-                    "Retired event number          : %d\n"
-                    "Implemented PMC               : ",
-                    pm_info.pal_perf_mon_info_s.generic, pm_info.pal_perf_mon_info_s.width,
-                    pm_info.pal_perf_mon_info_s.cycles, pm_info.pal_perf_mon_info_s.retired);
+       if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0)
+               return 0;
 
-       p = bitregister_process(p, pm_buffer, 256);
-       p += sprintf(p, "\nImplemented PMD               : ");
-       p = bitregister_process(p, pm_buffer+4, 256);
-       p += sprintf(p, "\nCycles count capable          : ");
-       p = bitregister_process(p, pm_buffer+8, 256);
-       p += sprintf(p, "\nRetired bundles count capable : ");
+       seq_printf(m,
+                  "PMC/PMD pairs                 : %d\n"
+                  "Counter width                 : %d bits\n"
+                  "Cycle event number            : %d\n"
+                  "Retired event number          : %d\n"
+                  "Implemented PMC               : ",
+                  pm_info.pal_perf_mon_info_s.generic,
+                  pm_info.pal_perf_mon_info_s.width,
+                  pm_info.pal_perf_mon_info_s.cycles,
+                  pm_info.pal_perf_mon_info_s.retired);
+
+       bitregister_process(m, pm_buffer, 256);
+       seq_puts(m, "\nImplemented PMD               : ");
+       bitregister_process(m, pm_buffer+4, 256);
+       seq_puts(m, "\nCycles count capable          : ");
+       bitregister_process(m, pm_buffer+8, 256);
+       seq_puts(m, "\nRetired bundles count capable : ");
 
 #ifdef CONFIG_ITANIUM
        /*
         * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES
         * which is wrong, both PMC4 and PMD5 support it.
         */
-       if (pm_buffer[12] == 0x10) pm_buffer[12]=0x30;
+       if (pm_buffer[12] == 0x10)
+               pm_buffer[12]=0x30;
 #endif
 
-       p = bitregister_process(p, pm_buffer+12, 256);
-
-       p += sprintf(p, "\n");
-
-       return p - page;
+       bitregister_process(m, pm_buffer+12, 256);
+       seq_putc(m, '\n');
+       return 0;
 }
 
-static int
-frequency_info(char *page)
+static int frequency_info(struct seq_file *m)
 {
-       char *p = page;
        struct pal_freq_ratio proc, itc, bus;
        unsigned long base;
 
        if (ia64_pal_freq_base(&base) == -1)
-               p += sprintf(p, "Output clock            : not implemented\n");
+               seq_puts(m, "Output clock            : not implemented\n");
        else
-               p += sprintf(p, "Output clock            : %ld ticks/s\n", base);
+               seq_printf(m, "Output clock            : %ld ticks/s\n", base);
 
        if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0;
 
-       p += sprintf(p,
+       seq_printf(m,
                     "Processor/Clock ratio   : %d/%d\n"
                     "Bus/Clock ratio         : %d/%d\n"
                     "ITC/Clock ratio         : %d/%d\n",
                     proc.num, proc.den, bus.num, bus.den, itc.num, itc.den);
-
-       return p - page;
+       return 0;
 }
 
-static int
-tr_info(char *page)
+static int tr_info(struct seq_file *m)
 {
-       char *p = page;
        long status;
        pal_tr_valid_u_t tr_valid;
        u64 tr_buffer[4];
@@ -794,39 +767,40 @@ tr_info(char *page)
 
                ifa_reg  = (struct ifa_reg *)&tr_buffer[2];
 
-               if (ifa_reg->valid == 0) continue;
+               if (ifa_reg->valid == 0)
+                       continue;
 
                gr_reg   = (struct gr_reg *)tr_buffer;
                itir_reg = (struct itir_reg *)&tr_buffer[1];
                rid_reg  = (struct rid_reg *)&tr_buffer[3];
 
                pgm      = -1 << (itir_reg->ps - 12);
-               p += sprintf(p,
-                            "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n"
-                            "\tppn  : 0x%lx\n"
-                            "\tvpn  : 0x%lx\n"
-                            "\tps   : ",
-                            "ID"[i], j,
-                            tr_valid.pal_tr_valid_s.access_rights_valid,
-                            tr_valid.pal_tr_valid_s.priv_level_valid,
-                            tr_valid.pal_tr_valid_s.dirty_bit_valid,
-                            tr_valid.pal_tr_valid_s.mem_attr_valid,
-                            (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12);
-
-               p = bitvector_process(p, 1<< itir_reg->ps);
-
-               p += sprintf(p,
-                            "\n\tpl   : %d\n"
-                            "\tar   : %d\n"
-                            "\trid  : %x\n"
-                            "\tp    : %d\n"
-                            "\tma   : %d\n"
-                            "\td    : %d\n",
-                            gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma,
-                            gr_reg->d);
+               seq_printf(m,
+                          "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n"
+                          "\tppn  : 0x%lx\n"
+                          "\tvpn  : 0x%lx\n"
+                          "\tps   : ",
+                          "ID"[i], j,
+                          tr_valid.pal_tr_valid_s.access_rights_valid,
+                          tr_valid.pal_tr_valid_s.priv_level_valid,
+                          tr_valid.pal_tr_valid_s.dirty_bit_valid,
+                          tr_valid.pal_tr_valid_s.mem_attr_valid,
+                          (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12);
+
+               bitvector_process(m, 1<< itir_reg->ps);
+
+               seq_printf(m,
+                          "\n\tpl   : %d\n"
+                          "\tar   : %d\n"
+                          "\trid  : %x\n"
+                          "\tp    : %d\n"
+                          "\tma   : %d\n"
+                          "\td    : %d\n",
+                          gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma,
+                          gr_reg->d);
                }
        }
-       return p - page;
+       return 0;
 }
 
 
@@ -834,7 +808,7 @@ tr_info(char *page)
 /*
  * List {name,function} pairs for every entry in /proc/palinfo/cpu*
  */
-static palinfo_entry_t palinfo_entries[]={
+static const palinfo_entry_t palinfo_entries[]={
        { "version_info",       version_info, },
        { "vm_info",            vm_info, },
        { "cache_info",         cache_info, },
@@ -849,17 +823,6 @@ static palinfo_entry_t palinfo_entries[]={
 
 #define NR_PALINFO_ENTRIES     (int) ARRAY_SIZE(palinfo_entries)
 
-/*
- * this array is used to keep track of the proc entries we create. This is
- * required in the module mode when we need to remove all entries. The procfs code
- * does not do recursion of deletion
- *
- * Notes:
- *     - +1 accounts for the cpuN directory entry in /proc/pal
- */
-#define NR_PALINFO_PROC_ENTRIES        (NR_CPUS*(NR_PALINFO_ENTRIES+1))
-
-static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES];
 static struct proc_dir_entry *palinfo_dir;
 
 /*
@@ -887,7 +850,7 @@ typedef union {
  */
 typedef struct {
        palinfo_func_t  func;   /* pointer to function to call */
-       char            *page;  /* buffer to store results */
+       struct seq_file *m;     /* buffer to store results */
        int             ret;    /* return value from call */
 } palinfo_smp_data_t;
 
@@ -900,7 +863,7 @@ static void
 palinfo_smp_call(void *info)
 {
        palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
-       data->ret = (*data->func)(data->page);
+       data->ret = (*data->func)(data->m);
 }
 
 /*
@@ -910,13 +873,13 @@ palinfo_smp_call(void *info)
  *     otherwise how many bytes in the "page" buffer were written
  */
 static
-int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
+int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f)
 {
        palinfo_smp_data_t ptr;
        int ret;
 
        ptr.func = palinfo_entries[f->func_id].proc_read;
-       ptr.page = page;
+       ptr.m = m;
        ptr.ret  = 0; /* just in case */
 
 
@@ -930,7 +893,7 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 }
 #else /* ! CONFIG_SMP */
 static
-int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
+int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f)
 {
        printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n");
        return 0;
@@ -940,91 +903,63 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 /*
  * Entry point routine: all calls go through this function
  */
-static int
-palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_palinfo_show(struct seq_file *m, void *v)
 {
-       int len=0;
-       pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&data;
+       pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&m->private;
 
        /*
         * in SMP mode, we may need to call another CPU to get correct
         * information. PAL, by definition, is processor specific
         */
        if (f->req_cpu == get_cpu())
-               len = (*palinfo_entries[f->func_id].proc_read)(page);
+               (*palinfo_entries[f->func_id].proc_read)(m);
        else
-               len = palinfo_handle_smp(f, page);
+               palinfo_handle_smp(m, f);
 
        put_cpu();
+       return 0;
+}
 
-       if (len <= off+count) *eof = 1;
-
-       *start = page + off;
-       len   -= off;
-
-       if (len>count) len = count;
-       if (len<0) len = 0;
-
-       return len;
+static int proc_palinfo_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_palinfo_show, PDE_DATA(inode));
 }
 
+static const struct file_operations proc_palinfo_fops = {
+       .open           = proc_palinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static void __cpuinit
 create_palinfo_proc_entries(unsigned int cpu)
 {
-#      define CPUSTR   "cpu%d"
-
        pal_func_cpu_u_t f;
-       struct proc_dir_entry **pdir;
        struct proc_dir_entry *cpu_dir;
        int j;
-       char cpustr[sizeof(CPUSTR)];
-
-
-       /*
-        * we keep track of created entries in a depth-first order for
-        * cleanup purposes. Each entry is stored into palinfo_proc_entries
-        */
-       sprintf(cpustr,CPUSTR, cpu);
+       char cpustr[3+4+1];     /* cpu numbers are up to 4095 on itanic */
+       sprintf(cpustr, "cpu%d", cpu);
 
        cpu_dir = proc_mkdir(cpustr, palinfo_dir);
+       if (!cpu_dir)
+               return;
 
        f.req_cpu = cpu;
 
-       /*
-        * Compute the location to store per cpu entries
-        * We dont store the top level entry in this list, but
-        * remove it finally after removing all cpu entries.
-        */
-       pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)];
-       *pdir++ = cpu_dir;
        for (j=0; j < NR_PALINFO_ENTRIES; j++) {
                f.func_id = j;
-               *pdir = create_proc_read_entry(
-                               palinfo_entries[j].name, 0, cpu_dir,
-                               palinfo_read_entry, (void *)f.value);
-               pdir++;
+               proc_create_data(palinfo_entries[j].name, 0, cpu_dir,
+                                &proc_palinfo_fops, (void *)f.value);
        }
 }
 
 static void
 remove_palinfo_proc_entries(unsigned int hcpu)
 {
-       int j;
-       struct proc_dir_entry *cpu_dir, **pdir;
-
-       pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)];
-       cpu_dir = *pdir;
-       *pdir++=NULL;
-       for (j=0; j < (NR_PALINFO_ENTRIES); j++) {
-               if ((*pdir)) {
-                       remove_proc_entry ((*pdir)->name, cpu_dir);
-                       *pdir ++= NULL;
-               }
-       }
-
-       if (cpu_dir) {
-               remove_proc_entry(cpu_dir->name, palinfo_dir);
-       }
+       char cpustr[3+4+1];     /* cpu numbers are up to 4095 on itanic */
+       sprintf(cpustr, "cpu%d", hcpu);
+       remove_proc_subtree(cpustr, palinfo_dir);
 }
 
 static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb,
@@ -1058,6 +993,8 @@ palinfo_init(void)
 
        printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION);
        palinfo_dir = proc_mkdir("pal", NULL);
+       if (!palinfo_dir)
+               return -ENOMEM;
 
        /* Create palinfo dirs in /proc for all online cpus */
        for_each_online_cpu(i) {
@@ -1073,22 +1010,8 @@ palinfo_init(void)
 static void __exit
 palinfo_exit(void)
 {
-       int i = 0;
-
-       /* remove all nodes: depth first pass. Could optimize this  */
-       for_each_online_cpu(i) {
-               remove_palinfo_proc_entries(i);
-       }
-
-       /*
-        * Remove the top level entry finally
-        */
-       remove_proc_entry(palinfo_dir->name, NULL);
-
-       /*
-        * Unregister from cpu notifier callbacks
-        */
        unregister_hotcpu_notifier(&palinfo_cpu_notifier);
+       remove_proc_subtree("pal", NULL);
 }
 
 module_init(palinfo_init);
index 433f5e8a2cd147cd7ae696d3e42b0123f6b4f306..2eda28414abb5a557e559387f6a6b46a76ae6819 100644 (file)
@@ -619,6 +619,7 @@ static struct file_system_type pfm_fs_type = {
        .mount    = pfmfs_mount,
        .kill_sb  = kill_anon_super,
 };
+MODULE_ALIAS_FS("pfmfs");
 
 DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
index aa527d7e91f26bb12449ce978a58f0a2530c3f16..5035245cb258cf9e6af07b071be0c481d64da1de 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/cpu.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/timer.h>
@@ -53,7 +54,7 @@ MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
 MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
 MODULE_LICENSE("GPL");
 
-static int salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static const struct file_operations proc_salinfo_fops;
 
 typedef struct {
        const char              *name;          /* name of the proc entry */
@@ -65,7 +66,7 @@ typedef struct {
  * List {name,feature} pairs for every entry in /proc/sal/<feature>
  * that this module exports
  */
-static salinfo_entry_t salinfo_entries[]={
+static const salinfo_entry_t salinfo_entries[]={
        { "bus_lock",           IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, },
        { "irq_redirection",    IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, },
        { "ipi_redirection",    IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, },
@@ -301,9 +302,7 @@ salinfo_event_open(struct inode *inode, struct file *file)
 static ssize_t
 salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
-       struct inode *inode = file_inode(file);
-       struct proc_dir_entry *entry = PDE(inode);
-       struct salinfo_data *data = entry->data;
+       struct salinfo_data *data = PDE_DATA(file_inode(file));
        char cmd[32];
        size_t size;
        int i, n, cpu = -1;
@@ -360,8 +359,7 @@ static const struct file_operations salinfo_event_fops = {
 static int
 salinfo_log_open(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *entry = PDE(inode);
-       struct salinfo_data *data = entry->data;
+       struct salinfo_data *data = PDE_DATA(inode);
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
@@ -386,8 +384,7 @@ salinfo_log_open(struct inode *inode, struct file *file)
 static int
 salinfo_log_release(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *entry = PDE(inode);
-       struct salinfo_data *data = entry->data;
+       struct salinfo_data *data = PDE_DATA(inode);
 
        if (data->state == STATE_NO_DATA) {
                vfree(data->log_buffer);
@@ -463,9 +460,7 @@ retry:
 static ssize_t
 salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
-       struct inode *inode = file_inode(file);
-       struct proc_dir_entry *entry = PDE(inode);
-       struct salinfo_data *data = entry->data;
+       struct salinfo_data *data = PDE_DATA(file_inode(file));
        u8 *buf;
        u64 bufsize;
 
@@ -524,9 +519,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu)
 static ssize_t
 salinfo_log_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
-       struct inode *inode = file_inode(file);
-       struct proc_dir_entry *entry = PDE(inode);
-       struct salinfo_data *data = entry->data;
+       struct salinfo_data *data = PDE_DATA(file_inode(file));
        char cmd[32];
        size_t size;
        u32 offset;
@@ -637,8 +630,9 @@ salinfo_init(void)
 
        for (i=0; i < NR_SALINFO_ENTRIES; i++) {
                /* pass the feature bit in question as misc data */
-               *sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
-                                                 salinfo_read, (void *)salinfo_entries[i].feature);
+               *sdir++ = proc_create_data(salinfo_entries[i].name, 0, salinfo_dir,
+                                          &proc_salinfo_fops,
+                                          (void *)salinfo_entries[i].feature);
        }
 
        for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
@@ -684,22 +678,23 @@ salinfo_init(void)
  * 'data' contains an integer that corresponds to the feature we're
  * testing
  */
-static int
-salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_salinfo_show(struct seq_file *m, void *v)
 {
-       int len = 0;
-
-       len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n");
-
-       if (len <= off+count) *eof = 1;
-
-       *start = page + off;
-       len   -= off;
-
-       if (len>count) len = count;
-       if (len<0) len = 0;
+       unsigned long data = (unsigned long)v;
+       seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n");
+       return 0;
+}
 
-       return len;
+static int proc_salinfo_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_salinfo_show, PDE_DATA(inode));
 }
 
+static const struct file_operations proc_salinfo_fops = {
+       .open           = proc_salinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 module_init(salinfo_init);
index 20b88cb1881a93e87b57d4d7b3e04e0c907eaa74..daa8d6badb160848659cddaed0b897b55a504deb 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/nodemask.h>
 #include <asm/io.h>
 #include <asm/sn/sn_sal.h>
@@ -101,18 +102,18 @@ get_fit_entry(unsigned long nasid, int index, unsigned long *fentry,
 /*
  * These two routines display the FIT table for each node.
  */
-static int dump_fit_entry(char *page, unsigned long *fentry)
+static void dump_fit_entry(struct seq_file *m, unsigned long *fentry)
 {
        unsigned type;
 
        type = FIT_TYPE(fentry[1]);
-       return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n",
-                      type,
-                      fit_type_name(type),
-                      FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]),
-                      fentry[0],
-                      /* mult by sixteen to get size in bytes */
-                      (unsigned)(fentry[1] & 0xffffff) * 16);
+       seq_printf(m, "%02x %-25s %x.%02x %016lx %u\n",
+                  type,
+                  fit_type_name(type),
+                  FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]),
+                  fentry[0],
+                  /* mult by sixteen to get size in bytes */
+                  (unsigned)(fentry[1] & 0xffffff) * 16);
 }
 
 
@@ -124,31 +125,39 @@ static int dump_fit_entry(char *page, unsigned long *fentry)
  * OK except for 4kB pages (and no one is going to do that on SN
  * anyway).
  */
-static int
-dump_fit(char *page, unsigned long nasid)
+static int proc_fit_show(struct seq_file *m, void *v)
 {
+       unsigned long nasid = (unsigned long)m->private;
        unsigned long fentry[2];
        int index;
-       char *p;
 
-       p = page;
        for (index=0;;index++) {
                BUG_ON(index * 60 > PAGE_SIZE);
                if (get_fit_entry(nasid, index, fentry, NULL, 0))
                        break;
-               p += dump_fit_entry(p, fentry);
+               dump_fit_entry(m, fentry);
        }
+       return 0;
+}
 
-       return p - page;
+static int proc_fit_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_fit_show, PDE_DATA(inode));
 }
 
-static int
-dump_version(char *page, unsigned long nasid)
+static const struct file_operations proc_fit_fops = {
+       .open           = proc_fit_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int proc_version_show(struct seq_file *m, void *v)
 {
+       unsigned long nasid = (unsigned long)m->private;
        unsigned long fentry[2];
        char banner[128];
        int index;
-       int len;
 
        for (index = 0; ; index++) {
                if (get_fit_entry(nasid, index, fentry, banner,
@@ -158,56 +167,24 @@ dump_version(char *page, unsigned long nasid)
                        break;
        }
 
-       len = sprintf(page, "%x.%02x\n", FIT_MAJOR(fentry[1]),
-                     FIT_MINOR(fentry[1]));
-       page += len;
+       seq_printf(m, "%x.%02x\n", FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]));
 
        if (banner[0])
-               len += snprintf(page, PAGE_SIZE-len, "%s\n", banner);
-
-       return len;
-}
-
-/* same as in proc_misc.c */
-static int
-proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof,
-                 int len)
-{
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
-       return len;
+               seq_printf(m, "%s\n", banner);
+       return 0;
 }
 
-static int
-read_version_entry(char *page, char **start, off_t off, int count, int *eof,
-                  void *data)
+static int proc_version_open(struct inode *inode, struct file *file)
 {
-       int len;
-
-       /* data holds the NASID of the node */
-       len = dump_version(page, (unsigned long)data);
-       len = proc_calc_metrics(page, start, off, count, eof, len);
-       return len;
+       return single_open(file, proc_version_show, PDE_DATA(inode));
 }
 
-static int
-read_fit_entry(char *page, char **start, off_t off, int count, int *eof,
-              void *data)
-{
-       int len;
-
-       /* data holds the NASID of the node */
-       len = dump_fit(page, (unsigned long)data);
-       len = proc_calc_metrics(page, start, off, count, eof, len);
-
-       return len;
-}
+static const struct file_operations proc_version_fops = {
+       .open           = proc_version_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
 /* module entry points */
 int __init prominfo_init(void);
@@ -216,58 +193,39 @@ void __exit prominfo_exit(void);
 module_init(prominfo_init);
 module_exit(prominfo_exit);
 
-static struct proc_dir_entry **proc_entries;
-static struct proc_dir_entry *sgi_prominfo_entry;
-
 #define NODE_NAME_LEN 11
 
 int __init prominfo_init(void)
 {
-       struct proc_dir_entry **entp;
+       struct proc_dir_entry *sgi_prominfo_entry;
        cnodeid_t cnodeid;
-       unsigned long nasid;
-       int size;
-       char name[NODE_NAME_LEN];
 
        if (!ia64_platform_is("sn2"))
                return 0;
 
-       size = num_online_nodes() * sizeof(struct proc_dir_entry *);
-       proc_entries = kzalloc(size, GFP_KERNEL);
-       if (!proc_entries)
-               return -ENOMEM;
-
        sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
+       if (!sgi_prominfo_entry)
+               return -ENOMEM;
 
-       entp = proc_entries;
        for_each_online_node(cnodeid) {
+               struct proc_dir_entry *dir;
+               unsigned long nasid;
+               char name[NODE_NAME_LEN];
+
                sprintf(name, "node%d", cnodeid);
-               *entp = proc_mkdir(name, sgi_prominfo_entry);
+               dir = proc_mkdir(name, sgi_prominfo_entry);
+               if (!dir)
+                       continue;
                nasid = cnodeid_to_nasid(cnodeid);
-               create_proc_read_entry("fit", 0, *entp, read_fit_entry,
-                                          (void *)nasid);
-               create_proc_read_entry("version", 0, *entp,
-                                          read_version_entry, (void *)nasid);
-               entp++;
+               proc_create_data("fit", 0, dir,
+                                &proc_fit_fops, (void *)nasid);
+               proc_create_data("version", 0, dir,
+                                &proc_version_fops, (void *)nasid);
        }
-
        return 0;
 }
 
 void __exit prominfo_exit(void)
 {
-       struct proc_dir_entry **entp;
-       unsigned int cnodeid;
-       char name[NODE_NAME_LEN];
-
-       entp = proc_entries;
-       for_each_online_node(cnodeid) {
-               remove_proc_entry("fit", *entp);
-               remove_proc_entry("version", *entp);
-               sprintf(name, "node%d", cnodeid);
-               remove_proc_entry(name, sgi_prominfo_entry);
-               entp++;
-       }
-       remove_proc_entry("sgi_prominfo", NULL);
-       kfree(proc_entries);
+       remove_proc_subtree("sgi_prominfo", NULL);
 }
index 92623818a1fe0ecb6147ceed0ebeb900a79df49e..bcd17b20657128ef42c2f68f0dd07880467f1c2c 100644 (file)
@@ -10,7 +10,7 @@ config M32R
        select ARCH_WANT_IPC_PARSE_VERSION
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
        select GENERIC_ATOMIC64
index da4518f82d6d31d71609d7a670924cbe79c88c2a..98470fe483b67861b952f7c35bb946111016c9db 100644 (file)
@@ -63,10 +63,10 @@ struct stat64 {
        long long       st_size;
        unsigned long   st_blksize;
 
-#if defined(__BIG_ENDIAN)
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
        unsigned long   __pad4;         /* future possible st_blocks high bits */
        unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
-#elif defined(__LITTLE_ENDIAN)
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
        unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
        unsigned long   __pad4;         /* future possible st_blocks high bits */
 #else
index 0e708c78e01c6f82cdc87af1c9cd60eef285173e..6de813370b8c7d01e8b98d78634baef15da6fe3b 100644 (file)
@@ -8,7 +8,7 @@ config M68K
        select GENERIC_IRQ_SHOW
        select GENERIC_ATOMIC64
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
        select GENERIC_CPU_DEVICES
        select GENERIC_STRNCPY_FROM_USER if MMU
index 7cdf6b010381f8ae31332012c18d93345232514a..7240584d343974847fbaab832bcf50388d8d2ba3 100644 (file)
@@ -310,7 +310,6 @@ config COBRA5282
 config SOM5282EM
        bool "EMAC.Inc SOM5282EM board support"
        depends on M528x
-       select EMAC_INC
        help
          Support for the EMAC.Inc SOM5282EM module.
 
index a337e56d09bf9118eea7004ee9ba21921b02faca..4ebf098b8a1fd58c9a222d864b9f4cea6f6c2171 100644 (file)
 /*
  * Here go the bitmasks themselves
  */
-#define IMR_MSPIM      (1 << SPIM _IRQ_NUM)    /* Mask SPI Master interrupt */
+#define IMR_MSPIM      (1 << SPIM_IRQ_NUM)     /* Mask SPI Master interrupt */
 #define        IMR_MTMR2       (1 << TMR2_IRQ_NUM)     /* Mask Timer 2 interrupt */
 #define IMR_MUART      (1 << UART_IRQ_NUM)     /* Mask UART interrupt */       
 #define        IMR_MWDT        (1 << WDT_IRQ_NUM)      /* Mask Watchdog Timer interrupt */
 #define IWR_ADDR       0xfffff308
 #define IWR            LONG_REF(IWR_ADDR)
 
-#define IWR_SPIM       (1 << SPIM _IRQ_NUM)    /* SPI Master interrupt */
+#define IWR_SPIM       (1 << SPIM_IRQ_NUM)     /* SPI Master interrupt */
 #define        IWR_TMR2        (1 << TMR2_IRQ_NUM)     /* Timer 2 interrupt */
 #define IWR_UART       (1 << UART_IRQ_NUM)     /* UART interrupt */    
 #define        IWR_WDT         (1 << WDT_IRQ_NUM)      /* Watchdog Timer interrupt */
 #define ISR_ADDR       0xfffff30c
 #define ISR            LONG_REF(ISR_ADDR)
 
-#define ISR_SPIM       (1 << SPIM _IRQ_NUM)    /* SPI Master interrupt */
+#define ISR_SPIM       (1 << SPIM_IRQ_NUM)     /* SPI Master interrupt */
 #define        ISR_TMR2        (1 << TMR2_IRQ_NUM)     /* Timer 2 interrupt */
 #define ISR_UART       (1 << UART_IRQ_NUM)     /* UART interrupt */    
 #define        ISR_WDT         (1 << WDT_IRQ_NUM)      /* Watchdog Timer interrupt */
 #define IPR_ADDR       0xfffff310
 #define IPR            LONG_REF(IPR_ADDR)
 
-#define IPR_SPIM       (1 << SPIM _IRQ_NUM)    /* SPI Master interrupt */
+#define IPR_SPIM       (1 << SPIM_IRQ_NUM)     /* SPI Master interrupt */
 #define        IPR_TMR2        (1 << TMR2_IRQ_NUM)     /* Timer 2 interrupt */
 #define IPR_UART       (1 << UART_IRQ_NUM)     /* UART interrupt */    
 #define        IPR_WDT         (1 << WDT_IRQ_NUM)      /* Watchdog Timer interrupt */
 
 /* 'EZ328-compatible definitions */
 #define TCN_ADDR       TCN1_ADDR
-#define TCN            TCN
+#define TCN            TCN1
 
 /*
  * Timer Unit 1 and 2 Status Registers
index 71fb29938dba260b6e5895c3d7eb5f10f2afbb16..911ba472e6c4abbd83dac862a561d98eb22526aa 100644 (file)
@@ -57,6 +57,9 @@ void (*mach_reset)(void);
 void (*mach_halt)(void);
 void (*mach_power_off)(void);
 
+#ifdef CONFIG_M68000
+#define CPU_NAME       "MC68000"
+#endif
 #ifdef CONFIG_M68328
 #define CPU_NAME       "MC68328"
 #endif
index afd8106fd83b10c2b1d51b956b178effd9a6b096..519aad8fa812ca6ac7ce07f82abb06ae080139bf 100644 (file)
@@ -188,7 +188,7 @@ void __init mem_init(void)
                }
        }
 
-#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
        /* insert pointer tables allocated so far into the tablelist */
        init_pointer_table((unsigned long)kernel_pg_dir);
        for (i = 0; i < PTRS_PER_PGD; i++) {
index 83b7dad7a84e7a1928d105fa6b08acfe3bc8c546..b03a9d271837a8efa46245eb7dc90b7a9a322b12 100644 (file)
@@ -69,7 +69,7 @@ static void __init m528x_uarts_init(void)
        u8 port;
 
        /* make sure PUAPAR is set for UART0 and UART1 */
-       port = readb(MCF5282_GPIO_PUAPAR);
+       port = readb(MCFGPIO_PUAPAR);
        port |= 0x03 | (0x03 << 2);
        writeb(port, MCFGPIO_PUAPAR);
 }
index d63b9d0e57dd1ca83e384c0221162cc6cac827ba..d2baf69617940d68399775a3030269ead857dc14 100644 (file)
@@ -100,9 +100,6 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) \
-       set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
-
 #define STACK_RND_MASK (0)
 
 #ifdef CONFIG_METAG_USER_TCM
index cd7f2f2ad416b9bf91fd7206c29117f753d1041f..975f2f4e3ecf55f17521a3605c883bfd434fe554 100644 (file)
@@ -40,6 +40,7 @@ endchoice
 
 config NUMA
        bool "Non Uniform Memory Access (NUMA) Support"
+       select ARCH_WANT_NUMA_VARIABLE_LOCALITY
        help
          Some Meta systems have MMU-mappable on-chip memories with
          lower latencies than main memory. This enables support for
index 7843d11156e60a36d20a5f499b2ff6623e8aa275..1323fa2530eb7c144abe5da9ab1318e410d1c643 100644 (file)
@@ -19,7 +19,7 @@ config MICROBLAZE
        select HAVE_DEBUG_KMEMLEAK
        select IRQ_DOMAIN
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
        select GENERIC_PCI_IOMAP
index ae9c716c46bbf5d93849f5ad9dcb5e3c9a47fd88..cd2e21ff562af434803045c048dbbfbcd28a50cb 100644 (file)
@@ -38,7 +38,7 @@ config MIPS
        select GENERIC_CLOCKEVENTS
        select GENERIC_CMOS_UPDATE
        select HAVE_MOD_ARCH_SPECIFIC
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_REL if MODULES
        select MODULES_USE_ELF_RELA if MODULES && 64BIT
        select CLONE_BACKWARDS
index aee7c8177b5df4a2e00cd24efad837f02a723921..9fb714450e95162b1a003a74cc705b1c70864ec7 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include <asm/smtc_proc.h>
 
@@ -30,51 +31,39 @@ unsigned long selfipis[NR_CPUS];
 
 struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
 
-static struct proc_dir_entry *smtc_stats;
-
 atomic_t smtc_fpu_recoveries;
 
-static int proc_read_smtc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+static int smtc_proc_show(struct seq_file *m, void *v)
 {
-       int totalen = 0;
-       int len;
        int i;
        extern unsigned long ebase;
 
-       len = sprintf(page, "SMTC Status Word: 0x%08x\n", smtc_status);
-       totalen += len;
-       page += len;
-       len = sprintf(page, "Config7: 0x%08x\n", read_c0_config7());
-       totalen += len;
-       page += len;
-       len = sprintf(page, "EBASE: 0x%08lx\n", ebase);
-       totalen += len;
-       page += len;
-       len = sprintf(page, "Counter Interrupts taken per CPU (TC)\n");
-       totalen += len;
-       page += len;
-       for (i=0; i < NR_CPUS; i++) {
-               len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].timerints);
-               totalen += len;
-               page += len;
-       }
-       len = sprintf(page, "Self-IPIs by CPU:\n");
-       totalen += len;
-       page += len;
-       for(i = 0; i < NR_CPUS; i++) {
-               len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
-               totalen += len;
-               page += len;
-       }
-       len = sprintf(page, "%d Recoveries of \"stolen\" FPU\n",
-                     atomic_read(&smtc_fpu_recoveries));
-       totalen += len;
-       page += len;
+       seq_printf(m, "SMTC Status Word: 0x%08x\n", smtc_status);
+       seq_printf(m, "Config7: 0x%08x\n", read_c0_config7());
+       seq_printf(m, "EBASE: 0x%08lx\n", ebase);
+       seq_printf(m, "Counter Interrupts taken per CPU (TC)\n");
+       for (i=0; i < NR_CPUS; i++)
+               seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].timerints);
+       seq_printf(m, "Self-IPIs by CPU:\n");
+       for(i = 0; i < NR_CPUS; i++)
+               seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
+       seq_printf(m, "%d Recoveries of \"stolen\" FPU\n",
+                  atomic_read(&smtc_fpu_recoveries));
+       return 0;
+}
 
-       return totalen;
+static int smtc_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, smtc_proc_show, NULL);
 }
 
+static const struct file_operations smtc_proc_fops = {
+       .open           = smtc_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 void init_smtc_stats(void)
 {
        int i;
@@ -86,6 +75,5 @@ void init_smtc_stats(void)
 
        atomic_set(&smtc_fpu_recoveries, 0);
 
-       smtc_stats = create_proc_read_entry("smtc", 0444, NULL,
-                                           proc_read_smtc, NULL);
+       proc_create("smtc", 0444, NULL, &smtc_proc_fops);
 }
index c592bc8b8c99521644d07d9e600b78a90b3a5bf2..638c5db122c924dca997725d58ee0fd34b36fe1b 100644 (file)
@@ -58,13 +58,13 @@ static int pvc_line_proc_show(struct seq_file *m, void *v)
 
 static int pvc_line_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pvc_line_proc_show, PDE(inode)->data);
+       return single_open(file, pvc_line_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf,
                                   size_t count, loff_t *pos)
 {
-       int lineno = *(int *)PDE(file_inode(file))->data;
+       int lineno = *(int *)PDE_DATA(file_inode(file));
        char kbuf[PVC_LINELEN];
        size_t len;
 
index 67929251286c983597492db0cb5ca08ceb944ee0..60547b7fe2ff97778e49ca5c86eb4bca10a45bf4 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pfn.h>
 #include <linux/hardirq.h>
 #include <linux/gfp.h>
+#include <linux/kcore.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/bootinfo.h>
index d0b6f8399b075eaf768c8fad5d95f20711b87a16..4eaab6327369c362537c35099496a3d586dccfa0 100644 (file)
@@ -53,56 +53,51 @@ static void pci_proc_init(void);
 
 /*****************************************************************************
  *
- *  FUNCTION: read_msp_pci_counts
+ *  FUNCTION: show_msp_pci_counts
  *  _________________________________________________________________________
  *
  *  DESCRIPTION: Prints the count of how many times each PCI
  *              interrupt has asserted. Can be invoked by the
  *              /proc filesystem.
  *
- *  INPUTS:     page    - part of STDOUT calculation
- *              off     - part of STDOUT calculation
- *              count   - part of STDOUT calculation
- *              data    - unused
+ *  INPUTS:     m       - synthetic file construction data
+ *              v       - iterator
  *
- *  OUTPUTS:    start   - new start location
- *              eof     - end of file pointer
- *
- *  RETURNS:    len     - STDOUT length
+ *  RETURNS:    0 or error
  *
  ****************************************************************************/
-static int read_msp_pci_counts(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+static int show_msp_pci_counts(struct seq_file *m, void *v)
 {
        int i;
-       int len = 0;
        unsigned int intcount, total = 0;
 
        for (i = 0; i < 32; ++i) {
                intcount = pci_int_count[i];
                if (intcount != 0) {
-                       len += sprintf(page + len, "[%d] = %u\n", i, intcount);
+                       seq_printf(m, "[%d] = %u\n", i, intcount);
                        total += intcount;
                }
        }
 
-       len += sprintf(page + len, "total = %u\n", total);
-       if (len <= off+count)
-               *eof = 1;
-
-       *start = page + off;
-       len -= off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+       seq_printf(m, "total = %u\n", total);
+       return 0;
+}
 
-       return len;
+static int msp_pci_rd_cnt_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_msp_pci_counts, NULL);
 }
 
+static const struct file_operations msp_pci_rd_cnt_fops = {
+       .open           = msp_pci_rd_cnt_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 /*****************************************************************************
  *
- *  FUNCTION: gen_pci_cfg_wr
+ *  FUNCTION: gen_pci_cfg_wr_show
  *  _________________________________________________________________________
  *
  *  DESCRIPTION: Generates a configuration write cycle for debug purposes.
@@ -112,37 +107,30 @@ static int read_msp_pci_counts(char *page, char **start, off_t off,
  *              PCI bus.  Intent is that this function by invocable from
  *              the /proc filesystem.
  *
- *  INPUTS:     page    - part of STDOUT calculation
- *              off     - part of STDOUT calculation
- *              count   - part of STDOUT calculation
- *              data    - unused
+ *  INPUTS:     m       - synthetic file construction data
+ *              v       - iterator
  *
- *  OUTPUTS:    start   - new start location
- *              eof     - end of file pointer
- *
- *  RETURNS:    len     - STDOUT length
+ *  RETURNS:    0 or error
  *
  ****************************************************************************/
-static int gen_pci_cfg_wr(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+static int gen_pci_cfg_wr_show(struct seq_file *m, void *v)
 {
        unsigned char where = 0; /* Write to static Device/Vendor ID */
        unsigned char bus_num = 0; /* Bus 0 */
        unsigned char dev_fn = 0xF; /* Arbitrary device number */
        u32 wr_data = 0xFF00AA00; /* Arbitrary data */
        struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
-       int len = 0;
        unsigned long value;
        int intr;
 
-       len += sprintf(page + len, "PMC MSP PCI: Beginning\n");
+       seq_puts(m, "PMC MSP PCI: Beginning\n");
 
        if (proc_init == 0) {
                pci_proc_init();
                proc_init = ~0;
        }
 
-       len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n");
+       seq_puts(m, "PMC MSP PCI: Before Cfg Wr\n");
 
        /*
         * Generate PCI Configuration Write Cycle
@@ -168,21 +156,22 @@ static int gen_pci_cfg_wr(char *page, char **start, off_t off,
         */
        intr = preg->if_status;
 
-       len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n");
-
-       /* Handle STDOUT calculations */
-       if (len <= off+count)
-               *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+       seq_puts(m, "PMC MSP PCI: After Cfg Wr\n");
+       return 0;
+}
 
-       return len;
+static int gen_pci_cfg_wr_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, gen_pci_cfg_wr_show, NULL);
 }
 
+static const struct file_operations gen_pci_cfg_wr_fops = {
+       .open           = gen_pci_cfg_wr_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 /*****************************************************************************
  *
  *  FUNCTION: pci_proc_init
@@ -199,10 +188,8 @@ static int gen_pci_cfg_wr(char *page, char **start, off_t off,
  ****************************************************************************/
 static void pci_proc_init(void)
 {
-       create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL,
-                               read_msp_pci_counts, NULL);
-       create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL,
-                               gen_pci_cfg_wr, NULL);
+       proc_create("pmc_msp_pci_rd_cnt", 0, NULL, &msp_pci_rd_cnt_fops);
+       proc_create("pmc_msp_pci_cfg_wr", 0, NULL, &gen_pci_cfg_wr_fops);
 }
 #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
 
index e651105b3f0bbc328f12a4aa5c81b052464b7e40..cb1e3cb37d703da3b06ebba3c7cc8da7fd035742 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <asm/io.h>
 
 #include <asm/sibyte/sb1250.h>
@@ -99,63 +100,60 @@ void check_bus_watcher(void)
                printk("Bus watcher indicates no error\n");
 }
 
-static int bw_print_buffer(char *page, struct bw_stats_struct *stats)
+#ifdef CONFIG_PROC_FS
+
+/* For simplicity, I want to assume a single read is required each
+   time */
+static int bw_proc_show(struct seq_file *m, void *v)
 {
-       int len;
-
-       len = sprintf(page, "SiByte Bus Watcher statistics\n");
-       len += sprintf(page+len, "-----------------------------\n");
-       len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
-                      stats->l2_cor_d, stats->l2_bad_d);
-       len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
-                      stats->l2_cor_t, stats->l2_bad_t);
-       len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
-                      stats->mem_cor_d, stats->mem_bad_d);
-       len += sprintf(page+len, "IO-err   %8ld\n", stats->bus_error);
-       len += sprintf(page+len, "\nLast recorded signature:\n");
-       len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n",
-                      (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
-                      (int)(G_SCD_BERR_TID(stats->status) >> 6),
-                      (int)G_SCD_BERR_RID(stats->status),
-                      (int)G_SCD_BERR_DCODE(stats->status));
+       struct bw_stats_struct *stats = m->private;
+
+       seq_puts(m, "SiByte Bus Watcher statistics\n");
+       seq_puts(m, "-----------------------------\n");
+       seq_printf(m, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
+                  stats->l2_cor_d, stats->l2_bad_d);
+       seq_printf(m, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
+                  stats->l2_cor_t, stats->l2_bad_t);
+       seq_printf(m, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
+                  stats->mem_cor_d, stats->mem_bad_d);
+       seq_printf(m, "IO-err   %8ld\n", stats->bus_error);
+       seq_puts(m, "\nLast recorded signature:\n");
+       seq_printf(m, "Request %02x from %d, answered by %d with Dcode %d\n",
+                  (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
+                  (int)(G_SCD_BERR_TID(stats->status) >> 6),
+                  (int)G_SCD_BERR_RID(stats->status),
+                  (int)G_SCD_BERR_DCODE(stats->status));
        /* XXXKW indicate multiple errors between printings, or stats
           collection (or both)? */
        if (stats->status & M_SCD_BERR_MULTERRS)
-               len += sprintf(page+len, "Multiple errors observed since last check.\n");
+               seq_puts(m, "Multiple errors observed since last check.\n");
        if (stats->status_printed) {
-               len += sprintf(page+len, "(no change since last printing)\n");
+               seq_puts(m, "(no change since last printing)\n");
        } else {
                stats->status_printed = 1;
        }
 
-       return len;
+       return 0;
 }
 
-#ifdef CONFIG_PROC_FS
-
-/* For simplicity, I want to assume a single read is required each
-   time */
-static int bw_read_proc(char *page, char **start, off_t off,
-                       int count, int *eof, void *data)
+static int bw_proc_open(struct inode *inode, struct file *file)
 {
-       int len;
-
-       if (off == 0) {
-               len = bw_print_buffer(page, data);
-               *start = page;
-       } else {
-               len = 0;
-               *eof = 1;
-       }
-       return len;
+       return single_open(file, bw_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations bw_proc_fops = {
+       .open           = bw_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static void create_proc_decoder(struct bw_stats_struct *stats)
 {
        struct proc_dir_entry *ent;
 
-       ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL,
-                                    bw_read_proc, stats);
+       ent = proc_create_data("bus_watcher", S_IWUSR | S_IRUGO, NULL,
+                              &bw_proc_fops, stats);
        if (!ent) {
                printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n");
                return;
@@ -210,11 +208,6 @@ static irqreturn_t sibyte_bw_int(int irq, void *data)
        stats->bus_error += G_SCD_MEM_BUSERR(cntr);
        csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS));
 
-#ifndef CONFIG_PROC_FS
-       bw_print_buffer(bw_buf, stats);
-       printk(bw_buf);
-#endif
-
        return IRQ_HANDLED;
 }
 
index b06c7360b1c6fafd6ba5ea9faba8d7dd0c9abbca..428da175d0734abab132fbbbad57154b05530b1d 100644 (file)
@@ -8,7 +8,7 @@ config MN10300
        select HAVE_ARCH_KGDB
        select GENERIC_ATOMIC64
        select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
        select OLD_SIGSUSPEND3
index 014a6482ed4ce3c38c44d4bef68c758f9e684a31..9ab3bf2eca8d2efeef9f0adbadc8b94c356cb857 100644 (file)
@@ -9,10 +9,9 @@ config OPENRISC
        select OF_EARLY_FLATTREE
        select IRQ_DOMAIN
        select HAVE_MEMBLOCK
-       select ARCH_WANT_OPTIONAL_GPIOLIB
+       select ARCH_REQUIRE_GPIOLIB
         select HAVE_ARCH_TRACEHOOK
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
        select GENERIC_IRQ_CHIP
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
index a9ff712a28643e235892c8ec426ed9b596ce77d6..0339181bf3ac3d377db760ef93a7e74933288eee 100644 (file)
@@ -21,7 +21,7 @@ config PARISC
        select GENERIC_STRNCPY_FROM_USER
        select SYSCTL_ARCH_UNALIGN_ALLOW
        select HAVE_MOD_ARCH_SPECIFIC
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_RELA
        select CLONE_BACKWARDS
        select TTY # Needed for pdc_cons.c
index d47ba1aa825376fdce235befca626b6cb95762d8..8fa314fbfb18bb9a8bc3e0e03da02cd8b92be9c1 100644 (file)
 #endif
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/notifier.h>
 #include <linux/cache.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include <asm/pdc_chassis.h>
 #include <asm/processor.h>
@@ -244,38 +246,38 @@ int pdc_chassis_send_status(int message)
 
 #ifdef CONFIG_PDC_CHASSIS_WARN
 #ifdef CONFIG_PROC_FS
-static int pdc_chassis_warn_pread(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static int pdc_chassis_warn_show(struct seq_file *m, void *v)
 {
-       char *out = page;
-       int len, ret;
        unsigned long warn;
        u32 warnreg;
 
-       ret = pdc_chassis_warn(&warn);
-       if (ret != PDC_OK)
+       if (pdc_chassis_warn(&warn) != PDC_OK)
                return -EIO;
 
        warnreg = (warn & 0xFFFFFFFF);
 
        if ((warnreg >> 24) & 0xFF)
-               out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF));
-
-       out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK");
-       out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK");
-       out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK");
-
-       len = out - page - off;
-       if (len < count) {
-               *eof = 1;
-               if (len <= 0) return 0;
-       } else {
-               len = count;
-       }
-       *start = page + off;
-       return len;
+               seq_printf(m, "Chassis component failure! (eg fan or PSU): 0x%.2x\n",
+                          (warnreg >> 24) & 0xFF);
+
+       seq_printf(m, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK");
+       seq_printf(m, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK");
+       seq_printf(m, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK");
+       return 0;
+}
+
+static int pdc_chassis_warn_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, pdc_chassis_warn_show, NULL);
 }
 
+static const struct file_operations pdc_chassis_warn_fops = {
+       .open           = pdc_chassis_warn_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static int __init pdc_chassis_create_procfs(void)
 {
        unsigned long test;
@@ -290,8 +292,7 @@ static int __init pdc_chassis_create_procfs(void)
 
        printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n",
                        PDC_CHASSIS_VER);
-       create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread,
-                               NULL);
+       proc_create("chassis", 0400, NULL, &pdc_chassis_warn_fops);
        return 0;
 }
 
index b89d7eb730a25360129d0d4b7f83136e130a227d..ea5bb045983a19070958b003a8408841bce35a7c 100644 (file)
@@ -90,6 +90,7 @@ config GENERIC_GPIO
 config PPC
        bool
        default y
+       select BINFMT_ELF
        select OF
        select OF_EARLY_FLATTREE
        select HAVE_FTRACE_MCOUNT_RECORD
@@ -98,7 +99,7 @@ config PPC
        select HAVE_FUNCTION_GRAPH_TRACER
        select SYSCTL_EXCEPTION_TRACE
        select ARCH_WANT_OPTIONAL_GPIOLIB
-       select HAVE_VIRT_TO_BUS if !PPC64
+       select VIRT_TO_BUS if !PPC64
        select HAVE_IDE
        select HAVE_IOREMAP_PROT
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
index a5f8264d2d3c3c58d5755af56d5e911fc3670212..125e16520061289aff815417fd7aa18ec41e3df7 100644 (file)
        STEPUP4((t)+16, fn)
 
 _GLOBAL(powerpc_sha_transform)
-       PPC_STLU r1,-STACKFRAMESIZE(r1)
+       PPC_STLU r1,-INT_FRAME_SIZE(r1)
        SAVE_8GPRS(14, r1)
        SAVE_10GPRS(22, r1)
 
@@ -175,5 +175,5 @@ _GLOBAL(powerpc_sha_transform)
 
        REST_8GPRS(14, r1)
        REST_10GPRS(22, r1)
-       addi    r1,r1,STACKFRAMESIZE
+       addi    r1,r1,INT_FRAME_SIZE
        blr
index ef918a2328bba044173e61a799d23f8ae3cf2576..08bd299c75b113d1dd55ea827853bb616fdb5899 100644 (file)
@@ -52,8 +52,6 @@
 #define smp_mb__before_clear_bit()     smp_mb()
 #define smp_mb__after_clear_bit()      smp_mb()
 
-#define BITOP_LE_SWIZZLE       ((BITS_PER_LONG-1) & ~0x7)
-
 /* Macro for generating the ***_bits() functions */
 #define DEFINE_BITOP(fn, op, prefix, postfix)  \
 static __inline__ void fn(unsigned long mask,  \
index 2fdb47a19efda298b8ddc3749f174be75e1e7a63..b59e06f507ea6c3f3af39688752e20a23096b666 100644 (file)
@@ -343,17 +343,16 @@ extern void slb_set_size(u16 size);
 /*
  * VSID allocation (256MB segment)
  *
- * We first generate a 38-bit "proto-VSID".  For kernel addresses this
- * is equal to the ESID | 1 << 37, for user addresses it is:
- *     (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1)
+ * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
+ * from mmu context id and effective segment id of the address.
  *
- * This splits the proto-VSID into the below range
- *  0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range
- *  2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range
- *
- * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1
- * That is, we assign half of the space to user processes and half
- * to the kernel.
+ * For user processes max context id is limited to ((1ul << 19) - 5)
+ * for kernel space, we use the top 4 context ids to map address as below
+ * NOTE: each context only support 64TB now.
+ * 0x7fffc -  [ 0xc000000000000000 - 0xc0003fffffffffff ]
+ * 0x7fffd -  [ 0xd000000000000000 - 0xd0003fffffffffff ]
+ * 0x7fffe -  [ 0xe000000000000000 - 0xe0003fffffffffff ]
+ * 0x7ffff -  [ 0xf000000000000000 - 0xf0003fffffffffff ]
  *
  * The proto-VSIDs are then scrambled into real VSIDs with the
  * multiplicative hash:
@@ -363,41 +362,49 @@ extern void slb_set_size(u16 size);
  * VSID_MULTIPLIER is prime, so in particular it is
  * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
  * Because the modulus is 2^n-1 we can compute it efficiently without
- * a divide or extra multiply (see below).
- *
- * This scheme has several advantages over older methods:
- *
- *     - We have VSIDs allocated for every kernel address
- * (i.e. everything above 0xC000000000000000), except the very top
- * segment, which simplifies several things.
+ * a divide or extra multiply (see below). The scramble function gives
+ * robust scattering in the hash table (at least based on some initial
+ * results).
  *
- *     - We allow for USER_ESID_BITS significant bits of ESID and
- * CONTEXT_BITS  bits of context for user addresses.
- *  i.e. 64T (46 bits) of address space for up to half a million contexts.
+ * We also consider VSID 0 special. We use VSID 0 for slb entries mapping
+ * bad address. This enables us to consolidate bad address handling in
+ * hash_page.
  *
- *     - The scramble function gives robust scattering in the hash
- * table (at least based on some initial results).  The previous
- * method was more susceptible to pathological cases giving excessive
- * hash collisions.
+ * We also need to avoid the last segment of the last context, because that
+ * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
+ * because of the modulo operation in vsid scramble. But the vmemmap
+ * (which is what uses region 0xf) will never be close to 64TB in size
+ * (it's 56 bytes per page of system memory).
  */
 
+#define CONTEXT_BITS           19
+#define ESID_BITS              18
+#define ESID_BITS_1T           6
+
+/*
+ * 256MB segment
+ * The proto-VSID space has 2^(CONTEX_BITS + ESID_BITS) - 1 segments
+ * available for user + kernel mapping. The top 4 contexts are used for
+ * kernel mapping. Each segment contains 2^28 bytes. Each
+ * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
+ * (19 == 37 + 28 - 46).
+ */
+#define MAX_USER_CONTEXT       ((ASM_CONST(1) << CONTEXT_BITS) - 5)
+
 /*
  * This should be computed such that protovosid * vsid_mulitplier
  * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
  */
 #define VSID_MULTIPLIER_256M   ASM_CONST(12538073)     /* 24-bit prime */
-#define VSID_BITS_256M         38
+#define VSID_BITS_256M         (CONTEXT_BITS + ESID_BITS)
 #define VSID_MODULUS_256M      ((1UL<<VSID_BITS_256M)-1)
 
 #define VSID_MULTIPLIER_1T     ASM_CONST(12538073)     /* 24-bit prime */
-#define VSID_BITS_1T           26
+#define VSID_BITS_1T           (CONTEXT_BITS + ESID_BITS_1T)
 #define VSID_MODULUS_1T                ((1UL<<VSID_BITS_1T)-1)
 
-#define CONTEXT_BITS           19
-#define USER_ESID_BITS         18
-#define USER_ESID_BITS_1T      6
 
-#define USER_VSID_RANGE        (1UL << (USER_ESID_BITS + SID_SHIFT))
+#define USER_VSID_RANGE        (1UL << (ESID_BITS + SID_SHIFT))
 
 /*
  * This macro generates asm code to compute the VSID scramble
@@ -421,7 +428,8 @@ extern void slb_set_size(u16 size);
        srdi    rx,rt,VSID_BITS_##size;                                 \
        clrldi  rt,rt,(64-VSID_BITS_##size);                            \
        add     rt,rt,rx;               /* add high and low bits */     \
-       /* Now, r3 == VSID (mod 2^36-1), and lies between 0 and         \
+       /* NOTE: explanation based on VSID_BITS_##size = 36             \
+        * Now, r3 == VSID (mod 2^36-1), and lies between 0 and         \
         * 2^36-1+2^28-1.  That in particular means that if r3 >=       \
         * 2^36-1, then r3+1 has the 2^36 bit set.  So, if r3+1 has     \
         * the bit clear, r3 already has the answer we want, if it      \
@@ -513,34 +521,6 @@ typedef struct {
        })
 #endif /* 1 */
 
-/*
- * This is only valid for addresses >= PAGE_OFFSET
- * The proto-VSID space is divided into two class
- * User:   0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1
- * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1
- *
- * With KERNEL_START at 0xc000000000000000, the proto vsid for
- * the kernel ends up with 0xc00000000 (36 bits). With 64TB
- * support we need to have kernel proto-VSID in the
- * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS.
- */
-static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
-{
-       unsigned long proto_vsid;
-       /*
-        * We need to make sure proto_vsid for the kernel is
-        * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T])
-        */
-       if (ssize == MMU_SEGSIZE_256M) {
-               proto_vsid = ea >> SID_SHIFT;
-               proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS));
-               return vsid_scramble(proto_vsid, 256M);
-       }
-       proto_vsid = ea >> SID_SHIFT_1T;
-       proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T));
-       return vsid_scramble(proto_vsid, 1T);
-}
-
 /* Returns the segment size indicator for a user address */
 static inline int user_segment_size(unsigned long addr)
 {
@@ -550,17 +530,41 @@ static inline int user_segment_size(unsigned long addr)
        return MMU_SEGSIZE_256M;
 }
 
-/* This is only valid for user addresses (which are below 2^44) */
 static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
                                     int ssize)
 {
+       /*
+        * Bad address. We return VSID 0 for that
+        */
+       if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
+               return 0;
+
        if (ssize == MMU_SEGSIZE_256M)
-               return vsid_scramble((context << USER_ESID_BITS)
+               return vsid_scramble((context << ESID_BITS)
                                     | (ea >> SID_SHIFT), 256M);
-       return vsid_scramble((context << USER_ESID_BITS_1T)
+       return vsid_scramble((context << ESID_BITS_1T)
                             | (ea >> SID_SHIFT_1T), 1T);
 }
 
+/*
+ * This is only valid for addresses >= PAGE_OFFSET
+ *
+ * For kernel space, we use the top 4 context ids to map address as below
+ * 0x7fffc -  [ 0xc000000000000000 - 0xc0003fffffffffff ]
+ * 0x7fffd -  [ 0xd000000000000000 - 0xd0003fffffffffff ]
+ * 0x7fffe -  [ 0xe000000000000000 - 0xe0003fffffffffff ]
+ * 0x7ffff -  [ 0xf000000000000000 - 0xf0003fffffffffff ]
+ */
+static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
+{
+       unsigned long context;
+
+       /*
+        * kernel take the top 4 context from the available range
+        */
+       context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1;
+       return get_vsid(context, ea, ssize);
+}
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
index e6658612203010aec0d3ba6ebb1f9c646e639575..c9c67fc888c93d229b23a617d0fd9c2aa7a71e79 100644 (file)
 #define SPRN_HSRR0     0x13A   /* Hypervisor Save/Restore 0 */
 #define SPRN_HSRR1     0x13B   /* Hypervisor Save/Restore 1 */
 #define SPRN_FSCR      0x099   /* Facility Status & Control Register */
-#define FSCR_TAR       (1<<8)  /* Enable Target Adress Register */
+#define   FSCR_TAR     (1 << (63-55)) /* Enable Target Address Register */
+#define   FSCR_DSCR    (1 << (63-61)) /* Enable Data Stream Control Register */
 #define SPRN_TAR       0x32f   /* Target Address Register */
 #define SPRN_LPCR      0x13E   /* LPAR Control Register */
 #define   LPCR_VPM0    (1ul << (63-0))
index 535b6d8a41ccae912590c0ec14d2fb355f0f4800..ebbec52d21bd69c634a547a82d707f1d7244b2e0 100644 (file)
@@ -358,3 +358,4 @@ SYSCALL_SPU(setns)
 COMPAT_SYS(process_vm_readv)
 COMPAT_SYS(process_vm_writev)
 SYSCALL(finit_module)
+SYSCALL(ni_syscall) /* sys_kcmp */
index f25b5c45c4359632d2b5259438173f493bfb6810..1487f0f12293bfd31ecdc1816072c52fc12d1b11 100644 (file)
@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define __NR_syscalls          354
+#define __NR_syscalls          355
 
 #define __NR__exit __NR_exit
 #define NR_syscalls    __NR_syscalls
index 8c478c6c6b1e41c7090b06a8b52815f7d537ff89..74cb4d72d6739baafba86eeb4fe1d591f5dd99fd 100644 (file)
 #define __NR_process_vm_readv  351
 #define __NR_process_vm_writev 352
 #define __NR_finit_module      353
+#define __NR_kcmp              354
 
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
index d29facbf9a288490a7552331e498eea259eb713f..ea847abb0d0a5fae6738c1bed0dc863d78358ded 100644 (file)
@@ -48,6 +48,7 @@ _GLOBAL(__restore_cpu_power7)
 
 _GLOBAL(__setup_cpu_power8)
        mflr    r11
+       bl      __init_FSCR
        bl      __init_hvmode_206
        mtlr    r11
        beqlr
@@ -56,13 +57,13 @@ _GLOBAL(__setup_cpu_power8)
        mfspr   r3,SPRN_LPCR
        oris    r3, r3, LPCR_AIL_3@h
        bl      __init_LPCR
-       bl      __init_FSCR
        bl      __init_TLB
        mtlr    r11
        blr
 
 _GLOBAL(__restore_cpu_power8)
        mflr    r11
+       bl      __init_FSCR
        mfmsr   r3
        rldicl. r0,r3,4,63
        beqlr
@@ -115,7 +116,7 @@ __init_LPCR:
 
 __init_FSCR:
        mfspr   r3,SPRN_FSCR
-       ori     r3,r3,FSCR_TAR
+       ori     r3,r3,FSCR_TAR|FSCR_DSCR
        mtspr   SPRN_FSCR,r3
        blr
 
index 75a3d71b895d985e20307bdd90dda88e4449ed9c..19599ef352bc89ddb8039a65cf22419d82c25c9f 100644 (file)
@@ -275,7 +275,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_features           = CPU_FTRS_PPC970,
                .cpu_user_features      = COMMON_USER_POWER4 |
                        PPC_FEATURE_HAS_ALTIVEC_COMP,
-               .mmu_features           = MMU_FTR_HPTE_TABLE,
+               .mmu_features           = MMU_FTRS_PPC970,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
index a8a5361fb70c716b74fe6abd880ce877be52c10a..200afa5bcfb73da1efa111c5b22ad62b09b3bb74 100644 (file)
@@ -74,13 +74,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)                              \
        mflr    r10 ;                                           \
        ld      r12,PACAKBASE(r13) ;                            \
        LOAD_HANDLER(r12, system_call_entry_direct) ;           \
-       mtlr    r12 ;                                           \
+       mtctr   r12 ;                                           \
        mfspr   r12,SPRN_SRR1 ;                                 \
        /* Re-use of r13... No spare regs to do this */ \
        li      r13,MSR_RI ;                                    \
        mtmsrd  r13,1 ;                                         \
        GET_PACA(r13) ; /* get r13 back */                      \
-       blr ;
+       bctr ;
 #else
        /* We can branch directly */
 #define SYSCALL_PSERIES_2_DIRECT                               \
@@ -1452,20 +1452,36 @@ do_ste_alloc:
 _GLOBAL(do_stab_bolted)
        stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
        std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
+       mfspr   r11,SPRN_DAR                    /* ea */
 
+       /*
+        * check for bad kernel/user address
+        * (ea & ~REGION_MASK) >= PGTABLE_RANGE
+        */
+       rldicr. r9,r11,4,(63 - 46 - 4)
+       li      r9,0    /* VSID = 0 for bad address */
+       bne-    0f
+
+       /*
+        * Calculate VSID:
+        * This is the kernel vsid, we take the top for context from
+        * the range. context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1
+        * Here we know that (ea >> 60) == 0xc
+        */
+       lis     r9,(MAX_USER_CONTEXT + 1)@ha
+       addi    r9,r9,(MAX_USER_CONTEXT + 1)@l
+
+       srdi    r10,r11,SID_SHIFT
+       rldimi  r10,r9,ESID_BITS,0 /* proto vsid */
+       ASM_VSID_SCRAMBLE(r10, r9, 256M)
+       rldic   r9,r10,12,16    /* r9 = vsid << 12 */
+
+0:
        /* Hash to the primary group */
        ld      r10,PACASTABVIRT(r13)
-       mfspr   r11,SPRN_DAR
-       srdi    r11,r11,28
+       srdi    r11,r11,SID_SHIFT
        rldimi  r10,r11,7,52    /* r10 = first ste of the group */
 
-       /* Calculate VSID */
-       /* This is a kernel address, so protovsid = ESID | 1 << 37 */
-       li      r9,0x1
-       rldimi  r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
-       ASM_VSID_SCRAMBLE(r11, r9, 256M)
-       rldic   r9,r11,12,16    /* r9 = vsid << 12 */
-
        /* Search the primary group for a free entry */
 1:     ld      r11,0(r10)      /* Test valid bit of the current ste    */
        andi.   r11,r11,0x80
index f5725bce9ed29c55583b2805749a542628977698..801a757c363000fc7f5c4bc44bfcd51b3f30a239 100644 (file)
@@ -41,8 +41,6 @@
 
 /* #define LPARCFG_DEBUG */
 
-static struct proc_dir_entry *proc_ppc64_lparcfg;
-
 /*
  * Track sum of all purrs across all processors. This is used to further
  * calculate usage values by different applications
@@ -688,27 +686,22 @@ static const struct file_operations lparcfg_fops = {
 
 static int __init lparcfg_init(void)
 {
-       struct proc_dir_entry *ent;
        umode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
 
        /* Allow writing if we have FW_FEATURE_SPLPAR */
        if (firmware_has_feature(FW_FEATURE_SPLPAR))
                mode |= S_IWUSR;
 
-       ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops);
-       if (!ent) {
+       if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) {
                printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
                return -EIO;
        }
-
-       proc_ppc64_lparcfg = ent;
        return 0;
 }
 
 static void __exit lparcfg_cleanup(void)
 {
-       if (proc_ppc64_lparcfg)
-               remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
+       remove_proc_subtree("powerpc/lparcfg", NULL);
 }
 
 module_init(lparcfg_init);
index f19d0bdc32411c29e4de5f0e41e86a4be3f73d71..feb8580fdc843acc485df310ed1c072907dc7159 100644 (file)
@@ -32,8 +32,6 @@
 static loff_t page_map_seek( struct file *file, loff_t off, int whence)
 {
        loff_t new;
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-
        switch(whence) {
        case 0:
                new = off;
@@ -42,12 +40,12 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence)
                new = file->f_pos + off;
                break;
        case 2:
-               new = dp->size + off;
+               new = PAGE_SIZE + off;
                break;
        default:
                return -EINVAL;
        }
-       if ( new < 0 || new > dp->size )
+       if ( new < 0 || new > PAGE_SIZE )
                return -EINVAL;
        return (file->f_pos = new);
 }
@@ -55,19 +53,18 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence)
 static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
                              loff_t *ppos)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
+       return simple_read_from_buffer(buf, nbytes, ppos,
+                       PDE_DATA(file_inode(file)), PAGE_SIZE);
 }
 
 static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-
-       if ((vma->vm_end - vma->vm_start) > dp->size)
+       if ((vma->vm_end - vma->vm_start) > PAGE_SIZE)
                return -EINVAL;
 
-       remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
-                                               dp->size, vma->vm_page_prot);
+       remap_pfn_range(vma, vma->vm_start,
+                       __pa(PDE_DATA(file_inode(file))) >> PAGE_SHIFT,
+                       PAGE_SIZE, vma->vm_page_prot);
        return 0;
 }
 
@@ -86,7 +83,7 @@ static int __init proc_ppc64_init(void)
                               &page_map_fops, vdso_data);
        if (!pde)
                return 1;
-       pde->size = PAGE_SIZE;
+       proc_set_size(pde, PAGE_SIZE);
 
        return 0;
 }
index 7f7fb7fd991bd4e6185937faf1864499433b0eb6..13f8d168b3f1e467599248c92457c442b456b7ee 100644 (file)
@@ -2832,11 +2832,13 @@ static void unreloc_toc(void)
 {
 }
 #else
-static void __reloc_toc(void *tocstart, unsigned long offset,
-                       unsigned long nr_entries)
+static void __reloc_toc(unsigned long offset, unsigned long nr_entries)
 {
        unsigned long i;
-       unsigned long *toc_entry = (unsigned long *)tocstart;
+       unsigned long *toc_entry;
+
+       /* Get the start of the TOC by using r2 directly. */
+       asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry));
 
        for (i = 0; i < nr_entries; i++) {
                *toc_entry = *toc_entry + offset;
@@ -2850,8 +2852,7 @@ static void reloc_toc(void)
        unsigned long nr_entries =
                (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
 
-       /* Need to add offset to get at __prom_init_toc_start */
-       __reloc_toc(__prom_init_toc_start + offset, offset, nr_entries);
+       __reloc_toc(offset, nr_entries);
 
        mb();
 }
@@ -2864,8 +2865,7 @@ static void unreloc_toc(void)
 
        mb();
 
-       /* __prom_init_toc_start has been relocated, no need to add offset */
-       __reloc_toc(__prom_init_toc_start, -offset, nr_entries);
+       __reloc_toc(-offset, nr_entries);
 }
 #endif
 #endif
index 245c1b6a08589d216d3389308c565668b720b597..f9b30c68ba473a7f51607936da0e124507f40362 100644 (file)
@@ -1428,6 +1428,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
 
        brk.address = bp_info->addr & ~7UL;
        brk.type = HW_BRK_TYPE_TRANSLATE;
+       brk.len = 8;
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
                brk.type |= HW_BRK_TYPE_READ;
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
index c642f01329887bca409d8da81d58f1129c6df6cd..5b770262c6737034dcb5c9947bde05375c71250f 100644 (file)
@@ -102,9 +102,10 @@ static struct kmem_cache *flash_block_cache = NULL;
 
 #define FLASH_BLOCK_LIST_VERSION (1UL)
 
-/* Local copy of the flash block list.
- * We only allow one open of the flash proc file and create this
- * list as we go.  The rtas_firmware_flash_list varable will be
+/*
+ * Local copy of the flash block list.
+ *
+ * The rtas_firmware_flash_list varable will be
  * set once the data is fully read.
  *
  * For convenience as we build the list we use virtual addrs,
@@ -125,23 +126,23 @@ struct rtas_update_flash_t
 struct rtas_manage_flash_t
 {
        int status;                     /* Returned status */
-       unsigned int op;                /* Reject or commit image */
 };
 
 /* Status int must be first member of struct */
 struct rtas_validate_flash_t
 {
        int status;                     /* Returned status */   
-       char buf[VALIDATE_BUF_SIZE];    /* Candidate image buffer */
+       char *buf;                      /* Candidate image buffer */
        unsigned int buf_size;          /* Size of image buf */
        unsigned int update_results;    /* Update results token */
 };
 
-static DEFINE_SPINLOCK(flash_file_open_lock);
-static struct proc_dir_entry *firmware_flash_pde;
-static struct proc_dir_entry *firmware_update_pde;
-static struct proc_dir_entry *validate_pde;
-static struct proc_dir_entry *manage_pde;
+static struct rtas_update_flash_t rtas_update_flash_data;
+static struct rtas_manage_flash_t rtas_manage_flash_data;
+static struct rtas_validate_flash_t rtas_validate_flash_data;
+static DEFINE_MUTEX(rtas_update_flash_mutex);
+static DEFINE_MUTEX(rtas_manage_flash_mutex);
+static DEFINE_MUTEX(rtas_validate_flash_mutex);
 
 /* Do simple sanity checks on the flash image. */
 static int flash_list_valid(struct flash_block_list *flist)
@@ -191,10 +192,10 @@ static void free_flash_list(struct flash_block_list *f)
 
 static int rtas_flash_release(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_update_flash_t *uf;
-       
-       uf = (struct rtas_update_flash_t *) dp->data;
+       struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
+
+       mutex_lock(&rtas_update_flash_mutex);
+
        if (uf->flist) {    
                /* File was opened in write mode for a new flash attempt */
                /* Clear saved list */
@@ -214,13 +215,14 @@ static int rtas_flash_release(struct inode *inode, struct file *file)
                uf->flist = NULL;
        }
 
-       atomic_dec(&dp->count);
+       mutex_unlock(&rtas_update_flash_mutex);
        return 0;
 }
 
-static void get_flash_status_msg(int status, char *buf)
+static size_t get_flash_status_msg(int status, char *buf)
 {
-       char *msg;
+       const char *msg;
+       size_t len;
 
        switch (status) {
        case FLASH_AUTH:
@@ -242,34 +244,51 @@ static void get_flash_status_msg(int status, char *buf)
                msg = "ready: firmware image ready for flash on reboot\n";
                break;
        default:
-               sprintf(buf, "error: unexpected status value %d\n", status);
-               return;
+               return sprintf(buf, "error: unexpected status value %d\n",
+                              status);
        }
 
-       strcpy(buf, msg);       
+       len = strlen(msg);
+       memcpy(buf, msg, len + 1);
+       return len;
 }
 
 /* Reading the proc file will show status (not the firmware contents) */
-static ssize_t rtas_flash_read(struct file *file, char __user *buf,
-                              size_t count, loff_t *ppos)
+static ssize_t rtas_flash_read_msg(struct file *file, char __user *buf,
+                                  size_t count, loff_t *ppos)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_update_flash_t *uf;
+       struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
        char msg[RTAS_MSG_MAXLEN];
+       size_t len;
+       int status;
 
-       uf = dp->data;
+       mutex_lock(&rtas_update_flash_mutex);
+       status = uf->status;
+       mutex_unlock(&rtas_update_flash_mutex);
 
-       if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
-               get_flash_status_msg(uf->status, msg);
-       } else {           /* FIRMWARE_UPDATE_NAME */
-               sprintf(msg, "%d\n", uf->status);
-       }
+       /* Read as text message */
+       len = get_flash_status_msg(status, msg);
+       return simple_read_from_buffer(buf, count, ppos, msg, len);
+}
+
+static ssize_t rtas_flash_read_num(struct file *file, char __user *buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
+       char msg[RTAS_MSG_MAXLEN];
+       int status;
 
+       mutex_lock(&rtas_update_flash_mutex);
+       status = uf->status;
+       mutex_unlock(&rtas_update_flash_mutex);
+
+       /* Read as number */
+       sprintf(msg, "%d\n", status);
        return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg));
 }
 
 /* constructor for flash_block_cache */
-void rtas_block_ctor(void *ptr)
+static void rtas_block_ctor(void *ptr)
 {
        memset(ptr, 0, RTAS_BLK_SIZE);
 }
@@ -282,16 +301,15 @@ void rtas_block_ctor(void *ptr)
 static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
                                size_t count, loff_t *off)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_update_flash_t *uf;
+       struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
        char *p;
-       int next_free;
+       int next_free, rc;
        struct flash_block_list *fl;
 
-       uf = (struct rtas_update_flash_t *) dp->data;
+       mutex_lock(&rtas_update_flash_mutex);
 
        if (uf->status == FLASH_AUTH || count == 0)
-               return count;   /* discard data */
+               goto out;       /* discard data */
 
        /* In the case that the image is not ready for flashing, the memory
         * allocated for the block list will be freed upon the release of the 
@@ -300,7 +318,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
        if (uf->flist == NULL) {
                uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
                if (!uf->flist)
-                       return -ENOMEM;
+                       goto nomem;
        }
 
        fl = uf->flist;
@@ -311,7 +329,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
                /* Need to allocate another block_list */
                fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
                if (!fl->next)
-                       return -ENOMEM;
+                       goto nomem;
                fl = fl->next;
                next_free = 0;
        }
@@ -320,52 +338,37 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
                count = RTAS_BLK_SIZE;
        p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
        if (!p)
-               return -ENOMEM;
+               goto nomem;
        
        if(copy_from_user(p, buffer, count)) {
                kmem_cache_free(flash_block_cache, p);
-               return -EFAULT;
+               rc = -EFAULT;
+               goto error;
        }
        fl->blocks[next_free].data = p;
        fl->blocks[next_free].length = count;
        fl->num_blocks++;
-
+out:
+       mutex_unlock(&rtas_update_flash_mutex);
        return count;
-}
-
-static int rtas_excl_open(struct inode *inode, struct file *file)
-{
-       struct proc_dir_entry *dp = PDE(inode);
-
-       /* Enforce exclusive open with use count of PDE */
-       spin_lock(&flash_file_open_lock);
-       if (atomic_read(&dp->count) > 2) {
-               spin_unlock(&flash_file_open_lock);
-               return -EBUSY;
-       }
-
-       atomic_inc(&dp->count);
-       spin_unlock(&flash_file_open_lock);
-       
-       return 0;
-}
-
-static int rtas_excl_release(struct inode *inode, struct file *file)
-{
-       struct proc_dir_entry *dp = PDE(inode);
 
-       atomic_dec(&dp->count);
-
-       return 0;
+nomem:
+       rc = -ENOMEM;
+error:
+       mutex_unlock(&rtas_update_flash_mutex);
+       return rc;
 }
 
-static void manage_flash(struct rtas_manage_flash_t *args_buf)
+/*
+ * Flash management routines.
+ */
+static void manage_flash(struct rtas_manage_flash_t *args_buf, unsigned int op)
 {
        s32 rc;
 
        do {
-               rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 
-                              1, NULL, args_buf->op);
+               rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1,
+                              NULL, op);
        } while (rtas_busy_delay(rc));
 
        args_buf->status = rc;
@@ -374,55 +377,62 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf)
 static ssize_t manage_flash_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_manage_flash_t *args_buf;
+       struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data;
        char msg[RTAS_MSG_MAXLEN];
-       int msglen;
+       int msglen, status;
 
-       args_buf = dp->data;
-       if (args_buf == NULL)
-               return 0;
-
-       msglen = sprintf(msg, "%d\n", args_buf->status);
+       mutex_lock(&rtas_manage_flash_mutex);
+       status = args_buf->status;
+       mutex_unlock(&rtas_manage_flash_mutex);
 
+       msglen = sprintf(msg, "%d\n", status);
        return simple_read_from_buffer(buf, count, ppos, msg, msglen);
 }
 
 static ssize_t manage_flash_write(struct file *file, const char __user *buf,
                                size_t count, loff_t *off)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_manage_flash_t *args_buf;
-       const char reject_str[] = "0";
-       const char commit_str[] = "1";
+       struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data;
+       static const char reject_str[] = "0";
+       static const char commit_str[] = "1";
        char stkbuf[10];
-       int op;
+       int op, rc;
+
+       mutex_lock(&rtas_manage_flash_mutex);
 
-       args_buf = (struct rtas_manage_flash_t *) dp->data;
        if ((args_buf->status == MANAGE_AUTH) || (count == 0))
-               return count;
+               goto out;
                
        op = -1;
        if (buf) {
                if (count > 9) count = 9;
-               if (copy_from_user (stkbuf, buf, count)) {
-                       return -EFAULT;
-               }
+               rc = -EFAULT;
+               if (copy_from_user (stkbuf, buf, count))
+                       goto error;
                if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) 
                        op = RTAS_REJECT_TMP_IMG;
                else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) 
                        op = RTAS_COMMIT_TMP_IMG;
        }
        
-       if (op == -1)   /* buf is empty, or contains invalid string */
-               return -EINVAL;
-
-       args_buf->op = op;
-       manage_flash(args_buf);
+       if (op == -1) {   /* buf is empty, or contains invalid string */
+               rc = -EINVAL;
+               goto error;
+       }
 
+       manage_flash(args_buf, op);
+out:
+       mutex_unlock(&rtas_manage_flash_mutex);
        return count;
+
+error:
+       mutex_unlock(&rtas_manage_flash_mutex);
+       return rc;
 }
 
+/*
+ * Validation routines.
+ */
 static void validate_flash(struct rtas_validate_flash_t *args_buf)
 {
        int token = rtas_token("ibm,validate-flash-image");
@@ -462,14 +472,14 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,
 static ssize_t validate_flash_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_validate_flash_t *args_buf;
+       struct rtas_validate_flash_t *const args_buf =
+               &rtas_validate_flash_data;
        char msg[RTAS_MSG_MAXLEN];
        int msglen;
 
-       args_buf = dp->data;
-
+       mutex_lock(&rtas_validate_flash_mutex);
        msglen = get_validate_flash_msg(args_buf, msg);
+       mutex_unlock(&rtas_validate_flash_mutex);
 
        return simple_read_from_buffer(buf, count, ppos, msg, msglen);
 }
@@ -477,24 +487,18 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf,
 static ssize_t validate_flash_write(struct file *file, const char __user *buf,
                                    size_t count, loff_t *off)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_validate_flash_t *args_buf;
+       struct rtas_validate_flash_t *const args_buf =
+               &rtas_validate_flash_data;
        int rc;
 
-       args_buf = (struct rtas_validate_flash_t *) dp->data;
-
-       if (dp->data == NULL) {
-               dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), 
-                               GFP_KERNEL);
-               if (dp->data == NULL) 
-                       return -ENOMEM;
-       }
+       mutex_lock(&rtas_validate_flash_mutex);
 
        /* We are only interested in the first 4K of the
         * candidate image */
        if ((*off >= VALIDATE_BUF_SIZE) || 
                (args_buf->status == VALIDATE_AUTH)) {
                *off += count;
+               mutex_unlock(&rtas_validate_flash_mutex);
                return count;
        }
 
@@ -517,31 +521,29 @@ static ssize_t validate_flash_write(struct file *file, const char __user *buf,
        *off += count;
        rc = count;
 done:
-       if (rc < 0) {
-               kfree(dp->data);
-               dp->data = NULL;
-       }
+       mutex_unlock(&rtas_validate_flash_mutex);
        return rc;
 }
 
 static int validate_flash_release(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct rtas_validate_flash_t *args_buf;
+       struct rtas_validate_flash_t *const args_buf =
+               &rtas_validate_flash_data;
 
-       args_buf = (struct rtas_validate_flash_t *) dp->data;
+       mutex_lock(&rtas_validate_flash_mutex);
 
        if (args_buf->status == VALIDATE_READY) {
                args_buf->buf_size = VALIDATE_BUF_SIZE;
                validate_flash(args_buf);
        }
 
-       /* The matching atomic_inc was in rtas_excl_open() */
-       atomic_dec(&dp->count);
-
+       mutex_unlock(&rtas_validate_flash_mutex);
        return 0;
 }
 
+/*
+ * On-reboot flash update applicator.
+ */
 static void rtas_flash_firmware(int reboot_type)
 {
        unsigned long image_size;
@@ -634,75 +636,57 @@ static void rtas_flash_firmware(int reboot_type)
        spin_unlock(&rtas_data_buf_lock);
 }
 
-static void remove_flash_pde(struct proc_dir_entry *dp)
-{
-       if (dp) {
-               kfree(dp->data);
-               remove_proc_entry(dp->name, dp->parent);
-       }
-}
-
-static int initialize_flash_pde_data(const char *rtas_call_name,
-                                    size_t buf_size,
-                                    struct proc_dir_entry *dp)
-{
+/*
+ * Manifest of proc files to create
+ */
+struct rtas_flash_file {
+       const char *filename;
+       const char *rtas_call_name;
        int *status;
-       int token;
-
-       dp->data = kzalloc(buf_size, GFP_KERNEL);
-       if (dp->data == NULL)
-               return -ENOMEM;
-
-       /*
-        * This code assumes that the status int is the first member of the
-        * struct 
-        */
-       status = (int *) dp->data;
-       token = rtas_token(rtas_call_name);
-       if (token == RTAS_UNKNOWN_SERVICE)
-               *status = FLASH_AUTH;
-       else
-               *status = FLASH_NO_OP;
-
-       return 0;
-}
-
-static struct proc_dir_entry *create_flash_pde(const char *filename,
-                                              const struct file_operations *fops)
-{
-       return proc_create(filename, S_IRUSR | S_IWUSR, NULL, fops);
-}
-
-static const struct file_operations rtas_flash_operations = {
-       .owner          = THIS_MODULE,
-       .read           = rtas_flash_read,
-       .write          = rtas_flash_write,
-       .open           = rtas_excl_open,
-       .release        = rtas_flash_release,
-       .llseek         = default_llseek,
-};
-
-static const struct file_operations manage_flash_operations = {
-       .owner          = THIS_MODULE,
-       .read           = manage_flash_read,
-       .write          = manage_flash_write,
-       .open           = rtas_excl_open,
-       .release        = rtas_excl_release,
-       .llseek         = default_llseek,
+       const struct file_operations fops;
 };
 
-static const struct file_operations validate_flash_operations = {
-       .owner          = THIS_MODULE,
-       .read           = validate_flash_read,
-       .write          = validate_flash_write,
-       .open           = rtas_excl_open,
-       .release        = validate_flash_release,
-       .llseek         = default_llseek,
+static const struct rtas_flash_file rtas_flash_files[] = {
+       {
+               .filename       = "powerpc/rtas/" FIRMWARE_FLASH_NAME,
+               .rtas_call_name = "ibm,update-flash-64-and-reboot",
+               .status         = &rtas_update_flash_data.status,
+               .fops.read      = rtas_flash_read_msg,
+               .fops.write     = rtas_flash_write,
+               .fops.release   = rtas_flash_release,
+               .fops.llseek    = default_llseek,
+       },
+       {
+               .filename       = "powerpc/rtas/" FIRMWARE_UPDATE_NAME,
+               .rtas_call_name = "ibm,update-flash-64-and-reboot",
+               .status         = &rtas_update_flash_data.status,
+               .fops.read      = rtas_flash_read_num,
+               .fops.write     = rtas_flash_write,
+               .fops.release   = rtas_flash_release,
+               .fops.llseek    = default_llseek,
+       },
+       {
+               .filename       = "powerpc/rtas/" VALIDATE_FLASH_NAME,
+               .rtas_call_name = "ibm,validate-flash-image",
+               .status         = &rtas_validate_flash_data.status,
+               .fops.read      = validate_flash_read,
+               .fops.write     = validate_flash_write,
+               .fops.release   = validate_flash_release,
+               .fops.llseek    = default_llseek,
+       },
+       {
+               .filename       = "powerpc/rtas/" MANAGE_FLASH_NAME,
+               .rtas_call_name = "ibm,manage-flash-image",
+               .status         = &rtas_manage_flash_data.status,
+               .fops.read      = manage_flash_read,
+               .fops.write     = manage_flash_write,
+               .fops.llseek    = default_llseek,
+       }
 };
 
 static int __init rtas_flash_init(void)
 {
-       int rc;
+       int i;
 
        if (rtas_token("ibm,update-flash-64-and-reboot") ==
                       RTAS_UNKNOWN_SERVICE) {
@@ -710,93 +694,65 @@ static int __init rtas_flash_init(void)
                return 1;
        }
 
-       firmware_flash_pde = create_flash_pde("powerpc/rtas/"
-                                             FIRMWARE_FLASH_NAME,
-                                             &rtas_flash_operations);
-       if (firmware_flash_pde == NULL) {
-               rc = -ENOMEM;
-               goto cleanup;
-       }
+       rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
+       if (!rtas_validate_flash_data.buf)
+               return -ENOMEM;
 
-       rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
-                                      sizeof(struct rtas_update_flash_t), 
-                                      firmware_flash_pde);
-       if (rc != 0)
-               goto cleanup;
-
-       firmware_update_pde = create_flash_pde("powerpc/rtas/"
-                                              FIRMWARE_UPDATE_NAME,
-                                              &rtas_flash_operations);
-       if (firmware_update_pde == NULL) {
-               rc = -ENOMEM;
-               goto cleanup;
+       flash_block_cache = kmem_cache_create("rtas_flash_cache",
+                                             RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
+                                             rtas_block_ctor);
+       if (!flash_block_cache) {
+               printk(KERN_ERR "%s: failed to create block cache\n",
+                               __func__);
+               goto enomem_buf;
        }
 
-       rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
-                                      sizeof(struct rtas_update_flash_t), 
-                                      firmware_update_pde);
-       if (rc != 0)
-               goto cleanup;
-
-       validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME,
-                                       &validate_flash_operations);
-       if (validate_pde == NULL) {
-               rc = -ENOMEM;
-               goto cleanup;
-       }
+       for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) {
+               const struct rtas_flash_file *f = &rtas_flash_files[i];
+               int token;
 
-       rc = initialize_flash_pde_data("ibm,validate-flash-image",
-                                      sizeof(struct rtas_validate_flash_t), 
-                                      validate_pde);
-       if (rc != 0)
-               goto cleanup;
-
-       manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME,
-                                     &manage_flash_operations);
-       if (manage_pde == NULL) {
-               rc = -ENOMEM;
-               goto cleanup;
-       }
+               if (!proc_create(f->filename, S_IRUSR | S_IWUSR, NULL, &f->fops))
+                       goto enomem;
 
-       rc = initialize_flash_pde_data("ibm,manage-flash-image",
-                                      sizeof(struct rtas_manage_flash_t),
-                                      manage_pde);
-       if (rc != 0)
-               goto cleanup;
+               /*
+                * This code assumes that the status int is the first member of the
+                * struct
+                */
+               token = rtas_token(f->rtas_call_name);
+               if (token == RTAS_UNKNOWN_SERVICE)
+                       *f->status = FLASH_AUTH;
+               else
+                       *f->status = FLASH_NO_OP;
+       }
 
        rtas_flash_term_hook = rtas_flash_firmware;
-
-       flash_block_cache = kmem_cache_create("rtas_flash_cache",
-                               RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
-                               rtas_block_ctor);
-       if (!flash_block_cache) {
-               printk(KERN_ERR "%s: failed to create block cache\n",
-                               __func__);
-               rc = -ENOMEM;
-               goto cleanup;
-       }
        return 0;
 
-cleanup:
-       remove_flash_pde(firmware_flash_pde);
-       remove_flash_pde(firmware_update_pde);
-       remove_flash_pde(validate_pde);
-       remove_flash_pde(manage_pde);
+enomem:
+       while (--i >= 0) {
+               const struct rtas_flash_file *f = &rtas_flash_files[i];
+               remove_proc_entry(f->filename, NULL);
+       }
 
-       return rc;
+       kmem_cache_destroy(flash_block_cache);
+enomem_buf:
+       kfree(rtas_validate_flash_data.buf);
+       return -ENOMEM;
 }
 
 static void __exit rtas_flash_cleanup(void)
 {
+       int i;
+
        rtas_flash_term_hook = NULL;
 
-       if (flash_block_cache)
-               kmem_cache_destroy(flash_block_cache);
+       for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) {
+               const struct rtas_flash_file *f = &rtas_flash_files[i];
+               remove_proc_entry(f->filename, NULL);
+       }
 
-       remove_flash_pde(firmware_flash_pde);
-       remove_flash_pde(firmware_update_pde);
-       remove_flash_pde(validate_pde);
-       remove_flash_pde(manage_pde);
+       kmem_cache_destroy(flash_block_cache);
+       kfree(rtas_validate_flash_data.buf);
 }
 
 module_init(rtas_flash_init);
index ead58e3172945d81e863ba937cc1d88b93922558..5d7d29a313eb99d8581f7bf2e515421020628fbe 100644 (file)
@@ -326,8 +326,8 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
        vcpu3s->context_id[0] = err;
 
        vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1)
-                                 << USER_ESID_BITS) - 1;
-       vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
+                                 << ESID_BITS) - 1;
+       vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << ESID_BITS;
        vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first;
 
        kvmppc_mmu_hpte_init(vcpu);
index 8cc18abd6dde6b486996bf9f4719fdeb12e0c65e..da98e26f6e454c95be4596a12f85da4840b6f1e9 100644 (file)
@@ -1467,7 +1467,7 @@ static int kvm_htab_release(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static struct file_operations kvm_htab_fops = {
+static const struct file_operations kvm_htab_fops = {
        .read           = kvm_htab_read,
        .write          = kvm_htab_write,
        .llseek         = default_llseek,
index 72ffc899c082213076f872bcba48d494d9dfecbb..b2d3f3b2de72a7a796e88bee5e28184adc3ae0a6 100644 (file)
@@ -92,7 +92,7 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static struct file_operations kvm_spapr_tce_fops = {
+static const struct file_operations kvm_spapr_tce_fops = {
        .mmap           = kvm_spapr_tce_mmap,
        .release        = kvm_spapr_tce_release,
 };
index 80dcc53a1abaf813659cf2102b9e701c30fc16cf..b62bd1b97c6878ffe2c8e655250fccb736b92b0a 100644 (file)
@@ -1483,7 +1483,7 @@ static int kvm_rma_release(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static struct file_operations kvm_rma_fops = {
+static const struct file_operations kvm_rma_fops = {
        .mmap           = kvm_rma_mmap,
        .release        = kvm_rma_release,
 };
index 1b6e1271719f994e1d16b21621851733658bffa5..f410c3e12c1e78c0a6c5e24ad9f41d86fdf01337 100644 (file)
@@ -195,6 +195,11 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                unsigned long vpn  = hpt_vpn(vaddr, vsid, ssize);
                unsigned long tprot = prot;
 
+               /*
+                * If we hit a bad address return error.
+                */
+               if (!vsid)
+                       return -1;
                /* Make kernel text executable */
                if (overlaps_kernel_text(vaddr, vaddr + step))
                        tprot &= ~HPTE_R_N;
@@ -759,6 +764,8 @@ void __init early_init_mmu(void)
        /* Initialize stab / SLB management */
        if (mmu_has_feature(MMU_FTR_SLB))
                slb_initialize();
+       else
+               stab_initialize(get_paca()->stab_real);
 }
 
 #ifdef CONFIG_SMP
@@ -922,11 +929,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
                ea, access, trap);
 
-       if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) {
-               DBG_LOW(" out of pgtable range !\n");
-               return 1;
-       }
-
        /* Get region & vsid */
        switch (REGION_ID(ea)) {
        case USER_REGION_ID:
@@ -957,6 +959,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        }
        DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
 
+       /* Bad address. */
+       if (!vsid) {
+               DBG_LOW("Bad address!\n");
+               return 1;
+       }
        /* Get pgdir */
        pgdir = mm->pgd;
        if (pgdir == NULL)
@@ -1126,6 +1133,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
        /* Get VSID */
        ssize = user_segment_size(ea);
        vsid = get_vsid(mm->context.id, ea, ssize);
+       if (!vsid)
+               return;
 
        /* Hash doesn't like irqs */
        local_irq_save(flags);
@@ -1233,6 +1242,9 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
        hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
        hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
 
+       /* Don't create HPTE entries for bad address */
+       if (!vsid)
+               return;
        ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr),
                                 mode, HPTE_V_BOLTED,
                                 mmu_linear_psize, mmu_kernel_ssize);
index 40bc5b0ace54354aea6944d77b6ef07e6f7f7b3d..d1d1b92c5b9964c3363f84a1719f0759507ba41d 100644 (file)
 static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDA(mmu_context_ida);
 
-/*
- * 256MB segment
- * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
- * available for user mappings. Each segment contains 2^28 bytes. Each
- * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
- * (19 == 37 + 28 - 46).
- */
-#define MAX_CONTEXT    ((1UL << CONTEXT_BITS) - 1)
-
 int __init_new_context(void)
 {
        int index;
@@ -56,7 +47,7 @@ again:
        else if (err)
                return err;
 
-       if (index > MAX_CONTEXT) {
+       if (index > MAX_USER_CONTEXT) {
                spin_lock(&mmu_context_lock);
                ida_remove(&mmu_context_ida, index);
                spin_unlock(&mmu_context_lock);
index e212a271c7a4bdadac512efd24da89de6c9ddd77..654258f165aeb9496ae96131c0f9b383927e8d20 100644 (file)
@@ -61,7 +61,7 @@
 #endif
 
 #ifdef CONFIG_PPC_STD_MMU_64
-#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
+#if TASK_SIZE_USER64 > (1UL << (ESID_BITS + SID_SHIFT))
 #error TASK_SIZE_USER64 exceeds user VSID range
 #endif
 #endif
index 1a16ca2277575fef9c0614df84f6e4f93df376f1..17aa6dfceb3498cbb0a09302485bdf1ab8049cbf 100644 (file)
  * No other registers are examined or changed.
  */
 _GLOBAL(slb_allocate_realmode)
-       /* r3 = faulting address */
+       /*
+        * check for bad kernel/user address
+        * (ea & ~REGION_MASK) >= PGTABLE_RANGE
+        */
+       rldicr. r9,r3,4,(63 - 46 - 4)
+       bne-    8f
 
        srdi    r9,r3,60                /* get region */
-       srdi    r10,r3,28               /* get esid */
+       srdi    r10,r3,SID_SHIFT        /* get esid */
        cmpldi  cr7,r9,0xc              /* cmp PAGE_OFFSET for later use */
 
        /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
@@ -56,12 +61,14 @@ _GLOBAL(slb_allocate_realmode)
         */
 _GLOBAL(slb_miss_kernel_load_linear)
        li      r11,0
-       li      r9,0x1
        /*
-        * for 1T we shift 12 bits more.  slb_finish_load_1T will do
-        * the necessary adjustment
+        * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1
+        * r9 = region id.
         */
-       rldimi  r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
+       addis   r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@ha
+       addi    r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@l
+
+
 BEGIN_FTR_SECTION
        b       slb_finish_load
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
@@ -91,24 +98,19 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
        _GLOBAL(slb_miss_kernel_load_io)
        li      r11,0
 6:
-       li      r9,0x1
        /*
-        * for 1T we shift 12 bits more.  slb_finish_load_1T will do
-        * the necessary adjustment
+        * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1
+        * r9 = region id.
         */
-       rldimi  r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
+       addis   r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@ha
+       addi    r9,r9,(MAX_USER_CONTEXT - 0xc + 1)@l
+
 BEGIN_FTR_SECTION
        b       slb_finish_load
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
        b       slb_finish_load_1T
 
-0:     /* user address: proto-VSID = context << 15 | ESID. First check
-        * if the address is within the boundaries of the user region
-        */
-       srdi.   r9,r10,USER_ESID_BITS
-       bne-    8f                      /* invalid ea bits set */
-
-
+0:
        /* when using slices, we extract the psize off the slice bitmaps
         * and then we need to get the sllp encoding off the mmu_psize_defs
         * array.
@@ -164,15 +166,13 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
        ld      r9,PACACONTEXTID(r13)
 BEGIN_FTR_SECTION
        cmpldi  r10,0x1000
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
-       rldimi  r10,r9,USER_ESID_BITS,0
-BEGIN_FTR_SECTION
        bge     slb_finish_load_1T
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
        b       slb_finish_load
 
 8:     /* invalid EA */
        li      r10,0                   /* BAD_VSID */
+       li      r9,0                    /* BAD_VSID */
        li      r11,SLB_VSID_USER       /* flags don't much matter */
        b       slb_finish_load
 
@@ -221,8 +221,6 @@ _GLOBAL(slb_allocate_user)
 
        /* get context to calculate proto-VSID */
        ld      r9,PACACONTEXTID(r13)
-       rldimi  r10,r9,USER_ESID_BITS,0
-
        /* fall through slb_finish_load */
 
 #endif /* __DISABLED__ */
@@ -231,9 +229,10 @@ _GLOBAL(slb_allocate_user)
 /*
  * Finish loading of an SLB entry and return
  *
- * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <> PAGE_OFFSET
+ * r3 = EA, r9 = context, r10 = ESID, r11 = flags, clobbers r9, cr7 = <> PAGE_OFFSET
  */
 slb_finish_load:
+       rldimi  r10,r9,ESID_BITS,0
        ASM_VSID_SCRAMBLE(r10,r9,256M)
        /*
         * bits above VSID_BITS_256M need to be ignored from r10
@@ -298,10 +297,11 @@ _GLOBAL(slb_compare_rr_to_size)
 /*
  * Finish loading of a 1T SLB entry (for the kernel linear mapping) and return.
  *
- * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9
+ * r3 = EA, r9 = context, r10 = ESID(256MB), r11 = flags, clobbers r9
  */
 slb_finish_load_1T:
-       srdi    r10,r10,40-28           /* get 1T ESID */
+       srdi    r10,r10,(SID_SHIFT_1T - SID_SHIFT)      /* get 1T ESID */
+       rldimi  r10,r9,ESID_BITS_1T,0
        ASM_VSID_SCRAMBLE(r10,r9,1T)
        /*
         * bits above VSID_BITS_1T need to be ignored from r10
index 0d82ef50dc3faf9269042bb09001320fbdacdaad..023ec8a13f38eed82e45fe37fc0f6e4be9518b83 100644 (file)
@@ -82,11 +82,11 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
        if (!is_kernel_addr(addr)) {
                ssize = user_segment_size(addr);
                vsid = get_vsid(mm->context.id, addr, ssize);
-               WARN_ON(vsid == 0);
        } else {
                vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
                ssize = mmu_kernel_ssize;
        }
+       WARN_ON(vsid == 0);
        vpn = hpt_vpn(addr, vsid, ssize);
        rpte = __real_pte(__pte(pte), ptep);
 
index b554879bd31e4c48cc6769092695c7f32a899af4..3c475d6267c75b0db98584b0f4c7cd0379fd19d1 100644 (file)
@@ -420,7 +420,20 @@ static struct attribute_group power7_pmu_events_group = {
        .attrs = power7_events_attr,
 };
 
+PMU_FORMAT_ATTR(event, "config:0-19");
+
+static struct attribute *power7_pmu_format_attr[] = {
+       &format_attr_event.attr,
+       NULL,
+};
+
+struct attribute_group power7_pmu_format_group = {
+       .name = "format",
+       .attrs = power7_pmu_format_attr,
+};
+
 static const struct attribute_group *power7_pmu_attr_groups[] = {
+       &power7_pmu_format_group,
        &power7_pmu_events_group,
        NULL,
 };
index 611e92f291c428765378140dbf5dc06890c44973..7179726ba5c5fdb521afa9a78509eefca7695131 100644 (file)
@@ -69,7 +69,7 @@ static irqreturn_t gpio_halt_irq(int irq, void *__data)
         return IRQ_HANDLED;
 };
 
-static int __devinit gpio_halt_probe(struct platform_device *pdev)
+static int gpio_halt_probe(struct platform_device *pdev)
 {
        enum of_gpio_flags flags;
        struct device_node *node = pdev->dev.of_node;
@@ -128,7 +128,7 @@ static int __devinit gpio_halt_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __devexit gpio_halt_remove(struct platform_device *pdev)
+static int gpio_halt_remove(struct platform_device *pdev)
 {
        if (halt_node) {
                int gpio = of_get_gpio(halt_node, 0);
@@ -165,7 +165,7 @@ static struct platform_driver gpio_halt_driver = {
                .of_match_table = gpio_halt_match,
        },
        .probe          = gpio_halt_probe,
-       .remove         = __devexit_p(gpio_halt_remove),
+       .remove         = gpio_halt_remove,
 };
 
 module_platform_driver(gpio_halt_driver);
index cea2f09c42418d101c78b445b18c9286a714b53b..18e3b76c78d7ca3d8372ccda9808a5b122deb78d 100644 (file)
@@ -124,9 +124,8 @@ config 6xx
        select PPC_HAVE_PMU_SUPPORT
 
 config POWER3
-       bool
        depends on PPC64 && PPC_BOOK3S
-       default y if !POWER4_ONLY
+       def_bool y
 
 config POWER4
        depends on PPC64 && PPC_BOOK3S
@@ -145,8 +144,7 @@ config TUNE_CELL
          but somewhat slower on other machines. This option only changes
          the scheduling of instructions, not the selection of instructions
          itself, so the resulting kernel will keep running on all other
-         machines. When building a kernel that is supposed to run only
-         on Cell, you should also select the POWER4_ONLY option.
+         machines.
 
 # this is temp to handle compat with arch=ppc
 config 8xx
index 68c57d38745a9d175c10964879b9c98ab3e3ea68..d43d2d0b90e3f3902a5687072246622b3b055983 100644 (file)
@@ -149,7 +149,6 @@ static int __fops ## _open(struct inode *inode, struct file *file)  \
        return spufs_attr_open(inode, file, __get, __set, __fmt);       \
 }                                                                      \
 static const struct file_operations __fops = {                         \
-       .owner   = THIS_MODULE,                                         \
        .open    = __fops ## _open,                                     \
        .release = spufs_attr_release,                                  \
        .read    = spufs_attr_read,                                     \
@@ -2591,7 +2590,6 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait)
 }
 
 static const struct file_operations spufs_switch_log_fops = {
-       .owner          = THIS_MODULE,
        .open           = spufs_switch_log_open,
        .read           = spufs_switch_log_read,
        .poll           = spufs_switch_log_poll,
index 863184b182f47c09e0626d8147ebcd1e508af328..3f3bb4cdbbecb9f5a92b4ab662a8fd234a5443ac 100644 (file)
@@ -749,6 +749,7 @@ static struct file_system_type spufs_type = {
        .mount = spufs_mount,
        .kill_sb = kill_litter_super,
 };
+MODULE_ALIAS_FS("spufs");
 
 static int __init spufs_init(void)
 {
index fcf4b4cbeaf331aa7986b0b705bc4bbe2148ee7b..4557e91626c43bd58d95a1730456557eab3aee2f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 
 #include <asm/hvcall.h>
 #include <asm/hvcserver.h>
@@ -188,9 +189,9 @@ int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head,
                        = (unsigned int)last_p_partition_ID;
 
                /* copy the Null-term char too */
-               strncpy(&next_partner_info->location_code[0],
+               strlcpy(&next_partner_info->location_code[0],
                        (char *)&pi_buff[2],
-                       strlen((char *)&pi_buff[2]) + 1);
+                       sizeof(next_partner_info->location_code));
 
                list_add_tail(&(next_partner_info->node), head);
                next_partner_info = NULL;
index d6491bd481d0cef934cf9873a0b014d28c7a25ac..f93cdf55628c13ab8832df5c4693303ba2d20a8f 100644 (file)
@@ -452,7 +452,7 @@ static int proc_ppc64_create_ofdt(void)
 
        ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
        if (ent)
-               ent->size = 0;
+               proc_set_size(ent, 0);
 
        return 0;
 }
index 47f3cda2a68ba526779ed84b7399d3fd5d5888dd..b502ab61aafa897e30261fac7cd5d0492617a098 100644 (file)
 
 
 static unsigned int ibm_scan_log_dump;                 /* RTAS token */
-static struct proc_dir_entry *proc_ppc64_scan_log_dump;        /* The proc file */
+static unsigned int *scanlog_buffer;                   /* The data buffer */
 
 static ssize_t scanlog_read(struct file *file, char __user *buf,
                            size_t count, loff_t *ppos)
 {
-       struct proc_dir_entry *dp = PDE(file_inode(file));
-       unsigned int *data = (unsigned int *)dp->data;
+       unsigned int *data = scanlog_buffer;
        int status;
        unsigned long len, off;
        unsigned int wait_time;
@@ -135,8 +134,7 @@ static ssize_t scanlog_write(struct file * file, const char __user * buf,
 
 static int scanlog_open(struct inode * inode, struct file * file)
 {
-       struct proc_dir_entry *dp = PDE(inode);
-       unsigned int *data = (unsigned int *)dp->data;
+       unsigned int *data = scanlog_buffer;
 
        if (data[0] != 0) {
                /* This imperfect test stops a second copy of the
@@ -152,11 +150,9 @@ static int scanlog_open(struct inode * inode, struct file * file)
 
 static int scanlog_release(struct inode * inode, struct file * file)
 {
-       struct proc_dir_entry *dp = PDE(inode);
-       unsigned int *data = (unsigned int *)dp->data;
+       unsigned int *data = scanlog_buffer;
 
        data[0] = 0;
-
        return 0;
 }
 
@@ -172,7 +168,6 @@ const struct file_operations scanlog_fops = {
 static int __init scanlog_init(void)
 {
        struct proc_dir_entry *ent;
-       void *data;
        int err = -ENOMEM;
 
        ibm_scan_log_dump = rtas_token("ibm,scan-log-dump");
@@ -180,29 +175,24 @@ static int __init scanlog_init(void)
                return -ENODEV;
 
        /* Ideally we could allocate a buffer < 4G */
-       data = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
-       if (!data)
+       scanlog_buffer = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+       if (!scanlog_buffer)
                goto err;
 
-       ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
-                              &scanlog_fops, data);
+       ent = proc_create("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
+                         &scanlog_fops);
        if (!ent)
                goto err;
-
-       proc_ppc64_scan_log_dump = ent;
-
        return 0;
 err:
-       kfree(data);
+       kfree(scanlog_buffer);
        return err;
 }
 
 static void __exit scanlog_cleanup(void)
 {
-       if (proc_ppc64_scan_log_dump) {
-               kfree(proc_ppc64_scan_log_dump->data);
-               remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
-       }
+       remove_proc_entry("powerpc/rtas/scan-log-dump", NULL);
+       kfree(scanlog_buffer);
 }
 
 module_init(scanlog_init);
index 4b505370a1d59430b0bc519c47b926b0ed29adab..eb8fb629f00bba774b195a475471d630d6bd8bd0 100644 (file)
@@ -134,7 +134,7 @@ config S390
        select HAVE_SYSCALL_WRAPPERS
        select HAVE_UID16 if 32BIT
        select HAVE_VIRT_CPU_ACCOUNTING
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select INIT_ALL_POSSIBLE
        select KTIME_SCALAR if 32BIT
        select MODULES_USE_ELF_RELA
index 8538015ed4a0487c52b80be2035b8e301cc94f5e..5f7d7ba2874c8a6fa14b49bcefc7ef09ef59dc6b 100644 (file)
@@ -456,6 +456,7 @@ static struct file_system_type hypfs_type = {
        .mount          = hypfs_mount,
        .kill_sb        = hypfs_kill_super
 };
+MODULE_ALIAS_FS("s390_hypfs");
 
 static const struct super_operations hypfs_s_ops = {
        .statfs         = simple_statfs,
index f1eddd150dd7e782876ed8faff25a6d004b3f841..c879fad404c8d36d73aff75ea1174df65374061b 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _ASM_S390_CPU_MF_H
 #define _ASM_S390_CPU_MF_H
 
+#include <linux/errno.h>
 #include <asm/facility.h>
 
 #define CPU_MF_INT_SF_IAE      (1 << 31)       /* invalid entry address */
index 8d4847191ecc52121cbe2afaa04fff7e2c6d2ad8..dc9200ca32eda4d3e5a819025b176f7af5a06d60 100644 (file)
@@ -34,6 +34,8 @@ struct arsb {
        u32 reserved[4];
 } __packed;
 
+#define EQC_WR_PROHIBIT 22
+
 struct msb {
        u8 fmt:4;
        u8 oc:4;
@@ -96,11 +98,13 @@ struct scm_device {
 #define OP_STATE_TEMP_ERR      2
 #define OP_STATE_PERM_ERR      3
 
+enum scm_event {SCM_CHANGE, SCM_AVAIL};
+
 struct scm_driver {
        struct device_driver drv;
        int (*probe) (struct scm_device *scmdev);
        int (*remove) (struct scm_device *scmdev);
-       void (*notify) (struct scm_device *scmdev);
+       void (*notify) (struct scm_device *scmdev, enum scm_event event);
        void (*handler) (struct scm_device *scmdev, void *data, int error);
 };
 
index 1d8fe2b17ef6f1d0069c0e3cc8ff70c7d9cc402a..6b32af30878cc6276c57079aeefcda38ea6ea685 100644 (file)
@@ -74,8 +74,6 @@ static inline void __tlb_flush_idte(unsigned long asce)
 
 static inline void __tlb_flush_mm(struct mm_struct * mm)
 {
-       if (unlikely(cpumask_empty(mm_cpumask(mm))))
-               return;
        /*
         * If the machine has IDTE we prefer to do a per mm flush
         * on all cpus instead of doing a local flush if the mm
index 3c98c4dc5aca5be0eae8aa2c98a829d589132913..4d720a6a6b25f47ace76c6d84355f18a99d21fe6 100644 (file)
@@ -1387,22 +1387,6 @@ ENTRY(compat_sys_keyctl_wrapper)
        llgfr   %r6,%r6                 # u32
        jg      compat_sys_keyctl       # branch to system call
 
-ENTRY(compat_sys_preadv_wrapper)
-       llgfr   %r2,%r2                 # unsigned long
-       llgtr   %r3,%r3                 # compat_iovec *
-       llgfr   %r4,%r4                 # unsigned long
-       llgfr   %r5,%r5                 # u32
-       llgfr   %r6,%r6                 # u32
-       jg      compat_sys_preadv       # branch to system call
-
-ENTRY(compat_sys_pwritev_wrapper)
-       llgfr   %r2,%r2                 # unsigned long
-       llgtr   %r3,%r3                 # compat_iovec *
-       llgfr   %r4,%r4                 # unsigned long
-       llgfr   %r5,%r5                 # u32
-       llgfr   %r6,%r6                 # u32
-       jg      compat_sys_pwritev      # branch to system call
-
 ENTRY(sys_perf_event_open_wrapper)
        llgtr   %r2,%r2                 # const struct perf_event_attr *
        lgfr    %r3,%r3                 # pid_t
index 55022852326748599c4a8f4a74e77468e3d1f5a3..94feff7d613233dca1ad45702181f161bb425caf 100644 (file)
@@ -636,7 +636,8 @@ ENTRY(mcck_int_handler)
        UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
 mcck_skip:
        SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
-       mvc     __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA
+       stm     %r0,%r7,__PT_R0(%r11)
+       mvc     __PT_R8(32,%r11),__LC_GPREGS_SAVE_AREA+32
        stm     %r8,%r9,__PT_PSW(%r11)
        xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
        l       %r1,BASED(.Ldo_machine_check)
index 9c837c101297a52536c726d2e6b2e2c2e9c79ce9..2e6d60c55f909259803a1b52d7fdc6d04277fd0b 100644 (file)
@@ -678,8 +678,9 @@ ENTRY(mcck_int_handler)
        UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
        LAST_BREAK %r14
 mcck_skip:
-       lghi    %r14,__LC_GPREGS_SAVE_AREA
-       mvc     __PT_R0(128,%r11),0(%r14)
+       lghi    %r14,__LC_GPREGS_SAVE_AREA+64
+       stmg    %r0,%r7,__PT_R0(%r11)
+       mvc     __PT_R8(64,%r11),0(%r14)
        stmg    %r8,%r9,__PT_PSW(%r11)
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
        lgr     %r2,%r11                # pass pointer to pt_regs
index 1630f439cd2a567d27d0ddb5828917808fec5f15..1580af3db31ae3bc49b33451e1c2e7e3a137e9d1 100644 (file)
@@ -162,10 +162,8 @@ asmlinkage void do_softirq(void)
 #ifdef CONFIG_PROC_FS
 void init_irq_proc(void)
 {
-       struct proc_dir_entry *root_irq_dir;
-
-       root_irq_dir = proc_mkdir("irq", NULL);
-       create_prof_cpu_mask(root_irq_dir);
+       if (proc_mkdir("irq", NULL))
+               create_prof_cpu_mask();
 }
 #endif
 
index 46480d81df00029aa395f39861a7d40dd7f49bde..d112fc66f993e84431b013b018c84f29144882aa 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/crash_dump.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <asm/checksum.h>
 #include <asm/lowcore.h>
 #include <asm/os_info.h>
index a5360de85ec7e7eb190f64de6028d08ea2e2c68e..29268859d8eebc405bc013fee0a2d05ee86d71b8 100644 (file)
@@ -571,6 +571,8 @@ static void __init setup_memory_end(void)
 
        /* Split remaining virtual space between 1:1 mapping & vmemmap array */
        tmp = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
+       /* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */
+       tmp = SECTION_ALIGN_UP(tmp);
        tmp = VMALLOC_START - tmp * sizeof(struct page);
        tmp &= ~((vmax >> 11) - 1);     /* align to page table level */
        tmp = min(tmp, 1UL << MAX_PHYSMEM_BITS);
index 630b935d128465fc9c2eacc76364c6e1398562f6..84e8b1a6bfcba5426f3de9aa28536945072b54e0 100644 (file)
@@ -336,8 +336,8 @@ SYSCALL(sys_inotify_init1,sys_inotify_init1,sys_inotify_init1_wrapper)
 SYSCALL(sys_pipe2,sys_pipe2,sys_pipe2_wrapper) /* 325 */
 SYSCALL(sys_dup3,sys_dup3,sys_dup3_wrapper)
 SYSCALL(sys_epoll_create1,sys_epoll_create1,sys_epoll_create1_wrapper)
-SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
-SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
+SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv)
+SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo) /* 330 */
 SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
 SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper)
index e569aa1fd2ba7a5c68d6dfb95564e98c2397f9d7..c8def8bc90209578a5a6d5cfaf8f9f258c4ec7fb 100644 (file)
@@ -12,7 +12,7 @@ config SCORE
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
        select HAVE_MOD_ARCH_SPECIFIC
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_REL
        select CLONE_BACKWARDS
 
index cee6bce1e30c3663490e05d66725f89c907e62a9..8b6f796c6ade537965b2df1706820cb6492c3b1e 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
-#include <linux/proc_fs.h>
+#include <linux/kcore.h>
 #include <linux/sched.h>
 #include <linux/initrd.h>
 
index f46848f088e47c2eb900b890cbe656580f5f3a37..851e5106e5809ca6f18c97bd70d87069194007a2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/mm.h>
@@ -308,11 +309,9 @@ int dma_extend(unsigned int chan, unsigned long op, void *param)
 }
 EXPORT_SYMBOL(dma_extend);
 
-static int dma_read_proc(char *buf, char **start, off_t off,
-                        int len, int *eof, void *data)
+static int dma_proc_show(struct seq_file *m, void *v)
 {
-       struct dma_info *info;
-       char *p = buf;
+       struct dma_info *info = v;
 
        if (list_empty(&registered_dmac_list))
                return 0;
@@ -332,14 +331,26 @@ static int dma_read_proc(char *buf, char **start, off_t off,
                        if (!(channel->flags & DMA_CONFIGURED))
                                continue;
 
-                       p += sprintf(p, "%2d: %14s    %s\n", i,
-                                    info->name, channel->dev_id);
+                       seq_printf(m, "%2d: %14s    %s\n", i,
+                                  info->name, channel->dev_id);
                }
        }
 
-       return p - buf;
+       return 0;
+}
+
+static int dma_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dma_proc_show, NULL);
 }
 
+static const struct file_operations dma_proc_fops = {
+       .open           = dma_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 int register_dmac(struct dma_info *info)
 {
        unsigned int total_channels, i;
@@ -412,8 +423,7 @@ EXPORT_SYMBOL(unregister_dmac);
 static int __init dma_api_init(void)
 {
        printk(KERN_NOTICE "DMA: Registering DMA API.\n");
-       return create_proc_read_entry("dma", 0, 0, dma_read_proc, 0)
-                   ? 0 : -ENOMEM;
+       return proc_create("dma", 0, NULL, &dma_proc_fops) ? 0 : -ENOMEM;
 }
 subsys_initcall(dma_api_init);
 
index aea14855e656dd629c2f8fc2ddce5dfeeae440c0..ec2b25302427ac63587b5c4ff9fbcdfd17f9a731 100644 (file)
@@ -140,7 +140,7 @@ static int alignment_proc_open(struct inode *inode, struct file *file)
 static ssize_t alignment_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *pos)
 {
-       int *data = PDE(file_inode(file))->data;
+       int *data = PDE_DATA(file_inode(file));
        char mode;
 
        if (count > 0) {
index 289127d5241ce7a2ee646e8b8211849ae1cc2eda..3d361f236308c13cde14286379ec418af3e52990 100644 (file)
@@ -84,12 +84,6 @@ config ARCH_DEFCONFIG
        default "arch/sparc/configs/sparc32_defconfig" if SPARC32
        default "arch/sparc/configs/sparc64_defconfig" if SPARC64
 
-# CONFIG_BITS can be used at source level to get 32/64 bits
-config BITS
-       int
-       default 32 if SPARC32
-       default 64 if SPARC64
-
 config IOMMU_HELPER
        bool
        default y if SPARC64
@@ -197,7 +191,7 @@ config RWSEM_XCHGADD_ALGORITHM
 
 config GENERIC_HWEIGHT
        bool
-       default y if !ULTRA_HAS_POPULATION_COUNT
+       default y
 
 config GENERIC_CALIBRATE_DELAY
        bool
index d06a266017534f406b41d0488e0c00eb296d0156..6b67e50fb9b4cf934dade73c9d10dfeec6afe364 100644 (file)
@@ -45,6 +45,7 @@
 #define SUN4V_CHIP_NIAGARA3    0x03
 #define SUN4V_CHIP_NIAGARA4    0x04
 #define SUN4V_CHIP_NIAGARA5    0x05
+#define SUN4V_CHIP_SPARC64X    0x8a
 #define SUN4V_CHIP_UNKNOWN     0xff
 
 #ifndef __ASSEMBLY__
index a6c94a2bf9d4b1150e41b63d3e71a81138fc1f63..5c5125895db86e4dacd9de9dee91b508628b30c2 100644 (file)
@@ -493,6 +493,12 @@ static void __init sun4v_cpu_probe(void)
                sparc_pmu_type = "niagara5";
                break;
 
+       case SUN4V_CHIP_SPARC64X:
+               sparc_cpu_type = "SPARC64-X";
+               sparc_fpu_type = "SPARC64-X integrated FPU";
+               sparc_pmu_type = "sparc64-x";
+               break;
+
        default:
                printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
                       prom_cpu_compatible);
index 2feb15c35d9e1bb0154d1f023accccca3a8ee460..26b706a1867dc6b9976b52e1e61ef8e54ce0df91 100644 (file)
@@ -134,6 +134,8 @@ prom_niagara_prefix:
        .asciz  "SUNW,UltraSPARC-T"
 prom_sparc_prefix:
        .asciz  "SPARC-"
+prom_sparc64x_prefix:
+       .asciz  "SPARC64-X"
        .align  4
 prom_root_compatible:
        .skip   64
@@ -412,7 +414,7 @@ sun4v_chip_type:
        cmp     %g2, 'T'
        be,pt   %xcc, 70f
         cmp    %g2, 'M'
-       bne,pn  %xcc, 4f
+       bne,pn  %xcc, 49f
         nop
 
 70:    ldub    [%g1 + 7], %g2
@@ -425,7 +427,7 @@ sun4v_chip_type:
        cmp     %g2, '5'
        be,pt   %xcc, 5f
         mov    SUN4V_CHIP_NIAGARA5, %g4
-       ba,pt   %xcc, 4f
+       ba,pt   %xcc, 49f
         nop
 
 91:    sethi   %hi(prom_cpu_compatible), %g1
@@ -439,6 +441,25 @@ sun4v_chip_type:
         mov    SUN4V_CHIP_NIAGARA2, %g4
        
 4:
+       /* Athena */
+       sethi   %hi(prom_cpu_compatible), %g1
+       or      %g1, %lo(prom_cpu_compatible), %g1
+       sethi   %hi(prom_sparc64x_prefix), %g7
+       or      %g7, %lo(prom_sparc64x_prefix), %g7
+       mov     9, %g3
+41:    ldub    [%g7], %g2
+       ldub    [%g1], %g4
+       cmp     %g2, %g4
+       bne,pn  %icc, 49f
+       add     %g7, 1, %g7
+       subcc   %g3, 1, %g3
+       bne,pt  %xcc, 41b
+       add     %g1, 1, %g1
+       mov     SUN4V_CHIP_SPARC64X, %g4
+       ba,pt   %xcc, 5f
+       nop
+
+49:
        mov     SUN4V_CHIP_UNKNOWN, %g4
 5:     sethi   %hi(sun4v_chip_type), %g2
        or      %g2, %lo(sun4v_chip_type), %g2
index 0f094db918c7f8b711aeaab6ba01ac46847332cd..2096468de9b27f7dd2bb54f17e3b308f8d359836 100644 (file)
@@ -693,7 +693,7 @@ static int sparc_io_proc_show(struct seq_file *m, void *v)
 
 static int sparc_io_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, sparc_io_proc_show, PDE(inode)->data);
+       return single_open(file, sparc_io_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations sparc_io_proc_fops = {
index fc4320886a3aa5d15f817075cfca261487d21438..4d1487138d260553005af8036734ef519395dd22 100644 (file)
@@ -186,6 +186,8 @@ struct grpci2_cap_first {
 #define CAP9_IOMAP_OFS 0x20
 #define CAP9_BARSIZE_OFS 0x24
 
+#define TGT 256
+
 struct grpci2_priv {
        struct leon_pci_info    info; /* must be on top of this structure */
        struct grpci2_regs      *regs;
@@ -237,8 +239,12 @@ static int grpci2_cfg_r32(struct grpci2_priv *priv, unsigned int bus,
        if (where & 0x3)
                return -EINVAL;
 
-       if (bus == 0 && PCI_SLOT(devfn) != 0)
-               devfn += (0x8 * 6);
+       if (bus == 0) {
+               devfn += (0x8 * 6); /* start at AD16=Device0 */
+       } else if (bus == TGT) {
+               bus = 0;
+               devfn = 0; /* special case: bridge controller itself */
+       }
 
        /* Select bus */
        spin_lock_irqsave(&grpci2_dev_lock, flags);
@@ -303,8 +309,12 @@ static int grpci2_cfg_w32(struct grpci2_priv *priv, unsigned int bus,
        if (where & 0x3)
                return -EINVAL;
 
-       if (bus == 0 && PCI_SLOT(devfn) != 0)
-               devfn += (0x8 * 6);
+       if (bus == 0) {
+               devfn += (0x8 * 6); /* start at AD16=Device0 */
+       } else if (bus == TGT) {
+               bus = 0;
+               devfn = 0; /* special case: bridge controller itself */
+       }
 
        /* Select bus */
        spin_lock_irqsave(&grpci2_dev_lock, flags);
@@ -368,7 +378,7 @@ static int grpci2_read_config(struct pci_bus *bus, unsigned int devfn,
        unsigned int busno = bus->number;
        int ret;
 
-       if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0)) {
+       if (PCI_SLOT(devfn) > 15 || busno > 255) {
                *val = ~0;
                return 0;
        }
@@ -406,7 +416,7 @@ static int grpci2_write_config(struct pci_bus *bus, unsigned int devfn,
        struct grpci2_priv *priv = grpci2priv;
        unsigned int busno = bus->number;
 
-       if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0))
+       if (PCI_SLOT(devfn) > 15 || busno > 255)
                return 0;
 
 #ifdef GRPCI2_DEBUG_CFGACCESS
@@ -578,15 +588,15 @@ void grpci2_hw_init(struct grpci2_priv *priv)
                REGSTORE(regs->ahbmst_map[i], priv->pci_area);
 
        /* Get the GRPCI2 Host PCI ID */
-       grpci2_cfg_r32(priv, 0, 0, PCI_VENDOR_ID, &priv->pciid);
+       grpci2_cfg_r32(priv, TGT, 0, PCI_VENDOR_ID, &priv->pciid);
 
        /* Get address to first (always defined) capability structure */
-       grpci2_cfg_r8(priv, 0, 0, PCI_CAPABILITY_LIST, &capptr);
+       grpci2_cfg_r8(priv, TGT, 0, PCI_CAPABILITY_LIST, &capptr);
 
        /* Enable/Disable Byte twisting */
-       grpci2_cfg_r32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, &io_map);
+       grpci2_cfg_r32(priv, TGT, 0, capptr+CAP9_IOMAP_OFS, &io_map);
        io_map = (io_map & ~0x1) | (priv->bt_enabled ? 1 : 0);
-       grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, io_map);
+       grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_IOMAP_OFS, io_map);
 
        /* Setup the Host's PCI Target BARs for other peripherals to access,
         * and do DMA to the host's memory. The target BARs can be sized and
@@ -617,17 +627,18 @@ void grpci2_hw_init(struct grpci2_priv *priv)
                                pciadr = 0;
                        }
                }
-               grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BARSIZE_OFS+i*4, bar_sz);
-               grpci2_cfg_w32(priv, 0, 0, PCI_BASE_ADDRESS_0+i*4, pciadr);
-               grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr);
+               grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_BARSIZE_OFS+i*4,
+                               bar_sz);
+               grpci2_cfg_w32(priv, TGT, 0, PCI_BASE_ADDRESS_0+i*4, pciadr);
+               grpci2_cfg_w32(priv, TGT, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr);
                printk(KERN_INFO "        TGT BAR[%d]: 0x%08x (PCI)-> 0x%08x\n",
                        i, pciadr, ahbadr);
        }
 
        /* set as bus master and enable pci memory responses */
-       grpci2_cfg_r32(priv, 0, 0, PCI_COMMAND, &data);
+       grpci2_cfg_r32(priv, TGT, 0, PCI_COMMAND, &data);
        data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-       grpci2_cfg_w32(priv, 0, 0, PCI_COMMAND, data);
+       grpci2_cfg_w32(priv, TGT, 0, PCI_COMMAND, data);
 
        /* Enable Error respone (CPU-TRAP) on illegal memory access. */
        REGSTORE(regs->ctrl, CTRL_ER | CTRL_PE);
index e490ac9327c7463462e30a31bf03f65cfd3e98a0..f8933be3ca8b211ae5c459adcecf0d80af6439f5 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/kernel_stat.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include <asm/timer.h>
index ff496ab1e79445472aabd261ef133e2565c2a513..25877aebc685fcde958145add51e09e7fcbcc341 100644 (file)
@@ -17,7 +17,7 @@ config TILE
        select GENERIC_IRQ_SHOW
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_SYSCALL_WRAPPERS if TILEGX
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select SYS_HYPERVISOR
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_CLOCKEVENTS
index 8c5eff6d6df5577ea987d01cbf79cde62cab3506..47684815e5c8a27bf51fd8854ca11ae7cb2a07f8 100644 (file)
@@ -330,7 +330,6 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID456=m
-CONFIG_MULTICORE_RAID456=y
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_DEBUG=y
index e7a3dfcbcda7094ef4c7fa818c650716d2103397..dd2b8f0c631fc4a1ffb047d322753d3b4cef95b4 100644 (file)
@@ -324,7 +324,6 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID456=m
-CONFIG_MULTICORE_RAID456=y
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_DEBUG=y
index 001d418a8957721c99c41947b1e54bdb2dfd10f2..78f1f2ded86c7ae6dac3c156f1aa393653058b33 100644 (file)
@@ -288,6 +288,9 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
 long compat_sys_fallocate(int fd, int mode,
                          u32 offset_lo, u32 offset_hi,
                          u32 len_lo, u32 len_hi);
+long compat_sys_llseek(unsigned int fd, unsigned int offset_high,
+                      unsigned int offset_low, loff_t __user * result,
+                      unsigned int origin);
 
 /* Assembly trampoline to avoid clobbering r0. */
 long _compat_sys_rt_sigreturn(void);
index 7f72401b4f458347d8cba0cc7fd4ab637a61b616..6ea4cdb3c6a03e3ab5991969bd485047cac23bc3 100644 (file)
  * adapt the usual convention.
  */
 
-long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE4(truncate64, char __user *, filename, u32, dummy,
+                       u32, low, u32, high)
 {
        return sys_truncate(filename, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE4(ftruncate64, unsigned int, fd, u32, dummy,
+                       u32, low, u32, high)
 {
        return sys_ftruncate(fd, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
-                       u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf,
+                       size_t, count, u32, dummy, u32, low, u32, high)
 {
        return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
-                        u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE6(pwrite64, unsigned int, fd, char __user *, ubuf,
+                       size_t, count, u32, dummy, u32, low, u32, high)
 {
        return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len)
+COMPAT_SYSCALL_DEFINE4(lookup_dcookie, u32, low, u32, high,
+                       char __user *, buf, size_t, len)
 {
        return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len);
 }
 
-long compat_sys_sync_file_range2(int fd, unsigned int flags,
-                                u32 offset_lo, u32 offset_hi,
-                                u32 nbytes_lo, u32 nbytes_hi)
+COMPAT_SYSCALL_DEFINE6(sync_file_range2, int, fd, unsigned int, flags,
+                       u32, offset_lo, u32, offset_hi,
+                       u32, nbytes_lo, u32, nbytes_hi)
 {
        return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo,
                                   ((loff_t)nbytes_hi << 32) | nbytes_lo,
                                   flags);
 }
 
-long compat_sys_fallocate(int fd, int mode,
-                         u32 offset_lo, u32 offset_hi,
-                         u32 len_lo, u32 len_hi)
+COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
+                       u32, offset_lo, u32, offset_hi,
+                       u32, len_lo, u32, len_hi)
 {
        return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo,
                             ((loff_t)len_hi << 32) | len_lo);
 }
 
+/*
+ * Avoid bug in generic sys_llseek() that specifies offset_high and
+ * offset_low as "unsigned long", thus making it possible to pass
+ * a sign-extended high 32 bits in offset_low.
+ */
+COMPAT_SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned int, offset_high,
+                      unsigned int, offset_low, loff_t __user *, result,
+                      unsigned int, origin)
+{
+       return sys_llseek(fd, offset_high, offset_low, result, origin);
+}
 /* Provide the compat syscall number to call mapping. */
 #undef __SYSCALL
 #define __SYSCALL(nr, call) [nr] = (call),
@@ -83,6 +98,7 @@ long compat_sys_fallocate(int fd, int mode,
 /* See comments in sys.c */
 #define compat_sys_fadvise64_64 sys32_fadvise64_64
 #define compat_sys_readahead sys32_readahead
+#define sys_llseek compat_sys_llseek
 
 /* Call the assembly trampolines where necessary. */
 #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
index 20273ee37deb78919667efa12fbaa7dff41a3cca..38ac189d95751a1a7d7a0fe074ad76179037f8a0 100644 (file)
@@ -914,7 +914,7 @@ static int hardwall_proc_show(struct seq_file *sf, void *v)
 static int hardwall_proc_open(struct inode *inode,
                              struct file *file)
 {
-       return single_open(file, hardwall_proc_show, PDE(inode)->data);
+       return single_open(file, hardwall_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations hardwall_proc_fops = {
index 78f1b899996446e9e769ff703938dbb7bedc6fe6..c512b0306dd41beff8039787d1eca7b90546ed40 100644 (file)
@@ -37,7 +37,7 @@ extern int console_write_chan(struct chan *chan, const char *buf,
 extern int console_open_chan(struct line *line, struct console *co);
 extern void deactivate_chan(struct chan *chan, int irq);
 extern void reactivate_chan(struct chan *chan, int irq);
-extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty);
+extern void chan_enable_winch(struct chan *chan, struct tty_port *port);
 extern int enable_chan(struct line *line);
 extern void close_chan(struct line *line);
 extern int chan_window_size(struct line *line, 
index 15c553c239a119259f2f948f8381e5a9a26f4ccb..80b47cb71e0a85e7ea1a10626f7a1e0efe8e5225 100644 (file)
@@ -122,10 +122,10 @@ static int open_chan(struct list_head *chans)
        return err;
 }
 
-void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
+void chan_enable_winch(struct chan *chan, struct tty_port *port)
 {
        if (chan && chan->primary && chan->ops->winch)
-               register_winch(chan->fd, tty);
+               register_winch(chan->fd, port);
 }
 
 static void line_timer_cb(struct work_struct *work)
index 9be670ad23b5fa6c94bb6b361bb9db59a0924a2d..3fd7c3efdb18df6b0f8f1dfd68e3883052b329c1 100644 (file)
@@ -216,7 +216,7 @@ static int winch_thread(void *arg)
        }
 }
 
-static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
+static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
                       unsigned long *stack_out)
 {
        struct winch_data data;
@@ -271,7 +271,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
        return err;
 }
 
-void register_winch(int fd, struct tty_struct *tty)
+void register_winch(int fd, struct tty_port *port)
 {
        unsigned long stack;
        int pid, thread, count, thread_fd = -1;
@@ -281,17 +281,17 @@ void register_winch(int fd, struct tty_struct *tty)
                return;
 
        pid = tcgetpgrp(fd);
-       if (is_skas_winch(pid, fd, tty)) {
-               register_winch_irq(-1, fd, -1, tty, 0);
+       if (is_skas_winch(pid, fd, port)) {
+               register_winch_irq(-1, fd, -1, port, 0);
                return;
        }
 
        if (pid == -1) {
-               thread = winch_tramp(fd, tty, &thread_fd, &stack);
+               thread = winch_tramp(fd, port, &thread_fd, &stack);
                if (thread < 0)
                        return;
 
-               register_winch_irq(thread_fd, fd, thread, tty, stack);
+               register_winch_irq(thread_fd, fd, thread, port, stack);
 
                count = write(thread_fd, &c, sizeof(c));
                if (count != sizeof(c))
index dc693298eb8fc0a73719d98521f8a4ae9f911dfa..03f1b565c5f9ac9028ed7b91444b89c1dde963f1 100644 (file)
@@ -38,10 +38,10 @@ extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
                               unsigned short *cols_out);
 extern void generic_free(void *data);
 
-struct tty_struct;
-extern void register_winch(int fd,  struct tty_struct *tty);
+struct tty_port;
+extern void register_winch(int fd,  struct tty_port *port);
 extern void register_winch_irq(int fd, int tty_fd, int pid,
-                              struct tty_struct *tty, unsigned long stack);
+                              struct tty_port *port, unsigned long stack);
 
 #define __channel_help(fn, prefix) \
 __uml_help(fn, prefix "[0-9]*=<channel description>\n" \
index f1b38571f94e7996d1c83712945583e3d1e75a06..be541cf69fd282cea191a3580e851549f25c39e0 100644 (file)
@@ -305,7 +305,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
                return ret;
 
        if (!line->sigio) {
-               chan_enable_winch(line->chan_out, tty);
+               chan_enable_winch(line->chan_out, port);
                line->sigio = 1;
        }
 
@@ -315,8 +315,22 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
        return 0;
 }
 
+static void unregister_winch(struct tty_struct *tty);
+
+static void line_destruct(struct tty_port *port)
+{
+       struct tty_struct *tty = tty_port_tty_get(port);
+       struct line *line = tty->driver_data;
+
+       if (line->sigio) {
+               unregister_winch(tty);
+               line->sigio = 0;
+       }
+}
+
 static const struct tty_port_operations line_port_ops = {
        .activate = line_activate,
+       .destruct = line_destruct,
 };
 
 int line_open(struct tty_struct *tty, struct file *filp)
@@ -340,18 +354,6 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty,
        return 0;
 }
 
-static void unregister_winch(struct tty_struct *tty);
-
-void line_cleanup(struct tty_struct *tty)
-{
-       struct line *line = tty->driver_data;
-
-       if (line->sigio) {
-               unregister_winch(tty);
-               line->sigio = 0;
-       }
-}
-
 void line_close(struct tty_struct *tty, struct file * filp)
 {
        struct line *line = tty->driver_data;
@@ -601,7 +603,7 @@ struct winch {
        int fd;
        int tty_fd;
        int pid;
-       struct tty_struct *tty;
+       struct tty_port *port;
        unsigned long stack;
        struct work_struct work;
 };
@@ -655,7 +657,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
                        goto out;
                }
        }
-       tty = winch->tty;
+       tty = tty_port_tty_get(winch->port);
        if (tty != NULL) {
                line = tty->driver_data;
                if (line != NULL) {
@@ -663,6 +665,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
                                         &tty->winsize.ws_col);
                        kill_pgrp(tty->pgrp, SIGWINCH, 1);
                }
+               tty_kref_put(tty);
        }
  out:
        if (winch->fd != -1)
@@ -670,7 +673,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
+void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
                        unsigned long stack)
 {
        struct winch *winch;
@@ -685,7 +688,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
                                   .fd          = fd,
                                   .tty_fd      = tty_fd,
                                   .pid         = pid,
-                                  .tty         = tty,
+                                  .port        = port,
                                   .stack       = stack });
 
        if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
@@ -714,15 +717,18 @@ static void unregister_winch(struct tty_struct *tty)
 {
        struct list_head *ele, *next;
        struct winch *winch;
+       struct tty_struct *wtty;
 
        spin_lock(&winch_handler_lock);
 
        list_for_each_safe(ele, next, &winch_handlers) {
                winch = list_entry(ele, struct winch, list);
-               if (winch->tty == tty) {
+               wtty = tty_port_tty_get(winch->port);
+               if (wtty == tty) {
                        free_winch(winch);
                        break;
                }
+               tty_kref_put(wtty);
        }
        spin_unlock(&winch_handler_lock);
 }
index 4bd82ac0210f27c8ef7c755480399ad9dce2f15b..d7d21851e60c12f0c3f64933a8c8e2856586ac46 100644 (file)
@@ -782,8 +782,7 @@ static int create_proc_mconsole(void)
 
        ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_fops);
        if (ent == NULL) {
-               printk(KERN_INFO "create_proc_mconsole : create_proc_entry "
-                      "failed\n");
+               printk(KERN_INFO "create_proc_mconsole : proc_create failed\n");
                return 0;
        }
        return 0;
index d8926c30362946475822ff21ca6a4d5dc9f20cbf..39f186252e02521ccc33eb0fad6b450ccfb19d73 100644 (file)
@@ -218,6 +218,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_lock_irqsave(&lp->lock, flags);
 
        len = (*lp->write)(lp->fd, skb, lp);
+       skb_tx_timestamp(skb);
 
        if (len == skb->len) {
                dev->stats.tx_packets++;
@@ -281,6 +282,7 @@ static void uml_net_get_drvinfo(struct net_device *dev,
 static const struct ethtool_ops uml_net_ethtool_ops = {
        .get_drvinfo    = uml_net_get_drvinfo,
        .get_link       = ethtool_op_get_link,
+       .get_ts_info    = ethtool_op_get_ts_info,
 };
 
 static void uml_net_user_timer_expire(unsigned long _conn)
index 16fdd0a0f9d617c67b7d99f0aa4317f2fcdfc7aa..b8d14fa5205901b0955b33735d4026d2ee49f8d2 100644 (file)
@@ -105,7 +105,6 @@ static const struct tty_operations ssl_ops = {
        .throttle               = line_throttle,
        .unthrottle             = line_unthrottle,
        .install                = ssl_install,
-       .cleanup                = line_cleanup,
        .hangup                 = line_hangup,
 };
 
index 827777af3f6d673bcb26570e4e28ccc370cfcd5e..7b361f36ca965f7b9ce202133f752e0347290c04 100644 (file)
@@ -110,7 +110,6 @@ static const struct tty_operations console_ops = {
        .set_termios            = line_set_termios,
        .throttle               = line_throttle,
        .unthrottle             = line_unthrottle,
-       .cleanup                = line_cleanup,
        .hangup                 = line_hangup,
 };
 
index b1469fe9329564dac95f1fc5b6320f0ed56ea31b..9d9f1b4bf8269d89af35a08b5e24064337a410e4 100644 (file)
@@ -15,7 +15,7 @@
 #include <sysdep/mcontext.h>
 #include "internal.h"
 
-void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
+void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
        [SIGTRAP]       = relay_signal,
        [SIGFPE]        = relay_signal,
        [SIGILL]        = relay_signal,
index da4b9e9999fd2640764c8a4afe0c11ca2f43bc3b..337518c5042a5cb4895e389202e6a4c5bc9654b2 100644 (file)
@@ -15,6 +15,8 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <asm/unistd.h>
 #include <init.h>
 #include <os.h>
index dc50b157fc83385b815768fb69ca2351fac83271..2943e3acdf0cba611bcd0fc222fbc59fb3f6602a 100644 (file)
@@ -9,7 +9,7 @@ config UNICORE32
        select GENERIC_ATOMIC64
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_LZMA
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_HAVE_CUSTOM_GPIO_H
        select GENERIC_FIND_FIRST_BIT
        select GENERIC_IRQ_PROBE
index a4f24f5b1218520074eacc4918bcf5fd04d139a4..70c0f3da0476a35ba93546689bb4b06b5f576bba 100644 (file)
@@ -112,7 +112,7 @@ config X86
        select GENERIC_STRNLEN_USER
        select HAVE_CONTEXT_TRACKING if X86_64
        select HAVE_IRQ_TIME_ACCOUNTING
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_REL if X86_32
        select MODULES_USE_ELF_RELA if X86_64
        select CLONE_BACKWARDS if X86_32
index 03abf9b70011c288d362d1faa7ac67fe9c57f4ed..03d721cbbc32c13c1d14f55fc978af949165a546 100644 (file)
@@ -323,11 +323,8 @@ static int load_aout_binary(struct linux_binprm *bprm)
 
        if (N_MAGIC(ex) == OMAGIC) {
                unsigned long text_addr, map_size;
-               loff_t pos;
 
                text_addr = N_TXTADDR(ex);
-
-               pos = 32;
                map_size = ex.a_text+ex.a_data;
 
                error = vm_brk(text_addr & PAGE_MASK, map_size);
@@ -337,15 +334,12 @@ static int load_aout_binary(struct linux_binprm *bprm)
                        return error;
                }
 
-               error = bprm->file->f_op->read(bprm->file,
-                        (char __user *)text_addr,
-                         ex.a_text+ex.a_data, &pos);
+               error = read_code(bprm->file, text_addr, 32,
+                                 ex.a_text + ex.a_data);
                if ((signed long)error < 0) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
-
-               flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
        } else {
 #ifdef WARN_OLD
                static unsigned long error_time, error_time2;
@@ -367,15 +361,9 @@ static int load_aout_binary(struct linux_binprm *bprm)
 #endif
 
                if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {
-                       loff_t pos = fd_offset;
-
                        vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
-                       bprm->file->f_op->read(bprm->file,
-                                       (char __user *)N_TXTADDR(ex),
-                                       ex.a_text+ex.a_data, &pos);
-                       flush_icache_range((unsigned long) N_TXTADDR(ex),
-                                          (unsigned long) N_TXTADDR(ex) +
-                                          ex.a_text+ex.a_data);
+                       read_code(bprm->file, N_TXTADDR(ex), fd_offset,
+                                       ex.a_text+ex.a_data);
                        goto beyond_if;
                }
 
@@ -452,8 +440,6 @@ static int load_aout_library(struct file *file)
        start_addr =  ex.a_entry & 0xfffff000;
 
        if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
-               loff_t pos = N_TXTOFF(ex);
-
 #ifdef WARN_OLD
                static unsigned long error_time;
                if (time_after(jiffies, error_time + 5*HZ)) {
@@ -466,12 +452,8 @@ static int load_aout_library(struct file *file)
 #endif
                vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
 
-               file->f_op->read(file, (char __user *)start_addr,
-                       ex.a_text + ex.a_data, &pos);
-               flush_icache_range((unsigned long) start_addr,
-                                  (unsigned long) start_addr + ex.a_text +
-                                  ex.a_data);
-
+               read_code(file, start_addr, N_TXTOFF(ex),
+                         ex.a_text + ex.a_data);
                retval = 0;
                goto out;
        }
index 5b5e9cb774b59c27471126091424d2b0a8eb50d9..653668d140f994e543ad52e46d0c8402d5fe9259 100644 (file)
  * analysis of kexec-tools; if other broken bootloaders initialize a
  * different set of fields we will need to figure out how to disambiguate.
  *
+ * Note: efi_info is commonly left uninitialized, but that field has a
+ * private magic, so it is better to leave it unchanged.
  */
 static void sanitize_boot_params(struct boot_params *boot_params)
 {
+       /* 
+        * IMPORTANT NOTE TO BOOTLOADER AUTHORS: do not simply clear
+        * this field.  The purpose of this field is to guarantee
+        * compliance with the x86 boot spec located in
+        * Documentation/x86/boot.txt .  That spec says that the
+        * *whole* structure should be cleared, after which only the
+        * portion defined by struct setup_header (boot_params->hdr)
+        * should be copied in.
+        *
+        * If you're having an issue because the sentinel is set, you
+        * need to change the whole structure to be cleared, not this
+        * (or any other) individual field, or you will soon have
+        * problems again.
+        */
        if (boot_params->sentinel) {
-               /*fields in boot_params are not valid, clear them */
+               /* fields in boot_params are left uninitialized, clear them */
                memset(&boot_params->olpc_ofw_header, 0,
-                      (char *)&boot_params->alt_mem_k -
+                      (char *)&boot_params->efi_info -
                        (char *)&boot_params->olpc_ofw_header);
                memset(&boot_params->kbd_status, 0,
                       (char *)&boot_params->hdr -
index d3ddd17405d07b1e288828a949ac9ecb363c3c2e..5a6d2873f80eb61e878ded58ff289cf59adc0341 100644 (file)
@@ -77,6 +77,7 @@ struct arch_specific_insn {
         * a post_handler or break_handler).
         */
        int boostable;
+       bool if_modifier;
 };
 
 struct arch_optimized_insn {
index 635a74d224098523c2fcdee0f26a71618f96bdd8..4979778cc7fb51a14f5fa5960eb02b36d5c235f9 100644 (file)
@@ -414,8 +414,8 @@ struct kvm_vcpu_arch {
        gpa_t time;
        struct pvclock_vcpu_time_info hv_clock;
        unsigned int hw_tsc_khz;
-       unsigned int time_offset;
-       struct page *time_page;
+       struct gfn_to_hva_cache pv_time;
+       bool pv_time_enabled;
        /* set guest stopped flag in pvclock flags field */
        bool pvclock_set_guest_stopped_request;
 
index 529c8931fc029faffb4f4437ef74dd4fedb538f3..dab7580c47aee2e71e501afbfa94c17e2790777d 100644 (file)
@@ -101,6 +101,10 @@ static struct event_constraint intel_snb_event_constraints[] __read_mostly =
        FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
        FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
        FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+       INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
+       INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
+       INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+       INTEL_UEVENT_CONSTRAINT(0x06a3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
        INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
        INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
        INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
index 826054a4f2ee4c54ea4cfb9d29ab117db35e7fc5..b05a575d56f42f4543504b999a3b4875de110772 100644 (file)
@@ -729,3 +729,13 @@ void intel_ds_init(void)
                }
        }
 }
+
+void perf_restore_debug_store(void)
+{
+       struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return;
+
+       wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
+}
index 3f06e61499814ee368ddcf6ec41a690cdfbea3c5..7bfe318d3d8a4a50b07bd8c02865c9f4af3496d7 100644 (file)
@@ -375,6 +375,9 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)
        else
                p->ainsn.boostable = -1;
 
+       /* Check whether the instruction modifies Interrupt Flag or not */
+       p->ainsn.if_modifier = is_IF_modifier(p->ainsn.insn);
+
        /* Also, displacement change doesn't affect the first byte */
        p->opcode = p->ainsn.insn[0];
 }
@@ -434,7 +437,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
        __this_cpu_write(current_kprobe, p);
        kcb->kprobe_saved_flags = kcb->kprobe_old_flags
                = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
-       if (is_IF_modifier(p->ainsn.insn))
+       if (p->ainsn.if_modifier)
                kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF;
 }
 
index 7890bc8389524d4a1e934e23b041ab1010abf4f7..d893e8ed8ac96559b2175b00c3d68d71658a4105 100644 (file)
@@ -90,13 +90,13 @@ microcode_phys(struct microcode_intel **mc_saved_tmp,
        struct microcode_intel ***mc_saved;
 
        mc_saved = (struct microcode_intel ***)
-                  __pa_symbol(&mc_saved_data->mc_saved);
+                  __pa_nodebug(&mc_saved_data->mc_saved);
        for (i = 0; i < mc_saved_data->mc_saved_count; i++) {
                struct microcode_intel *p;
 
                p = *(struct microcode_intel **)
-                       __pa(mc_saved_data->mc_saved + i);
-               mc_saved_tmp[i] = (struct microcode_intel *)__pa(p);
+                       __pa_nodebug(mc_saved_data->mc_saved + i);
+               mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p);
        }
 }
 #endif
@@ -562,7 +562,7 @@ scan_microcode(unsigned long start, unsigned long end,
        struct cpio_data cd;
        long offset = 0;
 #ifdef CONFIG_X86_32
-       char *p = (char *)__pa_symbol(ucode_name);
+       char *p = (char *)__pa_nodebug(ucode_name);
 #else
        char *p = ucode_name;
 #endif
@@ -630,8 +630,8 @@ static void __cpuinit print_ucode(struct ucode_cpu_info *uci)
        if (mc_intel == NULL)
                return;
 
-       delay_ucode_info_p = (int *)__pa_symbol(&delay_ucode_info);
-       current_mc_date_p = (int *)__pa_symbol(&current_mc_date);
+       delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info);
+       current_mc_date_p = (int *)__pa_nodebug(&current_mc_date);
 
        *delay_ucode_info_p = 1;
        *current_mc_date_p = mc_intel->hdr.date;
@@ -659,8 +659,8 @@ static inline void __cpuinit print_ucode(struct ucode_cpu_info *uci)
 }
 #endif
 
-static int apply_microcode_early(struct mc_saved_data *mc_saved_data,
-                                struct ucode_cpu_info *uci)
+static int __cpuinit apply_microcode_early(struct mc_saved_data *mc_saved_data,
+                                          struct ucode_cpu_info *uci)
 {
        struct microcode_intel *mc_intel;
        unsigned int val[2];
@@ -741,15 +741,15 @@ load_ucode_intel_bsp(void)
 #ifdef CONFIG_X86_32
        struct boot_params *boot_params_p;
 
-       boot_params_p = (struct boot_params *)__pa_symbol(&boot_params);
+       boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params);
        ramdisk_image = boot_params_p->hdr.ramdisk_image;
        ramdisk_size  = boot_params_p->hdr.ramdisk_size;
        initrd_start_early = ramdisk_image;
        initrd_end_early = initrd_start_early + ramdisk_size;
 
        _load_ucode_intel_bsp(
-               (struct mc_saved_data *)__pa_symbol(&mc_saved_data),
-               (unsigned long *)__pa_symbol(&mc_saved_in_initrd),
+               (struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
+               (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
                initrd_start_early, initrd_end_early, &uci);
 #else
        ramdisk_image = boot_params.hdr.ramdisk_image;
@@ -772,10 +772,10 @@ void __cpuinit load_ucode_intel_ap(void)
        unsigned long *initrd_start_p;
 
        mc_saved_in_initrd_p =
-               (unsigned long *)__pa_symbol(mc_saved_in_initrd);
-       mc_saved_data_p = (struct mc_saved_data *)__pa_symbol(&mc_saved_data);
-       initrd_start_p = (unsigned long *)__pa_symbol(&initrd_start);
-       initrd_start_addr = (unsigned long)__pa_symbol(*initrd_start_p);
+               (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
+       mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+       initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
+       initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
 #else
        mc_saved_data_p = &mc_saved_data;
        mc_saved_in_initrd_p = mc_saved_in_initrd;
index 84d32855f65c329c04dae97d4cd77bd2053e824e..90d8cc930f5ed134735f7697e016a83e5657dcb8 100644 (file)
@@ -171,9 +171,15 @@ static struct resource bss_resource = {
 
 #ifdef CONFIG_X86_32
 /* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 new_cpu_data __cpuinitdata = {
+       .wp_works_ok = -1,
+       .fdiv_bug = -1,
+};
 /* common cpu data for all cpus */
-struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {
+       .wp_works_ok = -1,
+       .fdiv_bug = -1,
+};
 EXPORT_SYMBOL(boot_cpu_data);
 
 unsigned int def_to_bigsmp;
index a6ceaedc396a2d67f3514e3f162a614b5444cd74..9f190a2a00e9916e2369e571a5eca8bf2b22d56c 100644 (file)
@@ -1365,9 +1365,8 @@ static inline void mwait_play_dead(void)
        unsigned int eax, ebx, ecx, edx;
        unsigned int highest_cstate = 0;
        unsigned int highest_subcstate = 0;
-       int i;
        void *mwait_ptr;
-       struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info);
+       int i;
 
        if (!this_cpu_has(X86_FEATURE_MWAIT))
                return;
index f71500af1f813245bb12092665ac7dea3ba5f24f..f19ac0aca60d9379ea5c625e8e6f35024d7bd239 100644 (file)
@@ -1406,25 +1406,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
        unsigned long flags, this_tsc_khz;
        struct kvm_vcpu_arch *vcpu = &v->arch;
        struct kvm_arch *ka = &v->kvm->arch;
-       void *shared_kaddr;
        s64 kernel_ns, max_kernel_ns;
        u64 tsc_timestamp, host_tsc;
-       struct pvclock_vcpu_time_info *guest_hv_clock;
+       struct pvclock_vcpu_time_info guest_hv_clock;
        u8 pvclock_flags;
        bool use_master_clock;
 
        kernel_ns = 0;
        host_tsc = 0;
 
-       /* Keep irq disabled to prevent changes to the clock */
-       local_irq_save(flags);
-       this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
-       if (unlikely(this_tsc_khz == 0)) {
-               local_irq_restore(flags);
-               kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
-               return 1;
-       }
-
        /*
         * If the host uses TSC clock, then passthrough TSC as stable
         * to the guest.
@@ -1436,6 +1426,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
                kernel_ns = ka->master_kernel_ns;
        }
        spin_unlock(&ka->pvclock_gtod_sync_lock);
+
+       /* Keep irq disabled to prevent changes to the clock */
+       local_irq_save(flags);
+       this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
+       if (unlikely(this_tsc_khz == 0)) {
+               local_irq_restore(flags);
+               kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
+               return 1;
+       }
        if (!use_master_clock) {
                host_tsc = native_read_tsc();
                kernel_ns = get_kernel_ns();
@@ -1463,7 +1462,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
 
        local_irq_restore(flags);
 
-       if (!vcpu->time_page)
+       if (!vcpu->pv_time_enabled)
                return 0;
 
        /*
@@ -1525,12 +1524,12 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
         */
        vcpu->hv_clock.version += 2;
 
-       shared_kaddr = kmap_atomic(vcpu->time_page);
-
-       guest_hv_clock = shared_kaddr + vcpu->time_offset;
+       if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time,
+               &guest_hv_clock, sizeof(guest_hv_clock))))
+               return 0;
 
        /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */
-       pvclock_flags = (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED);
+       pvclock_flags = (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED);
 
        if (vcpu->pvclock_set_guest_stopped_request) {
                pvclock_flags |= PVCLOCK_GUEST_STOPPED;
@@ -1543,12 +1542,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
 
        vcpu->hv_clock.flags = pvclock_flags;
 
-       memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
-              sizeof(vcpu->hv_clock));
-
-       kunmap_atomic(shared_kaddr);
-
-       mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
+       kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
+                               &vcpu->hv_clock,
+                               sizeof(vcpu->hv_clock));
        return 0;
 }
 
@@ -1837,10 +1833,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
 
 static void kvmclock_reset(struct kvm_vcpu *vcpu)
 {
-       if (vcpu->arch.time_page) {
-               kvm_release_page_dirty(vcpu->arch.time_page);
-               vcpu->arch.time_page = NULL;
-       }
+       vcpu->arch.pv_time_enabled = false;
 }
 
 static void accumulate_steal_time(struct kvm_vcpu *vcpu)
@@ -1947,6 +1940,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_KVM_SYSTEM_TIME_NEW:
        case MSR_KVM_SYSTEM_TIME: {
+               u64 gpa_offset;
                kvmclock_reset(vcpu);
 
                vcpu->arch.time = data;
@@ -1956,14 +1950,17 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                if (!(data & 1))
                        break;
 
-               /* ...but clean it before doing the actual write */
-               vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
+               gpa_offset = data & ~(PAGE_MASK | 1);
 
-               vcpu->arch.time_page =
-                               gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
+               /* Check that the address is 32-byte aligned. */
+               if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1))
+                       break;
 
-               if (is_error_page(vcpu->arch.time_page))
-                       vcpu->arch.time_page = NULL;
+               if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
+                    &vcpu->arch.pv_time, data & ~1ULL))
+                       vcpu->arch.pv_time_enabled = false;
+               else
+                       vcpu->arch.pv_time_enabled = true;
 
                break;
        }
@@ -2967,7 +2964,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
  */
 static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
 {
-       if (!vcpu->arch.time_page)
+       if (!vcpu->arch.pv_time_enabled)
                return -EINVAL;
        vcpu->arch.pvclock_set_guest_stopped_request = true;
        kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
@@ -6718,6 +6715,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
                goto fail_free_wbinvd_dirty_mask;
 
        vcpu->arch.ia32_tsc_adjust_msr = 0x0;
+       vcpu->arch.pv_time_enabled = false;
        kvm_async_pf_hash_reset(vcpu);
        kvm_pmu_init(vcpu);
 
index 05928aae911e0addaaaf1bd0fce5002ba3c9f96e..906fea3157919dcffabfe2bc4b23a1becb98aa7c 100644 (file)
@@ -74,10 +74,10 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest)
        char c;
        unsigned zero_len;
 
-       for (; len; --len) {
+       for (; len; --len, to++) {
                if (__get_user_nocheck(c, from++, sizeof(char)))
                        break;
-               if (__put_user_nocheck(c, to++, sizeof(char)))
+               if (__put_user_nocheck(c, to, sizeof(char)))
                        break;
        }
 
index 4903a03ae876338c2ad351f5db5988f35bb35d08..59b7fc453277399bd574dbde43b0bd8d295c9414 100644 (file)
@@ -410,9 +410,8 @@ void __init init_mem_mapping(void)
        /* the ISA range is always mapped regardless of memory holes */
        init_memory_mapping(0, ISA_END_ADDRESS);
 
-       /* xen has big range in reserved near end of ram, skip it at first */
-       addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE,
-                        PAGE_SIZE);
+       /* xen has big range in reserved near end of ram, skip it at first.*/
+       addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, PMD_SIZE);
        real_end = addr + PMD_SIZE;
 
        /* step_size need to be small so pgt_buf from BRK could cover it */
index 474e28f108151c67830a6e36476ff44ab4802126..24ceda0101bb65e8147cbc921f578c441c436bc8 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/memory_hotplug.h>
 #include <linux/nmi.h>
 #include <linux/gfp.h>
+#include <linux/kcore.h>
 
 #include <asm/processor.h>
 #include <asm/bios_ebda.h>
index 2610bd93c896871936caaa970abd414d039ff790..657438858e8358745484c828158634fba41a5b1c 100644 (file)
@@ -563,6 +563,13 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
        if (base > __pa(high_memory-1))
                return 0;
 
+       /*
+        * some areas in the middle of the kernel identity range
+        * are not mapped, like the PCI space.
+        */
+       if (!page_is_ram(base >> PAGE_SHIFT))
+               return 0;
+
        id_sz = (__pa(high_memory-1) <= base + size) ?
                                __pa(high_memory) - base :
                                size;
index 5f2ecaf3f9d8609ccdc7a56e4d232fd13bdd8dcc..55ea7dfb5b3c65e229a046400b2eb9ef8a82ba19 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/efi-bgrt.h>
 #include <linux/export.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 #include <linux/memblock.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
index 2b2003860615fbc5e24ef12e1c1fa3d855a1f09d..39a0e7f1f0a3ec1c7601888d30c724a5b8660e19 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
index 120cee1c3f8d6ab8d3873c537d063e3d45553778..3c68768d7a75963d8825f65b3ac28fff2f257361 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/suspend.h>
 #include <linux/export.h>
 #include <linux/smp.h>
+#include <linux/perf_event.h>
 
 #include <asm/pgtable.h>
 #include <asm/proto.h>
@@ -228,6 +229,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
        do_fpu_end();
        x86_platform.restore_sched_clock_state();
        mtrr_bp_restore();
+       perf_restore_debug_store();
 }
 
 /* Needed by apm.c */
index 35876ffac11d19875b15828a2d8bee3c51081baa..b09de49dbec5cf0a7d65590afc7c2a97158399bf 100644 (file)
@@ -9,7 +9,7 @@ config XTENSA
        select HAVE_IDE
        select GENERIC_ATOMIC64
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
        select MODULES_USE_ELF_RELA
index f58ffc3b68a855efe6929fe566753c2e07453d0f..4a06d70ddf5ed84b5f5d136f230f8d9e8029d70b 100644 (file)
@@ -214,20 +214,27 @@ static int simdisk_detach(struct simdisk *dev)
        return err;
 }
 
-static int proc_read_simdisk(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static ssize_t proc_read_simdisk(struct file *file, char __user *buf,
+                       size_t size, loff_t *ppos)
 {
-       int len;
-       struct simdisk *dev = (struct simdisk *) data;
-       len = sprintf(page, "%s\n", dev->filename ? dev->filename : "");
-       return len;
+       struct simdisk *dev = PDE_DATA(file_inode(file));
+       char *s = dev->filename;
+       if (s) {
+               ssize_t n = simple_read_from_buffer(buf, size, ppos,
+                                                       s, strlen(s));
+               if (n < 0)
+                       return n;
+               buf += n;
+               size -= n;
+       }
+       return simple_read_from_buffer(buf, size, ppos, "\n", 1);
 }
 
-static int proc_write_simdisk(struct file *file, const char *buffer,
-               unsigned long count, void *data)
+static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
+                       size_t size, loff_t *ppos)
 {
        char *tmp = kmalloc(count + 1, GFP_KERNEL);
-       struct simdisk *dev = (struct simdisk *) data;
+       struct simdisk *dev = PDE_DATA(file_inode(file));
        int err;
 
        if (tmp == NULL)
@@ -256,6 +263,12 @@ out_free:
        return err;
 }
 
+static const struct file_operations fops = {
+       .read = proc_read_simdisk,
+       .write = proc_write_simdisk,
+       .llseek = default_llseek,
+};
+
 static int __init simdisk_setup(struct simdisk *dev, int which,
                struct proc_dir_entry *procdir)
 {
@@ -289,10 +302,7 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
        set_capacity(dev->gd, 0);
        add_disk(dev->gd);
 
-       dev->procfile = create_proc_entry(tmp, 0644, procdir);
-       dev->procfile->data = dev;
-       dev->procfile->read_proc = proc_read_simdisk;
-       dev->procfile->write_proc = proc_write_simdisk;
+       dev->procfile = proc_create_data(tmp, 0644, procdir, &fops, dev);
        return 0;
 
 out_alloc_disk:
index 6d5bf649196dced64c75614fc586f1b16684e7bd..00d2efd674df5b7a2ecca39ac2e161cfcf14b719 100644 (file)
@@ -194,7 +194,7 @@ static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
 
 static int acpi_ac_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_ac_seq_show, PDE(inode)->data);
+       return single_open(file, acpi_ac_seq_show, PDE_DATA(inode));
 }
 
 static int acpi_ac_add_fs(struct acpi_device *device)
index c5cd5b5513e67a144ac3a7d2b5a76dc9f494bc48..169ced7e540da86374c5e85bdadf81ffd99a722f 100644 (file)
@@ -929,7 +929,7 @@ static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
 } \
 static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
 { \
-       return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
+       return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \
 }
 
 DECLARE_FILE_FUNCTIONS(info);
index 86c7d5445c38c962614b654a4149eef0ab057869..5d57cd513f4faf3ac4b6bc4da04e042728a1a00f 100644 (file)
@@ -128,7 +128,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
+       return single_open(file, acpi_button_state_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations acpi_button_state_fops = {
index ef6f155469b58ed370aa9d1232d5c2e6bb14c29a..40a84cc6740c6c6522afc6bac6d5d5d2178a86bd 100644 (file)
@@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
 {
        if (acpi_disabled)
                return -ENODEV;
-       if (type && type->bus && type->find_device) {
+       if (type && type->match && type->find_device) {
                down_write(&bus_type_sem);
                list_add_tail(&type->list, &bus_type_list);
                up_write(&bus_type_sem);
-               printk(KERN_INFO PREFIX "bus type %s registered\n",
-                      type->bus->name);
+               printk(KERN_INFO PREFIX "bus type %s registered\n", type->name);
                return 0;
        }
        return -ENODEV;
@@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
                down_write(&bus_type_sem);
                list_del_init(&type->list);
                up_write(&bus_type_sem);
-               printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n",
-                      type->bus->name);
+               printk(KERN_INFO PREFIX "bus type %s unregistered\n",
+                      type->name);
                return 0;
        }
        return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);
 
-static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
+static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
 {
        struct acpi_bus_type *tmp, *ret = NULL;
 
-       if (!type)
-               return NULL;
-
        down_read(&bus_type_sem);
        list_for_each_entry(tmp, &bus_type_list, list) {
-               if (tmp->bus == type) {
+               if (tmp->match(dev)) {
                        ret = tmp;
                        break;
                }
@@ -82,22 +78,6 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
        return ret;
 }
 
-static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
-{
-       struct acpi_bus_type *tmp;
-       int ret = -ENODEV;
-
-       down_read(&bus_type_sem);
-       list_for_each_entry(tmp, &bus_type_list, list) {
-               if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) {
-                       ret = 0;
-                       break;
-               }
-       }
-       up_read(&bus_type_sem);
-       return ret;
-}
-
 static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
                                      void *addr_p, void **ret_p)
 {
@@ -261,29 +241,12 @@ err:
 
 static int acpi_platform_notify(struct device *dev)
 {
-       struct acpi_bus_type *type;
+       struct acpi_bus_type *type = acpi_get_bus_type(dev);
        acpi_handle handle;
        int ret;
 
        ret = acpi_bind_one(dev, NULL);
-       if (ret && (!dev->bus || !dev->parent)) {
-               /* bridge devices genernally haven't bus or parent */
-               ret = acpi_find_bridge_device(dev, &handle);
-               if (!ret) {
-                       ret = acpi_bind_one(dev, handle);
-                       if (ret)
-                               goto out;
-               }
-       }
-
-       type = acpi_get_bus_type(dev->bus);
-       if (ret) {
-               if (!type || !type->find_device) {
-                       DBG("No ACPI bus support for %s\n", dev_name(dev));
-                       ret = -EINVAL;
-                       goto out;
-               }
-
+       if (ret && type) {
                ret = type->find_device(dev, &handle);
                if (ret) {
                        DBG("Unable to get handle for %s\n", dev_name(dev));
@@ -316,7 +279,7 @@ static int acpi_platform_notify_remove(struct device *dev)
 {
        struct acpi_bus_type *type;
 
-       type = acpi_get_bus_type(dev->bus);
+       type = acpi_get_bus_type(dev);
        if (type && type->cleanup)
                type->cleanup(dev);
 
index 52ce76725c2024bfea9bc20602ea239c0bc011ff..aa1227a7e3f23e349ed5050680d4fef8c135cfc8 100644 (file)
@@ -120,7 +120,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 
 static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data);
+       return single_open(file, acpi_system_alarm_seq_show, PDE_DATA(inode));
 }
 
 static int get_date_field(char **p, u32 * value)
@@ -397,7 +397,7 @@ static int
 acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
 {
        return single_open(file, acpi_system_wakeup_device_seq_show,
-                          PDE(inode)->data);
+                          PDE_DATA(inode));
 }
 
 static const struct file_operations acpi_system_wakeup_device_fops = {
index eff722278ff539535bec85d5f5f6f4f2b04b79bf..164d49569aebfbd3e15991bf68aa2eb13c42fe6a 100644 (file)
@@ -158,8 +158,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
        }
 
 exit:
-       if (buffer.pointer)
-               kfree(buffer.pointer);
+       kfree(buffer.pointer);
        return apic_id;
 }
 
index df34bd04ae62ba88e4acc6735515e41af03aff7d..bec717ffd25f5ff7c016f57365a380dc8e91b7fb 100644 (file)
@@ -559,7 +559,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
                return 0;
 #endif
 
-       BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+       BUG_ON(pr->id >= nr_cpu_ids);
 
        /*
         * Buggy BIOS check
index 53e7ac9403a7dc21502e90a698ef1b27ad668a37..e854582f29a672a5920500333e26a0b77b310e58 100644 (file)
@@ -465,7 +465,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
        return result;
 }
 
-static int acpi_processor_get_performance_info(struct acpi_processor *pr)
+int acpi_processor_get_performance_info(struct acpi_processor *pr)
 {
        int result = 0;
        acpi_status status = AE_OK;
@@ -509,7 +509,7 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
 #endif
        return result;
 }
-
+EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
 int acpi_processor_notify_smm(struct module *calling_module)
 {
        acpi_status status;
index e523245643acc6c65d68339c64fbf7e00ef09f95..b6241eeb1132a0b3afed934ba96f52545a4a1d13 100644 (file)
@@ -521,19 +521,6 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
        return 0;
 }
 
-static void
-acpi_sbs_remove_fs(struct proc_dir_entry **dir,
-                          struct proc_dir_entry *parent_dir)
-{
-       if (*dir) {
-               remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
-               remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
-               remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir);
-               remove_proc_entry((*dir)->name, parent_dir);
-               *dir = NULL;
-       }
-}
-
 /* Smart Battery Interface */
 static struct proc_dir_entry *acpi_battery_dir = NULL;
 
@@ -584,7 +571,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 
 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+       return single_open(file, acpi_battery_read_info, PDE_DATA(inode));
 }
 
 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
@@ -623,7 +610,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 
 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_battery_read_state, PDE(inode)->data);
+       return single_open(file, acpi_battery_read_state, PDE_DATA(inode));
 }
 
 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
@@ -688,7 +675,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 
 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
+       return single_open(file, acpi_battery_read_alarm, PDE_DATA(inode));
 }
 
 static const struct file_operations acpi_battery_info_fops = {
@@ -736,7 +723,7 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 
 static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, acpi_ac_read_state, PDE(inode)->data);
+       return single_open(file, acpi_ac_read_state, PDE_DATA(inode));
 }
 
 static const struct file_operations acpi_ac_state_fops = {
@@ -836,8 +823,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
                power_supply_unregister(&battery->bat);
        }
 #ifdef CONFIG_ACPI_PROCFS_POWER
-       if (battery->proc_entry)
-               acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
+       proc_remove(battery->proc_entry);
+       battery->proc_entry = NULL;
 #endif
 }
 
@@ -873,8 +860,8 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)
        if (sbs->charger.dev)
                power_supply_unregister(&sbs->charger);
 #ifdef CONFIG_ACPI_PROCFS_POWER
-       if (sbs->charger_entry)
-               acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+       proc_remove(sbs->charger_entry);
+       sbs->charger_entry = NULL;
 #endif
 }
 
index 6d3a06a629a1f8e1627f1218d88053cf7857053d..24213033fbae2aee5f033c2a776d2b37084fc88e 100644 (file)
@@ -599,7 +599,6 @@ static void acpi_sleep_suspend_setup(void)
                status = acpi_get_sleep_type_data(i, &type_a, &type_b);
                if (ACPI_SUCCESS(status)) {
                        sleep_states[i] = 1;
-                       pr_cont(" S%d", i);
                }
        }
 
@@ -742,7 +741,6 @@ static void acpi_sleep_hibernate_setup(void)
        hibernation_set_ops(old_suspend_ordering ?
                        &acpi_hibernation_ops_old : &acpi_hibernation_ops);
        sleep_states[ACPI_STATE_S4] = 1;
-       pr_cont(KERN_CONT " S4");
        if (nosigcheck)
                return;
 
@@ -788,6 +786,9 @@ int __init acpi_sleep_init(void)
 {
        acpi_status status;
        u8 type_a, type_b;
+       char supported[ACPI_S_STATE_COUNT * 3 + 1];
+       char *pos = supported;
+       int i;
 
        if (acpi_disabled)
                return 0;
@@ -795,7 +796,6 @@ int __init acpi_sleep_init(void)
        acpi_sleep_dmi_check();
 
        sleep_states[ACPI_STATE_S0] = 1;
-       pr_info(PREFIX "(supports S0");
 
        acpi_sleep_suspend_setup();
        acpi_sleep_hibernate_setup();
@@ -803,11 +803,17 @@ int __init acpi_sleep_init(void)
        status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
        if (ACPI_SUCCESS(status)) {
                sleep_states[ACPI_STATE_S5] = 1;
-               pr_cont(" S5");
                pm_power_off_prepare = acpi_power_off_prepare;
                pm_power_off = acpi_power_off;
        }
-       pr_cont(")\n");
+
+       supported[0] = 0;
+       for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
+               if (sleep_states[i])
+                       pos += sprintf(pos, " S%d", i);
+       }
+       pr_info(PREFIX "(supports%s)\n", supported);
+
        /*
         * Register the tts_notifier to reboot notifier list so that the _TTS
         * object can also be evaluated when the system enters S5.
index 093c435549631db21748b17827a433d8428ad862..1f44e56cc65d3c0262f4217c0040bd7c82c47569 100644 (file)
@@ -158,7 +158,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn)
 EXPORT_SYMBOL(tegra_ahb_enable_smmu);
 #endif
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 static int tegra_ahb_suspend(struct device *dev)
 {
        int i;
index 3e751b74615eac73bbf1835aa404337cd0cd6431..a5a3ebcbdd2cf6295028f62d0fe1d3bb21397633 100644 (file)
@@ -59,15 +59,16 @@ config ATA_ACPI
          option libata.noacpi=1
 
 config SATA_ZPODD
-       bool "SATA Zero Power ODD Support"
+       bool "SATA Zero Power Optical Disc Drive (ZPODD) support"
        depends on ATA_ACPI
        default n
        help
-         This option adds support for SATA ZPODD. It requires both
-         ODD and the platform support, and if enabled, will automatically
-         power on/off the ODD when certain condition is satisfied. This
-         does not impact user's experience of the ODD, only power is saved
-         when ODD is not in use(i.e. no disc inside).
+         This option adds support for SATA Zero Power Optical Disc
+         Drive (ZPODD). It requires both the ODD and the platform
+         support, and if enabled, will automatically power on/off the
+         ODD when certain condition is satisfied. This does not impact
+         end user's experience of the ODD, only power is saved when
+         the ODD is not in use (i.e. no disc inside).
 
          If unsure, say N.
 
index a99112cfd8b1e8524558ce659754d5c501e7c0fe..6a67b07de49439a1bbe3da827ef4750bd74269a8 100644 (file)
@@ -281,6 +281,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
+       { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
        { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
index d2ba439cfe54f33f3dd6ad040b8ea1e909602a9f..ffdd32d22602296875ff395a1fdc08e32509c393 100644 (file)
@@ -1547,6 +1547,10 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev)
 
 static int prefer_ms_hyperv = 1;
 module_param(prefer_ms_hyperv, int, 0);
+MODULE_PARM_DESC(prefer_ms_hyperv,
+       "Prefer Hyper-V paravirtualization drivers instead of ATA, "
+       "0 - Use ATA drivers, "
+       "1 (Default) - Use the paravirtualization drivers.");
 
 static void piix_ignore_devices_quirk(struct ata_host *host)
 {
index 0ea1018280bd5b3ee5f6bc60da2421e376fbb510..8a52dab412e2a8013f36bd547460924c79c996aa 100644 (file)
@@ -1027,7 +1027,7 @@ static void ata_acpi_register_power_resource(struct ata_device *dev)
 
        handle = ata_dev_acpi_handle(dev);
        if (handle)
-               acpi_dev_pm_remove_dependent(handle, &sdev->sdev_gendev);
+               acpi_dev_pm_add_dependent(handle, &sdev->sdev_gendev);
 }
 
 static void ata_acpi_unregister_power_resource(struct ata_device *dev)
@@ -1144,13 +1144,8 @@ static int ata_acpi_find_device(struct device *dev, acpi_handle *handle)
                return -ENODEV;
 }
 
-static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle)
-{
-       return -ENODEV;
-}
-
 static struct acpi_bus_type ata_acpi_bus = {
-       .find_bridge = ata_acpi_find_dummy,
+       .name = "ATA",
        .find_device = ata_acpi_find_device,
 };
 
index 70b0e01372b3da34564f53352aa075fa1ab39bf1..6ef27e98c50894190e74f396e19e13a44713157c 100644 (file)
@@ -661,18 +661,7 @@ static struct platform_driver pata_s3c_driver = {
        },
 };
 
-static int __init pata_s3c_init(void)
-{
-       return platform_driver_probe(&pata_s3c_driver, pata_s3c_probe);
-}
-
-static void __exit pata_s3c_exit(void)
-{
-       platform_driver_unregister(&pata_s3c_driver);
-}
-
-module_init(pata_s3c_init);
-module_exit(pata_s3c_exit);
+module_platform_driver_probe(pata_s3c_driver, pata_s3c_probe);
 
 MODULE_AUTHOR("Abhilash Kesavan, <a.kesavan@samsung.com>");
 MODULE_DESCRIPTION("low-level driver for Samsung PATA controller");
index 124b2c1d9c0b020255870dec161d41626562fcca..608f82fed632be1738c019f6fcfac6117b657a8d 100644 (file)
@@ -1511,8 +1511,7 @@ error_exit_with_cleanup:
 
        if (hcr_base)
                iounmap(hcr_base);
-       if (host_priv)
-               kfree(host_priv);
+       kfree(host_priv);
 
        return retval;
 }
index 08608de87e4e6a971e9a36ef701f343a6982d5b7..dc4f70179e7d37470dc358b02c96b328d8bbeeae 100644 (file)
@@ -322,23 +322,11 @@ static u8 k2_stat_check_status(struct ata_port *ap)
 }
 
 #ifdef CONFIG_PPC_OF
-/*
- * k2_sata_proc_info
- * inout : decides on the direction of the dataflow and the meaning of the
- *        variables
- * buffer: If inout==FALSE data is being written to it else read from it
- * *start: If inout==FALSE start of the valid data in the buffer
- * offset: If inout==FALSE offset from the beginning of the imaginary file
- *        from which we start writing into the buffer
- * length: If inout==FALSE max number of bytes to be written into the buffer
- *        else number of bytes in the buffer
- */
-static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
-                            off_t offset, int count, int inout)
+static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct ata_port *ap;
        struct device_node *np;
-       int len, index;
+       int index;
 
        /* Find  the ata_port */
        ap = ata_shost_to_port(shost);
@@ -356,15 +344,12 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
                const u32 *reg = of_get_property(np, "reg", NULL);
                if (!reg)
                        continue;
-               if (index == *reg)
+               if (index == *reg) {
+                       seq_printf(m, "devspec: %s\n", np->full_name);
                        break;
+               }
        }
-       if (np == NULL)
-               return 0;
-
-       len = sprintf(page, "devspec: %s\n", np->full_name);
-
-       return len;
+       return 0;
 }
 #endif /* CONFIG_PPC_OF */
 
@@ -372,7 +357,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
 static struct scsi_host_template k2_sata_sht = {
        ATA_BMDMA_SHT(DRV_NAME),
 #ifdef CONFIG_PPC_OF
-       .proc_info              = k2_sata_proc_info,
+       .show_info              = k2_sata_show_info,
 #endif
 };
 
index 2b7f77d3fcb0d518d2a1f4e041f29b61d6e4521b..15beb500a4e4c1a837092e75554ea368dbb1ea1f 100644 (file)
@@ -99,7 +99,6 @@ void device_pm_add(struct device *dev)
                dev_warn(dev, "parent %s should not be sleeping\n",
                        dev_name(dev->parent));
        list_add_tail(&dev->power.entry, &dpm_list);
-       dev_pm_qos_constraints_init(dev);
        mutex_unlock(&dpm_list_mtx);
 }
 
@@ -113,7 +112,6 @@ void device_pm_remove(struct device *dev)
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
        complete_all(&dev->power.completion);
        mutex_lock(&dpm_list_mtx);
-       dev_pm_qos_constraints_destroy(dev);
        list_del_init(&dev->power.entry);
        mutex_unlock(&dpm_list_mtx);
        device_wakeup_disable(dev);
index b16686a0a5a29b0d56a253c406a1e54b8b826228..cfc3226ec4928dee99ff95540eed87af1058d5af 100644 (file)
@@ -4,7 +4,7 @@ static inline void device_pm_init_common(struct device *dev)
 {
        if (!dev->power.early_init) {
                spin_lock_init(&dev->power.lock);
-               dev->power.power_state = PMSG_INVALID;
+               dev->power.qos = NULL;
                dev->power.early_init = true;
        }
 }
@@ -56,14 +56,10 @@ extern void device_pm_move_last(struct device *);
 
 static inline void device_pm_sleep_init(struct device *dev) {}
 
-static inline void device_pm_add(struct device *dev)
-{
-       dev_pm_qos_constraints_init(dev);
-}
+static inline void device_pm_add(struct device *dev) {}
 
 static inline void device_pm_remove(struct device *dev)
 {
-       dev_pm_qos_constraints_destroy(dev);
        pm_runtime_remove(dev);
 }
 
index 3d4d1f8aac5c3aa126dd1045f4d2eda48907c29e..5f74587ef258f4598e16c37bf9284d108c475ead 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/mutex.h>
 #include <linux/export.h>
 #include <linux/pm_runtime.h>
+#include <linux/err.h>
 
 #include "power.h"
 
@@ -61,7 +62,7 @@ enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask)
        struct pm_qos_flags *pqf;
        s32 val;
 
-       if (!qos)
+       if (IS_ERR_OR_NULL(qos))
                return PM_QOS_FLAGS_UNDEFINED;
 
        pqf = &qos->flags;
@@ -101,7 +102,8 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags);
  */
 s32 __dev_pm_qos_read_value(struct device *dev)
 {
-       return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0;
+       return IS_ERR_OR_NULL(dev->power.qos) ?
+               0 : pm_qos_read_value(&dev->power.qos->latency);
 }
 
 /**
@@ -198,20 +200,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
        return 0;
 }
 
-/**
- * dev_pm_qos_constraints_init - Initalize device's PM QoS constraints pointer.
- * @dev: target device
- *
- * Called from the device PM subsystem during device insertion under
- * device_pm_lock().
- */
-void dev_pm_qos_constraints_init(struct device *dev)
-{
-       mutex_lock(&dev_pm_qos_mtx);
-       dev->power.qos = NULL;
-       dev->power.power_state = PMSG_ON;
-       mutex_unlock(&dev_pm_qos_mtx);
-}
+static void __dev_pm_qos_hide_latency_limit(struct device *dev);
+static void __dev_pm_qos_hide_flags(struct device *dev);
 
 /**
  * dev_pm_qos_constraints_destroy
@@ -226,16 +216,15 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
        struct pm_qos_constraints *c;
        struct pm_qos_flags *f;
 
+       mutex_lock(&dev_pm_qos_mtx);
+
        /*
         * If the device's PM QoS resume latency limit or PM QoS flags have been
         * exposed to user space, they have to be hidden at this point.
         */
-       dev_pm_qos_hide_latency_limit(dev);
-       dev_pm_qos_hide_flags(dev);
+       __dev_pm_qos_hide_latency_limit(dev);
+       __dev_pm_qos_hide_flags(dev);
 
-       mutex_lock(&dev_pm_qos_mtx);
-
-       dev->power.power_state = PMSG_INVALID;
        qos = dev->power.qos;
        if (!qos)
                goto out;
@@ -257,7 +246,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
        }
 
        spin_lock_irq(&dev->power.lock);
-       dev->power.qos = NULL;
+       dev->power.qos = ERR_PTR(-ENODEV);
        spin_unlock_irq(&dev->power.lock);
 
        kfree(c->notifiers);
@@ -301,32 +290,19 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
                 "%s() called for already added request\n", __func__))
                return -EINVAL;
 
-       req->dev = dev;
-
        mutex_lock(&dev_pm_qos_mtx);
 
-       if (!dev->power.qos) {
-               if (dev->power.power_state.event == PM_EVENT_INVALID) {
-                       /* The device has been removed from the system. */
-                       req->dev = NULL;
-                       ret = -ENODEV;
-                       goto out;
-               } else {
-                       /*
-                        * Allocate the constraints data on the first call to
-                        * add_request, i.e. only if the data is not already
-                        * allocated and if the device has not been removed.
-                        */
-                       ret = dev_pm_qos_constraints_allocate(dev);
-               }
-       }
+       if (IS_ERR(dev->power.qos))
+               ret = -ENODEV;
+       else if (!dev->power.qos)
+               ret = dev_pm_qos_constraints_allocate(dev);
 
        if (!ret) {
+               req->dev = dev;
                req->type = type;
                ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
        }
 
- out:
        mutex_unlock(&dev_pm_qos_mtx);
 
        return ret;
@@ -344,7 +320,14 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
        s32 curr_value;
        int ret = 0;
 
-       if (!req->dev->power.qos)
+       if (!req) /*guard against callers passing in null */
+               return -EINVAL;
+
+       if (WARN(!dev_pm_qos_request_active(req),
+                "%s() called for unknown object\n", __func__))
+               return -EINVAL;
+
+       if (IS_ERR_OR_NULL(req->dev->power.qos))
                return -ENODEV;
 
        switch(req->type) {
@@ -386,6 +369,17 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)
 {
        int ret;
 
+       mutex_lock(&dev_pm_qos_mtx);
+       ret = __dev_pm_qos_update_request(req, new_value);
+       mutex_unlock(&dev_pm_qos_mtx);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
+
+static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
+{
+       int ret;
+
        if (!req) /*guard against callers passing in null */
                return -EINVAL;
 
@@ -393,13 +387,13 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)
                 "%s() called for unknown object\n", __func__))
                return -EINVAL;
 
-       mutex_lock(&dev_pm_qos_mtx);
-       ret = __dev_pm_qos_update_request(req, new_value);
-       mutex_unlock(&dev_pm_qos_mtx);
+       if (IS_ERR_OR_NULL(req->dev->power.qos))
+               return -ENODEV;
 
+       ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
+       memset(req, 0, sizeof(*req));
        return ret;
 }
-EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
 
 /**
  * dev_pm_qos_remove_request - modifies an existing qos request
@@ -418,26 +412,10 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
  */
 int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
 {
-       int ret = 0;
-
-       if (!req) /*guard against callers passing in null */
-               return -EINVAL;
-
-       if (WARN(!dev_pm_qos_request_active(req),
-                "%s() called for unknown object\n", __func__))
-               return -EINVAL;
+       int ret;
 
        mutex_lock(&dev_pm_qos_mtx);
-
-       if (req->dev->power.qos) {
-               ret = apply_constraint(req, PM_QOS_REMOVE_REQ,
-                                      PM_QOS_DEFAULT_VALUE);
-               memset(req, 0, sizeof(*req));
-       } else {
-               /* Return if the device has been removed */
-               ret = -ENODEV;
-       }
-
+       ret = __dev_pm_qos_remove_request(req);
        mutex_unlock(&dev_pm_qos_mtx);
        return ret;
 }
@@ -462,9 +440,10 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier)
 
        mutex_lock(&dev_pm_qos_mtx);
 
-       if (!dev->power.qos)
-               ret = dev->power.power_state.event != PM_EVENT_INVALID ?
-                       dev_pm_qos_constraints_allocate(dev) : -ENODEV;
+       if (IS_ERR(dev->power.qos))
+               ret = -ENODEV;
+       else if (!dev->power.qos)
+               ret = dev_pm_qos_constraints_allocate(dev);
 
        if (!ret)
                ret = blocking_notifier_chain_register(
@@ -493,7 +472,7 @@ int dev_pm_qos_remove_notifier(struct device *dev,
        mutex_lock(&dev_pm_qos_mtx);
 
        /* Silently return if the constraints object is not present. */
-       if (dev->power.qos)
+       if (!IS_ERR_OR_NULL(dev->power.qos))
                retval = blocking_notifier_chain_unregister(
                                dev->power.qos->latency.notifiers,
                                notifier);
@@ -563,16 +542,20 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
 static void __dev_pm_qos_drop_user_request(struct device *dev,
                                           enum dev_pm_qos_req_type type)
 {
+       struct dev_pm_qos_request *req = NULL;
+
        switch(type) {
        case DEV_PM_QOS_LATENCY:
-               dev_pm_qos_remove_request(dev->power.qos->latency_req);
+               req = dev->power.qos->latency_req;
                dev->power.qos->latency_req = NULL;
                break;
        case DEV_PM_QOS_FLAGS:
-               dev_pm_qos_remove_request(dev->power.qos->flags_req);
+               req = dev->power.qos->flags_req;
                dev->power.qos->flags_req = NULL;
                break;
        }
+       __dev_pm_qos_remove_request(req);
+       kfree(req);
 }
 
 /**
@@ -588,36 +571,57 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
        if (!device_is_registered(dev) || value < 0)
                return -EINVAL;
 
-       if (dev->power.qos && dev->power.qos->latency_req)
-               return -EEXIST;
-
        req = kzalloc(sizeof(*req), GFP_KERNEL);
        if (!req)
                return -ENOMEM;
 
        ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value);
-       if (ret < 0)
+       if (ret < 0) {
+               kfree(req);
                return ret;
+       }
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (IS_ERR_OR_NULL(dev->power.qos))
+               ret = -ENODEV;
+       else if (dev->power.qos->latency_req)
+               ret = -EEXIST;
+
+       if (ret < 0) {
+               __dev_pm_qos_remove_request(req);
+               kfree(req);
+               goto out;
+       }
 
        dev->power.qos->latency_req = req;
        ret = pm_qos_sysfs_add_latency(dev);
        if (ret)
                __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
 
+ out:
+       mutex_unlock(&dev_pm_qos_mtx);
        return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);
 
+static void __dev_pm_qos_hide_latency_limit(struct device *dev)
+{
+       if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) {
+               pm_qos_sysfs_remove_latency(dev);
+               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
+       }
+}
+
 /**
  * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space.
  * @dev: Device whose PM QoS latency limit is to be hidden from user space.
  */
 void dev_pm_qos_hide_latency_limit(struct device *dev)
 {
-       if (dev->power.qos && dev->power.qos->latency_req) {
-               pm_qos_sysfs_remove_latency(dev);
-               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
-       }
+       mutex_lock(&dev_pm_qos_mtx);
+       __dev_pm_qos_hide_latency_limit(dev);
+       mutex_unlock(&dev_pm_qos_mtx);
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);
 
@@ -634,41 +638,61 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val)
        if (!device_is_registered(dev))
                return -EINVAL;
 
-       if (dev->power.qos && dev->power.qos->flags_req)
-               return -EEXIST;
-
        req = kzalloc(sizeof(*req), GFP_KERNEL);
        if (!req)
                return -ENOMEM;
 
-       pm_runtime_get_sync(dev);
        ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val);
-       if (ret < 0)
-               goto fail;
+       if (ret < 0) {
+               kfree(req);
+               return ret;
+       }
+
+       pm_runtime_get_sync(dev);
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (IS_ERR_OR_NULL(dev->power.qos))
+               ret = -ENODEV;
+       else if (dev->power.qos->flags_req)
+               ret = -EEXIST;
+
+       if (ret < 0) {
+               __dev_pm_qos_remove_request(req);
+               kfree(req);
+               goto out;
+       }
 
        dev->power.qos->flags_req = req;
        ret = pm_qos_sysfs_add_flags(dev);
        if (ret)
                __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
 
-fail:
+ out:
+       mutex_unlock(&dev_pm_qos_mtx);
        pm_runtime_put(dev);
        return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags);
 
+static void __dev_pm_qos_hide_flags(struct device *dev)
+{
+       if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) {
+               pm_qos_sysfs_remove_flags(dev);
+               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
+       }
+}
+
 /**
  * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space.
  * @dev: Device whose PM QoS flags are to be hidden from user space.
  */
 void dev_pm_qos_hide_flags(struct device *dev)
 {
-       if (dev->power.qos && dev->power.qos->flags_req) {
-               pm_qos_sysfs_remove_flags(dev);
-               pm_runtime_get_sync(dev);
-               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
-               pm_runtime_put(dev);
-       }
+       pm_runtime_get_sync(dev);
+       mutex_lock(&dev_pm_qos_mtx);
+       __dev_pm_qos_hide_flags(dev);
+       mutex_unlock(&dev_pm_qos_mtx);
+       pm_runtime_put(dev);
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags);
 
@@ -683,12 +707,14 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)
        s32 value;
        int ret;
 
-       if (!dev->power.qos || !dev->power.qos->flags_req)
-               return -EINVAL;
-
        pm_runtime_get_sync(dev);
        mutex_lock(&dev_pm_qos_mtx);
 
+       if (IS_ERR_OR_NULL(dev->power.qos) || !dev->power.qos->flags_req) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        value = dev_pm_qos_requested_flags(dev);
        if (set)
                value |= mask;
@@ -697,9 +723,12 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)
 
        ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value);
 
+ out:
        mutex_unlock(&dev_pm_qos_mtx);
        pm_runtime_put(dev);
-
        return ret;
 }
+#else /* !CONFIG_PM_RUNTIME */
+static void __dev_pm_qos_hide_latency_limit(struct device *dev) {}
+static void __dev_pm_qos_hide_flags(struct device *dev) {}
 #endif /* CONFIG_PM_RUNTIME */
index 50d16e3cb0a91ad637124472ac6b570403e86229..a53ebd265701674e98901f2ba36c97a6e1954302 100644 (file)
@@ -708,6 +708,7 @@ void rpm_sysfs_remove(struct device *dev)
 
 void dpm_sysfs_remove(struct device *dev)
 {
+       dev_pm_qos_constraints_destroy(dev);
        rpm_sysfs_remove(dev);
        sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
        sysfs_remove_group(&dev->kobj, &pm_attr_group);
index 4706c63d0bc63fdc8d9bdba1e96d3e1cb543a806..020ea2b9fd2f347a0ac71119a9213bb1c655ae33 100644 (file)
@@ -184,6 +184,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                if (ret < 0) {
                        dev_err(map->dev, "IRQ thread failed to resume: %d\n",
                                ret);
+                       pm_runtime_put(map->dev);
                        return IRQ_NONE;
                }
        }
index d3bde6cec927643bdf02445e387e97d4d5f29d69..30629a3d44cc517b62ea2fff5f8a65e505266b81 100644 (file)
@@ -404,6 +404,8 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
                return;
        }
 
+       spin_lock_init(&pc_host->cfgspace_lock);
+
        pc->host_controller = pc_host;
        pc_host->pci_controller.io_resource = &pc_host->io_resource;
        pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
index 5b5ee79ff236b77e48a2afac8b668d59d4f279f2..eb3950113e42342d73f7863854cf85fec48dedbd 100644 (file)
@@ -6473,7 +6473,7 @@ static int dac960_initial_status_proc_show(struct seq_file *m, void *v)
 
 static int dac960_initial_status_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data);
+       return single_open(file, dac960_initial_status_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations dac960_initial_status_proc_fops = {
@@ -6519,7 +6519,7 @@ static int dac960_current_status_proc_show(struct seq_file *m, void *v)
 
 static int dac960_current_status_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, dac960_current_status_proc_show, PDE(inode)->data);
+       return single_open(file, dac960_current_status_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations dac960_current_status_proc_fops = {
@@ -6540,14 +6540,14 @@ static int dac960_user_command_proc_show(struct seq_file *m, void *v)
 
 static int dac960_user_command_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, dac960_user_command_proc_show, PDE(inode)->data);
+       return single_open(file, dac960_user_command_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t dac960_user_command_proc_write(struct file *file,
                                       const char __user *Buffer,
                                       size_t Count, loff_t *pos)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file_inode(file))->data;
+  DAC960_Controller_T *Controller = PDE_DATA(file_inode(file));
   unsigned char CommandBuffer[80];
   int Length;
   if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
index ade58bc8f3c4dee67f69edde4ce20b1ef18d7cc8..d150fe1248bf7dd1d99c147b19a6f6178144f099 100644 (file)
@@ -493,7 +493,7 @@ static int cciss_seq_open(struct inode *inode, struct file *file)
        struct seq_file *seq = file->private_data;
 
        if (!ret)
-               seq->private = PDE(inode)->data;
+               seq->private = PDE_DATA(inode);
 
        return ret;
 }
index da3311129a0c5b87b8cc8b3718cc63b5bdfd3928..ecd845cd28d8d111a42bbb120dbf8d006f1a0340 100644 (file)
@@ -54,13 +54,11 @@ static CommandList_struct *cmd_special_alloc(ctlr_info_t *h);
 static void cmd_free(ctlr_info_t *h, CommandList_struct *c);
 static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c);
 
-static int cciss_scsi_proc_info(
-               struct Scsi_Host *sh,
+static int cciss_scsi_write_info(struct Scsi_Host *sh,
                char *buffer, /* data buffer */
-               char **start,      /* where data in buffer starts */
-               off_t offset,      /* offset from start of imaginary file */
-               int length,        /* length of data in buffer */
-               int func);         /* 0 == read, 1 == write */
+               int length);       /* length of data in buffer */
+static int cciss_scsi_show_info(struct seq_file *m,
+                               struct Scsi_Host *sh);
 
 static int cciss_scsi_queue_command (struct Scsi_Host *h,
                                     struct scsi_cmnd *cmd);
@@ -82,7 +80,8 @@ static struct scsi_host_template cciss_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "cciss",
        .proc_name              = "cciss",
-       .proc_info              = cciss_scsi_proc_info,
+       .write_info             = cciss_scsi_write_info,
+       .show_info              = cciss_scsi_show_info,
        .queuecommand           = cciss_scsi_queue_command,
        .this_id                = 7,
        .cmd_per_lun            = 1,
@@ -1302,59 +1301,54 @@ cciss_scsi_user_command(ctlr_info_t *h, int hostno, char *buffer, int length)
        return length;
 }
 
-
 static int
-cciss_scsi_proc_info(struct Scsi_Host *sh,
+cciss_scsi_write_info(struct Scsi_Host *sh,
                char *buffer, /* data buffer */
-               char **start,      /* where data in buffer starts */
-               off_t offset,      /* offset from start of imaginary file */
-               int length,        /* length of data in buffer */
-               int func)          /* 0 == read, 1 == write */
+               int length)        /* length of data in buffer */
 {
+       ctlr_info_t *h = (ctlr_info_t *) sh->hostdata[0];
+       if (h == NULL)  /* This really shouldn't ever happen. */
+               return -EINVAL;
 
-       int buflen, datalen;
-       ctlr_info_t *h;
+       return cciss_scsi_user_command(h, sh->host_no,
+                       buffer, length);        
+} 
+
+static int
+cciss_scsi_show_info(struct seq_file *m, struct Scsi_Host *sh)
+{
+
+       ctlr_info_t *h = (ctlr_info_t *) sh->hostdata[0];
        int i;
 
-       h = (ctlr_info_t *) sh->hostdata[0];
        if (h == NULL)  /* This really shouldn't ever happen. */
                return -EINVAL;
 
-       if (func == 0) {        /* User is reading from /proc/scsi/ciss*?/?*  */
-               buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
-                               h->ctlr, sh->host_no);
-
-               /* this information is needed by apps to know which cciss
-                  device corresponds to which scsi host number without
-                  having to open a scsi target device node.  The device
-                  information is not a duplicate of /proc/scsi/scsi because
-                  the two may be out of sync due to scsi hotplug, rather
-                  this info is for an app to be able to use to know how to
-                  get them back in sync. */
-
-               for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) {
-                       struct cciss_scsi_dev_t *sd =
-                               &ccissscsi[h->ctlr].dev[i];
-                       buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
-                               "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                               sh->host_no, sd->bus, sd->target, sd->lun,
-                               sd->devtype,
-                               sd->scsi3addr[0], sd->scsi3addr[1],
-                               sd->scsi3addr[2], sd->scsi3addr[3],
-                               sd->scsi3addr[4], sd->scsi3addr[5],
-                               sd->scsi3addr[6], sd->scsi3addr[7]);
-               }
-               datalen = buflen - offset;
-               if (datalen < 0) {      /* they're reading past EOF. */
-                       datalen = 0;
-                       *start = buffer+buflen; 
-               } else
-                       *start = buffer + offset;
-               return(datalen);
-       } else  /* User is writing to /proc/scsi/cciss*?/?*  ... */
-               return cciss_scsi_user_command(h, sh->host_no,
-                       buffer, length);        
-} 
+       seq_printf(m, "cciss%d: SCSI host: %d\n",
+                       h->ctlr, sh->host_no);
+
+       /* this information is needed by apps to know which cciss
+          device corresponds to which scsi host number without
+          having to open a scsi target device node.  The device
+          information is not a duplicate of /proc/scsi/scsi because
+          the two may be out of sync due to scsi hotplug, rather
+          this info is for an app to be able to use to know how to
+          get them back in sync. */
+
+       for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) {
+               struct cciss_scsi_dev_t *sd =
+                       &ccissscsi[h->ctlr].dev[i];
+               seq_printf(m, "c%db%dt%dl%d %02d "
+                       "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                       sh->host_no, sd->bus, sd->target, sd->lun,
+                       sd->devtype,
+                       sd->scsi3addr[0], sd->scsi3addr[1],
+                       sd->scsi3addr[2], sd->scsi3addr[3],
+                       sd->scsi3addr[4], sd->scsi3addr[5],
+                       sd->scsi3addr[6], sd->scsi3addr[7]);
+       }
+       return 0;
+}
 
 /* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci 
    dma mapping  and fills in the scatter gather entries of the 
index 3f087133a25a0d2da7a0de32f26f83e7392ae4bd..3b9e8ebcb96bbbf1d367cb749ce7a7b5c7de029f 100644 (file)
@@ -296,7 +296,7 @@ static int ida_proc_show(struct seq_file *m, void *v)
 
 static int ida_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ida_proc_show, PDE(inode)->data);
+       return single_open(file, ida_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ida_proc_fops = {
index 56672a61eb940c4b3b562f471586a351e9dd0bf6..928adb815b09f6b83fc6420faaeeaf8bd64f8404 100644 (file)
@@ -314,7 +314,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
 static int drbd_proc_open(struct inode *inode, struct file *file)
 {
        if (try_module_get(THIS_MODULE))
-               return single_open(file, drbd_seq_show, PDE(inode)->data);
+               return single_open(file, drbd_seq_show, PDE_DATA(inode));
        return -ENODEV;
 }
 
index 747bb2af69dcc55fec530466a9f55d06914ba8f7..cd1e17460f03642179add8c92beff4c1ce2a2776 100644 (file)
@@ -230,9 +230,11 @@ static int __do_lo_send_write(struct file *file,
        ssize_t bw;
        mm_segment_t old_fs = get_fs();
 
+       file_start_write(file);
        set_fs(get_ds());
        bw = file->f_op->write(file, buf, len, &pos);
        set_fs(old_fs);
+       file_end_write(file);
        if (likely(bw == len))
                return 0;
        printk(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n",
index 07fb2dfaae13f02588128ea0d73372a8859b63ba..9dcefe40380bf23ca7c1675b4286c5f97a480d79 100644 (file)
@@ -135,6 +135,7 @@ static inline void _nvme_check_size(void)
        BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096);
        BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096);
        BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
+       BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
 }
 
 typedef void (*nvme_completion_fn)(struct nvme_dev *, void *,
@@ -237,7 +238,8 @@ static void *free_cmdid(struct nvme_queue *nvmeq, int cmdid,
                *fn = special_completion;
                return CMD_CTX_INVALID;
        }
-       *fn = info[cmdid].fn;
+       if (fn)
+               *fn = info[cmdid].fn;
        ctx = info[cmdid].ctx;
        info[cmdid].fn = special_completion;
        info[cmdid].ctx = CMD_CTX_COMPLETED;
@@ -335,6 +337,7 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp)
                iod->offset = offsetof(struct nvme_iod, sg[nseg]);
                iod->npages = -1;
                iod->length = nbytes;
+               iod->nents = 0;
        }
 
        return iod;
@@ -375,7 +378,8 @@ static void bio_completion(struct nvme_dev *dev, void *ctx,
        struct bio *bio = iod->private;
        u16 status = le16_to_cpup(&cqe->status) >> 1;
 
-       dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents,
+       if (iod->nents)
+               dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents,
                        bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
        nvme_free_iod(dev, iod);
        if (status) {
@@ -589,7 +593,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,
 
        result = nvme_map_bio(nvmeq->q_dmadev, iod, bio, dma_dir, psegs);
        if (result < 0)
-               goto free_iod;
+               goto free_cmdid;
        length = result;
 
        cmnd->rw.command_id = cmdid;
@@ -609,6 +613,8 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,
 
        return 0;
 
+ free_cmdid:
+       free_cmdid(nvmeq, cmdid, NULL);
  free_iod:
        nvme_free_iod(nvmeq->dev, iod);
  nomem:
@@ -835,8 +841,8 @@ static int nvme_identify(struct nvme_dev *dev, unsigned nsid, unsigned cns,
        return nvme_submit_admin_cmd(dev, &c, NULL);
 }
 
-static int nvme_get_features(struct nvme_dev *dev, unsigned fid,
-                               unsigned nsid, dma_addr_t dma_addr)
+static int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
+                                       dma_addr_t dma_addr, u32 *result)
 {
        struct nvme_command c;
 
@@ -846,7 +852,7 @@ static int nvme_get_features(struct nvme_dev *dev, unsigned fid,
        c.features.prp1 = cpu_to_le64(dma_addr);
        c.features.fid = cpu_to_le32(fid);
 
-       return nvme_submit_admin_cmd(dev, &c, NULL);
+       return nvme_submit_admin_cmd(dev, &c, result);
 }
 
 static int nvme_set_features(struct nvme_dev *dev, unsigned fid,
@@ -906,6 +912,10 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid)
 
        spin_lock_irq(&nvmeq->q_lock);
        nvme_cancel_ios(nvmeq, false);
+       while (bio_list_peek(&nvmeq->sq_cong)) {
+               struct bio *bio = bio_list_pop(&nvmeq->sq_cong);
+               bio_endio(bio, -EIO);
+       }
        spin_unlock_irq(&nvmeq->q_lock);
 
        irq_set_affinity_hint(vector, NULL);
@@ -1230,12 +1240,17 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev,
        if (length != cmd.data_len)
                status = -ENOMEM;
        else
-               status = nvme_submit_admin_cmd(dev, &c, NULL);
+               status = nvme_submit_admin_cmd(dev, &c, &cmd.result);
 
        if (cmd.data_len) {
                nvme_unmap_user_pages(dev, cmd.opcode & 1, iod);
                nvme_free_iod(dev, iod);
        }
+
+       if (!status && copy_to_user(&ucmd->result, &cmd.result,
+                                                       sizeof(cmd.result)))
+               status = -EFAULT;
+
        return status;
 }
 
@@ -1523,9 +1538,9 @@ static int nvme_dev_add(struct nvme_dev *dev)
                        continue;
 
                res = nvme_get_features(dev, NVME_FEAT_LBA_RANGE, i,
-                                                       dma_addr + 4096);
+                                                       dma_addr + 4096, NULL);
                if (res)
-                       continue;
+                       memset(mem + 4096, 0, 4096);
 
                ns = nvme_alloc_ns(dev, i, mem, mem + 4096);
                if (ns)
index 2e7de7a59bfca01c4a35edaa1824a7a38f90e52f..e0588c6dd86f824fdaa0bb99e8aadb5361e07312 100644 (file)
@@ -2648,7 +2648,7 @@ static int pkt_seq_show(struct seq_file *m, void *p)
 
 static int pkt_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pkt_seq_show, PDE(inode)->data);
+       return single_open(file, pkt_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations pkt_proc_fops = {
index 75e112d660069411f5cb7d60c15733bac7b248d4..06a2e53e5f37299191b1d9c7fe5e2caf036461a6 100644 (file)
@@ -525,7 +525,7 @@ static int ps3vram_proc_show(struct seq_file *m, void *v)
 
 static int ps3vram_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ps3vram_proc_show, PDE(inode)->data);
+       return single_open(file, ps3vram_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ps3vram_proc_fops = {
index a8a41e07a221695684fd78770980749b25ff2b5a..6aab00ef4379a5b9e4dfeb290461d3c177726f07 100644 (file)
@@ -73,9 +73,13 @@ static struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x03F0, 0x311D) },
 
        /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x0036) },
        { USB_DEVICE(0x0CF3, 0x3004) },
+       { USB_DEVICE(0x0CF3, 0x3008) },
        { USB_DEVICE(0x0CF3, 0x311D) },
+       { USB_DEVICE(0x0CF3, 0x817a) },
        { USB_DEVICE(0x13d3, 0x3375) },
+       { USB_DEVICE(0x04CA, 0x3004) },
        { USB_DEVICE(0x04CA, 0x3005) },
        { USB_DEVICE(0x04CA, 0x3006) },
        { USB_DEVICE(0x04CA, 0x3008) },
@@ -105,9 +109,13 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 static struct usb_device_id ath3k_blist_tbl[] = {
 
        /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
index 7e351e345476c1bcc2141f95e41fe43a3e65e612..2cc5f774a29c47140739361420564b3f7c15b095 100644 (file)
@@ -131,9 +131,13 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
        /* Atheros 3012 with sflash firmware */
+       { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
index 24ffd8cec51e1c62eea5dd4af7b7d32410321f58..544b4ce617f8910ed443692589935894f2fe0969 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/capability.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
@@ -329,9 +330,7 @@ ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 }
 
 #ifdef THERM_USE_PROC
-static int
-proc_therm_ds1620_read(char *buf, char **start, off_t offset,
-                      int len, int *eof, void *unused)
+static int ds1620_proc_therm_show(struct seq_file *m, void *v)
 {
        struct therm th;
        int temp;
@@ -339,17 +338,25 @@ proc_therm_ds1620_read(char *buf, char **start, off_t offset,
        ds1620_read_state(&th);
        temp =  cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
 
-       len = sprintf(buf, "Thermostat: HI %i.%i, LOW %i.%i; "
-                     "temperature: %i.%i C, fan %s\n",
-                     th.hi >> 1, th.hi & 1 ? 5 : 0,
-                     th.lo >> 1, th.lo & 1 ? 5 : 0,
-                     temp  >> 1, temp  & 1 ? 5 : 0,
-                     fan_state[netwinder_get_fan()]);
+       seq_printf(m, "Thermostat: HI %i.%i, LOW %i.%i; temperature: %i.%i C, fan %s\n",
+                  th.hi >> 1, th.hi & 1 ? 5 : 0,
+                  th.lo >> 1, th.lo & 1 ? 5 : 0,
+                  temp  >> 1, temp  & 1 ? 5 : 0,
+                  fan_state[netwinder_get_fan()]);
+       return 0;
+}
 
-       return len;
+static int ds1620_proc_therm_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ds1620_proc_therm_show, NULL);
 }
 
-static struct proc_dir_entry *proc_therm_ds1620;
+static const struct file_operations ds1620_proc_therm_fops = {
+       .open           = ds1620_proc_therm_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif
 
 static const struct file_operations ds1620_fops = {
@@ -397,10 +404,7 @@ static int __init ds1620_init(void)
                return ret;
 
 #ifdef THERM_USE_PROC
-       proc_therm_ds1620 = create_proc_entry("therm", 0, NULL);
-       if (proc_therm_ds1620)
-               proc_therm_ds1620->read_proc = proc_therm_ds1620_read;
-       else
+       if (!proc_create("therm", 0, NULL, &ds1620_proc_therm_fops))
                printk(KERN_ERR "therm: unable to register /proc/therm\n");
 #endif
 
index a082d00b0f115f0c0d9dfcca07ade43c9f15070e..ea54a6e3f5adfa5311eaccb03d09571961beeee9 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/rtc.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/efi.h>
 #include <linux/uaccess.h>
 
@@ -296,12 +297,10 @@ static struct miscdevice efi_rtc_dev= {
 /*
  *     We export RAW EFI information to /proc/driver/efirtc
  */
-static int
-efi_rtc_get_status(char *buf)
+static int efi_rtc_proc_show(struct seq_file *m, void *v)
 {
        efi_time_t      eft, alm;
        efi_time_cap_t  cap;
-       char            *p = buf;
        efi_bool_t      enabled, pending;       
        unsigned long   flags;
 
@@ -316,64 +315,63 @@ efi_rtc_get_status(char *buf)
 
        spin_unlock_irqrestore(&efi_rtc_lock,flags);
 
-       p += sprintf(p,
-                    "Time           : %u:%u:%u.%09u\n"
-                    "Date           : %u-%u-%u\n"
-                    "Daylight       : %u\n",
-                    eft.hour, eft.minute, eft.second, eft.nanosecond, 
-                    eft.year, eft.month, eft.day,
-                    eft.daylight);
+       seq_printf(m,
+                  "Time           : %u:%u:%u.%09u\n"
+                  "Date           : %u-%u-%u\n"
+                  "Daylight       : %u\n",
+                  eft.hour, eft.minute, eft.second, eft.nanosecond, 
+                  eft.year, eft.month, eft.day,
+                  eft.daylight);
 
        if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
-               p += sprintf(p, "Timezone       : unspecified\n");
+               seq_puts(m, "Timezone       : unspecified\n");
        else
                /* XXX fixme: convert to string? */
-               p += sprintf(p, "Timezone       : %u\n", eft.timezone);
+               seq_printf(m, "Timezone       : %u\n", eft.timezone);
                
 
-       p += sprintf(p,
-                    "Alarm Time     : %u:%u:%u.%09u\n"
-                    "Alarm Date     : %u-%u-%u\n"
-                    "Alarm Daylight : %u\n"
-                    "Enabled        : %s\n"
-                    "Pending        : %s\n",
-                    alm.hour, alm.minute, alm.second, alm.nanosecond, 
-                    alm.year, alm.month, alm.day, 
-                    alm.daylight,
-                    enabled == 1 ? "yes" : "no",
-                    pending == 1 ? "yes" : "no");
+       seq_printf(m,
+                  "Alarm Time     : %u:%u:%u.%09u\n"
+                  "Alarm Date     : %u-%u-%u\n"
+                  "Alarm Daylight : %u\n"
+                  "Enabled        : %s\n"
+                  "Pending        : %s\n",
+                  alm.hour, alm.minute, alm.second, alm.nanosecond, 
+                  alm.year, alm.month, alm.day, 
+                  alm.daylight,
+                  enabled == 1 ? "yes" : "no",
+                  pending == 1 ? "yes" : "no");
 
        if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
-               p += sprintf(p, "Timezone       : unspecified\n");
+               seq_puts(m, "Timezone       : unspecified\n");
        else
                /* XXX fixme: convert to string? */
-               p += sprintf(p, "Timezone       : %u\n", alm.timezone);
+               seq_printf(m, "Timezone       : %u\n", alm.timezone);
 
        /*
         * now prints the capabilities
         */
-       p += sprintf(p,
-                    "Resolution     : %u\n"
-                    "Accuracy       : %u\n"
-                    "SetstoZero     : %u\n",
-                     cap.resolution, cap.accuracy, cap.sets_to_zero);
+       seq_printf(m,
+                  "Resolution     : %u\n"
+                  "Accuracy       : %u\n"
+                  "SetstoZero     : %u\n",
+                  cap.resolution, cap.accuracy, cap.sets_to_zero);
 
-       return  p - buf;
+       return 0;
 }
 
-static int
-efi_rtc_read_proc(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
+static int efi_rtc_proc_open(struct inode *inode, struct file *file)
 {
-        int len = efi_rtc_get_status(page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
+       return single_open(file, efi_rtc_proc_show, NULL);
 }
 
+static const struct file_operations efi_rtc_proc_fops = {
+       .open           = efi_rtc_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static int __init 
 efi_rtc_init(void)
 {
@@ -389,8 +387,7 @@ efi_rtc_init(void)
                return ret;
        }
 
-       dir = create_proc_read_entry ("driver/efirtc", 0, NULL,
-                                     efi_rtc_read_proc, NULL);
+       dir = proc_create("driver/efirtc", 0, NULL, &efi_rtc_proc_fops);
        if (dir == NULL) {
                printk(KERN_ERR "efirtc: can't create /proc/driver/efirtc.\n");
                misc_deregister(&efi_rtc_dev);
index 21cb980f115782a2e80c4f46c442585f75ca806d..bc9b84d56ee4aed6f8e83ede52039f6f5ffa0def 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
 
@@ -386,18 +387,15 @@ static int gen_rtc_release(struct inode *inode, struct file *file)
  *     Info exported via "/proc/driver/rtc".
  */
 
-static int gen_rtc_proc_output(char *buf)
+static int gen_rtc_proc_show(struct seq_file *m, void *v)
 {
-       char *p;
        struct rtc_time tm;
        unsigned int flags;
        struct rtc_pll_info pll;
 
-       p = buf;
-
        flags = get_rtc_time(&tm);
 
-       p += sprintf(p,
+       seq_printf(m,
                     "rtc_time\t: %02d:%02d:%02d\n"
                     "rtc_date\t: %04d-%02d-%02d\n"
                     "rtc_epoch\t: %04u\n",
@@ -406,23 +404,23 @@ static int gen_rtc_proc_output(char *buf)
 
        tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
 
-       p += sprintf(p, "alarm\t\t: ");
+       seq_puts(m, "alarm\t\t: ");
        if (tm.tm_hour <= 24)
-               p += sprintf(p, "%02d:", tm.tm_hour);
+               seq_printf(m, "%02d:", tm.tm_hour);
        else
-               p += sprintf(p, "**:");
+               seq_puts(m, "**:");
 
        if (tm.tm_min <= 59)
-               p += sprintf(p, "%02d:", tm.tm_min);
+               seq_printf(m, "%02d:", tm.tm_min);
        else
-               p += sprintf(p, "**:");
+               seq_puts(m, "**:");
 
        if (tm.tm_sec <= 59)
-               p += sprintf(p, "%02d\n", tm.tm_sec);
+               seq_printf(m, "%02d\n", tm.tm_sec);
        else
-               p += sprintf(p, "**\n");
+               seq_puts(m, "**\n");
 
-       p += sprintf(p,
+       seq_printf(m,
                     "DST_enable\t: %s\n"
                     "BCD\t\t: %s\n"
                     "24hr\t\t: %s\n"
@@ -442,7 +440,7 @@ static int gen_rtc_proc_output(char *buf)
                     0L /* freq */,
                     (flags & RTC_BATT_BAD) ? "bad" : "okay");
        if (!get_rtc_pll(&pll))
-           p += sprintf(p,
+           seq_printf(m,
                         "PLL adjustment\t: %d\n"
                         "PLL max +ve adjustment\t: %d\n"
                         "PLL max -ve adjustment\t: %d\n"
@@ -455,26 +453,26 @@ static int gen_rtc_proc_output(char *buf)
                         pll.pll_posmult,
                         pll.pll_negmult,
                         pll.pll_clock);
-       return p - buf;
+       return 0;
 }
 
-static int gen_rtc_read_proc(char *page, char **start, off_t off,
-                            int count, int *eof, void *data)
+static int gen_rtc_proc_open(struct inode *inode, struct file *file)
 {
-       int len = gen_rtc_proc_output (page);
-        if (len <= off+count) *eof = 1;
-       *start = page + off;
-       len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-       return len;
+       return single_open(file, gen_rtc_proc_show, NULL);
 }
 
+static const struct file_operations gen_rtc_proc_fops = {
+       .open           = gen_rtc_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static int __init gen_rtc_proc_init(void)
 {
        struct proc_dir_entry *r;
 
-       r = create_proc_read_entry("driver/rtc", 0, NULL, gen_rtc_read_proc, NULL);
+       r = proc_create("driver/rtc", 0, NULL, &gen_rtc_proc_fops);
        if (!r)
                return -ENOMEM;
        return 0;
index 1bafb40ec8a213480f355b480819f092fdfebd08..69ae5972713cf814e968c3c9d9ad8743d3dd240d 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 
@@ -52,8 +53,12 @@ static struct hwrng *current_rng;
 static LIST_HEAD(rng_list);
 static DEFINE_MUTEX(rng_mutex);
 static int data_avail;
-static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
-       __cacheline_aligned;
+static u8 *rng_buffer;
+
+static size_t rng_buffer_size(void)
+{
+       return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
+}
 
 static inline int hwrng_init(struct hwrng *rng)
 {
@@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
 
                if (!data_avail) {
                        bytes_read = rng_get_data(current_rng, rng_buffer,
-                               sizeof(rng_buffer),
+                               rng_buffer_size(),
                                !(filp->f_flags & O_NONBLOCK));
                        if (bytes_read < 0) {
                                err = bytes_read;
@@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng)
 
        mutex_lock(&rng_mutex);
 
+       /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
+       err = -ENOMEM;
+       if (!rng_buffer) {
+               rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
+               if (!rng_buffer)
+                       goto out_unlock;
+       }
+
        /* Must not register two RNGs with the same name. */
        err = -EEXIST;
        list_for_each_entry(tmp, &rng_list, list) {
index 10fd71ccf587789858582b09f37e646b7119e937..6bf4d47324eb884e7f462678acf493fec4c518b1 100644 (file)
@@ -92,14 +92,22 @@ static int probe_common(struct virtio_device *vdev)
 {
        int err;
 
+       if (vq) {
+               /* We only support one device for now */
+               return -EBUSY;
+       }
        /* We expect a single virtqueue. */
        vq = virtio_find_single_vq(vdev, random_recv_done, "input");
-       if (IS_ERR(vq))
-               return PTR_ERR(vq);
+       if (IS_ERR(vq)) {
+               err = PTR_ERR(vq);
+               vq = NULL;
+               return err;
+       }
 
        err = hwrng_register(&virtio_hwrng);
        if (err) {
                vdev->config->del_vqs(vdev);
+               vq = NULL;
                return err;
        }
 
@@ -112,6 +120,7 @@ static void remove_common(struct virtio_device *vdev)
        busy = false;
        hwrng_unregister(&virtio_hwrng);
        vdev->config->del_vqs(vdev);
+       vq = NULL;
 }
 
 static int virtrng_probe(struct virtio_device *vdev)
index 053201b062a4cffce40422ad1e28c925d4ea5244..4d439d2fcfd685a7e3e969aee8d7cef5e1cf14ee 100644 (file)
@@ -1917,7 +1917,7 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v)
 
 static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, smi_ipmb_proc_show, PDE(inode)->data);
+       return single_open(file, smi_ipmb_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations smi_ipmb_proc_ops = {
@@ -1938,7 +1938,7 @@ static int smi_version_proc_show(struct seq_file *m, void *v)
 
 static int smi_version_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, smi_version_proc_show, PDE(inode)->data);
+       return single_open(file, smi_version_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations smi_version_proc_ops = {
@@ -2013,7 +2013,7 @@ static int smi_stats_proc_show(struct seq_file *m, void *v)
 
 static int smi_stats_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, smi_stats_proc_show, PDE(inode)->data);
+       return single_open(file, smi_stats_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations smi_stats_proc_ops = {
@@ -4541,7 +4541,7 @@ static void __exit cleanup_ipmi(void)
        del_timer_sync(&ipmi_timer);
 
 #ifdef CONFIG_PROC_FS
-       remove_proc_entry(proc_ipmi_root->name, NULL);
+       proc_remove(proc_ipmi_root);
 #endif /* CONFIG_PROC_FS */
 
        driver_unregister(&ipmidriver.driver);
index 0ac9b45a585e46e145f962e300fa2daf33590307..313538abe63ceaef860b0a9b6a86ceb64a134907 100644 (file)
@@ -2839,7 +2839,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v)
 
 static int smi_type_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, smi_type_proc_show, PDE(inode)->data);
+       return single_open(file, smi_type_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations smi_type_proc_ops = {
@@ -2882,7 +2882,7 @@ static int smi_si_stats_proc_show(struct seq_file *m, void *v)
 
 static int smi_si_stats_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, smi_si_stats_proc_show, PDE(inode)->data);
+       return single_open(file, smi_si_stats_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations smi_si_stats_proc_ops = {
@@ -2910,7 +2910,7 @@ static int smi_params_proc_show(struct seq_file *m, void *v)
 
 static int smi_params_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, smi_params_proc_show, PDE(inode)->data);
+       return single_open(file, smi_params_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations smi_params_proc_ops = {
index 594bda9dcfc8ef847b725f44b3bd2604a784375a..32a6c5764950f642d12ae884aa7eb95d9cd1ccc2 100644 (file)
@@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                      int reserved)
 {
        unsigned long flags;
+       int wakeup_write = 0;
 
        /* Hold lock while accounting */
        spin_lock_irqsave(&r->lock, flags);
@@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                else
                        r->entropy_count = reserved;
 
-               if (r->entropy_count < random_write_wakeup_thresh) {
-                       wake_up_interruptible(&random_write_wait);
-                       kill_fasync(&fasync, SIGIO, POLL_OUT);
-               }
+               if (r->entropy_count < random_write_wakeup_thresh)
+                       wakeup_write = 1;
        }
 
        DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
@@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
 
        spin_unlock_irqrestore(&r->lock, flags);
 
+       if (wakeup_write) {
+               wake_up_interruptible(&random_write_wait);
+               kill_fasync(&fasync, SIGIO, POLL_OUT);
+       }
+
        return nbytes;
 }
 
index b5538bba7a10b84581c70d51357a8e360fc81545..09c63315e57979f8d726f627279f0e5e88e94c3f 100644 (file)
@@ -157,7 +157,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
        divisor =  parent_rate / rate;
 
        /* If prate / rate would be decimal, incr the divisor */
-       if (rate * divisor < *prate)
+       if (rate * divisor < parent_rate)
                divisor++;
 
        if (divisor == cdev->div_mask + 1)
index 143ce1f899ad74a5ce447652f64bb48c34b39652..1e2de730536282da499d60a57397f56b7d871c5e 100644 (file)
@@ -1292,7 +1292,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
        TEGRA_CLK_DUPLICATE(usbd,   "tegra-ehci.0", NULL),
        TEGRA_CLK_DUPLICATE(usbd,   "tegra-otg",    NULL),
        TEGRA_CLK_DUPLICATE(cclk,   NULL,           "cpu"),
-       TEGRA_CLK_DUPLICATE(twd,    "smp_twd",      NULL),
        TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */
 };
 
index 32c61cb6d0bb186d01a37fbea5dc3b15ef126e86..ba6f51bc9f3b8bc229bf0900ff380002fbb51e14 100644 (file)
@@ -1931,7 +1931,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
        TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL),
        TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"),
        TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"),
-       TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL),
        TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"),
        TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */
 };
index fce2000eec31d658efb52251b7f6df60822d1798..1110478dd0fdb83b6bbdbae5fa1f40c0a2406655 100644 (file)
@@ -313,6 +313,12 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
            (task_active_pid_ns(current) != &init_pid_ns))
                return;
 
+       /* Can only change if privileged. */
+       if (!capable(CAP_NET_ADMIN)) {
+               err = EPERM;
+               goto out;
+       }
+
        mc_op = (enum proc_cn_mcast_op *)msg->data;
        switch (*mc_op) {
        case PROC_CN_MCAST_LISTEN:
@@ -325,6 +331,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
                err = EINVAL;
                break;
        }
+
+out:
        cn_proc_ack(err, msg->seq, msg->ack);
 }
 
index d2ac911506006be9e1c77b1e57853828c33fd99a..46bde01eee623bd443d582013425257fbd11ec50 100644 (file)
@@ -64,7 +64,7 @@ static void *get_cpu_dbs_info_s(int cpu)                              \
  * dbs: used as a shortform for demand based switching It helps to keep variable
  *     names smaller, simpler
  * cdbs: common dbs
- * on_*: On-demand governor
+ * od_*: On-demand governor
  * cs_*: Conservative governor
  */
 
index 66e3a71b81a32f5c71242aca6bdfe4961b16587b..b61b5a3fad64983cc1681f89dc599649bf129bde 100644 (file)
 
 static int hb_voltage_change(unsigned int freq)
 {
-       int i;
-       u32 msg[HB_CPUFREQ_IPC_LEN];
-
-       msg[0] = HB_CPUFREQ_CHANGE_NOTE;
-       msg[1] = freq / 1000000;
-       for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++)
-               msg[i] = 0;
+       u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 1000000};
 
        return pl320_ipc_transmit(msg);
 }
index 096fde0ebcb5b9e2fb2d411f62e12b0702a319d0..f6dd1e7611293bf5a66531f2acb285713439430c 100644 (file)
@@ -662,6 +662,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 
        cpu = all_cpu_data[policy->cpu];
 
+       if (!policy->cpuinfo.max_freq)
+               return -ENODEV;
+
        intel_pstate_get_min_max(cpu, &min, &max);
 
        limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
@@ -747,37 +750,11 @@ static struct cpufreq_driver intel_pstate_driver = {
        .owner          = THIS_MODULE,
 };
 
-static void intel_pstate_exit(void)
-{
-       int cpu;
-
-       sysfs_remove_group(intel_pstate_kobject,
-                               &intel_pstate_attr_group);
-       debugfs_remove_recursive(debugfs_parent);
-
-       cpufreq_unregister_driver(&intel_pstate_driver);
-
-       if (!all_cpu_data)
-               return;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               if (all_cpu_data[cpu]) {
-                       del_timer_sync(&all_cpu_data[cpu]->timer);
-                       kfree(all_cpu_data[cpu]);
-               }
-       }
-
-       put_online_cpus();
-       vfree(all_cpu_data);
-}
-module_exit(intel_pstate_exit);
-
 static int __initdata no_load;
 
 static int __init intel_pstate_init(void)
 {
-       int rc = 0;
+       int cpu, rc = 0;
        const struct x86_cpu_id *id;
 
        if (no_load)
@@ -802,7 +779,16 @@ static int __init intel_pstate_init(void)
        intel_pstate_sysfs_expose_params();
        return rc;
 out:
-       intel_pstate_exit();
+       get_online_cpus();
+       for_each_online_cpu(cpu) {
+               if (all_cpu_data[cpu]) {
+                       del_timer_sync(&all_cpu_data[cpu]->timer);
+                       kfree(all_cpu_data[cpu]);
+               }
+       }
+
+       put_online_cpus();
+       vfree(all_cpu_data);
        return -ENODEV;
 }
 device_initcall(intel_pstate_init);
index 910b0116c12872aaebb5e72707ddc920d0722ce1..e1d13c463c9094e4f1b996311b1767725619f90f 100644 (file)
@@ -2048,12 +2048,18 @@ static int init_csrows(struct mem_ctl_info *mci)
                edac_dbg(1, "MC node: %d, csrow: %d\n",
                            pvt->mc_node_id, i);
 
-               if (row_dct0)
+               if (row_dct0) {
                        nr_pages = amd64_csrow_nr_pages(pvt, 0, i);
+                       csrow->channels[0]->dimm->nr_pages = nr_pages;
+               }
 
                /* K8 has only one DCT */
-               if (boot_cpu_data.x86 != 0xf && row_dct1)
-                       nr_pages += amd64_csrow_nr_pages(pvt, 1, i);
+               if (boot_cpu_data.x86 != 0xf && row_dct1) {
+                       int row_dct1_pages = amd64_csrow_nr_pages(pvt, 1, i);
+
+                       csrow->channels[1]->dimm->nr_pages = row_dct1_pages;
+                       nr_pages += row_dct1_pages;
+               }
 
                mtype = amd64_determine_memory_type(pvt, i);
 
@@ -2072,9 +2078,7 @@ static int init_csrows(struct mem_ctl_info *mci)
                        dimm = csrow->channels[j]->dimm;
                        dimm->mtype = mtype;
                        dimm->edac_mode = edac_mode;
-                       dimm->nr_pages = nr_pages;
                }
-               csrow->nr_pages = nr_pages;
        }
 
        return empty;
@@ -2419,7 +2423,6 @@ static int amd64_init_one_instance(struct pci_dev *F2)
 
        mci->pvt_info = pvt;
        mci->pdev = &pvt->F2->dev;
-       mci->csbased = 1;
 
        setup_mci_misc_attrs(mci, fam_type);
 
index cdb81aa73ab7aeb595be53f77430488486947e66..27e86d93826280a62744a559332bf0cd9bc03b3b 100644 (file)
@@ -86,7 +86,7 @@ static void edac_mc_dump_dimm(struct dimm_info *dimm, int number)
        edac_dimm_info_location(dimm, location, sizeof(location));
 
        edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n",
-                dimm->mci->mem_is_per_rank ? "rank" : "dimm",
+                dimm->mci->csbased ? "rank" : "dimm",
                 number, location, dimm->csrow, dimm->cschannel);
        edac_dbg(4, "  dimm = %p\n", dimm);
        edac_dbg(4, "  dimm->label = '%s'\n", dimm->label);
@@ -341,7 +341,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        memcpy(mci->layers, layers, sizeof(*layer) * n_layers);
        mci->nr_csrows = tot_csrows;
        mci->num_cschannel = tot_channels;
-       mci->mem_is_per_rank = per_rank;
+       mci->csbased = per_rank;
 
        /*
         * Alocate and fill the csrow/channels structs
@@ -1235,7 +1235,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
                         * incrementing the compat API counters
                         */
                        edac_dbg(4, "%s csrows map: (%d,%d)\n",
-                                mci->mem_is_per_rank ? "rank" : "dimm",
+                                mci->csbased ? "rank" : "dimm",
                                 dimm->csrow, dimm->cschannel);
                        if (row == -1)
                                row = dimm->csrow;
index 4f4b6137d74e6c4ebd894e104cdeaf18cd565969..5899a76eec3bd9086d1edfc24fa1b4aca1ce7969 100644 (file)
@@ -143,7 +143,7 @@ static const char *edac_caps[] = {
  * and the per-dimm/per-rank one
  */
 #define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \
-       struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store)
+       static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store)
 
 struct dev_ch_attribute {
        struct device_attribute attr;
@@ -180,9 +180,6 @@ static ssize_t csrow_size_show(struct device *dev,
        int i;
        u32 nr_pages = 0;
 
-       if (csrow->mci->csbased)
-               return sprintf(data, "%u\n", PAGES_TO_MiB(csrow->nr_pages));
-
        for (i = 0; i < csrow->nr_channels; i++)
                nr_pages += csrow->channels[i]->dimm->nr_pages;
        return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages));
@@ -612,7 +609,7 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
        device_initialize(&dimm->dev);
 
        dimm->dev.parent = &mci->dev;
-       if (mci->mem_is_per_rank)
+       if (mci->csbased)
                dev_set_name(&dimm->dev, "rank%d", index);
        else
                dev_set_name(&dimm->dev, "dimm%d", index);
@@ -778,14 +775,10 @@ static ssize_t mci_size_mb_show(struct device *dev,
        for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) {
                struct csrow_info *csrow = mci->csrows[csrow_idx];
 
-               if (csrow->mci->csbased) {
-                       total_pages += csrow->nr_pages;
-               } else {
-                       for (j = 0; j < csrow->nr_channels; j++) {
-                               struct dimm_info *dimm = csrow->channels[j]->dimm;
+               for (j = 0; j < csrow->nr_channels; j++) {
+                       struct dimm_info *dimm = csrow->channels[j]->dimm;
 
-                               total_pages += dimm->nr_pages;
-                       }
+                       total_pages += dimm->nr_pages;
                }
        }
 
index 9b00072a020fb5141060c5ee89cfe31edbd651be..42c759a4d047f6754ddf8676a390d8d0dcdffafb 100644 (file)
@@ -53,6 +53,24 @@ config EFI_VARS
          Subsequent efibootmgr releases may be found at:
          <http://linux.dell.com/efibootmgr>
 
+config EFI_VARS_PSTORE
+       bool "Register efivars backend for pstore"
+       depends on EFI_VARS && PSTORE
+       default y
+       help
+         Say Y here to enable use efivars as a backend to pstore. This
+         will allow writing console messages, crash dumps, or anything
+         else supported by pstore to EFI variables.
+
+config EFI_VARS_PSTORE_DEFAULT_DISABLE
+       bool "Disable using efivars as a pstore backend by default"
+       depends on EFI_VARS_PSTORE
+       default n
+       help
+         Saying Y here will disable the use of efivars as a storage
+         backend for pstore by default. This setting can be overridden
+         using the efivars module's pstore_disable parameter.
+
 config EFI_PCDP
        bool "Console device selection via EFI PCDP or HCDP table"
        depends on ACPI && EFI && IA64
index 982f1f5f5742f21da9206f62fa622ce17adefe9f..4cd392dbf115075740cb546f4875f220517c7896 100644 (file)
@@ -442,7 +442,6 @@ static int __init dmi_present(const char __iomem *p)
 static int __init smbios_present(const char __iomem *p)
 {
        u8 buf[32];
-       int offset = 0;
 
        memcpy_fromio(buf, p, 32);
        if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
@@ -461,9 +460,9 @@ static int __init smbios_present(const char __iomem *p)
                        dmi_ver = 0x0206;
                        break;
                }
-               offset = 16;
+               return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
        }
-       return dmi_present(buf + offset);
+       return 1;
 }
 
 void __init dmi_scan_machine(void)
index 7320bf891706abaeb299c4bf976bf027aba5ec3b..0f1026019c0f8f13cbc0035115789ef9d2cf2ace 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/slab.h>
 #include <linux/pstore.h>
 #include <linux/ctype.h>
+#include <linux/magic.h>
 
 #include <linux/fs.h>
 #include <linux/ramfs.h>
@@ -103,6 +104,11 @@ MODULE_VERSION(EFIVARS_VERSION);
  */
 #define GUID_LEN 36
 
+static bool efivars_pstore_disable =
+       IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
+
+module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
+
 /*
  * The maximum size of VariableName + Data = 1024
  * Therefore, it's reasonable to save that much
@@ -165,6 +171,7 @@ efivar_create_sysfs_entry(struct efivars *efivars,
 
 static void efivar_update_sysfs_entries(struct work_struct *);
 static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
+static bool efivar_wq_enabled = true;
 
 /* Return the number of unicode characters in data */
 static unsigned long
@@ -426,6 +433,44 @@ get_var_data(struct efivars *efivars, struct efi_variable *var)
        return status;
 }
 
+static efi_status_t
+check_var_size_locked(struct efivars *efivars, u32 attributes,
+                       unsigned long size)
+{
+       u64 storage_size, remaining_size, max_size;
+       efi_status_t status;
+       const struct efivar_operations *fops = efivars->ops;
+
+       if (!efivars->ops->query_variable_info)
+               return EFI_UNSUPPORTED;
+
+       status = fops->query_variable_info(attributes, &storage_size,
+                                          &remaining_size, &max_size);
+
+       if (status != EFI_SUCCESS)
+               return status;
+
+       if (!storage_size || size > remaining_size || size > max_size ||
+           (remaining_size - size) < (storage_size / 2))
+               return EFI_OUT_OF_RESOURCES;
+
+       return status;
+}
+
+
+static efi_status_t
+check_var_size(struct efivars *efivars, u32 attributes, unsigned long size)
+{
+       efi_status_t status;
+       unsigned long flags;
+
+       spin_lock_irqsave(&efivars->lock, flags);
+       status = check_var_size_locked(efivars, attributes, size);
+       spin_unlock_irqrestore(&efivars->lock, flags);
+
+       return status;
+}
+
 static ssize_t
 efivar_guid_read(struct efivar_entry *entry, char *buf)
 {
@@ -547,11 +592,16 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
        }
 
        spin_lock_irq(&efivars->lock);
-       status = efivars->ops->set_variable(new_var->VariableName,
-                                           &new_var->VendorGuid,
-                                           new_var->Attributes,
-                                           new_var->DataSize,
-                                           new_var->Data);
+
+       status = check_var_size_locked(efivars, new_var->Attributes,
+              new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+       if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
+               status = efivars->ops->set_variable(new_var->VariableName,
+                                                   &new_var->VendorGuid,
+                                                   new_var->Attributes,
+                                                   new_var->DataSize,
+                                                   new_var->Data);
 
        spin_unlock_irq(&efivars->lock);
 
@@ -702,8 +752,7 @@ static ssize_t efivarfs_file_write(struct file *file,
        u32 attributes;
        struct inode *inode = file->f_mapping->host;
        unsigned long datasize = count - sizeof(attributes);
-       unsigned long newdatasize;
-       u64 storage_size, remaining_size, max_size;
+       unsigned long newdatasize, varsize;
        ssize_t bytes = 0;
 
        if (count < sizeof(attributes))
@@ -722,28 +771,18 @@ static ssize_t efivarfs_file_write(struct file *file,
         * amounts of memory. Pick a default size of 64K if
         * QueryVariableInfo() isn't supported by the firmware.
         */
-       spin_lock_irq(&efivars->lock);
 
-       if (!efivars->ops->query_variable_info)
-               status = EFI_UNSUPPORTED;
-       else {
-               const struct efivar_operations *fops = efivars->ops;
-               status = fops->query_variable_info(attributes, &storage_size,
-                                                  &remaining_size, &max_size);
-       }
-
-       spin_unlock_irq(&efivars->lock);
+       varsize = datasize + utf16_strsize(var->var.VariableName, 1024);
+       status = check_var_size(efivars, attributes, varsize);
 
        if (status != EFI_SUCCESS) {
                if (status != EFI_UNSUPPORTED)
                        return efi_status_to_err(status);
 
-               remaining_size = 65536;
+               if (datasize > 65536)
+                       return -ENOSPC;
        }
 
-       if (datasize > remaining_size)
-               return -ENOSPC;
-
        data = kmalloc(datasize, GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -765,6 +804,19 @@ static ssize_t efivarfs_file_write(struct file *file,
         */
        spin_lock_irq(&efivars->lock);
 
+       /*
+        * Ensure that the available space hasn't shrunk below the safe level
+        */
+
+       status = check_var_size_locked(efivars, attributes, varsize);
+
+       if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) {
+               spin_unlock_irq(&efivars->lock);
+               kfree(data);
+
+               return efi_status_to_err(status);
+       }
+
        status = efivars->ops->set_variable(var->var.VariableName,
                                            &var->var.VendorGuid,
                                            attributes, datasize,
@@ -929,8 +981,8 @@ static bool efivarfs_valid_name(const char *str, int len)
        if (len < GUID_LEN + 2)
                return false;
 
-       /* GUID should be right after the first '-' */
-       if (s - 1 != strchr(str, '-'))
+       /* GUID must be preceded by a '-' */
+       if (*(s - 1) != '-')
                return false;
 
        /*
@@ -1118,15 +1170,22 @@ static struct dentry_operations efivarfs_d_ops = {
 
 static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
 {
+       struct dentry *d;
        struct qstr q;
+       int err;
 
        q.name = name;
        q.len = strlen(name);
 
-       if (efivarfs_d_hash(NULL, NULL, &q))
-               return NULL;
+       err = efivarfs_d_hash(NULL, NULL, &q);
+       if (err)
+               return ERR_PTR(err);
+
+       d = d_alloc(parent, &q);
+       if (d)
+               return d;
 
-       return d_alloc(parent, &q);
+       return ERR_PTR(-ENOMEM);
 }
 
 static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -1136,6 +1195,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
        struct efivar_entry *entry, *n;
        struct efivars *efivars = &__efivars;
        char *name;
+       int err = -ENOMEM;
 
        efivarfs_sb = sb;
 
@@ -1186,8 +1246,10 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
                        goto fail_name;
 
                dentry = efivarfs_alloc_dentry(root, name);
-               if (!dentry)
+               if (IS_ERR(dentry)) {
+                       err = PTR_ERR(dentry);
                        goto fail_inode;
+               }
 
                /* copied by the above to local storage in the dentry. */
                kfree(name);
@@ -1214,7 +1276,7 @@ fail_inode:
 fail_name:
        kfree(name);
 fail:
-       return -ENOMEM;
+       return err;
 }
 
 static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
@@ -1234,6 +1296,7 @@ static struct file_system_type efivarfs_type = {
        .mount   = efivarfs_mount,
        .kill_sb = efivarfs_kill_sb,
 };
+MODULE_ALIAS_FS("efivarfs");
 
 /*
  * Handle negative dentry.
@@ -1253,9 +1316,7 @@ static const struct inode_operations efivarfs_dir_inode_operations = {
        .create = efivarfs_create,
 };
 
-static struct pstore_info efi_pstore_info;
-
-#ifdef CONFIG_PSTORE
+#ifdef CONFIG_EFI_VARS_PSTORE
 
 static int efi_pstore_open(struct pstore_info *psi)
 {
@@ -1345,7 +1406,6 @@ static int efi_pstore_write(enum pstore_type_id type,
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
        struct efivars *efivars = psi->data;
        int i, ret = 0;
-       u64 storage_space, remaining_space, max_variable_size;
        efi_status_t status = EFI_NOT_FOUND;
        unsigned long flags;
 
@@ -1365,11 +1425,11 @@ static int efi_pstore_write(enum pstore_type_id type,
         * size: a size of logging data
         * DUMP_NAME_LEN * 2: a maximum size of variable name
         */
-       status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
-                                                  &storage_space,
-                                                  &remaining_space,
-                                                  &max_variable_size);
-       if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+
+       status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
+                                        size + DUMP_NAME_LEN * 2);
+
+       if (status) {
                spin_unlock_irqrestore(&efivars->lock, flags);
                *id = part;
                return -ENOSPC;
@@ -1386,7 +1446,7 @@ static int efi_pstore_write(enum pstore_type_id type,
 
        spin_unlock_irqrestore(&efivars->lock, flags);
 
-       if (reason == KMSG_DUMP_OOPS)
+       if (reason == KMSG_DUMP_OOPS && efivar_wq_enabled)
                schedule_work(&efivar_work);
 
        *id = part;
@@ -1459,38 +1519,6 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 
        return 0;
 }
-#else
-static int efi_pstore_open(struct pstore_info *psi)
-{
-       return 0;
-}
-
-static int efi_pstore_close(struct pstore_info *psi)
-{
-       return 0;
-}
-
-static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count,
-                              struct timespec *timespec,
-                              char **buf, struct pstore_info *psi)
-{
-       return -1;
-}
-
-static int efi_pstore_write(enum pstore_type_id type,
-               enum kmsg_dump_reason reason, u64 *id,
-               unsigned int part, int count, size_t size,
-               struct pstore_info *psi)
-{
-       return 0;
-}
-
-static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
-                           struct timespec time, struct pstore_info *psi)
-{
-       return 0;
-}
-#endif
 
 static struct pstore_info efi_pstore_info = {
        .owner          = THIS_MODULE,
@@ -1502,6 +1530,24 @@ static struct pstore_info efi_pstore_info = {
        .erase          = efi_pstore_erase,
 };
 
+static void efivar_pstore_register(struct efivars *efivars)
+{
+       efivars->efi_pstore_info = efi_pstore_info;
+       efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+       if (efivars->efi_pstore_info.buf) {
+               efivars->efi_pstore_info.bufsize = 1024;
+               efivars->efi_pstore_info.data = efivars;
+               spin_lock_init(&efivars->efi_pstore_info.buf_lock);
+               pstore_register(&efivars->efi_pstore_info);
+       }
+}
+#else
+static void efivar_pstore_register(struct efivars *efivars)
+{
+       return;
+}
+#endif
+
 static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
                             struct bin_attribute *bin_attr,
                             char *buf, loff_t pos, size_t count)
@@ -1544,6 +1590,14 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
                return -EINVAL;
        }
 
+       status = check_var_size_locked(efivars, new_var->Attributes,
+              new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+       if (status && status != EFI_UNSUPPORTED) {
+               spin_unlock_irq(&efivars->lock);
+               return efi_status_to_err(status);
+       }
+
        /* now *really* create the variable via EFI */
        status = efivars->ops->set_variable(new_var->VariableName,
                                            &new_var->VendorGuid,
@@ -1653,6 +1707,31 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
        return found;
 }
 
+/*
+ * Returns the size of variable_name, in bytes, including the
+ * terminating NULL character, or variable_name_size if no NULL
+ * character is found among the first variable_name_size bytes.
+ */
+static unsigned long var_name_strnsize(efi_char16_t *variable_name,
+                                      unsigned long variable_name_size)
+{
+       unsigned long len;
+       efi_char16_t c;
+
+       /*
+        * The variable name is, by definition, a NULL-terminated
+        * string, so make absolutely sure that variable_name_size is
+        * the value we expect it to be. If not, return the real size.
+        */
+       for (len = 2; len <= variable_name_size; len += sizeof(c)) {
+               c = variable_name[(len / sizeof(c)) - 1];
+               if (!c)
+                       break;
+       }
+
+       return min(len, variable_name_size);
+}
+
 static void efivar_update_sysfs_entries(struct work_struct *work)
 {
        struct efivars *efivars = &__efivars;
@@ -1693,10 +1772,13 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
                if (!found) {
                        kfree(variable_name);
                        break;
-               } else
+               } else {
+                       variable_name_size = var_name_strnsize(variable_name,
+                                                              variable_name_size);
                        efivar_create_sysfs_entry(efivars,
                                                  variable_name_size,
                                                  variable_name, &vendor);
+               }
        }
 }
 
@@ -1895,6 +1977,35 @@ void unregister_efivars(struct efivars *efivars)
 }
 EXPORT_SYMBOL_GPL(unregister_efivars);
 
+/*
+ * Print a warning when duplicate EFI variables are encountered and
+ * disable the sysfs workqueue since the firmware is buggy.
+ */
+static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
+                            unsigned long len16)
+{
+       size_t i, len8 = len16 / sizeof(efi_char16_t);
+       char *s8;
+
+       /*
+        * Disable the workqueue since the algorithm it uses for
+        * detecting new variables won't work with this buggy
+        * implementation of GetNextVariableName().
+        */
+       efivar_wq_enabled = false;
+
+       s8 = kzalloc(len8, GFP_KERNEL);
+       if (!s8)
+               return;
+
+       for (i = 0; i < len8; i++)
+               s8[i] = s16[i];
+
+       printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
+              s8, vendor_guid);
+       kfree(s8);
+}
+
 int register_efivars(struct efivars *efivars,
                     const struct efivar_operations *ops,
                     struct kobject *parent_kobj)
@@ -1943,6 +2054,24 @@ int register_efivars(struct efivars *efivars,
                                                &vendor_guid);
                switch (status) {
                case EFI_SUCCESS:
+                       variable_name_size = var_name_strnsize(variable_name,
+                                                              variable_name_size);
+
+                       /*
+                        * Some firmware implementations return the
+                        * same variable name on multiple calls to
+                        * get_next_variable(). Terminate the loop
+                        * immediately as there is no guarantee that
+                        * we'll ever see a different variable name,
+                        * and may end up looping here forever.
+                        */
+                       if (variable_is_present(variable_name, &vendor_guid)) {
+                               dup_variable_bug(variable_name, &vendor_guid,
+                                                variable_name_size);
+                               status = EFI_NOT_FOUND;
+                               break;
+                       }
+
                        efivar_create_sysfs_entry(efivars,
                                                  variable_name_size,
                                                  variable_name,
@@ -1962,15 +2091,8 @@ int register_efivars(struct efivars *efivars,
        if (error)
                unregister_efivars(efivars);
 
-       efivars->efi_pstore_info = efi_pstore_info;
-
-       efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
-       if (efivars->efi_pstore_info.buf) {
-               efivars->efi_pstore_info.bufsize = 1024;
-               efivars->efi_pstore_info.data = efivars;
-               spin_lock_init(&efivars->efi_pstore_info.buf_lock);
-               pstore_register(&efivars->efi_pstore_info);
-       }
+       if (!efivars_pstore_disable)
+               efivar_pstore_register(efivars);
 
        register_filesystem(&efivarfs_type);
 
index 6f2306db85915eca2690895eda7e8f6b375091ab..f9dbd503fc40fb0f1bccd0fa8f0995816a06b538 100644 (file)
@@ -128,9 +128,9 @@ static int ichx_read_bit(int reg, unsigned nr)
        return data & (1 << bit) ? 1 : 0;
 }
 
-static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
+static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
 {
-       return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO;
+       return ichx_priv.use_gpio & (1 << (nr / 32));
 }
 
 static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
index 7472182967ce15b44d964d184038fbca247724e8..61a6fde6c089b28a76f3ca5012309c101ebcf2b2 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/io.h>
 #include <linux/of_irq.h>
 #include <linux/of_device.h>
+#include <linux/clk.h>
 #include <linux/pinctrl/consumer.h>
 
 /*
@@ -496,6 +497,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
        struct resource *res;
        struct irq_chip_generic *gc;
        struct irq_chip_type *ct;
+       struct clk *clk;
        unsigned int ngpios;
        int soc_variant;
        int i, cpu, id;
@@ -529,6 +531,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
                return id;
        }
 
+       clk = devm_clk_get(&pdev->dev, NULL);
+       /* Not all SoCs require a clock.*/
+       if (!IS_ERR(clk))
+               clk_prepare_enable(clk);
+
        mvchip->soc_variant = soc_variant;
        mvchip->chip.label = dev_name(&pdev->dev);
        mvchip->chip.dev = &pdev->dev;
index a71a54a3e3f783a4151ed5919c01290ade8ffd5d..5150df6cba0815623c9fc7c86e96ff2ad099f0ed 100644 (file)
@@ -193,7 +193,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
        if (!np)
                return;
 
-       do {
+       for (;; index++) {
                ret = of_parse_phandle_with_args(np, "gpio-ranges",
                                "#gpio-range-cells", index, &pinspec);
                if (ret)
@@ -222,8 +222,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
 
                if (ret)
                        break;
-
-       } while (index++);
+       }
 }
 
 #else
index fff9786cdc643120f933154366237a8d6b332e8d..c2534d62911cfd18434c9b2bb172cad265603e0d 100644 (file)
@@ -88,13 +88,14 @@ static int gpiod_request(struct gpio_desc *desc, const char *label);
 static void gpiod_free(struct gpio_desc *desc);
 static int gpiod_direction_input(struct gpio_desc *desc);
 static int gpiod_direction_output(struct gpio_desc *desc, int value);
+static int gpiod_get_direction(const struct gpio_desc *desc);
 static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
-static int gpiod_get_value_cansleep(struct gpio_desc *desc);
+static int gpiod_get_value_cansleep(const struct gpio_desc *desc);
 static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
-static int gpiod_get_value(struct gpio_desc *desc);
+static int gpiod_get_value(const struct gpio_desc *desc);
 static void gpiod_set_value(struct gpio_desc *desc, int value);
-static int gpiod_cansleep(struct gpio_desc *desc);
-static int gpiod_to_irq(struct gpio_desc *desc);
+static int gpiod_cansleep(const struct gpio_desc *desc);
+static int gpiod_to_irq(const struct gpio_desc *desc);
 static int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
 static int gpiod_export_link(struct device *dev, const char *name,
                             struct gpio_desc *desc);
@@ -171,12 +172,12 @@ static int gpio_ensure_requested(struct gpio_desc *desc)
        return 0;
 }
 
-/* caller holds gpio_lock *OR* gpio is marked as requested */
-static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc)
+static struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
 {
-       return desc->chip;
+       return desc ? desc->chip : NULL;
 }
 
+/* caller holds gpio_lock *OR* gpio is marked as requested */
 struct gpio_chip *gpio_to_chip(unsigned gpio)
 {
        return gpiod_to_chip(gpio_to_desc(gpio));
@@ -207,7 +208,7 @@ static int gpiochip_find_base(int ngpio)
 }
 
 /* caller ensures gpio is valid and requested, chip->get_direction may sleep  */
-static int gpiod_get_direction(struct gpio_desc *desc)
+static int gpiod_get_direction(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        unsigned                offset;
@@ -223,11 +224,13 @@ static int gpiod_get_direction(struct gpio_desc *desc)
        if (status > 0) {
                /* GPIOF_DIR_IN, or other positive */
                status = 1;
-               clear_bit(FLAG_IS_OUT, &desc->flags);
+               /* FLAG_IS_OUT is just a cache of the result of get_direction(),
+                * so it does not affect constness per se */
+               clear_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags);
        }
        if (status == 0) {
                /* GPIOF_DIR_OUT */
-               set_bit(FLAG_IS_OUT, &desc->flags);
+               set_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags);
        }
        return status;
 }
@@ -263,7 +266,7 @@ static DEFINE_MUTEX(sysfs_lock);
 static ssize_t gpio_direction_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
+       const struct gpio_desc  *desc = dev_get_drvdata(dev);
        ssize_t                 status;
 
        mutex_lock(&sysfs_lock);
@@ -654,6 +657,11 @@ static ssize_t export_store(struct class *class,
                goto done;
 
        desc = gpio_to_desc(gpio);
+       /* reject invalid GPIOs */
+       if (!desc) {
+               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+               return -EINVAL;
+       }
 
        /* No extra locking here; FLAG_SYSFS just signifies that the
         * request and export were done by on behalf of userspace, so
@@ -690,12 +698,14 @@ static ssize_t unexport_store(struct class *class,
        if (status < 0)
                goto done;
 
-       status = -EINVAL;
-
        desc = gpio_to_desc(gpio);
        /* reject bogus commands (gpio_unexport ignores them) */
-       if (!desc)
-               goto done;
+       if (!desc) {
+               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+               return -EINVAL;
+       }
+
+       status = -EINVAL;
 
        /* No extra locking here; FLAG_SYSFS just signifies that the
         * request and export were done by on behalf of userspace, so
@@ -846,8 +856,10 @@ static int gpiod_export_link(struct device *dev, const char *name,
 {
        int                     status = -EINVAL;
 
-       if (!desc)
-               goto done;
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
 
        mutex_lock(&sysfs_lock);
 
@@ -865,7 +877,6 @@ static int gpiod_export_link(struct device *dev, const char *name,
 
        mutex_unlock(&sysfs_lock);
 
-done:
        if (status)
                pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
                         status);
@@ -896,8 +907,10 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
        struct device           *dev = NULL;
        int                     status = -EINVAL;
 
-       if (!desc)
-               goto done;
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
 
        mutex_lock(&sysfs_lock);
 
@@ -914,7 +927,6 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
 unlock:
        mutex_unlock(&sysfs_lock);
 
-done:
        if (status)
                pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
                         status);
@@ -940,8 +952,8 @@ static void gpiod_unexport(struct gpio_desc *desc)
        struct device           *dev = NULL;
 
        if (!desc) {
-               status = -EINVAL;
-               goto done;
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return;
        }
 
        mutex_lock(&sysfs_lock);
@@ -962,7 +974,7 @@ static void gpiod_unexport(struct gpio_desc *desc)
                device_unregister(dev);
                put_device(dev);
        }
-done:
+
        if (status)
                pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
                         status);
@@ -1384,12 +1396,13 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
        int                     status = -EPROBE_DEFER;
        unsigned long           flags;
 
-       spin_lock_irqsave(&gpio_lock, flags);
-
        if (!desc) {
-               status = -EINVAL;
-               goto done;
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
        }
+
+       spin_lock_irqsave(&gpio_lock, flags);
+
        chip = desc->chip;
        if (chip == NULL)
                goto done;
@@ -1432,8 +1445,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
 done:
        if (status)
                pr_debug("_gpio_request: gpio-%d (%s) status %d\n",
-                        desc ? desc_to_gpio(desc) : -1,
-                        label ? : "?", status);
+                        desc_to_gpio(desc), label ? : "?", status);
        spin_unlock_irqrestore(&gpio_lock, flags);
        return status;
 }
@@ -1616,10 +1628,13 @@ static int gpiod_direction_input(struct gpio_desc *desc)
        int                     status = -EINVAL;
        int                     offset;
 
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!desc)
-               goto fail;
        chip = desc->chip;
        if (!chip || !chip->get || !chip->direction_input)
                goto fail;
@@ -1655,13 +1670,9 @@ lose:
        return status;
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status) {
-               int gpio = -1;
-               if (desc)
-                       gpio = desc_to_gpio(desc);
-               pr_debug("%s: gpio-%d status %d\n",
-                       __func__, gpio, status);
-       }
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n", __func__,
+                        desc_to_gpio(desc), status);
        return status;
 }
 
@@ -1678,6 +1689,11 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
        int                     status = -EINVAL;
        int offset;
 
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+
        /* Open drain pin should not be driven to 1 */
        if (value && test_bit(FLAG_OPEN_DRAIN,  &desc->flags))
                return gpiod_direction_input(desc);
@@ -1688,8 +1704,6 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
 
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!desc)
-               goto fail;
        chip = desc->chip;
        if (!chip || !chip->set || !chip->direction_output)
                goto fail;
@@ -1725,13 +1739,9 @@ lose:
        return status;
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status) {
-               int gpio = -1;
-               if (desc)
-                       gpio = desc_to_gpio(desc);
-               pr_debug("%s: gpio-%d status %d\n",
-                       __func__, gpio, status);
-       }
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n", __func__,
+                        desc_to_gpio(desc), status);
        return status;
 }
 
@@ -1753,10 +1763,13 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
        int                     status = -EINVAL;
        int                     offset;
 
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!desc)
-               goto fail;
        chip = desc->chip;
        if (!chip || !chip->set || !chip->set_debounce)
                goto fail;
@@ -1776,13 +1789,9 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
 
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status) {
-               int gpio = -1;
-               if (desc)
-                       gpio = desc_to_gpio(desc);
-               pr_debug("%s: gpio-%d status %d\n",
-                       __func__, gpio, status);
-       }
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n", __func__,
+                        desc_to_gpio(desc), status);
 
        return status;
 }
@@ -1824,12 +1833,14 @@ EXPORT_SYMBOL_GPL(gpio_set_debounce);
  * It returns the zero or nonzero value provided by the associated
  * gpio_chip.get() method; or zero if no such method is provided.
  */
-static int gpiod_get_value(struct gpio_desc *desc)
+static int gpiod_get_value(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        int value;
        int offset;
 
+       if (!desc)
+               return 0;
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        /* Should be using gpio_get_value_cansleep() */
@@ -1912,6 +1923,8 @@ static void gpiod_set_value(struct gpio_desc *desc, int value)
 {
        struct gpio_chip        *chip;
 
+       if (!desc)
+               return;
        chip = desc->chip;
        /* Should be using gpio_set_value_cansleep() */
        WARN_ON(chip->can_sleep);
@@ -1938,8 +1951,10 @@ EXPORT_SYMBOL_GPL(__gpio_set_value);
  * This is used directly or indirectly to implement gpio_cansleep().  It
  * returns nonzero if access reading or writing the GPIO value can sleep.
  */
-static int gpiod_cansleep(struct gpio_desc *desc)
+static int gpiod_cansleep(const struct gpio_desc *desc)
 {
+       if (!desc)
+               return 0;
        /* only call this on GPIOs that are valid! */
        return desc->chip->can_sleep;
 }
@@ -1959,11 +1974,13 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep);
  * It returns the number of the IRQ signaled by this (input) GPIO,
  * or a negative errno.
  */
-static int gpiod_to_irq(struct gpio_desc *desc)
+static int gpiod_to_irq(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        int                     offset;
 
+       if (!desc)
+               return -EINVAL;
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO;
@@ -1980,13 +1997,15 @@ EXPORT_SYMBOL_GPL(__gpio_to_irq);
  * Common examples include ones connected to I2C or SPI chips.
  */
 
-static int gpiod_get_value_cansleep(struct gpio_desc *desc)
+static int gpiod_get_value_cansleep(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        int value;
        int offset;
 
        might_sleep_if(extra_checks);
+       if (!desc)
+               return 0;
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        value = chip->get ? chip->get(chip, offset) : 0;
@@ -2005,6 +2024,8 @@ static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
        struct gpio_chip        *chip;
 
        might_sleep_if(extra_checks);
+       if (!desc)
+               return;
        chip = desc->chip;
        trace_gpio_value(desc_to_gpio(desc), 0, value);
        if (test_bit(FLAG_OPEN_DRAIN,  &desc->flags))
index c194f4e680ad17cf7d2b665a277b10ad2f2edc6a..e2acfdbf7d3cc7f60104ba5b6c3fce3142e538b8 100644 (file)
@@ -1634,7 +1634,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
        unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
        unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
        unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
-       unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4;
+       unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
        unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
 
        /* ignore tiny modes */
@@ -1715,6 +1715,7 @@ set_size:
        }
 
        mode->type = DRM_MODE_TYPE_DRIVER;
+       mode->vrefresh = drm_mode_vrefresh(mode);
        drm_mode_set_name(mode);
 
        return mode;
index ff5456b7df728ebc7c5bc32fce102fb65ed5d5bf..d7f2324b4fb14d3e83589a65c535bd72da8101a0 100644 (file)
@@ -49,7 +49,7 @@
 /**
  * Proc file list.
  */
-static struct drm_info_list drm_proc_list[] = {
+static const struct drm_info_list drm_proc_list[] = {
        {"name", drm_name_info, 0},
        {"vm", drm_vm_info, 0},
        {"clients", drm_clients_info, 0},
@@ -63,7 +63,7 @@ static struct drm_info_list drm_proc_list[] = {
 
 static int drm_proc_open(struct inode *inode, struct file *file)
 {
-       struct drm_info_node* node = PDE(inode)->data;
+       struct drm_info_node* node = PDE_DATA(inode);
 
        return single_open(file, node->info_ent->show, node);
 }
@@ -89,13 +89,13 @@ static const struct file_operations drm_proc_fops = {
  * Create a given set of proc files represented by an array of
  * gdm_proc_lists in the given root directory.
  */
-static int drm_proc_create_files(struct drm_info_list *files, int count,
+static int drm_proc_create_files(const struct drm_info_list *files, int count,
                          struct proc_dir_entry *root, struct drm_minor *minor)
 {
        struct drm_device *dev = minor->dev;
        struct proc_dir_entry *ent;
        struct drm_info_node *tmp;
-       int i, ret;
+       int i;
 
        for (i = 0; i < count; i++) {
                u32 features = files[i].driver_features;
@@ -105,10 +105,9 @@ static int drm_proc_create_files(struct drm_info_list *files, int count,
                        continue;
 
                tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
-               if (tmp == NULL) {
-                       ret = -1;
-                       goto fail;
-               }
+               if (!tmp)
+                       return -1;
+
                tmp->minor = minor;
                tmp->info_ent = &files[i];
                list_add(&tmp->list, &minor->proc_nodes.list);
@@ -116,28 +115,20 @@ static int drm_proc_create_files(struct drm_info_list *files, int count,
                ent = proc_create_data(files[i].name, S_IRUGO, root,
                                       &drm_proc_fops, tmp);
                if (!ent) {
-                       DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
-                                 root->name, files[i].name);
+                       DRM_ERROR("Cannot create /proc/dri/%u/%s\n",
+                                 minor->index, files[i].name);
                        list_del(&tmp->list);
                        kfree(tmp);
-                       ret = -1;
-                       goto fail;
+                       return -1;
                }
-
        }
        return 0;
-
-fail:
-       for (i = 0; i < count; i++)
-               remove_proc_entry(drm_proc_list[i].name, minor->proc_root);
-       return ret;
 }
 
 /**
  * Initialize the DRI proc filesystem for a device
  *
  * \param dev DRM device
- * \param minor device minor number
  * \param root DRI proc dir entry.
  * \param dev_root resulting DRI device proc dir entry.
  * \return root entry pointer on success, or NULL on failure.
@@ -146,14 +137,13 @@ fail:
  * "/proc/dri/%minor%/", and each entry in proc_list as
  * "/proc/dri/%minor%/%name%".
  */
-int drm_proc_init(struct drm_minor *minor, int minor_id,
-                 struct proc_dir_entry *root)
+int drm_proc_init(struct drm_minor *minor, struct proc_dir_entry *root)
 {
-       char name[64];
+       char name[12];
        int ret;
 
        INIT_LIST_HEAD(&minor->proc_nodes.list);
-       sprintf(name, "%d", minor_id);
+       sprintf(name, "%u", minor->index);
        minor->proc_root = proc_mkdir(name, root);
        if (!minor->proc_root) {
                DRM_ERROR("Cannot create /proc/dri/%s\n", name);
@@ -163,7 +153,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
        ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES,
                                    minor->proc_root, minor);
        if (ret) {
-               remove_proc_entry(name, root);
+               remove_proc_subtree(name, root);
                minor->proc_root = NULL;
                DRM_ERROR("Failed to create core drm proc files\n");
                return ret;
@@ -172,7 +162,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
        return 0;
 }
 
-static int drm_proc_remove_files(struct drm_info_list *files, int count,
+static int drm_proc_remove_files(const struct drm_info_list *files, int count,
                          struct drm_minor *minor)
 {
        struct list_head *pos, *q;
@@ -213,8 +203,7 @@ int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
        drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor);
 
        sprintf(name, "%d", minor->index);
-       remove_proc_entry(name, root);
-
+       remove_proc_subtree(name, root);
        return 0;
 }
 
index 7d30802a018f75f293470024dd2fdd2092a1d0ca..16f3ec579b3bb2b8448523422634cf3fcdbb70c1 100644 (file)
@@ -352,7 +352,7 @@ int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
        idr_replace(&drm_minors_idr, new_minor, minor_id);
 
        if (type == DRM_MINOR_LEGACY) {
-               ret = drm_proc_init(new_minor, minor_id, drm_proc_root);
+               ret = drm_proc_init(new_minor, drm_proc_root);
                if (ret) {
                        DRM_ERROR("DRM: Failed to initialize /proc/dri.\n");
                        goto err_mem;
index 36493ce71f9a8c217ebe8af960598b299f1a95bb..98cc14725ba94c4d1dcd0d44242bb26d92eb75fa 100644 (file)
 /* position control register for hardware window 0, 2 ~ 4.*/
 #define VIDOSD_A(win)          (VIDOSD_BASE + 0x00 + (win) * 16)
 #define VIDOSD_B(win)          (VIDOSD_BASE + 0x04 + (win) * 16)
-/* size control register for hardware window 0. */
-#define VIDOSD_C_SIZE_W0       (VIDOSD_BASE + 0x08)
-/* alpha control register for hardware window 1 ~ 4. */
-#define VIDOSD_C(win)          (VIDOSD_BASE + 0x18 + (win) * 16)
-/* size control register for hardware window 1 ~ 4. */
+/*
+ * size control register for hardware windows 0 and alpha control register
+ * for hardware windows 1 ~ 4
+ */
+#define VIDOSD_C(win)          (VIDOSD_BASE + 0x08 + (win) * 16)
+/* size control register for hardware windows 1 ~ 2. */
 #define VIDOSD_D(win)          (VIDOSD_BASE + 0x0C + (win) * 16)
 
 #define VIDWx_BUF_START(win, buf)      (VIDW_BUF_START(buf) + (win) * 8)
@@ -50,9 +51,9 @@
 #define VIDWx_BUF_SIZE(win, buf)       (VIDW_BUF_SIZE(buf) + (win) * 4)
 
 /* color key control register for hardware window 1 ~ 4. */
-#define WKEYCON0_BASE(x)               ((WKEYCON0 + 0x140) + (x * 8))
+#define WKEYCON0_BASE(x)               ((WKEYCON0 + 0x140) + ((x - 1) * 8))
 /* color key value register for hardware window 1 ~ 4. */
-#define WKEYCON1_BASE(x)               ((WKEYCON1 + 0x140) + (x * 8))
+#define WKEYCON1_BASE(x)               ((WKEYCON1 + 0x140) + ((x - 1) * 8))
 
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR     5
@@ -109,9 +110,9 @@ struct fimd_context {
 
 #ifdef CONFIG_OF
 static const struct of_device_id fimd_driver_dt_match[] = {
-       { .compatible = "samsung,exynos4-fimd",
+       { .compatible = "samsung,exynos4210-fimd",
          .data = &exynos4_fimd_driver_data },
-       { .compatible = "samsung,exynos5-fimd",
+       { .compatible = "samsung,exynos5250-fimd",
          .data = &exynos5_fimd_driver_data },
        {},
 };
@@ -581,7 +582,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
        if (win != 3 && win != 4) {
                u32 offset = VIDOSD_D(win);
                if (win == 0)
-                       offset = VIDOSD_C_SIZE_W0;
+                       offset = VIDOSD_C(win);
                val = win_data->ovl_width * win_data->ovl_height;
                writel(val, ctx->regs + offset);
 
index 3b0da0378acf509976361d85322dc1fbc5c6779f..47a493c8a71f2629b7acf0de109bcd3eefc15bfd 100644 (file)
 
 /* registers for base address */
 #define G2D_SRC_BASE_ADDR              0x0304
+#define G2D_SRC_COLOR_MODE             0x030C
+#define G2D_SRC_LEFT_TOP               0x0310
+#define G2D_SRC_RIGHT_BOTTOM           0x0314
 #define G2D_SRC_PLANE2_BASE_ADDR       0x0318
 #define G2D_DST_BASE_ADDR              0x0404
+#define G2D_DST_COLOR_MODE             0x040C
+#define G2D_DST_LEFT_TOP               0x0410
+#define G2D_DST_RIGHT_BOTTOM           0x0414
 #define G2D_DST_PLANE2_BASE_ADDR       0x0418
 #define G2D_PAT_BASE_ADDR              0x0500
 #define G2D_MSK_BASE_ADDR              0x0520
@@ -82,7 +88,7 @@
 #define G2D_DMA_LIST_DONE_COUNT_OFFSET 17
 
 /* G2D_DMA_HOLD_CMD */
-#define G2D_USET_HOLD                  (1 << 2)
+#define G2D_USER_HOLD                  (1 << 2)
 #define G2D_LIST_HOLD                  (1 << 1)
 #define G2D_BITBLT_HOLD                        (1 << 0)
 
 #define G2D_START_NHOLT                        (1 << 1)
 #define G2D_START_BITBLT               (1 << 0)
 
+/* buffer color format */
+#define G2D_FMT_XRGB8888               0
+#define G2D_FMT_ARGB8888               1
+#define G2D_FMT_RGB565                 2
+#define G2D_FMT_XRGB1555               3
+#define G2D_FMT_ARGB1555               4
+#define G2D_FMT_XRGB4444               5
+#define G2D_FMT_ARGB4444               6
+#define G2D_FMT_PACKED_RGB888          7
+#define G2D_FMT_A8                     11
+#define G2D_FMT_L8                     12
+
+/* buffer valid length */
+#define G2D_LEN_MIN                    1
+#define G2D_LEN_MAX                    8000
+
 #define G2D_CMDLIST_SIZE               (PAGE_SIZE / 4)
 #define G2D_CMDLIST_NUM                        64
 #define G2D_CMDLIST_POOL_SIZE          (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM)
 #define G2D_CMDLIST_DATA_NUM           (G2D_CMDLIST_SIZE / sizeof(u32) - 2)
 
-#define MAX_BUF_ADDR_NR                        6
-
 /* maximum buffer pool size of userptr is 64MB as default */
 #define MAX_POOL               (64 * 1024 * 1024)
 
@@ -106,6 +126,17 @@ enum {
        BUF_TYPE_USERPTR,
 };
 
+enum g2d_reg_type {
+       REG_TYPE_NONE = -1,
+       REG_TYPE_SRC,
+       REG_TYPE_SRC_PLANE2,
+       REG_TYPE_DST,
+       REG_TYPE_DST_PLANE2,
+       REG_TYPE_PAT,
+       REG_TYPE_MSK,
+       MAX_REG_TYPE_NR
+};
+
 /* cmdlist data structure */
 struct g2d_cmdlist {
        u32             head;
@@ -113,6 +144,42 @@ struct g2d_cmdlist {
        u32             last;   /* last data offset */
 };
 
+/*
+ * A structure of buffer description
+ *
+ * @format: color format
+ * @left_x: the x coordinates of left top corner
+ * @top_y: the y coordinates of left top corner
+ * @right_x: the x coordinates of right bottom corner
+ * @bottom_y: the y coordinates of right bottom corner
+ *
+ */
+struct g2d_buf_desc {
+       unsigned int    format;
+       unsigned int    left_x;
+       unsigned int    top_y;
+       unsigned int    right_x;
+       unsigned int    bottom_y;
+};
+
+/*
+ * A structure of buffer information
+ *
+ * @map_nr: manages the number of mapped buffers
+ * @reg_types: stores regitster type in the order of requested command
+ * @handles: stores buffer handle in its reg_type position
+ * @types: stores buffer type in its reg_type position
+ * @descs: stores buffer description in its reg_type position
+ *
+ */
+struct g2d_buf_info {
+       unsigned int            map_nr;
+       enum g2d_reg_type       reg_types[MAX_REG_TYPE_NR];
+       unsigned long           handles[MAX_REG_TYPE_NR];
+       unsigned int            types[MAX_REG_TYPE_NR];
+       struct g2d_buf_desc     descs[MAX_REG_TYPE_NR];
+};
+
 struct drm_exynos_pending_g2d_event {
        struct drm_pending_event        base;
        struct drm_exynos_g2d_event     event;
@@ -131,14 +198,11 @@ struct g2d_cmdlist_userptr {
        bool                    in_pool;
        bool                    out_of_list;
 };
-
 struct g2d_cmdlist_node {
        struct list_head        list;
        struct g2d_cmdlist      *cmdlist;
-       unsigned int            map_nr;
-       unsigned long           handles[MAX_BUF_ADDR_NR];
-       unsigned int            obj_type[MAX_BUF_ADDR_NR];
        dma_addr_t              dma_addr;
+       struct g2d_buf_info     buf_info;
 
        struct drm_exynos_pending_g2d_event     *event;
 };
@@ -188,6 +252,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
        int nr;
        int ret;
+       struct g2d_buf_info *buf_info;
 
        init_dma_attrs(&g2d->cmdlist_dma_attrs);
        dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs);
@@ -209,11 +274,17 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
        }
 
        for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) {
+               unsigned int i;
+
                node[nr].cmdlist =
                        g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE;
                node[nr].dma_addr =
                        g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE;
 
+               buf_info = &node[nr].buf_info;
+               for (i = 0; i < MAX_REG_TYPE_NR; i++)
+                       buf_info->reg_types[i] = REG_TYPE_NONE;
+
                list_add_tail(&node[nr].list, &g2d->free_cmdlist);
        }
 
@@ -450,7 +521,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
                                                DMA_BIDIRECTIONAL);
        if (ret < 0) {
                DRM_ERROR("failed to map sgt with dma region.\n");
-               goto err_free_sgt;
+               goto err_sg_free_table;
        }
 
        g2d_userptr->dma_addr = sgt->sgl[0].dma_address;
@@ -467,8 +538,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 
        return &g2d_userptr->dma_addr;
 
-err_free_sgt:
+err_sg_free_table:
        sg_free_table(sgt);
+
+err_free_sgt:
        kfree(sgt);
        sgt = NULL;
 
@@ -506,36 +579,172 @@ static void g2d_userptr_free_all(struct drm_device *drm_dev,
        g2d->current_pool = 0;
 }
 
+static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
+{
+       enum g2d_reg_type reg_type;
+
+       switch (reg_offset) {
+       case G2D_SRC_BASE_ADDR:
+       case G2D_SRC_COLOR_MODE:
+       case G2D_SRC_LEFT_TOP:
+       case G2D_SRC_RIGHT_BOTTOM:
+               reg_type = REG_TYPE_SRC;
+               break;
+       case G2D_SRC_PLANE2_BASE_ADDR:
+               reg_type = REG_TYPE_SRC_PLANE2;
+               break;
+       case G2D_DST_BASE_ADDR:
+       case G2D_DST_COLOR_MODE:
+       case G2D_DST_LEFT_TOP:
+       case G2D_DST_RIGHT_BOTTOM:
+               reg_type = REG_TYPE_DST;
+               break;
+       case G2D_DST_PLANE2_BASE_ADDR:
+               reg_type = REG_TYPE_DST_PLANE2;
+               break;
+       case G2D_PAT_BASE_ADDR:
+               reg_type = REG_TYPE_PAT;
+               break;
+       case G2D_MSK_BASE_ADDR:
+               reg_type = REG_TYPE_MSK;
+               break;
+       default:
+               reg_type = REG_TYPE_NONE;
+               DRM_ERROR("Unknown register offset![%d]\n", reg_offset);
+               break;
+       };
+
+       return reg_type;
+}
+
+static unsigned long g2d_get_buf_bpp(unsigned int format)
+{
+       unsigned long bpp;
+
+       switch (format) {
+       case G2D_FMT_XRGB8888:
+       case G2D_FMT_ARGB8888:
+               bpp = 4;
+               break;
+       case G2D_FMT_RGB565:
+       case G2D_FMT_XRGB1555:
+       case G2D_FMT_ARGB1555:
+       case G2D_FMT_XRGB4444:
+       case G2D_FMT_ARGB4444:
+               bpp = 2;
+               break;
+       case G2D_FMT_PACKED_RGB888:
+               bpp = 3;
+               break;
+       default:
+               bpp = 1;
+               break;
+       }
+
+       return bpp;
+}
+
+static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc,
+                                               enum g2d_reg_type reg_type,
+                                               unsigned long size)
+{
+       unsigned int width, height;
+       unsigned long area;
+
+       /*
+        * check source and destination buffers only.
+        * so the others are always valid.
+        */
+       if (reg_type != REG_TYPE_SRC && reg_type != REG_TYPE_DST)
+               return true;
+
+       width = buf_desc->right_x - buf_desc->left_x;
+       if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) {
+               DRM_ERROR("width[%u] is out of range!\n", width);
+               return false;
+       }
+
+       height = buf_desc->bottom_y - buf_desc->top_y;
+       if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) {
+               DRM_ERROR("height[%u] is out of range!\n", height);
+               return false;
+       }
+
+       area = (unsigned long)width * (unsigned long)height *
+                                       g2d_get_buf_bpp(buf_desc->format);
+       if (area > size) {
+               DRM_ERROR("area[%lu] is out of range[%lu]!\n", area, size);
+               return false;
+       }
+
+       return true;
+}
+
 static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
                                struct g2d_cmdlist_node *node,
                                struct drm_device *drm_dev,
                                struct drm_file *file)
 {
        struct g2d_cmdlist *cmdlist = node->cmdlist;
+       struct g2d_buf_info *buf_info = &node->buf_info;
        int offset;
+       int ret;
        int i;
 
-       for (i = 0; i < node->map_nr; i++) {
+       for (i = 0; i < buf_info->map_nr; i++) {
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+               int reg_pos;
                unsigned long handle;
                dma_addr_t *addr;
 
-               offset = cmdlist->last - (i * 2 + 1);
-               handle = cmdlist->data[offset];
+               reg_pos = cmdlist->last - 2 * (i + 1);
+
+               offset = cmdlist->data[reg_pos];
+               handle = cmdlist->data[reg_pos + 1];
+
+               reg_type = g2d_get_reg_type(offset);
+               if (reg_type == REG_TYPE_NONE) {
+                       ret = -EFAULT;
+                       goto err;
+               }
+
+               buf_desc = &buf_info->descs[reg_type];
+
+               if (buf_info->types[reg_type] == BUF_TYPE_GEM) {
+                       unsigned long size;
+
+                       size = exynos_drm_gem_get_size(drm_dev, handle, file);
+                       if (!size) {
+                               ret = -EFAULT;
+                               goto err;
+                       }
+
+                       if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
+                                                                       size)) {
+                               ret = -EFAULT;
+                               goto err;
+                       }
 
-               if (node->obj_type[i] == BUF_TYPE_GEM) {
                        addr = exynos_drm_gem_get_dma_addr(drm_dev, handle,
                                                                file);
                        if (IS_ERR(addr)) {
-                               node->map_nr = i;
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto err;
                        }
                } else {
                        struct drm_exynos_g2d_userptr g2d_userptr;
 
                        if (copy_from_user(&g2d_userptr, (void __user *)handle,
                                sizeof(struct drm_exynos_g2d_userptr))) {
-                               node->map_nr = i;
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto err;
+                       }
+
+                       if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
+                                                       g2d_userptr.size)) {
+                               ret = -EFAULT;
+                               goto err;
                        }
 
                        addr = g2d_userptr_get_dma_addr(drm_dev,
@@ -544,16 +753,21 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
                                                        file,
                                                        &handle);
                        if (IS_ERR(addr)) {
-                               node->map_nr = i;
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto err;
                        }
                }
 
-               cmdlist->data[offset] = *addr;
-               node->handles[i] = handle;
+               cmdlist->data[reg_pos + 1] = *addr;
+               buf_info->reg_types[i] = reg_type;
+               buf_info->handles[reg_type] = handle;
        }
 
        return 0;
+
+err:
+       buf_info->map_nr = i;
+       return ret;
 }
 
 static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
@@ -561,22 +775,33 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
                                  struct drm_file *filp)
 {
        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
+       struct g2d_buf_info *buf_info = &node->buf_info;
        int i;
 
-       for (i = 0; i < node->map_nr; i++) {
-               unsigned long handle = node->handles[i];
+       for (i = 0; i < buf_info->map_nr; i++) {
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+               unsigned long handle;
+
+               reg_type = buf_info->reg_types[i];
+
+               buf_desc = &buf_info->descs[reg_type];
+               handle = buf_info->handles[reg_type];
 
-               if (node->obj_type[i] == BUF_TYPE_GEM)
+               if (buf_info->types[reg_type] == BUF_TYPE_GEM)
                        exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle,
                                                        filp);
                else
                        g2d_userptr_put_dma_addr(subdrv->drm_dev, handle,
                                                        false);
 
-               node->handles[i] = 0;
+               buf_info->reg_types[i] = REG_TYPE_NONE;
+               buf_info->handles[reg_type] = 0;
+               buf_info->types[reg_type] = 0;
+               memset(buf_desc, 0x00, sizeof(*buf_desc));
        }
 
-       node->map_nr = 0;
+       buf_info->map_nr = 0;
 }
 
 static void g2d_dma_start(struct g2d_data *g2d,
@@ -589,10 +814,6 @@ static void g2d_dma_start(struct g2d_data *g2d,
        pm_runtime_get_sync(g2d->dev);
        clk_enable(g2d->gate_clk);
 
-       /* interrupt enable */
-       writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF,
-                       g2d->regs + G2D_INTEN);
-
        writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
        writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
 }
@@ -643,7 +864,6 @@ static void g2d_runqueue_worker(struct work_struct *work)
        struct g2d_data *g2d = container_of(work, struct g2d_data,
                                            runqueue_work);
 
-
        mutex_lock(&g2d->runqueue_mutex);
        clk_disable(g2d->gate_clk);
        pm_runtime_put_sync(g2d->dev);
@@ -724,20 +944,14 @@ static int g2d_check_reg_offset(struct device *dev,
        int i;
 
        for (i = 0; i < nr; i++) {
-               index = cmdlist->last - 2 * (i + 1);
+               struct g2d_buf_info *buf_info = &node->buf_info;
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+               unsigned long value;
 
-               if (for_addr) {
-                       /* check userptr buffer type. */
-                       reg_offset = (cmdlist->data[index] &
-                                       ~0x7fffffff) >> 31;
-                       if (reg_offset) {
-                               node->obj_type[i] = BUF_TYPE_USERPTR;
-                               cmdlist->data[index] &= ~G2D_BUF_USERPTR;
-                       }
-               }
+               index = cmdlist->last - 2 * (i + 1);
 
                reg_offset = cmdlist->data[index] & ~0xfffff000;
-
                if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END)
                        goto err;
                if (reg_offset % 4)
@@ -753,8 +967,60 @@ static int g2d_check_reg_offset(struct device *dev,
                        if (!for_addr)
                                goto err;
 
-                       if (node->obj_type[i] != BUF_TYPE_USERPTR)
-                               node->obj_type[i] = BUF_TYPE_GEM;
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       /* check userptr buffer type. */
+                       if ((cmdlist->data[index] & ~0x7fffffff) >> 31) {
+                               buf_info->types[reg_type] = BUF_TYPE_USERPTR;
+                               cmdlist->data[index] &= ~G2D_BUF_USERPTR;
+                       } else
+                               buf_info->types[reg_type] = BUF_TYPE_GEM;
+                       break;
+               case G2D_SRC_COLOR_MODE:
+               case G2D_DST_COLOR_MODE:
+                       if (for_addr)
+                               goto err;
+
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       buf_desc = &buf_info->descs[reg_type];
+                       value = cmdlist->data[index + 1];
+
+                       buf_desc->format = value & 0xf;
+                       break;
+               case G2D_SRC_LEFT_TOP:
+               case G2D_DST_LEFT_TOP:
+                       if (for_addr)
+                               goto err;
+
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       buf_desc = &buf_info->descs[reg_type];
+                       value = cmdlist->data[index + 1];
+
+                       buf_desc->left_x = value & 0x1fff;
+                       buf_desc->top_y = (value & 0x1fff0000) >> 16;
+                       break;
+               case G2D_SRC_RIGHT_BOTTOM:
+               case G2D_DST_RIGHT_BOTTOM:
+                       if (for_addr)
+                               goto err;
+
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       buf_desc = &buf_info->descs[reg_type];
+                       value = cmdlist->data[index + 1];
+
+                       buf_desc->right_x = value & 0x1fff;
+                       buf_desc->bottom_y = (value & 0x1fff0000) >> 16;
                        break;
                default:
                        if (for_addr)
@@ -860,9 +1126,23 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
        cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
        cmdlist->data[cmdlist->last++] = 0;
 
+       /*
+        * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG
+        * and GCF bit should be set to INTEN register if user wants
+        * G2D interrupt event once current command list execution is
+        * finished.
+        * Otherwise only ACF bit should be set to INTEN register so
+        * that one interrupt is occured after all command lists
+        * have been completed.
+        */
        if (node->event) {
+               cmdlist->data[cmdlist->last++] = G2D_INTEN;
+               cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF | G2D_INTEN_GCF;
                cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD;
                cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD;
+       } else {
+               cmdlist->data[cmdlist->last++] = G2D_INTEN;
+               cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF;
        }
 
        /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */
@@ -887,7 +1167,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
        if (ret < 0)
                goto err_free_event;
 
-       node->map_nr = req->cmd_buf_nr;
+       node->buf_info.map_nr = req->cmd_buf_nr;
        if (req->cmd_buf_nr) {
                struct drm_exynos_g2d_cmd *cmd_buf;
 
index 67e17ce112b69eb5ce795358e1471fd9db2ad841..0e6fe000578c08c78be0df9fa00e2205429e8576 100644 (file)
@@ -164,6 +164,27 @@ out:
        exynos_gem_obj = NULL;
 }
 
+unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
+                                               unsigned int gem_handle,
+                                               struct drm_file *file_priv)
+{
+       struct exynos_drm_gem_obj *exynos_gem_obj;
+       struct drm_gem_object *obj;
+
+       obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
+       if (!obj) {
+               DRM_ERROR("failed to lookup gem object.\n");
+               return 0;
+       }
+
+       exynos_gem_obj = to_exynos_gem_obj(obj);
+
+       drm_gem_object_unreference_unlocked(obj);
+
+       return exynos_gem_obj->buffer->size;
+}
+
+
 struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
                                                      unsigned long size)
 {
index 35ebac47dc2bacfec928d54001b6065aa9e75564..468766bee450837eefe19f37db7e7fdcc00133c6 100644 (file)
@@ -130,6 +130,11 @@ int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data,
 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
                                      struct drm_file *file_priv);
 
+/* get buffer size to gem handle. */
+unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
+                                               unsigned int gem_handle,
+                                               struct drm_file *file_priv);
+
 /* initialize gem object. */
 int exynos_drm_gem_init_object(struct drm_gem_object *obj);
 
index 13ccbd4bcfaa8c863f27d24870101c32166ecb47..9504b0cd825a4dc9d4b81c2be674eb0897eb137d 100644 (file)
@@ -117,13 +117,12 @@ static struct edid *vidi_get_edid(struct device *dev,
        }
 
        edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
-       edid = kzalloc(edid_len, GFP_KERNEL);
+       edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
        if (!edid) {
                DRM_DEBUG_KMS("failed to allocate edid\n");
                return ERR_PTR(-ENOMEM);
        }
 
-       memcpy(edid, ctx->raw_edid, edid_len);
        return edid;
 }
 
@@ -563,12 +562,11 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
                        return -EINVAL;
                }
                edid_len = (1 + raw_edid->extensions) * EDID_LENGTH;
-               ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL);
+               ctx->raw_edid = kmemdup(raw_edid, edid_len, GFP_KERNEL);
                if (!ctx->raw_edid) {
                        DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
                        return -ENOMEM;
                }
-               memcpy(ctx->raw_edid, raw_edid, edid_len);
        } else {
                /*
                 * with connection = 0, free raw_edid
index e919aba29b3dfde038979f5c417966bc8bf147c1..2f4f72f070475a62f77ce15451540962eb011153 100644 (file)
@@ -818,7 +818,7 @@ static void mixer_win_disable(void *ctx, int win)
        mixer_ctx->win_data[win].enabled = false;
 }
 
-int mixer_check_timing(void *ctx, struct fb_videomode *timing)
+static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
 {
        struct mixer_context *mixer_ctx = ctx;
        u32 w, h;
index aae31489c89304f8d79ad2319bbb0ecb97897cef..7299ea45dd03dec217944f31422f5f1a62bcc6eb 100644 (file)
@@ -103,7 +103,7 @@ static const char *cache_level_str(int type)
 static void
 describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 {
-       seq_printf(m, "%p: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s",
+       seq_printf(m, "%pK: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s",
                   &obj->base,
                   get_pin_flag(obj),
                   get_tiling_flag(obj),
index c5b8c81b94402321f599f4c3e5d99b88ee82a9e3..e9b57893db2b1ebba1348a71e37c845f98c3286b 100644 (file)
@@ -125,6 +125,11 @@ MODULE_PARM_DESC(preliminary_hw_support,
                "Enable Haswell and ValleyView Support. "
                "(default: false)");
 
+int i915_disable_power_well __read_mostly = 0;
+module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
+MODULE_PARM_DESC(disable_power_well,
+                "Disable the power well when possible (default: false)");
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
@@ -379,15 +384,15 @@ static const struct pci_device_id pciidlist[] = {         /* aka */
        INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
        INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
        INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
-       INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */
+       INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
+       INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
        INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
-       INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */
-       INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */
+       INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
+       INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
        INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
-       INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */
-       INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */
+       INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
+       INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
        INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
-       INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */
        INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
@@ -495,6 +500,7 @@ static int i915_drm_freeze(struct drm_device *dev)
                intel_modeset_disable(dev);
 
                drm_irq_uninstall(dev);
+               dev_priv->enable_hotplug_processing = false;
        }
 
        i915_save_state(dev);
@@ -568,10 +574,20 @@ static int __i915_drm_thaw(struct drm_device *dev)
                error = i915_gem_init_hw(dev);
                mutex_unlock(&dev->struct_mutex);
 
+               /* We need working interrupts for modeset enabling ... */
+               drm_irq_install(dev);
+
                intel_modeset_init_hw(dev);
                intel_modeset_setup_hw_state(dev, false);
-               drm_irq_install(dev);
+
+               /*
+                * ... but also need to make sure that hotplug processing
+                * doesn't cause havoc. Like in the driver load code we don't
+                * bother with the tiny race here where we might loose hotplug
+                * notifications.
+                * */
                intel_hpd_init(dev);
+               dev_priv->enable_hotplug_processing = true;
        }
 
        intel_opregion_init(dev);
index e95337c974594d34c936d071975f5040c78754d1..01769e2a99538e9e99cd191b328d7746439d328b 100644 (file)
@@ -1398,6 +1398,7 @@ extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 extern int i915_enable_ppgtt __read_mostly;
 extern unsigned int i915_preliminary_hw_support __read_mostly;
+extern int i915_disable_power_well __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
index 2f2daebd0eefd581c38415489164ed080e0d141a..3b11ab0fbc960ab1ff58fd842a2d51ff10ca15db 100644 (file)
@@ -732,6 +732,8 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
                   int count)
 {
        int i;
+       int relocs_total = 0;
+       int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
 
        for (i = 0; i < count; i++) {
                char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
@@ -740,10 +742,13 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
                if (exec[i].flags & __EXEC_OBJECT_UNKNOWN_FLAGS)
                        return -EINVAL;
 
-               /* First check for malicious input causing overflow */
-               if (exec[i].relocation_count >
-                   INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
+               /* First check for malicious input causing overflow in
+                * the worst case where we need to allocate the entire
+                * relocation tree as a single array.
+                */
+               if (exec[i].relocation_count > relocs_max - relocs_total)
                        return -EINVAL;
+               relocs_total += exec[i].relocation_count;
 
                length = exec[i].relocation_count *
                        sizeof(struct drm_i915_gem_relocation_entry);
index 2cd97d1cc920dbf1555af5d28d97d7cf893f6567..3c7bb0410b517fe84ae696c720441d553f63cd7f 100644 (file)
@@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 de_iir, gt_iir, de_ier, pm_iir;
+       u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
        irqreturn_t ret = IRQ_NONE;
        int i;
 
@@ -711,6 +711,15 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
        de_ier = I915_READ(DEIER);
        I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
 
+       /* Disable south interrupts. We'll only write to SDEIIR once, so further
+        * interrupts will will be stored on its back queue, and then we'll be
+        * able to process them after we restore SDEIER (as soon as we restore
+        * it, we'll get an interrupt if SDEIIR still has something to process
+        * due to its back queue). */
+       sde_ier = I915_READ(SDEIER);
+       I915_WRITE(SDEIER, 0);
+       POSTING_READ(SDEIER);
+
        gt_iir = I915_READ(GTIIR);
        if (gt_iir) {
                snb_gt_irq_handler(dev, dev_priv, gt_iir);
@@ -759,6 +768,8 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
 
        I915_WRITE(DEIER, de_ier);
        POSTING_READ(DEIER);
+       I915_WRITE(SDEIER, sde_ier);
+       POSTING_READ(SDEIER);
 
        return ret;
 }
@@ -778,7 +789,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int ret = IRQ_NONE;
-       u32 de_iir, gt_iir, de_ier, pm_iir;
+       u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
 
        atomic_inc(&dev_priv->irq_received);
 
@@ -787,6 +798,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
        I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
        POSTING_READ(DEIER);
 
+       /* Disable south interrupts. We'll only write to SDEIIR once, so further
+        * interrupts will will be stored on its back queue, and then we'll be
+        * able to process them after we restore SDEIER (as soon as we restore
+        * it, we'll get an interrupt if SDEIIR still has something to process
+        * due to its back queue). */
+       sde_ier = I915_READ(SDEIER);
+       I915_WRITE(SDEIER, 0);
+       POSTING_READ(SDEIER);
+
        de_iir = I915_READ(DEIIR);
        gt_iir = I915_READ(GTIIR);
        pm_iir = I915_READ(GEN6_PMIIR);
@@ -849,6 +869,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 done:
        I915_WRITE(DEIER, de_ier);
        POSTING_READ(DEIER);
+       I915_WRITE(SDEIER, sde_ier);
+       POSTING_READ(SDEIER);
 
        return ret;
 }
index 527b664d343490238aded9ce08d42e2f4e4549a6..848992f67d56daa8910ce0e66210f51bddb2f604 100644 (file)
 #define   ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
 #define   ADPA_USE_VGA_HVPOLARITY (1<<15)
 #define   ADPA_SETS_HVPOLARITY 0
-#define   ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define   ADPA_VSYNC_CNTL_DISABLE (1<<10)
 #define   ADPA_VSYNC_CNTL_ENABLE 0
-#define   ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define   ADPA_HSYNC_CNTL_DISABLE (1<<11)
 #define   ADPA_HSYNC_CNTL_ENABLE 0
 #define   ADPA_VSYNC_ACTIVE_HIGH (1<<4)
 #define   ADPA_VSYNC_ACTIVE_LOW        0
index 969d08c72d1023c89116234fcf1844622d0f1081..32a3693905ecb14f697fd82b4f8a2419e2818552 100644 (file)
@@ -88,7 +88,7 @@ static void intel_disable_crt(struct intel_encoder *encoder)
        u32 temp;
 
        temp = I915_READ(crt->adpa_reg);
-       temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
+       temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
        temp &= ~ADPA_DAC_ENABLE;
        I915_WRITE(crt->adpa_reg, temp);
 }
index d64af5aa4a1caeccc1b5f5f6d85e68cc4e5c7fff..8d0bac3c35d7df012225ea47e922c60b353a0915 100644 (file)
@@ -1391,8 +1391,8 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
        struct intel_dp *intel_dp = &intel_dig_port->dp;
        struct drm_i915_private *dev_priv = encoder->dev->dev_private;
        enum port port = intel_dig_port->port;
-       bool wait;
        uint32_t val;
+       bool wait = false;
 
        if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
                val = I915_READ(DDI_BUF_CTL(port));
index a05ac2c91ba2cd3cf5a8599794a74674a5ac04ed..b20d50192fcc8f3dda5c7efbe098d1a560e95f71 100644 (file)
@@ -3604,6 +3604,30 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
         */
 }
 
+/**
+ * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware
+ * cursor plane briefly if not already running after enabling the display
+ * plane.
+ * This workaround avoids occasional blank screens when self refresh is
+ * enabled.
+ */
+static void
+g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+       u32 cntl = I915_READ(CURCNTR(pipe));
+
+       if ((cntl & CURSOR_MODE) == 0) {
+               u32 fw_bcl_self = I915_READ(FW_BLC_SELF);
+
+               I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN);
+               I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX);
+               intel_wait_for_vblank(dev_priv->dev, pipe);
+               I915_WRITE(CURCNTR(pipe), cntl);
+               I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
+               I915_WRITE(FW_BLC_SELF, fw_bcl_self);
+       }
+}
+
 static void i9xx_crtc_enable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -3629,6 +3653,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 
        intel_enable_pipe(dev_priv, pipe, false);
        intel_enable_plane(dev_priv, plane, pipe);
+       if (IS_G4X(dev))
+               g4x_fixup_plane(dev_priv, pipe);
 
        intel_crtc_load_lut(crtc);
        intel_update_fbc(dev);
@@ -5745,6 +5771,11 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
                num_connectors++;
        }
 
+       if (is_cpu_edp)
+               intel_crtc->cpu_transcoder = TRANSCODER_EDP;
+       else
+               intel_crtc->cpu_transcoder = pipe;
+
        /* We are not sure yet this won't happen. */
        WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n",
             INTEL_PCH_TYPE(dev));
@@ -5811,11 +5842,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        int pipe = intel_crtc->pipe;
        int ret;
 
-       if (IS_HASWELL(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
-               intel_crtc->cpu_transcoder = TRANSCODER_EDP;
-       else
-               intel_crtc->cpu_transcoder = pipe;
-
        drm_vblank_pre_modeset(dev, pipe);
 
        ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
@@ -7256,8 +7282,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_framebuffer *intel_fb;
-       struct drm_i915_gem_object *obj;
+       struct drm_framebuffer *old_fb = crtc->fb;
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_unpin_work *work;
        unsigned long flags;
@@ -7282,8 +7308,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        work->event = event;
        work->crtc = crtc;
-       intel_fb = to_intel_framebuffer(crtc->fb);
-       work->old_fb_obj = intel_fb->obj;
+       work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
        INIT_WORK(&work->work, intel_unpin_work_fn);
 
        ret = drm_vblank_get(dev, intel_crtc->pipe);
@@ -7303,9 +7328,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        intel_crtc->unpin_work = work;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
-       intel_fb = to_intel_framebuffer(fb);
-       obj = intel_fb->obj;
-
        if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
                flush_workqueue(dev_priv->wq);
 
@@ -7340,6 +7362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
 cleanup_pending:
        atomic_dec(&intel_crtc->unpin_work_count);
+       crtc->fb = old_fb;
        drm_gem_object_unreference(&work->old_fb_obj->base);
        drm_gem_object_unreference(&obj->base);
        mutex_unlock(&dev->struct_mutex);
index f61cb7998c7230d28c83850aeab068958be5df3a..d7d4afe013417f489934dbab8e5bafbf48614aa9 100644 (file)
@@ -353,7 +353,8 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
 
 #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
        if (has_aux_irq)
-               done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10);
+               done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
+                                         msecs_to_jiffies(10));
        else
                done = wait_for_atomic(C, 10) == 0;
        if (!done)
@@ -819,6 +820,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
        struct intel_link_m_n m_n;
        int pipe = intel_crtc->pipe;
        enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
+       int target_clock;
 
        /*
         * Find the lane count in the intel_encoder private
@@ -834,13 +836,22 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                }
        }
 
+       target_clock = mode->clock;
+       for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+               if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+                       target_clock = intel_edp_target_clock(intel_encoder,
+                                                             mode);
+                       break;
+               }
+       }
+
        /*
         * Compute the GMCH and Link ratios. The '3' here is
         * the number of bytes_per_pixel post-LUT, which we always
         * set up for 8-bits of R/G/B, or 3 bytes total.
         */
        intel_link_compute_m_n(intel_crtc->bpp, lane_count,
-                              mode->clock, adjusted_mode->clock, &m_n);
+                              target_clock, adjusted_mode->clock, &m_n);
 
        if (IS_HASWELL(dev)) {
                I915_WRITE(PIPE_DATA_M1(cpu_transcoder),
@@ -1929,7 +1940,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                for (i = 0; i < intel_dp->lane_count; i++)
                        if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
                                break;
-               if (i == intel_dp->lane_count && voltage_tries == 5) {
+               if (i == intel_dp->lane_count) {
                        ++loop_tries;
                        if (loop_tries == 5) {
                                DRM_DEBUG_KMS("too many full retries, give up\n");
index acf8aec9ada7162543954e4adf7c7b28d1bb4770..ef4744e1bf0bc44be8424a2cb936c26ff716da28 100644 (file)
@@ -203,7 +203,13 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
        algo->data = bus;
 }
 
-#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 4)
+/*
+ * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI
+ * mode. This results in spurious interrupt warnings if the legacy irq no. is
+ * shared with another device. The kernel then disables that interrupt source
+ * and so prevents the other device from working properly.
+ */
+#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
 static int
 gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
                     u32 gmbus2_status,
@@ -214,6 +220,9 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
        u32 gmbus2 = 0;
        DEFINE_WAIT(wait);
 
+       if (!HAS_GMBUS_IRQ(dev_priv->dev))
+               gmbus4_irq_en = 0;
+
        /* Important: The hw handles only the first bit, so set only one! Since
         * we also need to check for NAKs besides the hw ready/idle signal, we
         * need to wake up periodically and check that ourselves. */
index a3730e0289e5eefa15afb9f04a54c65c817f7886..bee8cb6108a7d44883286ef4b35bb6d7f8713a0f 100644 (file)
@@ -321,9 +321,6 @@ void intel_panel_enable_backlight(struct drm_device *dev,
        if (dev_priv->backlight_level == 0)
                dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
 
-       dev_priv->backlight_enabled = true;
-       intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
-
        if (INTEL_INFO(dev)->gen >= 4) {
                uint32_t reg, tmp;
 
@@ -359,12 +356,12 @@ void intel_panel_enable_backlight(struct drm_device *dev,
        }
 
 set_level:
-       /* Check the current backlight level and try to set again if it's zero.
-        * On some machines, BLC_PWM_CPU_CTL is cleared to zero automatically
-        * when BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1 are written.
+       /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
+        * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
+        * registers are set.
         */
-       if (!intel_panel_get_backlight(dev))
-               intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
+       dev_priv->backlight_enabled = true;
+       intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
 }
 
 static void intel_panel_init_backlight(struct drm_device *dev)
index 61fee7fcdc2c1efeb7c7c0fd1d0fd058e2dd3199..adca00783e61b304723d3d05197b53f47b6b33db 100644 (file)
@@ -2574,7 +2574,7 @@ static void gen6_enable_rps(struct drm_device *dev)
        I915_WRITE(GEN6_RC_SLEEP, 0);
        I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
        I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
-       I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
+       I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
        I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
        /* Check if we are enabling RC6 */
@@ -4079,6 +4079,9 @@ void intel_set_power_well(struct drm_device *dev, bool enable)
        if (!IS_HASWELL(dev))
                return;
 
+       if (!i915_disable_power_well && !enable)
+               return;
+
        tmp = I915_READ(HSW_PWR_WELL_DRIVER);
        is_enabled = tmp & HSW_PWR_WELL_STATE;
        enable_requested = tmp & HSW_PWR_WELL_ENABLE;
index 5ea5033eae0a4109d9230dd663508273da0bfd7c..4d932c46725dda950a4b2cd197e1923fca18ab50 100644 (file)
@@ -112,7 +112,6 @@ struct mga_framebuffer {
 struct mga_fbdev {
        struct drm_fb_helper helper;
        struct mga_framebuffer mfb;
-       struct list_head fbdev_list;
        void *sysram;
        int size;
        struct ttm_bo_kmap_obj mapping;
index 5a88ec51b5137604c0a0824fea72941e6de8ccc7..d3dcf54e6233dd332e36a18e8b683272a9c63a04 100644 (file)
@@ -92,6 +92,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev)
        int ret;
        int data, clock;
 
+       WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
        WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
        WREG_DAC(MGA1064_GEN_IO_CTL, 0);
 
index d3d99a28ddef770d78525cd2e32786f40f047084..fe22bb780e1d048efc76e92d7296ab98f94294db 100644 (file)
@@ -382,19 +382,19 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
        m = n = p = 0;
        vcomax = 800000;
        vcomin = 400000;
-       pllreffreq = 3333;
+       pllreffreq = 33333;
 
        delta = 0xffffffff;
        permitteddelta = clock * 5 / 1000;
 
-       for (testp = 16; testp > 0; testp--) {
+       for (testp = 16; testp > 0; testp >>= 1) {
                if (clock * testp > vcomax)
                        continue;
                if (clock * testp < vcomin)
                        continue;
 
                for (testm = 1; testm < 33; testm++) {
-                       for (testn = 1; testn < 257; testn++) {
+                       for (testn = 17; testn < 257; testn++) {
                                computed = (pllreffreq * testn) /
                                        (testm * testp);
                                if (computed > clock)
@@ -404,11 +404,11 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
                                if (tmpdelta < delta) {
                                        delta = tmpdelta;
                                        n = testn - 1;
-                                       m = (testm - 1) | ((n >> 1) & 0x80);
+                                       m = (testm - 1);
                                        p = testp - 1;
                                }
                                if ((clock * testp) >= 600000)
-                                       p |= 80;
+                                       p |= 0x80;
                        }
                }
        }
@@ -1406,6 +1406,14 @@ static int mga_vga_get_modes(struct drm_connector *connector)
 static int mga_vga_mode_valid(struct drm_connector *connector,
                                 struct drm_display_mode *mode)
 {
+       struct drm_device *dev = connector->dev;
+       struct mga_device *mdev = (struct mga_device*)dev->dev_private;
+       struct mga_fbdev *mfbdev = mdev->mfbdev;
+       struct drm_fb_helper *fb_helper = &mfbdev->helper;
+       struct drm_fb_helper_connector *fb_helper_conn = NULL;
+       int bpp = 32;
+       int i = 0;
+
        /* FIXME: Add bandwidth and g200se limitations */
 
        if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
@@ -1415,6 +1423,25 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
                return MODE_BAD;
        }
 
+       /* Validate the mode input by the user */
+       for (i = 0; i < fb_helper->connector_count; i++) {
+               if (fb_helper->connector_info[i]->connector == connector) {
+                       /* Found the helper for this connector */
+                       fb_helper_conn = fb_helper->connector_info[i];
+                       if (fb_helper_conn->cmdline_mode.specified) {
+                               if (fb_helper_conn->cmdline_mode.bpp_specified) {
+                                       bpp = fb_helper_conn->cmdline_mode.bpp;
+                               }
+                       }
+               }
+       }
+
+       if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) {
+               if (fb_helper_conn)
+                       fb_helper_conn->cmdline_mode.specified = false;
+               return MODE_BAD;
+       }
+
        return MODE_OK;
 }
 
index 0daab62ea14c68a13f9fa1e58b681f4d39d760e0..3b2e7b6304d39862ac60159416018d4417f33ec6 100644 (file)
@@ -278,7 +278,6 @@ nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle)
        struct nouveau_object *parent = NULL;
        struct nouveau_object *namedb = NULL;
        struct nouveau_handle *handle = NULL;
-       int ret = -EINVAL;
 
        parent = nouveau_handle_ref(client, _parent);
        if (!parent)
@@ -295,7 +294,7 @@ nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle)
        }
 
        nouveau_object_ref(NULL, &parent);
-       return ret;
+       return handle ? 0 : -EINVAL;
 }
 
 int
index 5fa13267bd9f427b7f83251f22e6bd13a80683b3..02e369f80449a2d222375349aa4937623f2ac9e7 100644 (file)
@@ -544,13 +544,13 @@ nv50_disp_curs_ofuncs = {
 static void
 nv50_disp_base_vblank_enable(struct nouveau_event *event, int head)
 {
-       nv_mask(event->priv, 0x61002c, (1 << head), (1 << head));
+       nv_mask(event->priv, 0x61002c, (4 << head), (4 << head));
 }
 
 static void
 nv50_disp_base_vblank_disable(struct nouveau_event *event, int head)
 {
-       nv_mask(event->priv, 0x61002c, (1 << head), (0 << head));
+       nv_mask(event->priv, 0x61002c, (4 << head), 0);
 }
 
 static int
index 61cec0f6ff1cae895c85562351cfcdaf777df82f..4857f913efddd3226c9a8d9362031c337bcefbdf 100644 (file)
@@ -350,7 +350,7 @@ nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
                nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
        }
 
-       nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
+       nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918);
        nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
 }
 
index 6b17b614629f64172a6ace41ed5a1593889c94ad..0b20fc0d19c16861f969f5acdda2938559243be1 100644 (file)
@@ -4,7 +4,7 @@
 #include <core/device.h>
 #include <core/subdev.h>
 
-enum nouveau_therm_mode {
+enum nouveau_therm_fan_mode {
        NOUVEAU_THERM_CTRL_NONE = 0,
        NOUVEAU_THERM_CTRL_MANUAL = 1,
        NOUVEAU_THERM_CTRL_AUTO = 2,
index 2cc1e6a5eb6aa2b46eb27632ecafe71222cc9041..9c41b58d57e2511a2988447dbb46eb376d853868 100644 (file)
@@ -869,7 +869,7 @@ init_idx_addr_latched(struct nvbios_init *init)
                init->offset += 2;
 
                init_wr32(init, dreg, idata);
-               init_mask(init, creg, ~mask, data | idata);
+               init_mask(init, creg, ~mask, data | iaddr);
        }
 }
 
index a114a0ed7e98d13546a2d8672990985fd3f4c257..2e98e8a3f1aa33c8ccf9673334d7fd3e73dab708 100644 (file)
@@ -142,6 +142,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
        /* drop port's i2c subdev refcount, i2c handles this itself */
        if (ret == 0) {
                list_add_tail(&port->head, &i2c->ports);
+               atomic_dec(&parent->refcount);
                atomic_dec(&engine->refcount);
        }
 
index f794dc89a3b2a1ddaf68dc686b5ef13c0f9bbbcb..a00a5a76e2d62b82d5717923e98e85541bb7597c 100644 (file)
@@ -134,7 +134,7 @@ nouveau_therm_alarm(struct nouveau_alarm *alarm)
 }
 
 int
-nouveau_therm_mode(struct nouveau_therm *therm, int mode)
+nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode)
 {
        struct nouveau_therm_priv *priv = (void *)therm;
        struct nouveau_device *device = nv_device(therm);
@@ -149,10 +149,15 @@ nouveau_therm_mode(struct nouveau_therm *therm, int mode)
            (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0))
                return -EINVAL;
 
+       /* do not allow automatic fan management if the thermal sensor is
+        * not available */
+       if (priv->mode == 2 && therm->temp_get(therm) < 0)
+               return -EINVAL;
+
        if (priv->mode == mode)
                return 0;
 
-       nv_info(therm, "Thermal management: %s\n", name[mode]);
+       nv_info(therm, "fan management: %s\n", name[mode]);
        nouveau_therm_update(therm, mode);
        return 0;
 }
@@ -213,7 +218,7 @@ nouveau_therm_attr_set(struct nouveau_therm *therm,
                priv->fan->bios.max_duty = value;
                return 0;
        case NOUVEAU_THERM_ATTR_FAN_MODE:
-               return nouveau_therm_mode(therm, value);
+               return nouveau_therm_fan_mode(therm, value);
        case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
                priv->bios_sensor.thrs_fan_boost.temp = value;
                priv->sensor.program_alarms(therm);
@@ -263,7 +268,7 @@ _nouveau_therm_init(struct nouveau_object *object)
                return ret;
 
        if (priv->suspend >= 0)
-               nouveau_therm_mode(therm, priv->mode);
+               nouveau_therm_fan_mode(therm, priv->mode);
        priv->sensor.program_alarms(therm);
        return 0;
 }
@@ -313,11 +318,12 @@ nouveau_therm_create_(struct nouveau_object *parent,
 int
 nouveau_therm_preinit(struct nouveau_therm *therm)
 {
-       nouveau_therm_ic_ctor(therm);
        nouveau_therm_sensor_ctor(therm);
+       nouveau_therm_ic_ctor(therm);
        nouveau_therm_fan_ctor(therm);
 
-       nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_NONE);
+       nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE);
+       nouveau_therm_sensor_preinit(therm);
        return 0;
 }
 
index e24090bac195687c34f9175103b34a9e7e0cb8d5..8b3adec5fbb19e8a34cdb53fa83420f7b57f21b2 100644 (file)
@@ -32,6 +32,7 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c,
                        struct i2c_board_info *info)
 {
        struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c);
+       struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
        struct i2c_client *client;
 
        request_module("%s%s", I2C_MODULE_PREFIX, info->type);
@@ -46,8 +47,9 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c,
        }
 
        nv_info(priv,
-               "Found an %s at address 0x%x (controlled by lm_sensors)\n",
-               info->type, info->addr);
+               "Found an %s at address 0x%x (controlled by lm_sensors, "
+               "temp offset %+i C)\n",
+               info->type, info->addr, sensor->offset_constant);
        priv->ic = client;
 
        return true;
index 0f5363edb96435ec8fb992abab3479a462bcdf88..a70d1b7e397b4b3ffe280b1f0ad6152679f6f15b 100644 (file)
@@ -29,54 +29,83 @@ struct nv40_therm_priv {
        struct nouveau_therm_priv base;
 };
 
+enum nv40_sensor_style { INVALID_STYLE = -1, OLD_STYLE = 0, NEW_STYLE = 1 };
+
+static enum nv40_sensor_style
+nv40_sensor_style(struct nouveau_therm *therm)
+{
+       struct nouveau_device *device = nv_device(therm);
+
+       switch (device->chipset) {
+       case 0x43:
+       case 0x44:
+       case 0x4a:
+       case 0x47:
+               return OLD_STYLE;
+
+       case 0x46:
+       case 0x49:
+       case 0x4b:
+       case 0x4e:
+       case 0x4c:
+       case 0x67:
+       case 0x68:
+       case 0x63:
+               return NEW_STYLE;
+       default:
+               return INVALID_STYLE;
+       }
+}
+
 static int
 nv40_sensor_setup(struct nouveau_therm *therm)
 {
-       struct nouveau_device *device = nv_device(therm);
+       enum nv40_sensor_style style = nv40_sensor_style(therm);
 
        /* enable ADC readout and disable the ALARM threshold */
-       if (device->chipset >= 0x46) {
+       if (style == NEW_STYLE) {
                nv_mask(therm, 0x15b8, 0x80000000, 0);
                nv_wr32(therm, 0x15b0, 0x80003fff);
-               mdelay(10); /* wait for the temperature to stabilize */
+               mdelay(20); /* wait for the temperature to stabilize */
                return nv_rd32(therm, 0x15b4) & 0x3fff;
-       } else {
+       } else if (style == OLD_STYLE) {
                nv_wr32(therm, 0x15b0, 0xff);
+               mdelay(20); /* wait for the temperature to stabilize */
                return nv_rd32(therm, 0x15b4) & 0xff;
-       }
+       } else
+               return -ENODEV;
 }
 
 static int
 nv40_temp_get(struct nouveau_therm *therm)
 {
        struct nouveau_therm_priv *priv = (void *)therm;
-       struct nouveau_device *device = nv_device(therm);
        struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
+       enum nv40_sensor_style style = nv40_sensor_style(therm);
        int core_temp;
 
-       if (device->chipset >= 0x46) {
+       if (style == NEW_STYLE) {
                nv_wr32(therm, 0x15b0, 0x80003fff);
                core_temp = nv_rd32(therm, 0x15b4) & 0x3fff;
-       } else {
+       } else if (style == OLD_STYLE) {
                nv_wr32(therm, 0x15b0, 0xff);
                core_temp = nv_rd32(therm, 0x15b4) & 0xff;
-       }
-
-       /* Setup the sensor if the temperature is 0 */
-       if (core_temp == 0)
-               core_temp = nv40_sensor_setup(therm);
+       } else
+               return -ENODEV;
 
-       if (sensor->slope_div == 0)
-               sensor->slope_div = 1;
-       if (sensor->offset_den == 0)
-               sensor->offset_den = 1;
-       if (sensor->slope_mult < 1)
-               sensor->slope_mult = 1;
+       /* if the slope or the offset is unset, do no use the sensor */
+       if (!sensor->slope_div || !sensor->slope_mult ||
+           !sensor->offset_num || !sensor->offset_den)
+           return -ENODEV;
 
        core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
        core_temp = core_temp + sensor->offset_num / sensor->offset_den;
        core_temp = core_temp + sensor->offset_constant - 8;
 
+       /* reserve negative temperatures for errors */
+       if (core_temp < 0)
+               core_temp = 0;
+
        return core_temp;
 }
 
index 06b98706b3fc163460aa807af2a699ec62a8af98..438d9824b7741c5733bf2aa0f8ec306784569efe 100644 (file)
@@ -102,7 +102,7 @@ struct nouveau_therm_priv {
        struct i2c_client *ic;
 };
 
-int nouveau_therm_mode(struct nouveau_therm *therm, int mode);
+int nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode);
 int nouveau_therm_attr_get(struct nouveau_therm *therm,
                       enum nouveau_therm_attr_type type);
 int nouveau_therm_attr_set(struct nouveau_therm *therm,
@@ -122,6 +122,7 @@ int nouveau_therm_fan_sense(struct nouveau_therm *therm);
 
 int nouveau_therm_preinit(struct nouveau_therm *);
 
+void nouveau_therm_sensor_preinit(struct nouveau_therm *);
 void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm,
                                             enum nouveau_therm_thrs thrs,
                                             enum nouveau_therm_thrs_state st);
index b37624af82977543142f7035a2f2ba7b8a89cc63..470f6a47b6565bfe4d3ad257fa5d7f038ca25755 100644 (file)
@@ -34,10 +34,6 @@ nouveau_therm_temp_set_defaults(struct nouveau_therm *therm)
 {
        struct nouveau_therm_priv *priv = (void *)therm;
 
-       priv->bios_sensor.slope_mult = 1;
-       priv->bios_sensor.slope_div = 1;
-       priv->bios_sensor.offset_num = 0;
-       priv->bios_sensor.offset_den = 1;
        priv->bios_sensor.offset_constant = 0;
 
        priv->bios_sensor.thrs_fan_boost.temp = 90;
@@ -60,11 +56,6 @@ nouveau_therm_temp_safety_checks(struct nouveau_therm *therm)
        struct nouveau_therm_priv *priv = (void *)therm;
        struct nvbios_therm_sensor *s = &priv->bios_sensor;
 
-       if (!priv->bios_sensor.slope_div)
-               priv->bios_sensor.slope_div = 1;
-       if (!priv->bios_sensor.offset_den)
-               priv->bios_sensor.offset_den = 1;
-
        /* enforce a minimum hysteresis on thresholds */
        s->thrs_fan_boost.hysteresis = max_t(u8, s->thrs_fan_boost.hysteresis, 2);
        s->thrs_down_clock.hysteresis = max_t(u8, s->thrs_down_clock.hysteresis, 2);
@@ -106,16 +97,16 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
        const char *thresolds[] = {
                "fanboost", "downclock", "critical", "shutdown"
        };
-       uint8_t temperature = therm->temp_get(therm);
+       int temperature = therm->temp_get(therm);
 
        if (thrs < 0 || thrs > 3)
                return;
 
        if (dir == NOUVEAU_THERM_THRS_FALLING)
-               nv_info(therm, "temperature (%u C) went below the '%s' threshold\n",
+               nv_info(therm, "temperature (%i C) went below the '%s' threshold\n",
                        temperature, thresolds[thrs]);
        else
-               nv_info(therm, "temperature (%u C) hit the '%s' threshold\n",
+               nv_info(therm, "temperature (%i C) hit the '%s' threshold\n",
                        temperature, thresolds[thrs]);
 
        active = (dir == NOUVEAU_THERM_THRS_RISING);
@@ -123,7 +114,7 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
        case NOUVEAU_THERM_THRS_FANBOOST:
                if (active) {
                        nouveau_therm_fan_set(therm, true, 100);
-                       nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
+                       nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
                }
                break;
        case NOUVEAU_THERM_THRS_DOWNCLOCK:
@@ -202,7 +193,7 @@ alarm_timer_callback(struct nouveau_alarm *alarm)
                                             NOUVEAU_THERM_THRS_SHUTDOWN);
 
        /* schedule the next poll in one second */
-       if (list_empty(&alarm->head))
+       if (therm->temp_get(therm) >= 0 && list_empty(&alarm->head))
                ptimer->alarm(ptimer, 1000 * 1000 * 1000, alarm);
 
        spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
@@ -225,6 +216,17 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm)
        alarm_timer_callback(&priv->sensor.therm_poll_alarm);
 }
 
+void
+nouveau_therm_sensor_preinit(struct nouveau_therm *therm)
+{
+       const char *sensor_avail = "yes";
+
+       if (therm->temp_get(therm) < 0)
+               sensor_avail = "no";
+
+       nv_info(therm, "internal sensor: %s\n", sensor_avail);
+}
+
 int
 nouveau_therm_sensor_ctor(struct nouveau_therm *therm)
 {
index 41241922263fd79641a2486033d933932025524e..3b6dc883e150a4b8d3493cfd6104d7f827967e98 100644 (file)
@@ -116,6 +116,11 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
 {
        struct nouveau_abi16_ntfy *ntfy, *temp;
 
+       /* wait for all activity to stop before releasing notify object, which
+        * may be still in use */
+       if (chan->chan && chan->ntfy)
+               nouveau_channel_idle(chan->chan);
+
        /* cleanup notifier state */
        list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) {
                nouveau_abi16_ntfy_fini(chan, ntfy);
index d28430cd2ba6066ad62c118b8d13d59fa7a88793..6e7a55f93a85207c10198b890b31df7dd0f7bd3c 100644 (file)
@@ -47,6 +47,18 @@ nouveau_agp_enabled(struct nouveau_drm *drm)
        if (drm->agp.stat == UNKNOWN) {
                if (!nouveau_agpmode)
                        return false;
+#ifdef __powerpc__
+               /* Disable AGP by default on all PowerPC machines for
+                * now -- At least some UniNorth-2 AGP bridges are
+                * known to be broken: DMA from the host to the card
+                * works just fine, but writeback from the card to the
+                * host goes straight to memory untranslated bypassing
+                * the GATT somehow, making them quite painful to deal
+                * with...
+                */
+               if (nouveau_agpmode == -1)
+                       return false;
+#endif
                return true;
        }
 
index 11ca82148edcb13505d9c7d06a303ad25053b04b..7ff10711a4d0a437d856df1dafbb0eddf9cee82e 100644 (file)
@@ -801,7 +801,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                stride  = 16 * 4;
                height  = amount / stride;
 
-               if (new_mem->mem_type == TTM_PL_VRAM &&
+               if (old_mem->mem_type == TTM_PL_VRAM &&
                    nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
@@ -823,7 +823,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                        BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
                        OUT_RING  (chan, 1);
                }
-               if (old_mem->mem_type == TTM_PL_VRAM &&
+               if (new_mem->mem_type == TTM_PL_VRAM &&
                    nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
index bb54098c6d970bd4c0b45582220490fb11b15426..936b442a6ab7f3f2e09ecea341e3105df51ed630 100644 (file)
@@ -402,8 +402,12 @@ nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
        struct drm_device *dev = dev_get_drvdata(d);
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nouveau_therm *therm = nouveau_therm(drm->device);
+       int temp = therm->temp_get(therm);
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", therm->temp_get(therm) * 1000);
+       if (temp < 0)
+               return temp;
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
 }
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
                                                  NULL, 0);
@@ -871,7 +875,12 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
                          nouveau_hwmon_get_pwm1_max,
                          nouveau_hwmon_set_pwm1_max, 0);
 
-static struct attribute *hwmon_attributes[] = {
+static struct attribute *hwmon_default_attributes[] = {
+       &sensor_dev_attr_name.dev_attr.attr,
+       &sensor_dev_attr_update_rate.dev_attr.attr,
+       NULL
+};
+static struct attribute *hwmon_temp_attributes[] = {
        &sensor_dev_attr_temp1_input.dev_attr.attr,
        &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
@@ -882,8 +891,6 @@ static struct attribute *hwmon_attributes[] = {
        &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
        &sensor_dev_attr_temp1_emergency.dev_attr.attr,
        &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr,
-       &sensor_dev_attr_name.dev_attr.attr,
-       &sensor_dev_attr_update_rate.dev_attr.attr,
        NULL
 };
 static struct attribute *hwmon_fan_rpm_attributes[] = {
@@ -898,8 +905,11 @@ static struct attribute *hwmon_pwm_fan_attributes[] = {
        NULL
 };
 
-static const struct attribute_group hwmon_attrgroup = {
-       .attrs = hwmon_attributes,
+static const struct attribute_group hwmon_default_attrgroup = {
+       .attrs = hwmon_default_attributes,
+};
+static const struct attribute_group hwmon_temp_attrgroup = {
+       .attrs = hwmon_temp_attributes,
 };
 static const struct attribute_group hwmon_fan_rpm_attrgroup = {
        .attrs = hwmon_fan_rpm_attributes,
@@ -931,13 +941,22 @@ nouveau_hwmon_init(struct drm_device *dev)
        }
        dev_set_drvdata(hwmon_dev, dev);
 
-       /* default sysfs entries */
-       ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_attrgroup);
+       /* set the default attributes */
+       ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup);
        if (ret) {
                if (ret)
                        goto error;
        }
 
+       /* if the card has a working thermal sensor */
+       if (therm->temp_get(therm) >= 0) {
+               ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup);
+               if (ret) {
+                       if (ret)
+                               goto error;
+               }
+       }
+
        /* if the card has a pwm fan */
        /*XXX: incorrect, need better detection for this, some boards have
         *     the gpio entries for pwm fan control even when there's no
@@ -979,11 +998,10 @@ nouveau_hwmon_fini(struct drm_device *dev)
        struct nouveau_pm *pm = nouveau_pm(dev);
 
        if (pm->hwmon) {
-               sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup);
-               sysfs_remove_group(&pm->hwmon->kobj,
-                                  &hwmon_pwm_fan_attrgroup);
-               sysfs_remove_group(&pm->hwmon->kobj,
-                                  &hwmon_fan_rpm_attrgroup);
+               sysfs_remove_group(&pm->hwmon->kobj, &hwmon_default_attrgroup);
+               sysfs_remove_group(&pm->hwmon->kobj, &hwmon_temp_attrgroup);
+               sysfs_remove_group(&pm->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
+               sysfs_remove_group(&pm->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
 
                hwmon_device_unregister(pm->hwmon);
        }
index a6237c9cbbc30c5cacfc246733fdbf1c67e68588..7f0e6c3f37d1fae4983bd6d8270364e52f00fc30 100644 (file)
@@ -55,9 +55,9 @@
 
 /* offsets in shared sync bo of various structures */
 #define EVO_SYNC(c, o) ((c) * 0x0100 + (o))
-#define EVO_MAST_NTFY     EVO_SYNC(  0, 0x00)
-#define EVO_FLIP_SEM0(c)  EVO_SYNC((c), 0x00)
-#define EVO_FLIP_SEM1(c)  EVO_SYNC((c), 0x10)
+#define EVO_MAST_NTFY     EVO_SYNC(      0, 0x00)
+#define EVO_FLIP_SEM0(c)  EVO_SYNC((c) + 1, 0x00)
+#define EVO_FLIP_SEM1(c)  EVO_SYNC((c) + 1, 0x10)
 
 #define EVO_CORE_HANDLE      (0xd1500000)
 #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i))
@@ -341,10 +341,8 @@ struct nv50_curs {
 
 struct nv50_sync {
        struct nv50_dmac base;
-       struct {
-               u32 offset;
-               u16 value;
-       } sem;
+       u32 addr;
+       u32 data;
 };
 
 struct nv50_ovly {
@@ -471,13 +469,33 @@ nv50_display_crtc_sema(struct drm_device *dev, int crtc)
        return nv50_disp(dev)->sync;
 }
 
+struct nv50_display_flip {
+       struct nv50_disp *disp;
+       struct nv50_sync *chan;
+};
+
+static bool
+nv50_display_flip_wait(void *data)
+{
+       struct nv50_display_flip *flip = data;
+       if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) ==
+                                             flip->chan->data);
+               return true;
+       usleep_range(1, 2);
+       return false;
+}
+
 void
 nv50_display_flip_stop(struct drm_crtc *crtc)
 {
-       struct nv50_sync *sync = nv50_sync(crtc);
+       struct nouveau_device *device = nouveau_dev(crtc->dev);
+       struct nv50_display_flip flip = {
+               .disp = nv50_disp(crtc->dev),
+               .chan = nv50_sync(crtc),
+       };
        u32 *push;
 
-       push = evo_wait(sync, 8);
+       push = evo_wait(flip.chan, 8);
        if (push) {
                evo_mthd(push, 0x0084, 1);
                evo_data(push, 0x00000000);
@@ -487,8 +505,10 @@ nv50_display_flip_stop(struct drm_crtc *crtc)
                evo_data(push, 0x00000000);
                evo_mthd(push, 0x0080, 1);
                evo_data(push, 0x00000000);
-               evo_kick(push, sync);
+               evo_kick(push, flip.chan);
        }
+
+       nv_wait_cb(device, nv50_display_flip_wait, &flip);
 }
 
 int
@@ -496,73 +516,78 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                       struct nouveau_channel *chan, u32 swap_interval)
 {
        struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
-       struct nv50_disp *disp = nv50_disp(crtc->dev);
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct nv50_sync *sync = nv50_sync(crtc);
+       int head = nv_crtc->index, ret;
        u32 *push;
-       int ret;
 
        swap_interval <<= 4;
        if (swap_interval == 0)
                swap_interval |= 0x100;
+       if (chan == NULL)
+               evo_sync(crtc->dev);
 
        push = evo_wait(sync, 128);
        if (unlikely(push == NULL))
                return -EBUSY;
 
-       /* synchronise with the rendering channel, if necessary */
-       if (likely(chan)) {
+       if (chan && nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) {
+               ret = RING_SPACE(chan, 8);
+               if (ret)
+                       return ret;
+
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
+               OUT_RING  (chan, NvEvoSema0 + head);
+               OUT_RING  (chan, sync->addr ^ 0x10);
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
+               OUT_RING  (chan, sync->data + 1);
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2);
+               OUT_RING  (chan, sync->addr);
+               OUT_RING  (chan, sync->data);
+       } else
+       if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) {
+               u64 addr = nv84_fence_crtc(chan, head) + sync->addr;
+               ret = RING_SPACE(chan, 12);
+               if (ret)
+                       return ret;
+
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
+               OUT_RING  (chan, chan->vram);
+               BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, lower_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, sync->data + 1);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
+               BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr));
+               OUT_RING  (chan, lower_32_bits(addr));
+               OUT_RING  (chan, sync->data);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
+       } else
+       if (chan) {
+               u64 addr = nv84_fence_crtc(chan, head) + sync->addr;
                ret = RING_SPACE(chan, 10);
                if (ret)
                        return ret;
 
-               if (nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) {
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
-                       OUT_RING  (chan, NvEvoSema0 + nv_crtc->index);
-                       OUT_RING  (chan, sync->sem.offset);
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
-                       OUT_RING  (chan, 0xf00d0000 | sync->sem.value);
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2);
-                       OUT_RING  (chan, sync->sem.offset ^ 0x10);
-                       OUT_RING  (chan, 0x74b1e000);
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
-                       OUT_RING  (chan, NvSema);
-               } else
-               if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) {
-                       u64 offset = nv84_fence_crtc(chan, nv_crtc->index);
-                       offset += sync->sem.offset;
-
-                       BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset));
-                       OUT_RING  (chan, 0xf00d0000 | sync->sem.value);
-                       OUT_RING  (chan, 0x00000002);
-                       BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset ^ 0x10));
-                       OUT_RING  (chan, 0x74b1e000);
-                       OUT_RING  (chan, 0x00000001);
-               } else {
-                       u64 offset = nv84_fence_crtc(chan, nv_crtc->index);
-                       offset += sync->sem.offset;
-
-                       BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset));
-                       OUT_RING  (chan, 0xf00d0000 | sync->sem.value);
-                       OUT_RING  (chan, 0x00001002);
-                       BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset ^ 0x10));
-                       OUT_RING  (chan, 0x74b1e000);
-                       OUT_RING  (chan, 0x00001001);
-               }
+               BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, lower_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, sync->data + 1);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG |
+                                NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
+               BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr));
+               OUT_RING  (chan, lower_32_bits(addr));
+               OUT_RING  (chan, sync->data);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL |
+                                NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
+       }
 
+       if (chan) {
+               sync->addr ^= 0x10;
+               sync->data++;
                FIRE_RING (chan);
-       } else {
-               nouveau_bo_wr32(disp->sync, sync->sem.offset / 4,
-                               0xf00d0000 | sync->sem.value);
-               evo_sync(crtc->dev);
        }
 
        /* queue the flip */
@@ -575,9 +600,9 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                evo_data(push, 0x40000000);
        }
        evo_mthd(push, 0x0088, 4);
-       evo_data(push, sync->sem.offset);
-       evo_data(push, 0xf00d0000 | sync->sem.value);
-       evo_data(push, 0x74b1e000);
+       evo_data(push, sync->addr);
+       evo_data(push, sync->data++);
+       evo_data(push, sync->data);
        evo_data(push, NvEvoSync);
        evo_mthd(push, 0x00a0, 2);
        evo_data(push, 0x00000000);
@@ -605,9 +630,6 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        evo_mthd(push, 0x0080, 1);
        evo_data(push, 0x00000000);
        evo_kick(push, sync);
-
-       sync->sem.offset ^= 0x10;
-       sync->sem.value++;
        return 0;
 }
 
@@ -1379,7 +1401,8 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index)
        if (ret)
                goto out;
 
-       head->sync.sem.offset = EVO_SYNC(1 + index, 0x00);
+       head->sync.addr = EVO_FLIP_SEM0(index);
+       head->sync.data = 0x00000000;
 
        /* allocate overlay resources */
        ret = nv50_pioc_create(disp->core, NV50_DISP_OIMM_CLASS, index,
@@ -2112,15 +2135,23 @@ nv50_display_fini(struct drm_device *dev)
 int
 nv50_display_init(struct drm_device *dev)
 {
-       u32 *push = evo_wait(nv50_mast(dev), 32);
-       if (push) {
-               evo_mthd(push, 0x0088, 1);
-               evo_data(push, NvEvoSync);
-               evo_kick(push, nv50_mast(dev));
-               return 0;
+       struct nv50_disp *disp = nv50_disp(dev);
+       struct drm_crtc *crtc;
+       u32 *push;
+
+       push = evo_wait(nv50_mast(dev), 32);
+       if (!push)
+               return -EBUSY;
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct nv50_sync *sync = nv50_sync(crtc);
+               nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data);
        }
 
-       return -EBUSY;
+       evo_mthd(push, 0x0088, 1);
+       evo_data(push, NvEvoSync);
+       evo_kick(push, nv50_mast(dev));
+       return 0;
 }
 
 void
@@ -2245,6 +2276,7 @@ nv50_display_create(struct drm_device *dev)
                        NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n",
                                     dcbe->location, dcbe->type,
                                     ffs(dcbe->or) - 1, ret);
+                       ret = 0;
                }
        }
 
index 3c38ea46531cfe6b9bc6397c01337393fe3e8a51..305a657bf21561242991e56365439781df54c2df 100644 (file)
@@ -2438,6 +2438,12 @@ static u32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev)
        if (tmp & L2_BUSY)
                reset_mask |= RADEON_RESET_VMC;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
index 99fb13286fd02d3393ff09e28b9c10e91cb9d9e7..eb8ac315f92faa3cbd58468b6bf9ba360a8c0986 100644 (file)
@@ -834,7 +834,7 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
                         __func__, __LINE__, toffset, surf.base_align);
                return -EINVAL;
        }
-       if (moffset & (surf.base_align - 1)) {
+       if (surf.nsamples <= 1 && moffset & (surf.base_align - 1)) {
                dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n",
                         __func__, __LINE__, moffset, surf.base_align);
                return -EINVAL;
index 7cead763be9ec760ad05919ae11d4e5a6b504d85..27769e724b6de1d238fc402b844d056ed69bb4b8 100644 (file)
@@ -468,13 +468,19 @@ static void cayman_gpu_init(struct radeon_device *rdev)
                    (rdev->pdev->device == 0x9907) ||
                    (rdev->pdev->device == 0x9908) ||
                    (rdev->pdev->device == 0x9909) ||
+                   (rdev->pdev->device == 0x990B) ||
+                   (rdev->pdev->device == 0x990C) ||
+                   (rdev->pdev->device == 0x990F) ||
                    (rdev->pdev->device == 0x9910) ||
-                   (rdev->pdev->device == 0x9917)) {
+                   (rdev->pdev->device == 0x9917) ||
+                   (rdev->pdev->device == 0x9999)) {
                        rdev->config.cayman.max_simds_per_se = 6;
                        rdev->config.cayman.max_backends_per_se = 2;
                } else if ((rdev->pdev->device == 0x9903) ||
                           (rdev->pdev->device == 0x9904) ||
                           (rdev->pdev->device == 0x990A) ||
+                          (rdev->pdev->device == 0x990D) ||
+                          (rdev->pdev->device == 0x990E) ||
                           (rdev->pdev->device == 0x9913) ||
                           (rdev->pdev->device == 0x9918)) {
                        rdev->config.cayman.max_simds_per_se = 4;
@@ -483,6 +489,9 @@ static void cayman_gpu_init(struct radeon_device *rdev)
                           (rdev->pdev->device == 0x9990) ||
                           (rdev->pdev->device == 0x9991) ||
                           (rdev->pdev->device == 0x9994) ||
+                          (rdev->pdev->device == 0x9995) ||
+                          (rdev->pdev->device == 0x9996) ||
+                          (rdev->pdev->device == 0x999A) ||
                           (rdev->pdev->device == 0x99A0)) {
                        rdev->config.cayman.max_simds_per_se = 3;
                        rdev->config.cayman.max_backends_per_se = 1;
@@ -616,11 +625,22 @@ static void cayman_gpu_init(struct radeon_device *rdev)
        WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
        WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
 
-       tmp = gb_addr_config & NUM_PIPES_MASK;
-       tmp = r6xx_remap_render_backend(rdev, tmp,
-                                       rdev->config.cayman.max_backends_per_se *
-                                       rdev->config.cayman.max_shader_engines,
-                                       CAYMAN_MAX_BACKENDS, disabled_rb_mask);
+       if ((rdev->config.cayman.max_backends_per_se == 1) &&
+           (rdev->flags & RADEON_IS_IGP)) {
+               if ((disabled_rb_mask & 3) == 1) {
+                       /* RB0 disabled, RB1 enabled */
+                       tmp = 0x11111111;
+               } else {
+                       /* RB1 disabled, RB0 enabled */
+                       tmp = 0x00000000;
+               }
+       } else {
+               tmp = gb_addr_config & NUM_PIPES_MASK;
+               tmp = r6xx_remap_render_backend(rdev, tmp,
+                                               rdev->config.cayman.max_backends_per_se *
+                                               rdev->config.cayman.max_shader_engines,
+                                               CAYMAN_MAX_BACKENDS, disabled_rb_mask);
+       }
        WREG32(GB_BACKEND_MAP, tmp);
 
        cgts_tcc_disable = 0xffff0000;
@@ -1381,6 +1401,12 @@ static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
        if (tmp & L2_BUSY)
                reset_mask |= RADEON_RESET_VMC;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
@@ -1765,6 +1791,7 @@ int cayman_resume(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
        r600_audio_fini(rdev);
+       radeon_vm_manager_fini(rdev);
        cayman_cp_enable(rdev, false);
        cayman_dma_stop(rdev);
        evergreen_irq_suspend(rdev);
index 6d4b5611daf4b2f96c05c00593c186acbb015e7f..0740db3fcd2268af78e286ec6ec634570ff7efcd 100644 (file)
@@ -1394,6 +1394,12 @@ static u32 r600_gpu_check_soft_reset(struct radeon_device *rdev)
        if (r600_is_display_hung(rdev))
                reset_mask |= RADEON_RESET_DISPLAY;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
index bedda9caadd9fe7d43bca2539bf51fd5df669f1f..6e05a2e75a46c211bcd5b4236e7c094b1636c9a1 100644 (file)
@@ -122,10 +122,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
                goto out_cleanup;
        }
 
-       /* r100 doesn't have dma engine so skip the test */
-       /* also, VRAM-to-VRAM test doesn't make much sense for DMA */
-       /* skip it as well if domains are the same */
-       if ((rdev->asic->copy.dma) && (sdomain != ddomain)) {
+       if (rdev->asic->copy.dma) {
                time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
                                                RADEON_BENCHMARK_COPY_DMA, n);
                if (time < 0)
@@ -135,13 +132,15 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
                                                     sdomain, ddomain, "dma");
        }
 
-       time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
-                                       RADEON_BENCHMARK_COPY_BLIT, n);
-       if (time < 0)
-               goto out_cleanup;
-       if (time > 0)
-               radeon_benchmark_log_results(n, size, time,
-                                            sdomain, ddomain, "blit");
+       if (rdev->asic->copy.blit) {
+               time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
+                                               RADEON_BENCHMARK_COPY_BLIT, n);
+               if (time < 0)
+                       goto out_cleanup;
+               if (time > 0)
+                       radeon_benchmark_log_results(n, size, time,
+                                                    sdomain, ddomain, "blit");
+       }
 
 out_cleanup:
        if (sobj) {
index 3e403bdda58fc8eb69b3583d647770f2b9b41210..78edadc9e86b22b8ec64d5877f4b98365cafcffd 100644 (file)
@@ -970,6 +970,15 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
                        found = 1;
        }
 
+       /* quirks */
+       /* Radeon 9100 (R200) */
+       if ((dev->pdev->device == 0x514D) &&
+           (dev->pdev->subsystem_vendor == 0x174B) &&
+           (dev->pdev->subsystem_device == 0x7149)) {
+               /* vbios value is bad, use the default */
+               found = 0;
+       }
+
        if (!found) /* fallback to defaults */
                radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
 
index 167758488ed6fd6781cbf3fa5d8a5b5a1e3c10a1..66a7f0fd96201f09a7f540057d62c9bd89d6b23e 100644 (file)
  *   2.27.0 - r600-SI: Add CS ioctl support for async DMA
  *   2.28.0 - r600-eg: Add MEM_WRITE packet support
  *   2.29.0 - R500 FP16 color clear registers
+ *   2.30.0 - fix for FMASK texturing
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       29
+#define KMS_DRIVER_MINOR       30
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
index 90374dd7796003381adb8a774e061d722579adda..48f80cd42d8f35a8a4e8757c6268172288c4573a 100644 (file)
@@ -400,6 +400,9 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block)
 {
        unsigned long irqflags;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        rdev->irq.afmt[block] = true;
        radeon_irq_set(rdev);
@@ -419,6 +422,9 @@ void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block)
 {
        unsigned long irqflags;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        rdev->irq.afmt[block] = false;
        radeon_irq_set(rdev);
@@ -438,6 +444,9 @@ void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
        unsigned long irqflags;
        int i;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
                rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i));
@@ -458,6 +467,9 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
        unsigned long irqflags;
        int i;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
                rdev->irq.hpd[i] &= !(hpd_mask & (1 << i));
index 80979ed951eb1afdacafa23b89ac7e116075858f..bafbe3216952510dc4736c823c08aa4e4de0a8c6 100644 (file)
@@ -2284,6 +2284,12 @@ static u32 si_gpu_check_soft_reset(struct radeon_device *rdev)
        if (tmp & L2_BUSY)
                reset_mask |= RADEON_RESET_VMC;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
@@ -4463,6 +4469,7 @@ int si_resume(struct radeon_device *rdev)
 
 int si_suspend(struct radeon_device *rdev)
 {
+       radeon_vm_manager_fini(rdev);
        si_cp_enable(rdev, false);
        cayman_dma_stop(rdev);
        si_irq_suspend(rdev);
index c92955df065888b3c5898b91093bf1d3cb195807..be1daf7344d3bde2fccd59c7a156f575b594dae4 100644 (file)
@@ -4,7 +4,6 @@ config DRM_TEGRA
        select DRM_KMS_HELPER
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_CMA_HELPER
-       select DRM_HDMI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index 9500f2f3f8fea702432e683a56dc0eea53dbf3fe..8758f38c948c2022b45da342f15025228ea6b22d 100644 (file)
@@ -459,19 +459,25 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
                                    struct dj_report *dj_report)
 {
        struct hid_device *hdev = djrcv_dev->hdev;
-       int sent_bytes;
+       struct hid_report *report;
+       struct hid_report_enum *output_report_enum;
+       u8 *data = (u8 *)(&dj_report->device_index);
+       int i;
 
-       if (!hdev->hid_output_raw_report) {
-               dev_err(&hdev->dev, "%s:"
-                       "hid_output_raw_report is null\n", __func__);
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+
+       if (!report) {
+               dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
                return -ENODEV;
        }
 
-       sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
-                                                sizeof(struct dj_report),
-                                                HID_OUTPUT_REPORT);
+       for (i = 0; i < report->field[0]->report_count; i++)
+               report->field[0]->value[i] = data[i];
+
+       usbhid_submit_report(hdev, report, USB_DIR_OUT);
 
-       return (sent_bytes < 0) ? sent_bytes : 0;
+       return 0;
 }
 
 static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
index 41df29f59b0e5dd011f8258c228b14650a174f5f..ebbb9f4f27a3357714f9c654979d73def306c766 100644 (file)
@@ -422,6 +422,7 @@ static struct attribute *pem_input_attributes[] = {
        &sensor_dev_attr_in2_input.dev_attr.attr,
        &sensor_dev_attr_curr1_input.dev_attr.attr,
        &sensor_dev_attr_power1_input.dev_attr.attr,
+       NULL
 };
 
 static const struct attribute_group pem_input_group = {
@@ -432,6 +433,7 @@ static struct attribute *pem_fan_attributes[] = {
        &sensor_dev_attr_fan1_input.dev_attr.attr,
        &sensor_dev_attr_fan2_input.dev_attr.attr,
        &sensor_dev_attr_fan3_input.dev_attr.attr,
+       NULL
 };
 
 static const struct attribute_group pem_fan_group = {
index 668ff4721323a22842b94823d17505da6bf68b27..5cde94e56f17cf3105b9d84d5b5dd0359661821a 100644 (file)
@@ -25,7 +25,7 @@
     which contains this code, we don't worry about the wasted space.
 */
 
-#include <linux/hwmon.h>
+#include <linux/kernel.h>
 
 /* straight from the datasheet */
 #define LM75_TEMP_MIN (-55000)
index 9652a2c92a24ddfa00d4100584093da96b6821fe..6d6130752f942380b6fe475504c9a2f75b422f44 100644 (file)
@@ -59,10 +59,10 @@ enum chips { ltc2978, ltc3880 };
 struct ltc2978_data {
        enum chips id;
        int vin_min, vin_max;
-       int temp_min, temp_max;
+       int temp_min, temp_max[2];
        int vout_min[8], vout_max[8];
        int iout_max[2];
-       int temp2_max[2];
+       int temp2_max;
        struct pmbus_driver_info info;
 };
 
@@ -113,9 +113,10 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
                ret = pmbus_read_word_data(client, page,
                                           LTC2978_MFR_TEMPERATURE_PEAK);
                if (ret >= 0) {
-                       if (lin11_to_val(ret) > lin11_to_val(data->temp_max))
-                               data->temp_max = ret;
-                       ret = data->temp_max;
+                       if (lin11_to_val(ret)
+                           > lin11_to_val(data->temp_max[page]))
+                               data->temp_max[page] = ret;
+                       ret = data->temp_max[page];
                }
                break;
        case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -204,10 +205,9 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
                ret = pmbus_read_word_data(client, page,
                                           LTC3880_MFR_TEMPERATURE2_PEAK);
                if (ret >= 0) {
-                       if (lin11_to_val(ret)
-                           > lin11_to_val(data->temp2_max[page]))
-                               data->temp2_max[page] = ret;
-                       ret = data->temp2_max[page];
+                       if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
+                               data->temp2_max = ret;
+                       ret = data->temp2_max;
                }
                break;
        case PMBUS_VIRT_READ_VIN_MIN:
@@ -248,11 +248,11 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
 
        switch (reg) {
        case PMBUS_VIRT_RESET_IOUT_HISTORY:
-               data->iout_max[page] = 0x7fff;
+               data->iout_max[page] = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        case PMBUS_VIRT_RESET_TEMP2_HISTORY:
-               data->temp2_max[page] = 0x7fff;
+               data->temp2_max = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -262,12 +262,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
                break;
        case PMBUS_VIRT_RESET_VIN_HISTORY:
                data->vin_min = 0x7bff;
-               data->vin_max = 0;
+               data->vin_max = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        case PMBUS_VIRT_RESET_TEMP_HISTORY:
                data->temp_min = 0x7bff;
-               data->temp_max = 0x7fff;
+               data->temp_max[page] = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        default:
@@ -321,12 +321,14 @@ static int ltc2978_probe(struct i2c_client *client,
        info = &data->info;
        info->write_word_data = ltc2978_write_word_data;
 
-       data->vout_min[0] = 0xffff;
        data->vin_min = 0x7bff;
+       data->vin_max = 0x7c00;
        data->temp_min = 0x7bff;
-       data->temp_max = 0x7fff;
+       for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
+               data->temp_max[i] = 0x7c00;
+       data->temp2_max = 0x7c00;
 
-       switch (id->driver_data) {
+       switch (data->id) {
        case ltc2978:
                info->read_word_data = ltc2978_read_word_data;
                info->pages = 8;
@@ -336,7 +338,6 @@ static int ltc2978_probe(struct i2c_client *client,
                for (i = 1; i < 8; i++) {
                        info->func[i] = PMBUS_HAVE_VOUT
                          | PMBUS_HAVE_STATUS_VOUT;
-                       data->vout_min[i] = 0xffff;
                }
                break;
        case ltc3880:
@@ -352,11 +353,14 @@ static int ltc2978_probe(struct i2c_client *client,
                  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
                  | PMBUS_HAVE_POUT
                  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
-               data->vout_min[1] = 0xffff;
+               data->iout_max[0] = 0x7c00;
+               data->iout_max[1] = 0x7c00;
                break;
        default:
                return -ENODEV;
        }
+       for (i = 0; i < info->pages; i++)
+               data->vout_min[i] = 0xffff;
 
        return pmbus_do_probe(client, id, info);
 }
index 80eef50c50fd27f9022f3f3176ff6434ad945867..9add60920ac00ed5aa70ca0e1113887836e0ae7d 100644 (file)
@@ -766,12 +766,14 @@ static ssize_t pmbus_show_label(struct device *dev,
 static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr)
 {
        if (data->num_attributes >= data->max_attributes - 1) {
-               data->max_attributes += PMBUS_ATTR_ALLOC_SIZE;
-               data->group.attrs = krealloc(data->group.attrs,
-                                            sizeof(struct attribute *) *
-                                            data->max_attributes, GFP_KERNEL);
-               if (data->group.attrs == NULL)
+               int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE;
+               void *new_attrs = krealloc(data->group.attrs,
+                                          new_max_attrs * sizeof(void *),
+                                          GFP_KERNEL);
+               if (!new_attrs)
                        return -ENOMEM;
+               data->group.attrs = new_attrs;
+               data->max_attributes = new_max_attrs;
        }
 
        data->group.attrs[data->num_attributes++] = attr;
index bfe326e896dfd6d277ed22aec18ff9431ae8b8c1..2507f902fb7aa4ea450079a69bbbf8234e7e0ef4 100644 (file)
@@ -965,7 +965,13 @@ static int sht15_probe(struct platform_device *pdev)
                if (voltage)
                        data->supply_uv = voltage;
 
-               regulator_enable(data->reg);
+               ret = regulator_enable(data->reg);
+               if (ret != 0) {
+                       dev_err(&pdev->dev,
+                               "failed to enable regulator: %d\n", ret);
+                       return ret;
+               }
+
                /*
                 * Setup a notifier block to update this if another device
                 * causes the voltage to change
index 46cde098c11c2fe993dea722f1dd37d0ec3c7498..e380c6eef3af6500edc94b3a8db668bb59dfa258 100644 (file)
@@ -4,7 +4,6 @@
 
 menuconfig I2C
        tristate "I2C support"
-       depends on !S390
        select RT_MUTEXES
        ---help---
          I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
@@ -76,6 +75,7 @@ config I2C_HELPER_AUTO
 
 config I2C_SMBUS
        tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
+       depends on GENERIC_HARDIRQS
        help
          Say Y here if you want support for SMBus extensions to the I2C
          specification. At the moment, the only supported extension is
index a3725de923848baba3c55f3067588f42759b5227..adfee98486b159843b38ff107c8ea9dd25189ed5 100644 (file)
@@ -114,7 +114,7 @@ config I2C_I801
 
 config I2C_ISCH
        tristate "Intel SCH SMBus 1.0"
-       depends on PCI
+       depends on PCI && GENERIC_HARDIRQS
        select LPC_SCH
        help
          Say Y here if you want to use SMBus controller on the Intel SCH
@@ -543,6 +543,7 @@ config I2C_NUC900
 
 config I2C_OCORES
        tristate "OpenCores I2C Controller"
+       depends on GENERIC_HARDIRQS
        help
          If you say yes to this option, support will be included for the
          OpenCores I2C controller. For details see
@@ -777,7 +778,7 @@ config I2C_DIOLAN_U2C
 
 config I2C_PARPORT
        tristate "Parallel port adapter"
-       depends on PARPORT
+       depends on PARPORT && GENERIC_HARDIRQS
        select I2C_ALGOBIT
        select I2C_SMBUS
        help
@@ -802,6 +803,7 @@ config I2C_PARPORT
 
 config I2C_PARPORT_LIGHT
        tristate "Parallel port adapter (light)"
+       depends on GENERIC_HARDIRQS
        select I2C_ALGOBIT
        select I2C_SMBUS
        help
index e9205ee8cf94cb5a822635346df8451e5d5155bc..130f02cc9d94a233eacce7857214d34278141939 100644 (file)
@@ -80,6 +80,7 @@
 /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */
 #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59
 #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a
+#define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15
 
 #define ISMT_DESC_ENTRIES      32      /* number of descriptor entries */
 #define ISMT_MAX_RETRIES       3       /* number of SMBus retries to attempt */
@@ -185,6 +186,7 @@ struct ismt_priv {
 static const DEFINE_PCI_DEVICE_TABLE(ismt_ids) = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) },
        { 0, }
 };
 
index 36704e3ab3fa9a87cdd9ca53e825f80792c28732..b714776b6ddd1828258ee1a81d33728d1aba3c75 100644 (file)
@@ -411,7 +411,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
        int clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE;
        u32 clk_divisor;
 
-       tegra_i2c_clock_enable(i2c_dev);
+       err = tegra_i2c_clock_enable(i2c_dev);
+       if (err < 0) {
+               dev_err(i2c_dev->dev, "Clock enable failed %d\n", err);
+               return err;
+       }
 
        tegra_periph_reset_assert(i2c_dev->div_clk);
        udelay(2);
@@ -628,7 +632,12 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
        if (i2c_dev->is_suspended)
                return -EBUSY;
 
-       tegra_i2c_clock_enable(i2c_dev);
+       ret = tegra_i2c_clock_enable(i2c_dev);
+       if (ret < 0) {
+               dev_err(i2c_dev->dev, "Clock enable failed %d\n", ret);
+               return ret;
+       }
+
        for (i = 0; i < num; i++) {
                enum msg_end_type end_type = MSG_END_STOP;
                if (i < (num - 1)) {
index f3b8f9a6a89b65eb29050c591e181b908d0358f3..966a18a5d12d2397d2a43f25bcd22a65420cc5e4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2010 Ericsson AB.
  *
- * Author: Guenter Roeck <guenter.roeck@ericsson.com>
+ * Author: Guenter Roeck <linux@roeck-us.net>
  *
  * Derived from:
  *  pca954x.c
index 8126824daccba7726b637ef1358b80cfa3b49468..b231139263883e128bc084329d08fcebf4ee06a0 100644 (file)
@@ -1408,7 +1408,7 @@ static int idecd_capacity_proc_show(struct seq_file *m, void *v)
 
 static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idecd_capacity_proc_show, PDE(inode)->data);
+       return single_open(file, idecd_capacity_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idecd_capacity_proc_fops = {
index 8b570a17bcd99476093b93a8e748e66a3ae0b30a..0d1fae6cba6d571f3754bdffe6d209b57b150c73 100644 (file)
@@ -53,7 +53,7 @@ static int idedisk_cache_proc_show(struct seq_file *m, void *v)
 
 static int idedisk_cache_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idedisk_cache_proc_show, PDE(inode)->data);
+       return single_open(file, idedisk_cache_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idedisk_cache_proc_fops = {
@@ -74,7 +74,7 @@ static int idedisk_capacity_proc_show(struct seq_file *m, void *v)
 
 static int idedisk_capacity_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idedisk_capacity_proc_show, PDE(inode)->data);
+       return single_open(file, idedisk_capacity_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idedisk_capacity_proc_fops = {
@@ -115,7 +115,7 @@ static int idedisk_sv_proc_show(struct seq_file *m, void *v)
 
 static int idedisk_sv_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idedisk_sv_proc_show, PDE(inode)->data);
+       return single_open(file, idedisk_sv_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idedisk_sv_proc_fops = {
@@ -133,7 +133,7 @@ static int idedisk_st_proc_show(struct seq_file *m, void *v)
 
 static int idedisk_st_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idedisk_st_proc_show, PDE(inode)->data);
+       return single_open(file, idedisk_st_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idedisk_st_proc_fops = {
index 1600720f3e8654b93da870db04b90de1dbd92c5d..e7a25ea757dfe76e827cdff00c64b60ab63eec4d 100644 (file)
@@ -15,7 +15,7 @@ static int idefloppy_capacity_proc_show(struct seq_file *m, void *v)
 
 static int idefloppy_capacity_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idefloppy_capacity_proc_show, PDE(inode)->data);
+       return single_open(file, idefloppy_capacity_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idefloppy_capacity_proc_fops = {
index 2abcc4790f1235d5098729c8f39ef5304f5381f7..97c070077774b74201df5bda2f4053cc57debc28 100644 (file)
@@ -58,7 +58,7 @@ static int ide_imodel_proc_show(struct seq_file *m, void *v)
 
 static int ide_imodel_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_imodel_proc_show, PDE(inode)->data);
+       return single_open(file, ide_imodel_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ide_imodel_proc_fops = {
@@ -82,7 +82,7 @@ static int ide_mate_proc_show(struct seq_file *m, void *v)
 
 static int ide_mate_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_mate_proc_show, PDE(inode)->data);
+       return single_open(file, ide_mate_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ide_mate_proc_fops = {
@@ -103,7 +103,7 @@ static int ide_channel_proc_show(struct seq_file *m, void *v)
 
 static int ide_channel_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_channel_proc_show, PDE(inode)->data);
+       return single_open(file, ide_channel_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ide_channel_proc_fops = {
@@ -143,7 +143,7 @@ static int ide_identify_proc_show(struct seq_file *m, void *v)
 
 static int ide_identify_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_identify_proc_show, PDE(inode)->data);
+       return single_open(file, ide_identify_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ide_identify_proc_fops = {
@@ -325,7 +325,7 @@ static int ide_settings_proc_show(struct seq_file *m, void *v)
 
 static int ide_settings_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_settings_proc_show, PDE(inode)->data);
+       return single_open(file, ide_settings_proc_show, PDE_DATA(inode));
 }
 
 #define MAX_LEN        30
@@ -333,7 +333,7 @@ static int ide_settings_proc_open(struct inode *inode, struct file *file)
 static ssize_t ide_settings_proc_write(struct file *file, const char __user *buffer,
                                       size_t count, loff_t *pos)
 {
-       ide_drive_t     *drive = (ide_drive_t *) PDE(file_inode(file))->data;
+       ide_drive_t     *drive = PDE_DATA(file_inode(file));
        char            name[MAX_LEN + 1];
        int             for_real = 0, mul_factor, div_factor;
        unsigned long   n;
@@ -474,7 +474,7 @@ static int ide_geometry_proc_show(struct seq_file *m, void *v)
 
 static int ide_geometry_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_geometry_proc_show, PDE(inode)->data);
+       return single_open(file, ide_geometry_proc_show, PDE_DATA(inode));
 }
 
 const struct file_operations ide_geometry_proc_fops = {
@@ -497,7 +497,7 @@ static int ide_dmodel_proc_show(struct seq_file *seq, void *v)
 
 static int ide_dmodel_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_dmodel_proc_show, PDE(inode)->data);
+       return single_open(file, ide_dmodel_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ide_dmodel_proc_fops = {
@@ -525,7 +525,7 @@ static int ide_driver_proc_show(struct seq_file *m, void *v)
 
 static int ide_driver_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_driver_proc_show, PDE(inode)->data);
+       return single_open(file, ide_driver_proc_show, PDE_DATA(inode));
 }
 
 static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
@@ -558,7 +558,7 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
 static ssize_t ide_driver_proc_write(struct file *file, const char __user *buffer,
                                     size_t count, loff_t *pos)
 {
-       ide_drive_t     *drive = (ide_drive_t *) PDE(file_inode(file))->data;
+       ide_drive_t     *drive = PDE_DATA(file_inode(file));
        char name[32];
 
        if (!capable(CAP_SYS_ADMIN))
@@ -601,7 +601,7 @@ static int ide_media_proc_show(struct seq_file *m, void *v)
 
 static int ide_media_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, ide_media_proc_show, PDE(inode)->data);
+       return single_open(file, ide_media_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ide_media_proc_fops = {
index ce8237d361596840cb679c6f41dbd89bb0ad7d48..89f859591bbb4ff49e1ac5ddde8139607e78ec9a 100644 (file)
@@ -1847,7 +1847,7 @@ static int idetape_name_proc_show(struct seq_file *m, void *v)
 
 static int idetape_name_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, idetape_name_proc_show, PDE(inode)->data);
+       return single_open(file, idetape_name_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations idetape_name_proc_fops = {
index 0198324a8b0cf87c5f6b1f84f31b0b8f7b9070eb..bd33473f8e38afd4deeeb243f12c2bf981587740 100644 (file)
@@ -62,7 +62,7 @@ st_sensors_match_odr_error:
 int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
 {
        int err;
-       struct st_sensor_odr_avl odr_out;
+       struct st_sensor_odr_avl odr_out = {0, 0};
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
        err = st_sensors_match_odr(sdata->sensor, odr, &odr_out);
@@ -114,7 +114,7 @@ st_sensors_match_odr_error:
 
 static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
 {
-       int err, i;
+       int err, i = 0;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
        err = st_sensors_match_fs(sdata->sensor, fs, &i);
@@ -139,14 +139,13 @@ st_accel_set_fullscale_error:
 
 int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
 {
-       bool found;
        u8 tmp_value;
        int err = -EINVAL;
-       struct st_sensor_odr_avl odr_out;
+       bool found = false;
+       struct st_sensor_odr_avl odr_out = {0, 0};
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
        if (enable) {
-               found = false;
                tmp_value = sdata->sensor->pw.value_on;
                if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) &&
                        (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) {
index 2fe1d4edcb2f2b93fdc21b30fdb777d9d4bc923b..74f2d52795f6e6c44fe49025b49adbe13f33fc39 100644 (file)
@@ -27,7 +27,6 @@
 #define AD5064_ADDR(x)                         ((x) << 20)
 #define AD5064_CMD(x)                          ((x) << 24)
 
-#define AD5064_ADDR_DAC(chan)                  (chan)
 #define AD5064_ADDR_ALL_DAC                    0xF
 
 #define AD5064_CMD_WRITE_INPUT_N               0x0
@@ -131,15 +130,15 @@ static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
 }
 
 static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
-       unsigned int channel)
+       const struct iio_chan_spec *chan)
 {
        unsigned int val;
        int ret;
 
-       val = (0x1 << channel);
+       val = (0x1 << chan->address);
 
-       if (st->pwr_down[channel])
-               val |= st->pwr_down_mode[channel] << 8;
+       if (st->pwr_down[chan->channel])
+               val |= st->pwr_down_mode[chan->channel] << 8;
 
        ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
 
@@ -169,7 +168,7 @@ static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        st->pwr_down_mode[chan->channel] = mode + 1;
 
-       ret = ad5064_sync_powerdown_mode(st, chan->channel);
+       ret = ad5064_sync_powerdown_mode(st, chan);
        mutex_unlock(&indio_dev->mlock);
 
        return ret;
@@ -205,7 +204,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        st->pwr_down[chan->channel] = pwr_down;
 
-       ret = ad5064_sync_powerdown_mode(st, chan->channel);
+       ret = ad5064_sync_powerdown_mode(st, chan);
        mutex_unlock(&indio_dev->mlock);
        return ret ? ret : len;
 }
@@ -258,7 +257,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev,
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
-               if (val > (1 << chan->scan_type.realbits) || val < 0)
+               if (val >= (1 << chan->scan_type.realbits) || val < 0)
                        return -EINVAL;
 
                mutex_lock(&indio_dev->mlock);
@@ -292,34 +291,44 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
        { },
 };
 
-#define AD5064_CHANNEL(chan, bits) {                           \
+#define AD5064_CHANNEL(chan, addr, bits) {                     \
        .type = IIO_VOLTAGE,                                    \
        .indexed = 1,                                           \
        .output = 1,                                            \
        .channel = (chan),                                      \
        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
        IIO_CHAN_INFO_SCALE_SEPARATE_BIT,                       \
-       .address = AD5064_ADDR_DAC(chan),                       \
+       .address = addr,                                        \
        .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)),      \
        .ext_info = ad5064_ext_info,                            \
 }
 
 #define DECLARE_AD5064_CHANNELS(name, bits) \
 const struct iio_chan_spec name[] = { \
-       AD5064_CHANNEL(0, bits), \
-       AD5064_CHANNEL(1, bits), \
-       AD5064_CHANNEL(2, bits), \
-       AD5064_CHANNEL(3, bits), \
-       AD5064_CHANNEL(4, bits), \
-       AD5064_CHANNEL(5, bits), \
-       AD5064_CHANNEL(6, bits), \
-       AD5064_CHANNEL(7, bits), \
+       AD5064_CHANNEL(0, 0, bits), \
+       AD5064_CHANNEL(1, 1, bits), \
+       AD5064_CHANNEL(2, 2, bits), \
+       AD5064_CHANNEL(3, 3, bits), \
+       AD5064_CHANNEL(4, 4, bits), \
+       AD5064_CHANNEL(5, 5, bits), \
+       AD5064_CHANNEL(6, 6, bits), \
+       AD5064_CHANNEL(7, 7, bits), \
+}
+
+#define DECLARE_AD5065_CHANNELS(name, bits) \
+const struct iio_chan_spec name[] = { \
+       AD5064_CHANNEL(0, 0, bits), \
+       AD5064_CHANNEL(1, 3, bits), \
 }
 
 static DECLARE_AD5064_CHANNELS(ad5024_channels, 12);
 static DECLARE_AD5064_CHANNELS(ad5044_channels, 14);
 static DECLARE_AD5064_CHANNELS(ad5064_channels, 16);
 
+static DECLARE_AD5065_CHANNELS(ad5025_channels, 12);
+static DECLARE_AD5065_CHANNELS(ad5045_channels, 14);
+static DECLARE_AD5065_CHANNELS(ad5065_channels, 16);
+
 static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        [ID_AD5024] = {
                .shared_vref = false,
@@ -328,7 +337,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        },
        [ID_AD5025] = {
                .shared_vref = false,
-               .channels = ad5024_channels,
+               .channels = ad5025_channels,
                .num_channels = 2,
        },
        [ID_AD5044] = {
@@ -338,7 +347,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        },
        [ID_AD5045] = {
                .shared_vref = false,
-               .channels = ad5044_channels,
+               .channels = ad5045_channels,
                .num_channels = 2,
        },
        [ID_AD5064] = {
@@ -353,7 +362,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        },
        [ID_AD5065] = {
                .shared_vref = false,
-               .channels = ad5064_channels,
+               .channels = ad5065_channels,
                .num_channels = 2,
        },
        [ID_AD5628_1] = {
@@ -429,6 +438,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
 {
        struct iio_dev *indio_dev;
        struct ad5064_state *st;
+       unsigned int midscale;
        unsigned int i;
        int ret;
 
@@ -465,11 +475,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
                        goto error_free_reg;
        }
 
-       for (i = 0; i < st->chip_info->num_channels; ++i) {
-               st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
-               st->dac_cache[i] = 0x8000;
-       }
-
        indio_dev->dev.parent = dev;
        indio_dev->name = name;
        indio_dev->info = &ad5064_info;
@@ -477,6 +482,13 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
        indio_dev->channels = st->chip_info->channels;
        indio_dev->num_channels = st->chip_info->num_channels;
 
+       midscale = (1 << indio_dev->channels[0].scan_type.realbits) /  2;
+
+       for (i = 0; i < st->chip_info->num_channels; ++i) {
+               st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
+               st->dac_cache[i] = midscale;
+       }
+
        ret = iio_device_register(indio_dev);
        if (ret)
                goto error_disable_reg;
index b5cfa3a354cfe5e98ad9dd7b664adbaff10a00f9..361b2328453d478cd5ba945e91b9c242310b6119 100644 (file)
@@ -5,6 +5,7 @@
 config INV_MPU6050_IIO
        tristate "Invensense MPU6050 devices"
        depends on I2C && SYSFS
+       select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
          This driver supports the Invensense MPU6050 devices.
index 565bfb161c1a7d34098cb1c6ef7919aebe38f382..a3fde52840ca29b5c046e11533a86b2dcdad67b3 100644 (file)
@@ -1575,6 +1575,12 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
 
        neigh = dst_neigh_lookup(ep->dst,
                        &ep->com.cm_id->remote_addr.sin_addr.s_addr);
+       if (!neigh) {
+               pr_err("%s - cannot alloc neigh.\n", __func__);
+               err = -ENOMEM;
+               goto fail4;
+       }
+
        /* get a l2t entry */
        if (neigh->dev->flags & IFF_LOOPBACK) {
                PDBG("%s LOOPBACK\n", __func__);
@@ -3053,6 +3059,12 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
        dst = &rt->dst;
        neigh = dst_neigh_lookup_skb(dst, skb);
 
+       if (!neigh) {
+               pr_err("%s - failed to allocate neigh!\n",
+                      __func__);
+               goto free_dst;
+       }
+
        if (neigh->dev->flags & IFF_LOOPBACK) {
                pdev = ip_dev_find(&init_net, iph->daddr);
                e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
index 17ba4f8bc12d0b19ec7d380dc6677796d79f12de..70b1808a08f4d12bf9d1668cb5bae06d1cd2e202 100644 (file)
@@ -186,8 +186,10 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
        wq->rq.queue = dma_alloc_coherent(&(rdev->lldi.pdev->dev),
                                          wq->rq.memsize, &(wq->rq.dma_addr),
                                          GFP_KERNEL);
-       if (!wq->rq.queue)
+       if (!wq->rq.queue) {
+               ret = -ENOMEM;
                goto free_sq;
+       }
        PDBG("%s sq base va 0x%p pa 0x%llx rq base va 0x%p pa 0x%llx\n",
                __func__, wq->sq.queue,
                (unsigned long long)virt_to_phys(wq->sq.queue),
index a479375a8fd8067ad5cabd21974f441f996f90d6..e0c404bdc4a8333d60cef68189e8d2513d7ccc1a 100644 (file)
@@ -410,6 +410,7 @@ static struct file_system_type ipathfs_fs_type = {
        .mount =        ipathfs_mount,
        .kill_sb =      ipathfs_kill_super,
 };
+MODULE_ALIAS_FS("ipathfs");
 
 int __init ipath_init_ipathfs(void)
 {
index 439c35d4a669978aba8820151f2f6c98f5a47558..ea93870266eb7fda30ddf502b5d233fb1116423b 100644 (file)
@@ -620,7 +620,7 @@ void ipath_ib_rcv(struct ipath_ibdev *dev, void *rhdr, void *data,
                goto bail;
        }
 
-       opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
+       opcode = (be32_to_cpu(ohdr->bth[0]) >> 24) & 0x7f;
        dev->opstats[opcode].n_bytes += tlen;
        dev->opstats[opcode].n_packets++;
 
index e0d79b2395e4f859f51c51e9c314f9306834f123..add98d01476c1307629bd813d341bac6d34c9a76 100644 (file)
@@ -362,7 +362,6 @@ void mlx4_ib_cm_paravirt_init(struct mlx4_ib_dev *dev)
        INIT_LIST_HEAD(&dev->sriov.cm_list);
        dev->sriov.sl_id_map = RB_ROOT;
        idr_init(&dev->sriov.pv_id_table);
-       idr_pre_get(&dev->sriov.pv_id_table, GFP_KERNEL);
 }
 
 /* slave = -1 ==> all slaves */
index 8349f9c5064c042d568cf56619b76dd391410402..1e603a375069022bfed295f071f8c729b4ad826b 100644 (file)
@@ -1,7 +1,7 @@
 config INFINIBAND_QIB
-       tristate "QLogic PCIe HCA support"
+       tristate "Intel PCIe HCA support"
        depends on 64BIT
        ---help---
-       This is a low-level driver for QLogic PCIe QLE InfiniBand host
-       channel adapters.  This driver does not support the QLogic
+       This is a low-level driver for Intel PCIe QLE InfiniBand host
+       channel adapters.  This driver does not support the Intel
        HyperTransport card (model QHT7140).
index 5423edcab51f4404905e47674957cb32e5f33b9f..216092477dfcf7eb4a51187ffe825110c5eb3286 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -63,8 +64,8 @@ MODULE_PARM_DESC(compat_ddr_negotiate,
                 "Attempt pre-IBTA 1.2 DDR speed negotiation");
 
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("QLogic <support@qlogic.com>");
-MODULE_DESCRIPTION("QLogic IB driver");
+MODULE_AUTHOR("Intel <ibsupport@intel.com>");
+MODULE_DESCRIPTION("Intel IB driver");
 MODULE_VERSION(QIB_DRIVER_VERSION);
 
 /*
index 644bd6f6467ca0d7a38c9aa915c49873eea72f38..f247fc6e61826db010b2ac6c267e5fe1ee3ae09b 100644 (file)
@@ -604,6 +604,7 @@ static struct file_system_type qibfs_fs_type = {
        .mount =        qibfs_mount,
        .kill_sb =      qibfs_kill_super,
 };
+MODULE_ALIAS_FS("ipathfs");
 
 int __init qib_init_qibfs(void)
 {
index a099ac171e226f1073f4a70ccb680e669b2ff048..0232ae56b1fa2b185e1a551e074e5d256f15c087 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
  * All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
@@ -51,7 +52,7 @@ static u32 qib_6120_iblink_state(u64);
 
 /*
  * This file contains all the chip-specific register information and
- * access functions for the QLogic QLogic_IB PCI-Express chip.
+ * access functions for the Intel Intel_IB PCI-Express chip.
  *
  */
 
index 50e33aa0b4e39628c5de95e314d57de68bbc4be5..173f805790da4522f3f4a8881b8b2df5883b9b4b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -1138,7 +1138,7 @@ void qib_disable_after_error(struct qib_devdata *dd)
 static void qib_remove_one(struct pci_dev *);
 static int qib_init_one(struct pci_dev *, const struct pci_device_id *);
 
-#define DRIVER_LOAD_MSG "QLogic " QIB_DRV_NAME " loaded: "
+#define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: "
 #define PFX QIB_DRV_NAME ": "
 
 static DEFINE_PCI_DEVICE_TABLE(qib_pci_tbl) = {
@@ -1355,7 +1355,7 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                dd = qib_init_iba6120_funcs(pdev, ent);
 #else
                qib_early_err(&pdev->dev,
-                       "QLogic PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n",
+                       "Intel PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n",
                        ent->device);
                dd = ERR_PTR(-ENODEV);
 #endif
@@ -1371,7 +1371,7 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        default:
                qib_early_err(&pdev->dev,
-                       "Failing on unknown QLogic deviceid 0x%x\n",
+                       "Failing on unknown Intel deviceid 0x%x\n",
                        ent->device);
                ret = -ENODEV;
        }
index 50a8a0d4fe676f5467c677d66a4985170900059d..08a6c6d39e5666228cd842b1597fc5d9dcf48052 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation. All rights reserved.
+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -44,7 +44,7 @@
 #include "qib.h"
 #include "qib_7220.h"
 
-#define SD7220_FW_NAME "qlogic/sd7220.fw"
+#define SD7220_FW_NAME "intel/sd7220.fw"
 MODULE_FIRMWARE(SD7220_FW_NAME);
 
 /*
index ba51a4715a1dcdd5963261d84497dc1e6974c070..7c0ab16a2fe230fc31b44fd43b04f3e92d2a26b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -2224,7 +2224,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
        ibdev->dma_ops = &qib_dma_mapping_ops;
 
        snprintf(ibdev->node_desc, sizeof(ibdev->node_desc),
-                "QLogic Infiniband HCA %s", init_utsname()->nodename);
+                "Intel Infiniband HCA %s", init_utsname()->nodename);
 
        ret = ib_register_device(ibdev, qib_create_port_files);
        if (ret)
index 67b0c1d23678d26565981cf9815993027c0a1b5e..1ef880de3a41d97fe328951069f3b6c30066daf1 100644 (file)
@@ -758,9 +758,13 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
                if (++priv->tx_outstanding == ipoib_sendq_size) {
                        ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
                                  tx->qp->qp_num);
-                       if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
-                               ipoib_warn(priv, "request notify on send CQ failed\n");
                        netif_stop_queue(dev);
+                       rc = ib_req_notify_cq(priv->send_cq,
+                               IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
+                       if (rc < 0)
+                               ipoib_warn(priv, "request notify on send CQ failed\n");
+                       else if (rc)
+                               ipoib_send_comp_handler(priv->send_cq, dev);
                }
        }
 }
index 7cd74e29cbc87a6495277ecd74d7135ebcd75ad3..9135606c86496511919a5238898aa98cf1c74996 100644 (file)
@@ -158,14 +158,10 @@ static unsigned int get_time_pit(void)
 #define GET_TIME(x)    rdtscl(x)
 #define DELTA(x,y)     ((y)-(x))
 #define TIME_NAME      "TSC"
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE)
 #define GET_TIME(x)    do { x = get_cycles(); } while (0)
 #define DELTA(x,y)     ((y)-(x))
-#define TIME_NAME      "PCC"
-#elif defined(CONFIG_MN10300) || defined(CONFIG_TILE)
-#define GET_TIME(x)    do { x = get_cycles(); } while (0)
-#define DELTA(x, y)    ((x) - (y))
-#define TIME_NAME      "TSC"
+#define TIME_NAME      "get_cycles"
 #else
 #define FAKE_TIME
 static unsigned long analog_faketime = 0;
index 2fb0d76a04c4f06d072a45765349406c2d2810f7..208de7cbb7fae2460dac5576c69f5847165ac3c9 100644 (file)
@@ -70,8 +70,6 @@
 #define TC3589x_EVT_INT_CLR    0x2
 #define TC3589x_KBD_INT_CLR    0x1
 
-#define TC3589x_KBD_KEYMAP_SIZE     64
-
 /**
  * struct tc_keypad - data structure used by keypad driver
  * @tc3589x:    pointer to tc35893
@@ -88,7 +86,7 @@ struct tc_keypad {
        const struct tc3589x_keypad_platform_data *board;
        unsigned int krow;
        unsigned int kcol;
-       unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE];
+       unsigned short *keymap;
        bool keypad_stopped;
 };
 
@@ -338,12 +336,14 @@ static int tc3589x_keypad_probe(struct platform_device *pdev)
 
        error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
                                           TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL,
-                                          keypad->keymap, input);
+                                          NULL, input);
        if (error) {
                dev_err(&pdev->dev, "Failed to build keymap\n");
                goto err_free_mem;
        }
 
+       keypad->keymap = input->keycode;
+
        input_set_capability(input, EV_MSC, MSC_SCAN);
        if (!plat->no_autorepeat)
                __set_bit(EV_REP, input->evbit);
index 2e3334b8f82d29ba96e38d6d985f1f9cfbdacf62..770479df865742a3c0d2beaa58291945f6501868 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/time.h>
 #include <linux/miscdevice.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/poll.h>
 #include <linux/rtc.h>
 #include <linux/mutex.h>
@@ -74,9 +75,6 @@ static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait);
 static int hp_sdc_rtc_open(struct inode *inode, struct file *file);
 static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on);
 
-static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
-                               int count, int *eof, void *data);
-
 static void hp_sdc_rtc_isr (int irq, void *dev_id, 
                            uint8_t status, uint8_t data) 
 {
@@ -427,22 +425,19 @@ static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on)
         return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue);
 }
 
-static int hp_sdc_rtc_proc_output (char *buf)
+static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v)
 {
 #define YN(bit) ("no")
 #define NY(bit) ("yes")
-        char *p;
         struct rtc_time tm;
        struct timeval tv;
 
        memset(&tm, 0, sizeof(struct rtc_time));
 
-       p = buf;
-
        if (hp_sdc_rtc_read_bbrtc(&tm)) {
-               p += sprintf(p, "BBRTC\t\t: READ FAILED!\n");
+               seq_puts(m, "BBRTC\t\t: READ FAILED!\n");
        } else {
-               p += sprintf(p,
+               seq_printf(m,
                             "rtc_time\t: %02d:%02d:%02d\n"
                             "rtc_date\t: %04d-%02d-%02d\n"
                             "rtc_epoch\t: %04lu\n",
@@ -452,41 +447,41 @@ static int hp_sdc_rtc_proc_output (char *buf)
        }
 
        if (hp_sdc_rtc_read_rt(&tv)) {
-               p += sprintf(p, "i8042 rtc\t: READ FAILED!\n");
+               seq_puts(m, "i8042 rtc\t: READ FAILED!\n");
        } else {
-               p += sprintf(p, "i8042 rtc\t: %ld.%02d seconds\n", 
+               seq_printf(m, "i8042 rtc\t: %ld.%02d seconds\n", 
                             tv.tv_sec, (int)tv.tv_usec/1000);
        }
 
        if (hp_sdc_rtc_read_fhs(&tv)) {
-               p += sprintf(p, "handshake\t: READ FAILED!\n");
+               seq_puts(m, "handshake\t: READ FAILED!\n");
        } else {
-               p += sprintf(p, "handshake\t: %ld.%02d seconds\n", 
+               seq_printf(m, "handshake\t: %ld.%02d seconds\n", 
                             tv.tv_sec, (int)tv.tv_usec/1000);
        }
 
        if (hp_sdc_rtc_read_mt(&tv)) {
-               p += sprintf(p, "alarm\t\t: READ FAILED!\n");
+               seq_puts(m, "alarm\t\t: READ FAILED!\n");
        } else {
-               p += sprintf(p, "alarm\t\t: %ld.%02d seconds\n", 
+               seq_printf(m, "alarm\t\t: %ld.%02d seconds\n", 
                             tv.tv_sec, (int)tv.tv_usec/1000);
        }
 
        if (hp_sdc_rtc_read_dt(&tv)) {
-               p += sprintf(p, "delay\t\t: READ FAILED!\n");
+               seq_puts(m, "delay\t\t: READ FAILED!\n");
        } else {
-               p += sprintf(p, "delay\t\t: %ld.%02d seconds\n", 
+               seq_printf(m, "delay\t\t: %ld.%02d seconds\n", 
                             tv.tv_sec, (int)tv.tv_usec/1000);
        }
 
        if (hp_sdc_rtc_read_ct(&tv)) {
-               p += sprintf(p, "periodic\t: READ FAILED!\n");
+               seq_puts(m, "periodic\t: READ FAILED!\n");
        } else {
-               p += sprintf(p, "periodic\t: %ld.%02d seconds\n", 
+               seq_printf(m, "periodic\t: %ld.%02d seconds\n", 
                             tv.tv_sec, (int)tv.tv_usec/1000);
        }
 
-        p += sprintf(p,
+        seq_printf(m,
                      "DST_enable\t: %s\n"
                      "BCD\t\t: %s\n"
                      "24hr\t\t: %s\n"
@@ -506,23 +501,23 @@ static int hp_sdc_rtc_proc_output (char *buf)
                      1UL,
                      1 ? "okay" : "dead");
 
-        return  p - buf;
+        return 0;
 #undef YN
 #undef NY
 }
 
-static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+static int hp_sdc_rtc_proc_open(struct inode *inode, struct file *file)
 {
-       int len = hp_sdc_rtc_proc_output (page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
+       return single_open(file, hp_sdc_rtc_proc_show, NULL);
 }
 
+static const struct file_operations hp_sdc_rtc_proc_fops = {
+       .open           = hp_sdc_rtc_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static int hp_sdc_rtc_ioctl(struct file *file, 
                            unsigned int cmd, unsigned long arg)
 {
@@ -715,8 +710,7 @@ static int __init hp_sdc_rtc_init(void)
        if (misc_register(&hp_sdc_rtc_dev) != 0)
                printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n");
 
-        create_proc_read_entry ("driver/rtc", 0, NULL,
-                               hp_sdc_rtc_read_proc, NULL);
+        proc_create("driver/rtc", 0, NULL, &hp_sdc_rtc_proc_fops);
 
        printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded "
                         "(RTC v " RTC_VERSION ")\n");
index 7b99fc7c9438dbcbcc115248403e4b9704611f29..0238e0e143350a3254e07bf0f73e035e2b3cef57 100644 (file)
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
        f->y_map |= (p[5] & 0x20) << 6;
 }
 
+static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
+{
+       f->first_mp = !!(p[0] & 0x02);
+       f->is_mp = !!(p[0] & 0x20);
+
+       f->fingers = ((p[0] & 0x6) >> 1 |
+                    (p[0] & 0x10) >> 2);
+       f->x_map = ((p[2] & 0x60) >> 5) |
+                  ((p[4] & 0x7f) << 2) |
+                  ((p[5] & 0x7f) << 9) |
+                  ((p[3] & 0x07) << 16) |
+                  ((p[3] & 0x70) << 15) |
+                  ((p[0] & 0x01) << 22);
+       f->y_map = (p[1] & 0x7f) |
+                  ((p[2] & 0x1f) << 7);
+
+       f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
+       f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
+       f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
+
+       alps_decode_buttons_v3(f, p);
+}
+
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
 {
        struct alps_data *priv = psmouse->private;
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
        }
 
        /* Bytes 2 - pktsize should have 0 in the highest bit */
-       if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
+       if (priv->proto_version != ALPS_PROTO_V5 &&
+           psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
            (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
                psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
                            psmouse->pktcnt - 1,
@@ -994,8 +1018,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
        return 0;
 }
 
-static int alps_enter_command_mode(struct psmouse *psmouse,
-                                  unsigned char *resp)
+static int alps_enter_command_mode(struct psmouse *psmouse)
 {
        unsigned char param[4];
 
@@ -1004,14 +1027,12 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
                return -1;
        }
 
-       if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
+       if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
+           param[0] != 0x73) {
                psmouse_dbg(psmouse,
                            "unknown response while entering command mode\n");
                return -1;
        }
-
-       if (resp)
-               *resp = param[2];
        return 0;
 }
 
@@ -1176,7 +1197,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse,
 {
        int reg_val, ret = -1;
 
-       if (alps_enter_command_mode(psmouse, NULL))
+       if (alps_enter_command_mode(psmouse))
                return -1;
 
        reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
@@ -1216,7 +1237,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
 {
        int ret = -EIO, reg_val;
 
-       if (alps_enter_command_mode(psmouse, NULL))
+       if (alps_enter_command_mode(psmouse))
                goto error;
 
        reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
@@ -1279,7 +1300,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
                 * supported by this driver. If bit 1 isn't set the packet
                 * format is different.
                 */
-               if (alps_enter_command_mode(psmouse, NULL) ||
+               if (alps_enter_command_mode(psmouse) ||
                    alps_command_mode_write_reg(psmouse,
                                                reg_base + 0x08, 0x82) ||
                    alps_exit_command_mode(psmouse))
@@ -1306,7 +1327,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
            alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
                goto error;
 
-       if (alps_enter_command_mode(psmouse, NULL) ||
+       if (alps_enter_command_mode(psmouse) ||
            alps_absolute_mode_v3(psmouse)) {
                psmouse_err(psmouse, "Failed to enter absolute mode\n");
                goto error;
@@ -1381,7 +1402,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
                        priv->flags &= ~ALPS_DUALPOINT;
        }
 
-       if (alps_enter_command_mode(psmouse, NULL) ||
+       if (alps_enter_command_mode(psmouse) ||
            alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
            alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
                goto error;
@@ -1431,7 +1452,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse)
        struct ps2dev *ps2dev = &psmouse->ps2dev;
        unsigned char param[4];
 
-       if (alps_enter_command_mode(psmouse, NULL))
+       if (alps_enter_command_mode(psmouse))
                goto error;
 
        if (alps_absolute_mode_v4(psmouse)) {
@@ -1499,6 +1520,23 @@ error:
        return -1;
 }
 
+static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       unsigned char param[2];
+
+       /* This is dolphin "v1" as empirically defined by florin9doi */
+       param[0] = 0x64;
+       param[1] = 0x28;
+
+       if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+           ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
+           ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
+               return -1;
+
+       return 0;
+}
+
 static void alps_set_defaults(struct alps_data *priv)
 {
        priv->byte0 = 0x8f;
@@ -1532,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
                priv->nibble_commands = alps_v4_nibble_commands;
                priv->addr_command = PSMOUSE_CMD_DISABLE;
                break;
+       case ALPS_PROTO_V5:
+               priv->hw_init = alps_hw_init_dolphin_v1;
+               priv->process_packet = alps_process_packet_v3;
+               priv->decode_fields = alps_decode_dolphin;
+               priv->set_abs_params = alps_set_abs_params_mt;
+               priv->nibble_commands = alps_v3_nibble_commands;
+               priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
+               priv->byte0 = 0xc8;
+               priv->mask0 = 0xc8;
+               priv->flags = 0;
+               priv->x_max = 1360;
+               priv->y_max = 660;
+               priv->x_bits = 23;
+               priv->y_bits = 12;
+               break;
        }
 }
 
@@ -1591,6 +1644,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
                return -EIO;
 
        if (alps_match_table(psmouse, priv, e7, ec) == 0) {
+               return 0;
+       } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
+                  ec[0] == 0x73 && ec[1] == 0x01) {
+               priv->proto_version = ALPS_PROTO_V5;
+               alps_set_defaults(priv);
+
                return 0;
        } else if (ec[0] == 0x88 && ec[1] == 0x08) {
                priv->proto_version = ALPS_PROTO_V3;
index 970480551b6e67e540fdb76b2865e8dd573d550a..eee59853b9ce0c21bc755c206430911e15789964 100644 (file)
@@ -16,6 +16,7 @@
 #define ALPS_PROTO_V2  2
 #define ALPS_PROTO_V3  3
 #define ALPS_PROTO_V4  4
+#define ALPS_PROTO_V5  5
 
 /**
  * struct alps_model_info - touchpad ID table
index 1673dc6c8092b9697e95d2c5dc4beeffa92852f6..f51765fff0545e91be567942255cf19532f94a71 100644 (file)
@@ -236,6 +236,13 @@ static int cypress_read_fw_version(struct psmouse *psmouse)
        cytp->fw_version = param[2] & FW_VERSION_MASX;
        cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0;
 
+       /*
+        * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to
+        * CYTP_CMD_READ_TP_METRICS so do not try to use it. LP: #1103594.
+        */
+       if (cytp->fw_version >= 11)
+               cytp->tp_metrics_supported = 0;
+
        psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version);
        psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n",
                 cytp->tp_metrics_supported);
@@ -258,6 +265,9 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse)
        cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width;
        cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high;
 
+       if (!cytp->tp_metrics_supported)
+               return 0;
+
        memset(param, 0, sizeof(param));
        if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) {
                /* Update trackpad parameters. */
@@ -315,18 +325,15 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse)
 
 static int cypress_query_hardware(struct psmouse *psmouse)
 {
-       struct cytp_data *cytp = psmouse->private;
        int ret;
 
        ret = cypress_read_fw_version(psmouse);
        if (ret)
                return ret;
 
-       if (cytp->tp_metrics_supported) {
-               ret = cypress_read_tp_metrics(psmouse);
-               if (ret)
-                       return ret;
-       }
+       ret = cypress_read_tp_metrics(psmouse);
+       if (ret)
+               return ret;
 
        return 0;
 }
index 41b6fbf601122b26500c397d24e34f9789286f81..1daa97913b7d20068845865a405387404fffe1d8 100644 (file)
@@ -2017,6 +2017,9 @@ static const struct wacom_features wacom_features_0x100 =
 static const struct wacom_features wacom_features_0x101 =
        { "Wacom ISDv4 101",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
          0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x10D =
+       { "Wacom ISDv4 10D",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
+         0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0x4001 =
        { "Wacom ISDv4 4001",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
          0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2201,6 +2204,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xEF) },
        { USB_DEVICE_WACOM(0x100) },
        { USB_DEVICE_WACOM(0x101) },
+       { USB_DEVICE_WACOM(0x10D) },
        { USB_DEVICE_WACOM(0x4001) },
        { USB_DEVICE_WACOM(0x47) },
        { USB_DEVICE_WACOM(0xF4) },
index 4f702b3ec1a3f1f9e4210d4e666c5be1beea8801..434c3df250caa3bc0a058a890e6b64f9bd78b450 100644 (file)
@@ -236,7 +236,12 @@ static void __ads7846_disable(struct ads7846 *ts)
 /* Must be called with ts->lock held */
 static void __ads7846_enable(struct ads7846 *ts)
 {
-       regulator_enable(ts->reg);
+       int error;
+
+       error = regulator_enable(ts->reg);
+       if (error != 0)
+               dev_err(&ts->spi->dev, "Failed to enable supply: %d\n", error);
+
        ads7846_restart(ts);
 }
 
index d04f810cb1ddf8d617f1a77e7aa8d6d8657a6ca8..59aa24002c7bff9e1f8629787c7c0ce9eea36886 100644 (file)
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE         0xa5
 #define MXT_BACKUP_VALUE       0x55
-#define MXT_BACKUP_TIME                25      /* msec */
-#define MXT_RESET_TIME         65      /* msec */
+#define MXT_BACKUP_TIME                50      /* msec */
+#define MXT_RESET_TIME         200     /* msec */
 
 #define MXT_FWRESET_TIME       175     /* msec */
 
+/* MXT_SPT_GPIOPWM_T19 field */
+#define MXT_GPIO0_MASK         0x04
+#define MXT_GPIO1_MASK         0x08
+#define MXT_GPIO2_MASK         0x10
+#define MXT_GPIO3_MASK         0x20
+
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB     0xaa
 #define MXT_UNLOCK_CMD_LSB     0xdc
 /* Touchscreen absolute values */
 #define MXT_MAX_AREA           0xff
 
+#define MXT_PIXELS_PER_MM      20
+
 struct mxt_info {
        u8 family_id;
        u8 variant_id;
@@ -243,6 +251,8 @@ struct mxt_data {
        const struct mxt_platform_data *pdata;
        struct mxt_object *object_table;
        struct mxt_info info;
+       bool is_tp;
+
        unsigned int irq;
        unsigned int max_x;
        unsigned int max_y;
@@ -251,6 +261,7 @@ struct mxt_data {
        u8 T6_reportid;
        u8 T9_reportid_min;
        u8 T9_reportid_max;
+       u8 T19_reportid;
 };
 
 static bool mxt_object_readable(unsigned int type)
@@ -502,6 +513,21 @@ static int mxt_write_object(struct mxt_data *data,
        return mxt_write_reg(data->client, reg + offset, val);
 }
 
+static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
+{
+       struct input_dev *input = data->input_dev;
+       bool button;
+       int i;
+
+       /* Active-low switch */
+       for (i = 0; i < MXT_NUM_GPIO; i++) {
+               if (data->pdata->key_map[i] == KEY_RESERVED)
+                       continue;
+               button = !(message->message[0] & MXT_GPIO0_MASK << i);
+               input_report_key(input, data->pdata->key_map[i], button);
+       }
+}
+
 static void mxt_input_touchevent(struct mxt_data *data,
                                      struct mxt_message *message, int id)
 {
@@ -585,6 +611,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
                        int id = reportid - data->T9_reportid_min;
                        mxt_input_touchevent(data, &message, id);
                        update_input = true;
+               } else if (message.reportid == data->T19_reportid) {
+                       mxt_input_button(data, &message);
+                       update_input = true;
                } else {
                        mxt_dump_message(dev, &message);
                }
@@ -764,6 +793,9 @@ static int mxt_get_object_table(struct mxt_data *data)
                        data->T9_reportid_min = min_id;
                        data->T9_reportid_max = max_id;
                        break;
+               case MXT_SPT_GPIOPWM_T19:
+                       data->T19_reportid = min_id;
+                       break;
                }
        }
 
@@ -777,7 +809,7 @@ static void mxt_free_object_table(struct mxt_data *data)
        data->T6_reportid = 0;
        data->T9_reportid_min = 0;
        data->T9_reportid_max = 0;
-
+       data->T19_reportid = 0;
 }
 
 static int mxt_initialize(struct mxt_data *data)
@@ -1115,9 +1147,13 @@ static int mxt_probe(struct i2c_client *client,
                goto err_free_mem;
        }
 
-       input_dev->name = "Atmel maXTouch Touchscreen";
+       data->is_tp = pdata && pdata->is_tp;
+
+       input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
+                                         "Atmel maXTouch Touchscreen";
        snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
                 client->adapter->nr, client->addr);
+
        input_dev->phys = data->phys;
 
        input_dev->id.bustype = BUS_I2C;
@@ -1140,6 +1176,29 @@ static int mxt_probe(struct i2c_client *client,
        __set_bit(EV_KEY, input_dev->evbit);
        __set_bit(BTN_TOUCH, input_dev->keybit);
 
+       if (data->is_tp) {
+               int i;
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+               __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+
+               for (i = 0; i < MXT_NUM_GPIO; i++)
+                       if (pdata->key_map[i] != KEY_RESERVED)
+                               __set_bit(pdata->key_map[i], input_dev->keybit);
+
+               __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+               __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+               __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+               __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
+               __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
+
+               input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
+               input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
+               input_abs_set_res(input_dev, ABS_MT_POSITION_X,
+                                 MXT_PIXELS_PER_MM);
+               input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
+                                 MXT_PIXELS_PER_MM);
+       }
+
        /* For single touch */
        input_set_abs_params(input_dev, ABS_X,
                             0, data->max_x, 0, 0);
@@ -1258,6 +1317,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
 static const struct i2c_device_id mxt_id[] = {
        { "qt602240_ts", 0 },
        { "atmel_mxt_ts", 0 },
+       { "atmel_mxt_tp", 0 },
        { "mXT224", 0 },
        { }
 };
index 4a29ddf6bf1e9a9bfed9a1afcc8cba810e66800c..1443532fe6c4d112f15a317d598ddc4f4dc78fb5 100644 (file)
@@ -314,15 +314,27 @@ static int mms114_start(struct mms114_data *data)
        struct i2c_client *client = data->client;
        int error;
 
-       if (data->core_reg)
-               regulator_enable(data->core_reg);
-       if (data->io_reg)
-               regulator_enable(data->io_reg);
+       error = regulator_enable(data->core_reg);
+       if (error) {
+               dev_err(&client->dev, "Failed to enable avdd: %d\n", error);
+               return error;
+       }
+
+       error = regulator_enable(data->io_reg);
+       if (error) {
+               dev_err(&client->dev, "Failed to enable vdd: %d\n", error);
+               regulator_disable(data->core_reg);
+               return error;
+       }
+
        mdelay(MMS114_POWERON_DELAY);
 
        error = mms114_setup_regs(data);
-       if (error < 0)
+       if (error < 0) {
+               regulator_disable(data->io_reg);
+               regulator_disable(data->core_reg);
                return error;
+       }
 
        if (data->pdata->cfg_pin)
                data->pdata->cfg_pin(true);
@@ -335,16 +347,20 @@ static int mms114_start(struct mms114_data *data)
 static void mms114_stop(struct mms114_data *data)
 {
        struct i2c_client *client = data->client;
+       int error;
 
        disable_irq(client->irq);
 
        if (data->pdata->cfg_pin)
                data->pdata->cfg_pin(false);
 
-       if (data->io_reg)
-               regulator_disable(data->io_reg);
-       if (data->core_reg)
-               regulator_disable(data->core_reg);
+       error = regulator_disable(data->io_reg);
+       if (error)
+               dev_warn(&client->dev, "Failed to disable vdd: %d\n", error);
+
+       error = regulator_disable(data->core_reg);
+       if (error)
+               dev_warn(&client->dev, "Failed to disable avdd: %d\n", error);
 }
 
 static int mms114_input_open(struct input_dev *dev)
index dc7e478b7e5f88443e059a1afeca4b57b6e778a4..e5cdaf87822c3a5e53b07feedb47c33ffc5d2d09 100644 (file)
@@ -1083,6 +1083,7 @@ static const char *dma_remap_fault_reasons[] =
        "non-zero reserved fields in RTP",
        "non-zero reserved fields in CTP",
        "non-zero reserved fields in PTE",
+       "PCE for translation request specifies blocking",
 };
 
 static const char *irq_remap_fault_reasons[] =
index 644d724684232d9b389fcc056f78aaab1e155817..a32e0d5aa45f43eb71c91ab9020696436212ae95 100644 (file)
@@ -648,7 +648,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 
        /* Convert our logical CPU mask into a physical one. */
        for_each_cpu(cpu, mask)
-               map |= 1 << cpu_logical_map(cpu);
+               map |= gic_cpu_map[cpu];
 
        /*
         * Ensure that stores to Normal memory are visible to the
index 03a0a01a405451c8a85e0e9b83647c105a710f53..3286903a95d26a19d548dc7854c336f1ead2628f 100644 (file)
@@ -2334,7 +2334,7 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
 
 static int gigaset_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, gigaset_proc_show, PDE(inode)->data);
+       return single_open(file, gigaset_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations gigaset_proc_fops = {
index 821f7ac33b37f18febd2f8677e7e8dca4187f01e..4d9b195547c5cc253b827c7c6d79d036612e43f6 100644 (file)
@@ -702,7 +702,7 @@ static int b1ctl_proc_show(struct seq_file *m, void *v)
 
 static int b1ctl_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, b1ctl_proc_show, PDE(inode)->data);
+       return single_open(file, b1ctl_proc_show, PDE_DATA(inode));
 }
 
 const struct file_operations b1ctl_proc_fops = {
index 0896aa86fc08732dab2f2641b699dee31a1c0350..19b113faeb7b826b9f57e9ae103ad434ddca43b7 100644 (file)
@@ -944,7 +944,7 @@ static int b1dmactl_proc_show(struct seq_file *m, void *v)
 
 static int b1dmactl_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, b1dmactl_proc_show, PDE(inode)->data);
+       return single_open(file, b1dmactl_proc_show, PDE_DATA(inode));
 }
 
 const struct file_operations b1dmactl_proc_fops = {
index 1d7fc44e3eeffcbf5137592a270b31ad02de43fb..5d00d72fe482f1300c702efa98bf720e8bfe084f 100644 (file)
@@ -1129,7 +1129,7 @@ static int c4_proc_show(struct seq_file *m, void *v)
 
 static int c4_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, c4_proc_show, PDE(inode)->data);
+       return single_open(file, c4_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations c4_proc_fops = {
index 3a4165c611967e2518f6689b616db1c0976ac394..56ce98a4e24802c9c5a89311da18ed7807954302 100644 (file)
@@ -145,7 +145,7 @@ void remove_divas_proc(void)
 static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
                                  size_t count, loff_t *pos)
 {
-       diva_os_xdi_adapter_t *a = PDE(file_inode(file))->data;
+       diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file));
        PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
        if ((count == 1) || (count == 2)) {
@@ -172,7 +172,7 @@ static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
 static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer,
                                    size_t count, loff_t *pos)
 {
-       diva_os_xdi_adapter_t *a = PDE(file_inode(file))->data;
+       diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file));
        PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
        if ((count == 1) || (count == 2)) {
@@ -210,7 +210,7 @@ static int d_l1_down_proc_show(struct seq_file *m, void *v)
 
 static int d_l1_down_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, d_l1_down_proc_show, PDE(inode)->data);
+       return single_open(file, d_l1_down_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations d_l1_down_proc_fops = {
@@ -236,7 +236,7 @@ static int grp_opt_proc_show(struct seq_file *m, void *v)
 
 static int grp_opt_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, grp_opt_proc_show, PDE(inode)->data);
+       return single_open(file, grp_opt_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations grp_opt_proc_fops = {
@@ -251,7 +251,7 @@ static const struct file_operations grp_opt_proc_fops = {
 static ssize_t info_proc_write(struct file *file, const char __user *buffer,
                               size_t count, loff_t *pos)
 {
-       diva_os_xdi_adapter_t *a = PDE(file_inode(file))->data;
+       diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file));
        PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
        char c[4];
 
@@ -335,7 +335,7 @@ static int info_proc_show(struct seq_file *m, void *v)
 
 static int info_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, info_proc_show, PDE(inode)->data);
+       return single_open(file, info_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations info_proc_fops = {
index 5313c9ea44dc906acc7ce2069693bbc94c5be260..d9edcc94c2a878d2636f49ed7e7b682838749266 100644 (file)
@@ -237,7 +237,8 @@ config HISAX_MIC
 
 config HISAX_NETJET
        bool "NETjet card"
-       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
+       depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
+       depends on VIRT_TO_BUS
        help
          This enables HiSax support for the NetJet from Traverse
          Technologies.
@@ -248,7 +249,8 @@ config HISAX_NETJET
 
 config HISAX_NETJET_U
        bool "NETspider U card"
-       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
+       depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
+       depends on VIRT_TO_BUS
        help
          This enables HiSax support for the Netspider U interface ISDN card
          from Traverse Technologies.
index 017c67ea3f4c7681ef5fb0fbd66b7009b89ed14d..ead0a4fb7448643faa66cb8c3fceee3c2b62d9fd 100644 (file)
@@ -294,13 +294,13 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
        // Allocate URBs and buffers for interrupt endpoint
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb) {
-               return -ENOMEM;
+               goto err1;
        }
        intr->urb = urb;
 
        buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL);
        if (!buf) {
-               return -ENOMEM;
+               goto err2;
        }
 
        endpoint = &altsetting->endpoint[EP_INT-1];
@@ -313,6 +313,14 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
                         endpoint->desc.bInterval);
 
        return 0;
+err2:
+       usb_free_urb(intr->urb);
+       intr->urb = NULL;
+err1:
+       usb_free_urb(ctrl->urb);
+       ctrl->urb = NULL;
+
+       return -ENOMEM;
 }
 
 /*
index 931f916c9c235d33c753a3e8fda8ec6c7aea6eb5..00aad10507d8a05710b5955cb47f1c4c97612fd4 100644 (file)
@@ -469,7 +469,7 @@ static int hycapi_proc_show(struct seq_file *m, void *v)
 
 static int hycapi_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, hycapi_proc_show, PDE(inode)->data);
+       return single_open(file, hycapi_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations hycapi_proc_fops = {
index 8023d2510fbaba2f6bc80bd291bc6cf56ef566f2..73079213ec94611a8fed1677c887e5c3794f4d72 100644 (file)
@@ -229,23 +229,12 @@ static int
 hysdn_conf_open(struct inode *ino, struct file *filep)
 {
        hysdn_card *card;
-       struct proc_dir_entry *pd;
        struct conf_writedata *cnf;
        char *cp, *tmp;
 
        /* now search the addressed card */
        mutex_lock(&hysdn_conf_mutex);
-       card = card_root;
-       while (card) {
-               pd = card->procconf;
-               if (pd == PDE(ino))
-                       break;
-               card = card->next;      /* search next entry */
-       }
-       if (!card) {
-               mutex_unlock(&hysdn_conf_mutex);
-               return (-ENODEV);       /* device is unknown/invalid */
-       }
+       card = PDE_DATA(ino);
        if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
                hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x",
                             filep->f_cred->fsuid, filep->f_cred->fsgid,
@@ -317,21 +306,9 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
        hysdn_card *card;
        struct conf_writedata *cnf;
        int retval = 0;
-       struct proc_dir_entry *pd;
 
        mutex_lock(&hysdn_conf_mutex);
-       /* search the addressed card */
-       card = card_root;
-       while (card) {
-               pd = card->procconf;
-               if (pd == PDE(ino))
-                       break;
-               card = card->next;      /* search next entry */
-       }
-       if (!card) {
-               mutex_unlock(&hysdn_conf_mutex);
-               return (-ENODEV);       /* device is unknown/invalid */
-       }
+       card = PDE_DATA(ino);
        if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
                hysdn_addlog(card, "config close for uid=%d gid=%d mode=0x%x",
                             filep->f_cred->fsuid, filep->f_cred->fsgid,
@@ -394,10 +371,11 @@ hysdn_procconf_init(void)
        while (card) {
 
                sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
-               if ((card->procconf = (void *) proc_create(conf_name,
+               if ((card->procconf = (void *) proc_create_data(conf_name,
                                                           S_IFREG | S_IRUGO | S_IWUSR,
                                                           hysdn_proc_entry,
-                                                          &conf_fops)) != NULL) {
+                                                          &conf_fops,
+                                                          card)) != NULL) {
                        hysdn_proclog_init(card);       /* init the log file entry */
                }
                card = card->next;      /* next entry */
index 9a3ce93665c5e09b56ad9f633b036f264e8681f5..b61e8d5e84ad022e566f5bfa191ddcb392f3df7b 100644 (file)
@@ -173,27 +173,14 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
        struct log_data *inf;
        int len;
-       struct proc_dir_entry *pde = PDE(file_inode(file));
-       struct procdata *pd = NULL;
-       hysdn_card *card;
+       hysdn_card *card = PDE_DATA(file_inode(file));
 
        if (!*((struct log_data **) file->private_data)) {
+               struct procdata *pd = card->proclog;
                if (file->f_flags & O_NONBLOCK)
                        return (-EAGAIN);
 
-               /* sorry, but we need to search the card */
-               card = card_root;
-               while (card) {
-                       pd = card->proclog;
-                       if (pd->log == pde)
-                               break;
-                       card = card->next;      /* search next entry */
-               }
-               if (card)
-                       interruptible_sleep_on(&(pd->rd_queue));
-               else
-                       return (-EAGAIN);
-
+               interruptible_sleep_on(&(pd->rd_queue));
        }
        if (!(inf = *((struct log_data **) file->private_data)))
                return (0);
@@ -215,27 +202,15 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 static int
 hysdn_log_open(struct inode *ino, struct file *filep)
 {
-       hysdn_card *card;
-       struct procdata *pd = NULL;
-       unsigned long flags;
+       hysdn_card *card = PDE_DATA(ino);
 
        mutex_lock(&hysdn_log_mutex);
-       card = card_root;
-       while (card) {
-               pd = card->proclog;
-               if (pd->log == PDE(ino))
-                       break;
-               card = card->next;      /* search next entry */
-       }
-       if (!card) {
-               mutex_unlock(&hysdn_log_mutex);
-               return (-ENODEV);       /* device is unknown/invalid */
-       }
-       filep->private_data = card;     /* remember our own card */
-
        if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
                /* write only access -> write log level only */
+               filep->private_data = card;     /* remember our own card */
        } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
+               struct procdata *pd = card->proclog;
+               unsigned long flags;
 
                /* read access -> log/debug read */
                spin_lock_irqsave(&card->hysdn_lock, flags);
@@ -275,21 +250,13 @@ hysdn_log_close(struct inode *ino, struct file *filep)
        } else {
                /* read access -> log/debug read, mark one further file as closed */
 
-               pd = NULL;
                inf = *((struct log_data **) filep->private_data);      /* get first log entry */
                if (inf)
                        pd = (struct procdata *) inf->proc_ctrl;        /* still entries there */
                else {
                        /* no info available -> search card */
-                       card = card_root;
-                       while (card) {
-                               pd = card->proclog;
-                               if (pd->log == PDE(ino))
-                                       break;
-                               card = card->next;      /* search next entry */
-                       }
-                       if (card)
-                               pd = card->proclog;     /* pointer to procfs log */
+                       card = PDE_DATA(file_inode(filep));
+                       pd = card->proclog;     /* pointer to procfs log */
                }
                if (pd)
                        pd->if_used--;  /* decrement interface usage count by one */
@@ -319,24 +286,12 @@ static unsigned int
 hysdn_log_poll(struct file *file, poll_table *wait)
 {
        unsigned int mask = 0;
-       struct proc_dir_entry *pde = PDE(file_inode(file));
-       hysdn_card *card;
-       struct procdata *pd = NULL;
+       hysdn_card *card = PDE_DATA(file_inode(file));
+       struct procdata *pd = card->proclog;
 
        if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE)
                return (mask);  /* no polling for write supported */
 
-       /* we need to search the card */
-       card = card_root;
-       while (card) {
-               pd = card->proclog;
-               if (pd->log == pde)
-                       break;
-               card = card->next;      /* search next entry */
-       }
-       if (!card)
-               return (mask);  /* card not found */
-
        poll_wait(file, &(pd->rd_queue), wait);
 
        if (*((struct log_data **) file->private_data))
@@ -373,9 +328,9 @@ hysdn_proclog_init(hysdn_card *card)
 
        if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
                sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
-               pd->log = proc_create(pd->log_name,
+               pd->log = proc_create_data(pd->log_name,
                                      S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry,
-                                     &log_fops);
+                                     &log_fops, card);
 
                init_waitqueue_head(&(pd->rd_queue));
 
index d8a7d832341436ce62e1dfaacc6b6578ab79e224..ebaebdf30f98dce768d187a7e471ab6455604bd3 100644 (file)
@@ -902,7 +902,9 @@ isdn_tty_send_msg(modem_info *info, atemu *m, char *msg)
        int j;
        int l;
 
-       l = strlen(msg);
+       l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg)
+               + sizeof(cmd.parm.cmsg.para) - 2);
+
        if (!l) {
                isdn_tty_modem_result(RESULT_ERROR, info);
                return;
index 1094667d8f31aa7f920e9f8f778720f060c950dd..9438d7ec33080a442f140745e951ac5f01bf3b63 100644 (file)
@@ -64,7 +64,6 @@ mISDN_open(struct inode *ino, struct file *filep)
        dev->work = 0;
        init_waitqueue_head(&dev->wait);
        filep->private_data = dev;
-       __module_get(THIS_MODULE);
        return nonseekable_open(ino, filep);
 }
 
@@ -72,19 +71,28 @@ static int
 mISDN_close(struct inode *ino, struct file *filep)
 {
        struct mISDNtimerdev    *dev = filep->private_data;
+       struct list_head        *list = &dev->pending;
        struct mISDNtimer       *timer, *next;
 
        if (*debug & DEBUG_TIMER)
                printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
-       list_for_each_entry_safe(timer, next, &dev->pending, list) {
-               del_timer(&timer->tl);
+
+       spin_lock_irq(&dev->lock);
+       while (!list_empty(list)) {
+               timer = list_first_entry(list, struct mISDNtimer, list);
+               spin_unlock_irq(&dev->lock);
+               del_timer_sync(&timer->tl);
+               spin_lock_irq(&dev->lock);
+               /* it might have been moved to ->expired */
+               list_del(&timer->list);
                kfree(timer);
        }
+       spin_unlock_irq(&dev->lock);
+
        list_for_each_entry_safe(timer, next, &dev->expired, list) {
                kfree(timer);
        }
        kfree(dev);
-       module_put(THIS_MODULE);
        return 0;
 }
 
@@ -92,36 +100,41 @@ static ssize_t
 mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)
 {
        struct mISDNtimerdev    *dev = filep->private_data;
+       struct list_head *list = &dev->expired;
        struct mISDNtimer       *timer;
-       u_long  flags;
        int     ret = 0;
 
        if (*debug & DEBUG_TIMER)
                printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__,
                       filep, buf, (int)count, off);
 
-       if (list_empty(&dev->expired) && (dev->work == 0)) {
+       if (count < sizeof(int))
+               return -ENOSPC;
+
+       spin_lock_irq(&dev->lock);
+       while (list_empty(list) && (dev->work == 0)) {
+               spin_unlock_irq(&dev->lock);
                if (filep->f_flags & O_NONBLOCK)
                        return -EAGAIN;
                wait_event_interruptible(dev->wait, (dev->work ||
-                                                    !list_empty(&dev->expired)));
+                                                    !list_empty(list)));
                if (signal_pending(current))
                        return -ERESTARTSYS;
+               spin_lock_irq(&dev->lock);
        }
-       if (count < sizeof(int))
-               return -ENOSPC;
        if (dev->work)
                dev->work = 0;
-       if (!list_empty(&dev->expired)) {
-               spin_lock_irqsave(&dev->lock, flags);
-               timer = (struct mISDNtimer *)dev->expired.next;
+       if (!list_empty(list)) {
+               timer = list_first_entry(list, struct mISDNtimer, list);
                list_del(&timer->list);
-               spin_unlock_irqrestore(&dev->lock, flags);
+               spin_unlock_irq(&dev->lock);
                if (put_user(timer->id, (int __user *)buf))
                        ret = -EFAULT;
                else
                        ret = sizeof(int);
                kfree(timer);
+       } else {
+               spin_unlock_irq(&dev->lock);
        }
        return ret;
 }
@@ -153,7 +166,8 @@ dev_expire_timer(unsigned long data)
        u_long                  flags;
 
        spin_lock_irqsave(&timer->dev->lock, flags);
-       list_move_tail(&timer->list, &timer->dev->expired);
+       if (timer->id >= 0)
+               list_move_tail(&timer->list, &timer->dev->expired);
        spin_unlock_irqrestore(&timer->dev->lock, flags);
        wake_up_interruptible(&timer->dev->wait);
 }
@@ -162,7 +176,6 @@ static int
 misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
 {
        int                     id;
-       u_long                  flags;
        struct mISDNtimer       *timer;
 
        if (!timeout) {
@@ -173,19 +186,16 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
                timer = kzalloc(sizeof(struct mISDNtimer), GFP_KERNEL);
                if (!timer)
                        return -ENOMEM;
-               spin_lock_irqsave(&dev->lock, flags);
-               timer->id = dev->next_id++;
+               timer->dev = dev;
+               setup_timer(&timer->tl, dev_expire_timer, (long)timer);
+               spin_lock_irq(&dev->lock);
+               id = timer->id = dev->next_id++;
                if (dev->next_id < 0)
                        dev->next_id = 1;
                list_add_tail(&timer->list, &dev->pending);
-               spin_unlock_irqrestore(&dev->lock, flags);
-               timer->dev = dev;
-               timer->tl.data = (long)timer;
-               timer->tl.function = dev_expire_timer;
-               init_timer(&timer->tl);
                timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000);
                add_timer(&timer->tl);
-               id = timer->id;
+               spin_unlock_irq(&dev->lock);
        }
        return id;
 }
@@ -193,26 +203,21 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
 static int
 misdn_del_timer(struct mISDNtimerdev *dev, int id)
 {
-       u_long                  flags;
        struct mISDNtimer       *timer;
-       int                     ret = 0;
 
-       spin_lock_irqsave(&dev->lock, flags);
+       spin_lock_irq(&dev->lock);
        list_for_each_entry(timer, &dev->pending, list) {
                if (timer->id == id) {
                        list_del_init(&timer->list);
-                       /* RED-PEN AK: race -- timer can be still running on
-                        * other CPU. Needs reference count I think
-                        */
-                       del_timer(&timer->tl);
-                       ret = timer->id;
+                       timer->id = -1;
+                       spin_unlock_irq(&dev->lock);
+                       del_timer_sync(&timer->tl);
                        kfree(timer);
-                       goto unlock;
+                       return id;
                }
        }
-unlock:
-       spin_unlock_irqrestore(&dev->lock, flags);
-       return ret;
+       spin_unlock_irq(&dev->lock);
+       return 0;
 }
 
 static long
@@ -262,6 +267,7 @@ mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 }
 
 static const struct file_operations mISDN_fops = {
+       .owner          = THIS_MODULE,
        .read           = mISDN_read,
        .poll           = mISDN_poll,
        .unlocked_ioctl = mISDN_ioctl,
index 22b8ce4191ccd69d6b8740c61a71791efafd31bf..c31fbab6aa82f5561bd343caec3e183c09113236 100644 (file)
@@ -869,7 +869,7 @@ static int pmu_battery_proc_show(struct seq_file *m, void *v)
 
 static int pmu_battery_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pmu_battery_proc_show, PDE(inode)->data);
+       return single_open(file, pmu_battery_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations pmu_battery_proc_fops = {
index c45b3aedafba975f720a1ab422c764ef4fe1b0c4..d873cbae2fbb86acb6d9ad2ba02842d4144ac2b6 100644 (file)
@@ -138,8 +138,7 @@ int pl320_ipc_unregister_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier);
 
-static int __init pl320_probe(struct amba_device *adev,
-                               const struct amba_id *id)
+static int pl320_probe(struct amba_device *adev, const struct amba_id *id)
 {
        int ret;
 
index e30b490055aa8ce3ef3edf2229b6cd2724bf794a..4d8d90b4fe7812ea5169619d3945b0722d46f1ec 100644 (file)
@@ -154,17 +154,6 @@ config MD_RAID456
 
          If unsure, say Y.
 
-config MULTICORE_RAID456
-       bool "RAID-4/RAID-5/RAID-6 Multicore processing (EXPERIMENTAL)"
-       depends on MD_RAID456
-       depends on SMP
-       depends on EXPERIMENTAL
-       ---help---
-         Enable the raid456 module to dispatch per-stripe raid operations to a
-         thread pool.
-
-         If unsure, say N.
-
 config MD_MULTIPATH
        tristate "Multipath I/O support"
        depends on BLK_DEV_MD
index 3c955e10a618c2487422efa8063d1f9924a483cc..c6083132c4b8ccaf21c7addb61cf8596165bf915 100644 (file)
@@ -1025,6 +1025,8 @@ void dm_bufio_prefetch(struct dm_bufio_client *c,
 {
        struct blk_plug plug;
 
+       BUG_ON(dm_bufio_in_request());
+
        blk_start_plug(&plug);
        dm_bufio_lock(c);
 
index fbd3625f27480f2611d81eed181d13f11b3ab7a1..83e995fece88c1330335c85a23ef42b2ed54a1f4 100644 (file)
@@ -83,6 +83,8 @@ struct cache_disk_superblock {
        __le32 read_misses;
        __le32 write_hits;
        __le32 write_misses;
+
+       __le32 policy_version[CACHE_POLICY_VERSION_SIZE];
 } __packed;
 
 struct dm_cache_metadata {
@@ -109,6 +111,7 @@ struct dm_cache_metadata {
        bool clean_when_opened:1;
 
        char policy_name[CACHE_POLICY_NAME_SIZE];
+       unsigned policy_version[CACHE_POLICY_VERSION_SIZE];
        size_t policy_hint_size;
        struct dm_cache_statistics stats;
 };
@@ -268,7 +271,8 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
        memset(disk_super->uuid, 0, sizeof(disk_super->uuid));
        disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC);
        disk_super->version = cpu_to_le32(CACHE_VERSION);
-       memset(disk_super->policy_name, 0, CACHE_POLICY_NAME_SIZE);
+       memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
+       memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
        disk_super->policy_hint_size = 0;
 
        r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
@@ -284,7 +288,6 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
        disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
        disk_super->data_block_size = cpu_to_le32(cmd->data_block_size);
        disk_super->cache_blocks = cpu_to_le32(0);
-       memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
 
        disk_super->read_hits = cpu_to_le32(0);
        disk_super->read_misses = cpu_to_le32(0);
@@ -478,6 +481,9 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd,
        cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
        cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
        strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
+       cmd->policy_version[0] = le32_to_cpu(disk_super->policy_version[0]);
+       cmd->policy_version[1] = le32_to_cpu(disk_super->policy_version[1]);
+       cmd->policy_version[2] = le32_to_cpu(disk_super->policy_version[2]);
        cmd->policy_hint_size = le32_to_cpu(disk_super->policy_hint_size);
 
        cmd->stats.read_hits = le32_to_cpu(disk_super->read_hits);
@@ -572,6 +578,9 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
        disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
        disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
        strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
+       disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
+       disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
+       disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
 
        disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
        disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
@@ -854,18 +863,43 @@ struct thunk {
        bool hints_valid;
 };
 
+static bool policy_unchanged(struct dm_cache_metadata *cmd,
+                            struct dm_cache_policy *policy)
+{
+       const char *policy_name = dm_cache_policy_get_name(policy);
+       const unsigned *policy_version = dm_cache_policy_get_version(policy);
+       size_t policy_hint_size = dm_cache_policy_get_hint_size(policy);
+
+       /*
+        * Ensure policy names match.
+        */
+       if (strncmp(cmd->policy_name, policy_name, sizeof(cmd->policy_name)))
+               return false;
+
+       /*
+        * Ensure policy major versions match.
+        */
+       if (cmd->policy_version[0] != policy_version[0])
+               return false;
+
+       /*
+        * Ensure policy hint sizes match.
+        */
+       if (cmd->policy_hint_size != policy_hint_size)
+               return false;
+
+       return true;
+}
+
 static bool hints_array_initialized(struct dm_cache_metadata *cmd)
 {
        return cmd->hint_root && cmd->policy_hint_size;
 }
 
 static bool hints_array_available(struct dm_cache_metadata *cmd,
-                                 const char *policy_name)
+                                 struct dm_cache_policy *policy)
 {
-       bool policy_names_match = !strncmp(cmd->policy_name, policy_name,
-                                          sizeof(cmd->policy_name));
-
-       return cmd->clean_when_opened && policy_names_match &&
+       return cmd->clean_when_opened && policy_unchanged(cmd, policy) &&
                hints_array_initialized(cmd);
 }
 
@@ -899,7 +933,8 @@ static int __load_mapping(void *context, uint64_t cblock, void *leaf)
        return r;
 }
 
-static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_name,
+static int __load_mappings(struct dm_cache_metadata *cmd,
+                          struct dm_cache_policy *policy,
                           load_mapping_fn fn, void *context)
 {
        struct thunk thunk;
@@ -909,18 +944,19 @@ static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_nam
 
        thunk.cmd = cmd;
        thunk.respect_dirty_flags = cmd->clean_when_opened;
-       thunk.hints_valid = hints_array_available(cmd, policy_name);
+       thunk.hints_valid = hints_array_available(cmd, policy);
 
        return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk);
 }
 
-int dm_cache_load_mappings(struct dm_cache_metadata *cmd, const char *policy_name,
+int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
+                          struct dm_cache_policy *policy,
                           load_mapping_fn fn, void *context)
 {
        int r;
 
        down_read(&cmd->root_lock);
-       r = __load_mappings(cmd, policy_name, fn, context);
+       r = __load_mappings(cmd, policy, fn, context);
        up_read(&cmd->root_lock);
 
        return r;
@@ -979,7 +1015,7 @@ static int __dirty(struct dm_cache_metadata *cmd, dm_cblock_t cblock, bool dirty
                /* nothing to be done */
                return 0;
 
-       value = pack_value(oblock, flags | (dirty ? M_DIRTY : 0));
+       value = pack_value(oblock, (flags & ~M_DIRTY) | (dirty ? M_DIRTY : 0));
        __dm_bless_for_disk(&value);
 
        r = dm_array_set_value(&cmd->info, cmd->root, from_cblock(cblock),
@@ -1070,13 +1106,15 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
        __le32 value;
        size_t hint_size;
        const char *policy_name = dm_cache_policy_get_name(policy);
+       const unsigned *policy_version = dm_cache_policy_get_version(policy);
 
        if (!policy_name[0] ||
            (strlen(policy_name) > sizeof(cmd->policy_name) - 1))
                return -EINVAL;
 
-       if (strcmp(cmd->policy_name, policy_name)) {
+       if (!policy_unchanged(cmd, policy)) {
                strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
+               memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version));
 
                hint_size = dm_cache_policy_get_hint_size(policy);
                if (!hint_size)
index 135864ea0eee18343853d950e68a96a227a53622..f45cef21f3d0dac7f5437aac6edf5c2551bd0183 100644 (file)
@@ -89,7 +89,7 @@ typedef int (*load_mapping_fn)(void *context, dm_oblock_t oblock,
                               dm_cblock_t cblock, bool dirty,
                               uint32_t hint, bool hint_valid);
 int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
-                          const char *policy_name,
+                          struct dm_cache_policy *policy,
                           load_mapping_fn fn,
                           void *context);
 
index cc05d70b3cb89a4f8fdcb8cf1887baadca365323..b04d1f904d0763c43870e38c857fcd25baad4b7e 100644 (file)
@@ -17,7 +17,6 @@
 /*----------------------------------------------------------------*/
 
 #define DM_MSG_PREFIX "cache cleaner"
-#define CLEANER_VERSION "1.0.0"
 
 /* Cache entry struct. */
 struct wb_cache_entry {
@@ -434,6 +433,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size,
 
 static struct dm_cache_policy_type wb_policy_type = {
        .name = "cleaner",
+       .version = {1, 0, 0},
        .hint_size = 0,
        .owner = THIS_MODULE,
        .create = wb_create
@@ -446,7 +446,10 @@ static int __init wb_init(void)
        if (r < 0)
                DMERR("register failed %d", r);
        else
-               DMINFO("version " CLEANER_VERSION " loaded");
+               DMINFO("version %u.%u.%u loaded",
+                      wb_policy_type.version[0],
+                      wb_policy_type.version[1],
+                      wb_policy_type.version[2]);
 
        return r;
 }
index 52a75beeced59a4ac50a27a7b646bce3d194e668..0928abdc49f023de5a696dd082e160bc65d37cdd 100644 (file)
@@ -117,6 +117,8 @@ void dm_cache_policy_destroy(struct dm_cache_policy *p);
  */
 const char *dm_cache_policy_get_name(struct dm_cache_policy *p);
 
+const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p);
+
 size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p);
 
 /*----------------------------------------------------------------*/
index 964153255076bad8a1a24765ec9b7f884af4cd4b..dc112a7137fe9280fca348908ed99b77f36f9417 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/vmalloc.h>
 
 #define DM_MSG_PREFIX "cache-policy-mq"
-#define MQ_VERSION     "1.0.0"
 
 static struct kmem_cache *mq_entry_cache;
 
@@ -1133,6 +1132,7 @@ bad_cache_alloc:
 
 static struct dm_cache_policy_type mq_policy_type = {
        .name = "mq",
+       .version = {1, 0, 0},
        .hint_size = 4,
        .owner = THIS_MODULE,
        .create = mq_create
@@ -1140,6 +1140,7 @@ static struct dm_cache_policy_type mq_policy_type = {
 
 static struct dm_cache_policy_type default_policy_type = {
        .name = "default",
+       .version = {1, 0, 0},
        .hint_size = 4,
        .owner = THIS_MODULE,
        .create = mq_create
@@ -1164,7 +1165,10 @@ static int __init mq_init(void)
 
        r = dm_cache_policy_register(&default_policy_type);
        if (!r) {
-               DMINFO("version " MQ_VERSION " loaded");
+               DMINFO("version %u.%u.%u loaded",
+                      mq_policy_type.version[0],
+                      mq_policy_type.version[1],
+                      mq_policy_type.version[2]);
                return 0;
        }
 
index 2cbf5fdaac52e8573eed195fe17330c456243bd6..21c03c570c06b7d2bac4bf1abc1d41147d7cd168 100644 (file)
@@ -150,6 +150,14 @@ const char *dm_cache_policy_get_name(struct dm_cache_policy *p)
 }
 EXPORT_SYMBOL_GPL(dm_cache_policy_get_name);
 
+const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p)
+{
+       struct dm_cache_policy_type *t = p->private;
+
+       return t->version;
+}
+EXPORT_SYMBOL_GPL(dm_cache_policy_get_version);
+
 size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p)
 {
        struct dm_cache_policy_type *t = p->private;
index f0f51b260544decc116a193fc2a2a45ede286a78..558bdfdabf5f2da39e5bef487dc5008a2399b659 100644 (file)
@@ -196,6 +196,7 @@ struct dm_cache_policy {
  * We maintain a little register of the different policy types.
  */
 #define CACHE_POLICY_NAME_SIZE 16
+#define CACHE_POLICY_VERSION_SIZE 3
 
 struct dm_cache_policy_type {
        /* For use by the register code only. */
@@ -206,6 +207,7 @@ struct dm_cache_policy_type {
         * what gets passed on the target line to select your policy.
         */
        char name[CACHE_POLICY_NAME_SIZE];
+       unsigned version[CACHE_POLICY_VERSION_SIZE];
 
        /*
         * Policies may store a hint for each each cache block.
index 0f4e84b15c303c0de380dbeb6a683f693b1b0592..66120bd46d15639613cdeaf09b4474db48550845 100644 (file)
@@ -142,6 +142,7 @@ struct cache {
        spinlock_t lock;
        struct bio_list deferred_bios;
        struct bio_list deferred_flush_bios;
+       struct bio_list deferred_writethrough_bios;
        struct list_head quiesced_migrations;
        struct list_head completed_migrations;
        struct list_head need_commit_migrations;
@@ -158,7 +159,7 @@ struct cache {
        /*
         * origin_blocks entries, discarded if set.
         */
-       sector_t discard_block_size; /* a power of 2 times sectors per block */
+       uint32_t discard_block_size; /* a power of 2 times sectors per block */
        dm_dblock_t discard_nr_blocks;
        unsigned long *discard_bitset;
 
@@ -199,6 +200,11 @@ struct per_bio_data {
        bool tick:1;
        unsigned req_nr:2;
        struct dm_deferred_entry *all_io_entry;
+
+       /* writethrough fields */
+       struct cache *cache;
+       dm_cblock_t cblock;
+       bio_end_io_t *saved_bi_end_io;
 };
 
 struct dm_cache_migration {
@@ -412,17 +418,24 @@ static bool block_size_is_power_of_two(struct cache *cache)
        return cache->sectors_per_block_shift >= 0;
 }
 
+static dm_block_t block_div(dm_block_t b, uint32_t n)
+{
+       do_div(b, n);
+
+       return b;
+}
+
 static dm_dblock_t oblock_to_dblock(struct cache *cache, dm_oblock_t oblock)
 {
-       sector_t discard_blocks = cache->discard_block_size;
+       uint32_t discard_blocks = cache->discard_block_size;
        dm_block_t b = from_oblock(oblock);
 
        if (!block_size_is_power_of_two(cache))
-               (void) sector_div(discard_blocks, cache->sectors_per_block);
+               discard_blocks = discard_blocks / cache->sectors_per_block;
        else
                discard_blocks >>= cache->sectors_per_block_shift;
 
-       (void) sector_div(b, discard_blocks);
+       b = block_div(b, discard_blocks);
 
        return to_dblock(b);
 }
@@ -609,6 +622,56 @@ static void issue(struct cache *cache, struct bio *bio)
        spin_unlock_irqrestore(&cache->lock, flags);
 }
 
+static void defer_writethrough_bio(struct cache *cache, struct bio *bio)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&cache->lock, flags);
+       bio_list_add(&cache->deferred_writethrough_bios, bio);
+       spin_unlock_irqrestore(&cache->lock, flags);
+
+       wake_worker(cache);
+}
+
+static void writethrough_endio(struct bio *bio, int err)
+{
+       struct per_bio_data *pb = get_per_bio_data(bio);
+       bio->bi_end_io = pb->saved_bi_end_io;
+
+       if (err) {
+               bio_endio(bio, err);
+               return;
+       }
+
+       remap_to_cache(pb->cache, bio, pb->cblock);
+
+       /*
+        * We can't issue this bio directly, since we're in interrupt
+        * context.  So it get's put on a bio list for processing by the
+        * worker thread.
+        */
+       defer_writethrough_bio(pb->cache, bio);
+}
+
+/*
+ * When running in writethrough mode we need to send writes to clean blocks
+ * to both the cache and origin devices.  In future we'd like to clone the
+ * bio and send them in parallel, but for now we're doing them in
+ * series as this is easier.
+ */
+static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio,
+                                      dm_oblock_t oblock, dm_cblock_t cblock)
+{
+       struct per_bio_data *pb = get_per_bio_data(bio);
+
+       pb->cache = cache;
+       pb->cblock = cblock;
+       pb->saved_bi_end_io = bio->bi_end_io;
+       bio->bi_end_io = writethrough_endio;
+
+       remap_to_origin_clear_discard(pb->cache, bio, oblock);
+}
+
 /*----------------------------------------------------------------
  * Migration processing
  *
@@ -1002,7 +1065,7 @@ static void process_discard_bio(struct cache *cache, struct bio *bio)
        dm_block_t end_block = bio->bi_sector + bio_sectors(bio);
        dm_block_t b;
 
-       (void) sector_div(end_block, cache->discard_block_size);
+       end_block = block_div(end_block, cache->discard_block_size);
 
        for (b = start_block; b < end_block; b++)
                set_discard(cache, to_dblock(b));
@@ -1070,14 +1133,9 @@ static void process_bio(struct cache *cache, struct prealloc *structs,
                inc_hit_counter(cache, bio);
                pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds);
 
-               if (is_writethrough_io(cache, bio, lookup_result.cblock)) {
-                       /*
-                        * No need to mark anything dirty in write through mode.
-                        */
-                       pb->req_nr == 0 ?
-                               remap_to_cache(cache, bio, lookup_result.cblock) :
-                               remap_to_origin_clear_discard(cache, bio, block);
-               } else
+               if (is_writethrough_io(cache, bio, lookup_result.cblock))
+                       remap_to_origin_then_cache(cache, bio, block, lookup_result.cblock);
+               else
                        remap_to_cache_dirty(cache, bio, block, lookup_result.cblock);
 
                issue(cache, bio);
@@ -1086,17 +1144,8 @@ static void process_bio(struct cache *cache, struct prealloc *structs,
        case POLICY_MISS:
                inc_miss_counter(cache, bio);
                pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds);
-
-               if (pb->req_nr != 0) {
-                       /*
-                        * This is a duplicate writethrough io that is no
-                        * longer needed because the block has been demoted.
-                        */
-                       bio_endio(bio, 0);
-               } else {
-                       remap_to_origin_clear_discard(cache, bio, block);
-                       issue(cache, bio);
-               }
+               remap_to_origin_clear_discard(cache, bio, block);
+               issue(cache, bio);
                break;
 
        case POLICY_NEW:
@@ -1217,6 +1266,23 @@ static void process_deferred_flush_bios(struct cache *cache, bool submit_bios)
                submit_bios ? generic_make_request(bio) : bio_io_error(bio);
 }
 
+static void process_deferred_writethrough_bios(struct cache *cache)
+{
+       unsigned long flags;
+       struct bio_list bios;
+       struct bio *bio;
+
+       bio_list_init(&bios);
+
+       spin_lock_irqsave(&cache->lock, flags);
+       bio_list_merge(&bios, &cache->deferred_writethrough_bios);
+       bio_list_init(&cache->deferred_writethrough_bios);
+       spin_unlock_irqrestore(&cache->lock, flags);
+
+       while ((bio = bio_list_pop(&bios)))
+               generic_make_request(bio);
+}
+
 static void writeback_some_dirty_blocks(struct cache *cache)
 {
        int r = 0;
@@ -1313,6 +1379,7 @@ static int more_work(struct cache *cache)
        else
                return !bio_list_empty(&cache->deferred_bios) ||
                        !bio_list_empty(&cache->deferred_flush_bios) ||
+                       !bio_list_empty(&cache->deferred_writethrough_bios) ||
                        !list_empty(&cache->quiesced_migrations) ||
                        !list_empty(&cache->completed_migrations) ||
                        !list_empty(&cache->need_commit_migrations);
@@ -1331,6 +1398,8 @@ static void do_worker(struct work_struct *ws)
 
                writeback_some_dirty_blocks(cache);
 
+               process_deferred_writethrough_bios(cache);
+
                if (commit_if_needed(cache)) {
                        process_deferred_flush_bios(cache, false);
 
@@ -1756,8 +1825,11 @@ static int create_cache_policy(struct cache *cache, struct cache_args *ca,
        }
 
        r = set_config_values(cache->policy, ca->policy_argc, ca->policy_argv);
-       if (r)
+       if (r) {
+               *error = "Error setting cache policy's config values";
                dm_cache_policy_destroy(cache->policy);
+               cache->policy = NULL;
+       }
 
        return r;
 }
@@ -1793,8 +1865,6 @@ static sector_t calculate_discard_block_size(sector_t cache_block_size,
 
 #define DEFAULT_MIGRATION_THRESHOLD (2048 * 100)
 
-static unsigned cache_num_write_bios(struct dm_target *ti, struct bio *bio);
-
 static int cache_create(struct cache_args *ca, struct cache **result)
 {
        int r = 0;
@@ -1821,9 +1891,6 @@ static int cache_create(struct cache_args *ca, struct cache **result)
 
        memcpy(&cache->features, &ca->features, sizeof(cache->features));
 
-       if (cache->features.write_through)
-               ti->num_write_bios = cache_num_write_bios;
-
        cache->callbacks.congested_fn = cache_is_congested;
        dm_table_add_target_callbacks(ti->table, &cache->callbacks);
 
@@ -1835,7 +1902,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
 
        /* FIXME: factor out this whole section */
        origin_blocks = cache->origin_sectors = ca->origin_sectors;
-       (void) sector_div(origin_blocks, ca->block_size);
+       origin_blocks = block_div(origin_blocks, ca->block_size);
        cache->origin_blocks = to_oblock(origin_blocks);
 
        cache->sectors_per_block = ca->block_size;
@@ -1848,7 +1915,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
                dm_block_t cache_size = ca->cache_sectors;
 
                cache->sectors_per_block_shift = -1;
-               (void) sector_div(cache_size, ca->block_size);
+               cache_size = block_div(cache_size, ca->block_size);
                cache->cache_size = to_cblock(cache_size);
        } else {
                cache->sectors_per_block_shift = __ffs(ca->block_size);
@@ -1873,6 +1940,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
        spin_lock_init(&cache->lock);
        bio_list_init(&cache->deferred_bios);
        bio_list_init(&cache->deferred_flush_bios);
+       bio_list_init(&cache->deferred_writethrough_bios);
        INIT_LIST_HEAD(&cache->quiesced_migrations);
        INIT_LIST_HEAD(&cache->completed_migrations);
        INIT_LIST_HEAD(&cache->need_commit_migrations);
@@ -2002,6 +2070,8 @@ static int cache_ctr(struct dm_target *ti, unsigned argc, char **argv)
                goto out;
 
        r = cache_create(ca, &cache);
+       if (r)
+               goto out;
 
        r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3);
        if (r) {
@@ -2016,20 +2086,6 @@ out:
        return r;
 }
 
-static unsigned cache_num_write_bios(struct dm_target *ti, struct bio *bio)
-{
-       int r;
-       struct cache *cache = ti->private;
-       dm_oblock_t block = get_bio_block(cache, bio);
-       dm_cblock_t cblock;
-
-       r = policy_lookup(cache->policy, block, &cblock);
-       if (r < 0)
-               return 2;       /* assume the worst */
-
-       return (!r && !is_dirty(cache, cblock)) ? 2 : 1;
-}
-
 static int cache_map(struct dm_target *ti, struct bio *bio)
 {
        struct cache *cache = ti->private;
@@ -2097,18 +2153,12 @@ static int cache_map(struct dm_target *ti, struct bio *bio)
                inc_hit_counter(cache, bio);
                pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds);
 
-               if (is_writethrough_io(cache, bio, lookup_result.cblock)) {
-                       /*
-                        * No need to mark anything dirty in write through mode.
-                        */
-                       pb->req_nr == 0 ?
-                               remap_to_cache(cache, bio, lookup_result.cblock) :
-                               remap_to_origin_clear_discard(cache, bio, block);
-                       cell_defer(cache, cell, false);
-               } else {
+               if (is_writethrough_io(cache, bio, lookup_result.cblock))
+                       remap_to_origin_then_cache(cache, bio, block, lookup_result.cblock);
+               else
                        remap_to_cache_dirty(cache, bio, block, lookup_result.cblock);
-                       cell_defer(cache, cell, false);
-               }
+
+               cell_defer(cache, cell, false);
                break;
 
        case POLICY_MISS:
@@ -2319,8 +2369,7 @@ static int cache_preresume(struct dm_target *ti)
        }
 
        if (!cache->loaded_mappings) {
-               r = dm_cache_load_mappings(cache->cmd,
-                                          dm_cache_policy_get_name(cache->policy),
+               r = dm_cache_load_mappings(cache->cmd, cache->policy,
                                           load_mapping, cache);
                if (r) {
                        DMERR("could not load cache mappings");
@@ -2535,7 +2584,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
 static struct target_type cache_target = {
        .name = "cache",
-       .version = {1, 0, 0},
+       .version = {1, 1, 0},
        .module = THIS_MODULE,
        .ctr = cache_ctr,
        .dtr = cache_dtr,
index 9a01d1e4c78302a0fef677e2c516f2bf3daeca70..311e3d35b272e4ae30fa32b3bca9f567394896ef 100644 (file)
@@ -91,15 +91,44 @@ static struct raid_type {
        {"raid6_nc", "RAID6 (N continue)",              2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE}
 };
 
+static char *raid10_md_layout_to_format(int layout)
+{
+       /*
+        * Bit 16 and 17 stand for "offset" and "use_far_sets"
+        * Refer to MD's raid10.c for details
+        */
+       if ((layout & 0x10000) && (layout & 0x20000))
+               return "offset";
+
+       if ((layout & 0xFF) > 1)
+               return "near";
+
+       return "far";
+}
+
 static unsigned raid10_md_layout_to_copies(int layout)
 {
-       return layout & 0xFF;
+       if ((layout & 0xFF) > 1)
+               return layout & 0xFF;
+       return (layout >> 8) & 0xFF;
 }
 
 static int raid10_format_to_md_layout(char *format, unsigned copies)
 {
-       /* 1 "far" copy, and 'copies' "near" copies */
-       return (1 << 8) | (copies & 0xFF);
+       unsigned n = 1, f = 1;
+
+       if (!strcmp("near", format))
+               n = copies;
+       else
+               f = copies;
+
+       if (!strcmp("offset", format))
+               return 0x30000 | (f << 8) | n;
+
+       if (!strcmp("far", format))
+               return 0x20000 | (f << 8) | n;
+
+       return (f << 8) | n;
 }
 
 static struct raid_type *get_raid_type(char *name)
@@ -352,6 +381,7 @@ static int validate_raid_redundancy(struct raid_set *rs)
 {
        unsigned i, rebuild_cnt = 0;
        unsigned rebuilds_per_group, copies, d;
+       unsigned group_size, last_group_start;
 
        for (i = 0; i < rs->md.raid_disks; i++)
                if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
@@ -379,9 +409,6 @@ static int validate_raid_redundancy(struct raid_set *rs)
                 * as long as the failed devices occur in different mirror
                 * groups (i.e. different stripes).
                 *
-                * Right now, we only allow for "near" copies.  When other
-                * formats are added, we will have to check those too.
-                *
                 * When checking "near" format, make sure no adjacent devices
                 * have failed beyond what can be handled.  In addition to the
                 * simple case where the number of devices is a multiple of the
@@ -391,14 +418,41 @@ static int validate_raid_redundancy(struct raid_set *rs)
                 *          A    A    B    B    C
                 *          C    D    D    E    E
                 */
-               for (i = 0; i < rs->md.raid_disks * copies; i++) {
-                       if (!(i % copies))
+               if (!strcmp("near", raid10_md_layout_to_format(rs->md.layout))) {
+                       for (i = 0; i < rs->md.raid_disks * copies; i++) {
+                               if (!(i % copies))
+                                       rebuilds_per_group = 0;
+                               d = i % rs->md.raid_disks;
+                               if ((!rs->dev[d].rdev.sb_page ||
+                                    !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
+                                   (++rebuilds_per_group >= copies))
+                                       goto too_many;
+                       }
+                       break;
+               }
+
+               /*
+                * When checking "far" and "offset" formats, we need to ensure
+                * that the device that holds its copy is not also dead or
+                * being rebuilt.  (Note that "far" and "offset" formats only
+                * support two copies right now.  These formats also only ever
+                * use the 'use_far_sets' variant.)
+                *
+                * This check is somewhat complicated by the need to account
+                * for arrays that are not a multiple of (far) copies.  This
+                * results in the need to treat the last (potentially larger)
+                * set differently.
+                */
+               group_size = (rs->md.raid_disks / copies);
+               last_group_start = (rs->md.raid_disks / group_size) - 1;
+               last_group_start *= group_size;
+               for (i = 0; i < rs->md.raid_disks; i++) {
+                       if (!(i % copies) && !(i > last_group_start))
                                rebuilds_per_group = 0;
-                       d = i % rs->md.raid_disks;
-                       if ((!rs->dev[d].rdev.sb_page ||
-                            !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
+                       if ((!rs->dev[i].rdev.sb_page ||
+                            !test_bit(In_sync, &rs->dev[i].rdev.flags)) &&
                            (++rebuilds_per_group >= copies))
-                               goto too_many;
+                                       goto too_many;
                }
                break;
        default:
@@ -433,7 +487,7 @@ too_many:
  *
  * RAID10-only options:
  *    [raid10_copies <# copies>]        Number of copies.  (Default: 2)
- *    [raid10_format <near>]            Layout algorithm.  (Default: near)
+ *    [raid10_format <near|far|offset>] Layout algorithm.  (Default: near)
  */
 static int parse_raid_params(struct raid_set *rs, char **argv,
                             unsigned num_raid_params)
@@ -520,7 +574,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
                                rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type";
                                return -EINVAL;
                        }
-                       if (strcmp("near", argv[i])) {
+                       if (strcmp("near", argv[i]) &&
+                           strcmp("far", argv[i]) &&
+                           strcmp("offset", argv[i])) {
                                rs->ti->error = "Invalid 'raid10_format' value given";
                                return -EINVAL;
                        }
@@ -644,6 +700,15 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
                        return -EINVAL;
                }
 
+               /*
+                * If the format is not "near", we only support
+                * two copies at the moment.
+                */
+               if (strcmp("near", raid10_format) && (raid10_copies > 2)) {
+                       rs->ti->error = "Too many copies for given RAID10 format.";
+                       return -EINVAL;
+               }
+
                /* (Len * #mirrors) / #devices */
                sectors_per_dev = rs->ti->len * raid10_copies;
                sector_div(sectors_per_dev, rs->md.raid_disks);
@@ -854,17 +919,30 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev)
        /*
         * Reshaping is not currently allowed
         */
-       if ((le32_to_cpu(sb->level) != mddev->level) ||
-           (le32_to_cpu(sb->layout) != mddev->layout) ||
-           (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors)) {
-               DMERR("Reshaping arrays not yet supported.");
+       if (le32_to_cpu(sb->level) != mddev->level) {
+               DMERR("Reshaping arrays not yet supported. (RAID level change)");
+               return -EINVAL;
+       }
+       if (le32_to_cpu(sb->layout) != mddev->layout) {
+               DMERR("Reshaping arrays not yet supported. (RAID layout change)");
+               DMERR("  0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout);
+               DMERR("  Old layout: %s w/ %d copies",
+                     raid10_md_layout_to_format(le32_to_cpu(sb->layout)),
+                     raid10_md_layout_to_copies(le32_to_cpu(sb->layout)));
+               DMERR("  New layout: %s w/ %d copies",
+                     raid10_md_layout_to_format(mddev->layout),
+                     raid10_md_layout_to_copies(mddev->layout));
+               return -EINVAL;
+       }
+       if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) {
+               DMERR("Reshaping arrays not yet supported. (stripe sectors change)");
                return -EINVAL;
        }
 
        /* We can only change the number of devices in RAID1 right now */
        if ((rs->raid_type->level != 1) &&
            (le32_to_cpu(sb->num_devices) != mddev->raid_disks)) {
-               DMERR("Reshaping arrays not yet supported.");
+               DMERR("Reshaping arrays not yet supported. (device count change)");
                return -EINVAL;
        }
 
@@ -1329,7 +1407,8 @@ static void raid_status(struct dm_target *ti, status_type_t type,
                               raid10_md_layout_to_copies(rs->md.layout));
 
                if (rs->print_flags & DMPF_RAID10_FORMAT)
-                       DMEMIT(" raid10_format near");
+                       DMEMIT(" raid10_format %s",
+                              raid10_md_layout_to_format(rs->md.layout));
 
                DMEMIT(" %d", rs->md.raid_disks);
                for (i = 0; i < rs->md.raid_disks; i++) {
@@ -1418,6 +1497,10 @@ static struct target_type raid_target = {
 
 static int __init dm_raid_init(void)
 {
+       DMINFO("Loading target version %u.%u.%u",
+              raid_target.version[0],
+              raid_target.version[1],
+              raid_target.version[2]);
        return dm_register_target(&raid_target);
 }
 
index 009339d628287e9ab124d664677ffa69864732f1..004ad1652b73477dae0194b957842434cf48c38d 100644 (file)
@@ -1577,6 +1577,11 @@ static bool data_dev_supports_discard(struct pool_c *pt)
        return q && blk_queue_discard(q);
 }
 
+static bool is_factor(sector_t block_size, uint32_t n)
+{
+       return !sector_div(block_size, n);
+}
+
 /*
  * If discard_passdown was enabled verify that the data device
  * supports discards.  Disable discard_passdown if not.
@@ -1602,7 +1607,7 @@ static void disable_passdown_if_not_supported(struct pool_c *pt)
        else if (data_limits->discard_granularity > block_size)
                reason = "discard granularity larger than a block";
 
-       else if (block_size & (data_limits->discard_granularity - 1))
+       else if (!is_factor(block_size, data_limits->discard_granularity))
                reason = "discard granularity not a factor of block size";
 
        if (reason) {
@@ -2544,7 +2549,7 @@ static struct target_type pool_target = {
        .name = "thin-pool",
        .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
                    DM_TARGET_IMMUTABLE,
-       .version = {1, 6, 1},
+       .version = {1, 7, 0},
        .module = THIS_MODULE,
        .ctr = pool_ctr,
        .dtr = pool_dtr,
@@ -2831,7 +2836,7 @@ static int thin_iterate_devices(struct dm_target *ti,
 
 static struct target_type thin_target = {
        .name = "thin",
-       .version = {1, 7, 1},
+       .version = {1, 8, 0},
        .module = THIS_MODULE,
        .ctr = thin_ctr,
        .dtr = thin_dtr,
index 6ad538375c3c82ba0d345d2ccab3955b31ab3f30..a746f1d21c661bec7b809c9a688fddf44284581f 100644 (file)
@@ -93,6 +93,13 @@ struct dm_verity_io {
         */
 };
 
+struct dm_verity_prefetch_work {
+       struct work_struct work;
+       struct dm_verity *v;
+       sector_t block;
+       unsigned n_blocks;
+};
+
 static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io)
 {
        return (struct shash_desc *)(io + 1);
@@ -424,15 +431,18 @@ static void verity_end_io(struct bio *bio, int error)
  * The root buffer is not prefetched, it is assumed that it will be cached
  * all the time.
  */
-static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io)
+static void verity_prefetch_io(struct work_struct *work)
 {
+       struct dm_verity_prefetch_work *pw =
+               container_of(work, struct dm_verity_prefetch_work, work);
+       struct dm_verity *v = pw->v;
        int i;
 
        for (i = v->levels - 2; i >= 0; i--) {
                sector_t hash_block_start;
                sector_t hash_block_end;
-               verity_hash_at_level(v, io->block, i, &hash_block_start, NULL);
-               verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL);
+               verity_hash_at_level(v, pw->block, i, &hash_block_start, NULL);
+               verity_hash_at_level(v, pw->block + pw->n_blocks - 1, i, &hash_block_end, NULL);
                if (!i) {
                        unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster);
 
@@ -452,6 +462,25 @@ no_prefetch_cluster:
                dm_bufio_prefetch(v->bufio, hash_block_start,
                                  hash_block_end - hash_block_start + 1);
        }
+
+       kfree(pw);
+}
+
+static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io)
+{
+       struct dm_verity_prefetch_work *pw;
+
+       pw = kmalloc(sizeof(struct dm_verity_prefetch_work),
+               GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+
+       if (!pw)
+               return;
+
+       INIT_WORK(&pw->work, verity_prefetch_io);
+       pw->v = v;
+       pw->block = io->block;
+       pw->n_blocks = io->n_blocks;
+       queue_work(v->verify_wq, &pw->work);
 }
 
 /*
@@ -498,7 +527,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
        memcpy(io->io_vec, bio_iovec(bio),
               io->io_vec_size * sizeof(struct bio_vec));
 
-       verity_prefetch_io(v, io);
+       verity_submit_prefetch(v, io);
 
        generic_make_request(bio);
 
@@ -858,7 +887,7 @@ bad:
 
 static struct target_type verity_target = {
        .name           = "verity",
-       .version        = {1, 1, 1},
+       .version        = {1, 2, 0},
        .module         = THIS_MODULE,
        .ctr            = verity_ctr,
        .dtr            = verity_dtr,
index 3db3d1b271f7ef18650a227a8dd07dbc2b8fefbc..aeceedfc530b90b5da5b45e12ffdc9e4d665e16d 100644 (file)
@@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, struct bio *bio)
                bio_io_error(bio);
                return;
        }
+       if (mddev->ro == 1 && unlikely(rw == WRITE)) {
+               bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
+               return;
+       }
        smp_rmb(); /* Ensure implications of  'active' are visible */
        rcu_read_lock();
        if (mddev->suspended) {
@@ -2994,6 +2998,9 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len)
                } else if (!sectors)
                        sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
                                rdev->data_offset;
+               if (!my_mddev->pers->resize)
+                       /* Cannot change size for RAID0 or Linear etc */
+                       return -EINVAL;
        }
        if (sectors < my_mddev->dev_sectors)
                return -EINVAL; /* component must fit device */
@@ -6525,7 +6532,17 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
                        mddev->ro = 0;
                        sysfs_notify_dirent_safe(mddev->sysfs_state);
                        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-                       md_wakeup_thread(mddev->thread);
+                       /* mddev_unlock will wake thread */
+                       /* If a device failed while we were read-only, we
+                        * need to make sure the metadata is updated now.
+                        */
+                       if (test_bit(MD_CHANGE_DEVS, &mddev->flags)) {
+                               mddev_unlock(mddev);
+                               wait_event(mddev->sb_wait,
+                                          !test_bit(MD_CHANGE_DEVS, &mddev->flags) &&
+                                          !test_bit(MD_CHANGE_PENDING, &mddev->flags));
+                               mddev_lock(mddev);
+                       }
                } else {
                        err = -EROFS;
                        goto abort_unlock;
@@ -7646,10 +7663,8 @@ static int remove_and_add_spares(struct mddev *mddev)
                                removed++;
                        }
                }
-       if (removed)
-               sysfs_notify(&mddev->kobj, NULL,
-                            "degraded");
-
+       if (removed && mddev->kobj.sd)
+               sysfs_notify(&mddev->kobj, NULL, "degraded");
 
        rdev_for_each(rdev, mddev) {
                if (rdev->raid_disk >= 0 &&
index eca59c3074ef65bee75301f92411d9968adbaf9d..d90fb1a879e1902200c63117cc9465781a5eb871 100644 (file)
@@ -506,7 +506,7 @@ static inline char * mdname (struct mddev * mddev)
 static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
 {
        char nm[20];
-       if (!test_bit(Replacement, &rdev->flags)) {
+       if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
                sprintf(nm, "rd%d", rdev->raid_disk);
                return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
        } else
@@ -516,7 +516,7 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
 static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev)
 {
        char nm[20];
-       if (!test_bit(Replacement, &rdev->flags)) {
+       if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
                sprintf(nm, "rd%d", rdev->raid_disk);
                sysfs_remove_link(&mddev->kobj, nm);
        }
index c4f28133ef829340d966393f7e6d9eba6857111d..b88757cd0d1d93728d27d1c1366edf0c45479daf 100644 (file)
@@ -139,15 +139,8 @@ struct child {
        struct btree_node *n;
 };
 
-static struct dm_btree_value_type le64_type = {
-       .context = NULL,
-       .size = sizeof(__le64),
-       .inc = NULL,
-       .dec = NULL,
-       .equal = NULL
-};
-
-static int init_child(struct dm_btree_info *info, struct btree_node *parent,
+static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt,
+                     struct btree_node *parent,
                      unsigned index, struct child *result)
 {
        int r, inc;
@@ -164,7 +157,7 @@ static int init_child(struct dm_btree_info *info, struct btree_node *parent,
        result->n = dm_block_data(result->block);
 
        if (inc)
-               inc_children(info->tm, result->n, &le64_type);
+               inc_children(info->tm, result->n, vt);
 
        *((__le64 *) value_ptr(parent, index)) =
                cpu_to_le64(dm_block_location(result->block));
@@ -236,7 +229,7 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
 }
 
 static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
-                     unsigned left_index)
+                     struct dm_btree_value_type *vt, unsigned left_index)
 {
        int r;
        struct btree_node *parent;
@@ -244,11 +237,11 @@ static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
 
        parent = dm_block_data(shadow_current(s));
 
-       r = init_child(info, parent, left_index, &left);
+       r = init_child(info, vt, parent, left_index, &left);
        if (r)
                return r;
 
-       r = init_child(info, parent, left_index + 1, &right);
+       r = init_child(info, vt, parent, left_index + 1, &right);
        if (r) {
                exit_child(info, &left);
                return r;
@@ -368,7 +361,7 @@ static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
 }
 
 static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
-                     unsigned left_index)
+                     struct dm_btree_value_type *vt, unsigned left_index)
 {
        int r;
        struct btree_node *parent = dm_block_data(shadow_current(s));
@@ -377,17 +370,17 @@ static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
        /*
         * FIXME: fill out an array?
         */
-       r = init_child(info, parent, left_index, &left);
+       r = init_child(info, vt, parent, left_index, &left);
        if (r)
                return r;
 
-       r = init_child(info, parent, left_index + 1, &center);
+       r = init_child(info, vt, parent, left_index + 1, &center);
        if (r) {
                exit_child(info, &left);
                return r;
        }
 
-       r = init_child(info, parent, left_index + 2, &right);
+       r = init_child(info, vt, parent, left_index + 2, &right);
        if (r) {
                exit_child(info, &left);
                exit_child(info, &center);
@@ -434,7 +427,8 @@ static int get_nr_entries(struct dm_transaction_manager *tm,
 }
 
 static int rebalance_children(struct shadow_spine *s,
-                             struct dm_btree_info *info, uint64_t key)
+                             struct dm_btree_info *info,
+                             struct dm_btree_value_type *vt, uint64_t key)
 {
        int i, r, has_left_sibling, has_right_sibling;
        uint32_t child_entries;
@@ -472,13 +466,13 @@ static int rebalance_children(struct shadow_spine *s,
        has_right_sibling = i < (le32_to_cpu(n->header.nr_entries) - 1);
 
        if (!has_left_sibling)
-               r = rebalance2(s, info, i);
+               r = rebalance2(s, info, vt, i);
 
        else if (!has_right_sibling)
-               r = rebalance2(s, info, i - 1);
+               r = rebalance2(s, info, vt, i - 1);
 
        else
-               r = rebalance3(s, info, i - 1);
+               r = rebalance3(s, info, vt, i - 1);
 
        return r;
 }
@@ -529,7 +523,7 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
                if (le32_to_cpu(n->header.flags) & LEAF_NODE)
                        return do_leaf(n, key, index);
 
-               r = rebalance_children(s, info, key);
+               r = rebalance_children(s, info, vt, key);
                if (r)
                        break;
 
@@ -550,6 +544,14 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
        return r;
 }
 
+static struct dm_btree_value_type le64_type = {
+       .context = NULL,
+       .size = sizeof(__le64),
+       .inc = NULL,
+       .dec = NULL,
+       .equal = NULL
+};
+
 int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
                    uint64_t *keys, dm_block_t *new_root)
 {
index 24b359717a7e8917a4955e36651e6eb4009dc393..0505452de8d6ee2b3533c7930d62df544636b0c3 100644 (file)
@@ -175,7 +175,13 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
                        rdev1->new_raid_disk = j;
                }
 
-               if (j < 0 || j >= mddev->raid_disks) {
+               if (j < 0) {
+                       printk(KERN_ERR
+                              "md/raid0:%s: remove inactive devices before converting to RAID0\n",
+                              mdname(mddev));
+                       goto abort;
+               }
+               if (j >= mddev->raid_disks) {
                        printk(KERN_ERR "md/raid0:%s: bad disk number %d - "
                               "aborting!\n", mdname(mddev), j);
                        goto abort;
@@ -289,7 +295,7 @@ abort:
        kfree(conf->strip_zone);
        kfree(conf->devlist);
        kfree(conf);
-       *private_conf = NULL;
+       *private_conf = ERR_PTR(err);
        return err;
 }
 
@@ -411,7 +417,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks
                  "%s does not support generic reshape\n", __func__);
 
        rdev_for_each(rdev, mddev)
-               array_sectors += rdev->sectors;
+               array_sectors += (rdev->sectors &
+                                 ~(sector_t)(mddev->chunk_sectors-1));
 
        return array_sectors;
 }
index d5bddfc4010e4f77ea6d28a3f8fde5ff304bcc6e..fd86b372692db6d6bd5c6afdd498ae16be49f2c3 100644 (file)
@@ -967,6 +967,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
                spin_unlock_irq(&conf->device_lock);
+               wake_up(&conf->wait_barrier);
                md_wakeup_thread(mddev->thread);
                kfree(plug);
                return;
@@ -1000,6 +1001,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
        const unsigned long do_discard = (bio->bi_rw
                                          & (REQ_DISCARD | REQ_SECURE));
+       const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
        struct md_rdev *blocked_rdev;
        struct blk_plug_cb *cb;
        struct raid1_plug_cb *plug = NULL;
@@ -1301,7 +1303,8 @@ read_again:
                                   conf->mirrors[i].rdev->data_offset);
                mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
                mbio->bi_end_io = raid1_end_write_request;
-               mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard;
+               mbio->bi_rw =
+                       WRITE | do_flush_fua | do_sync | do_discard | do_same;
                mbio->bi_private = r1_bio;
 
                atomic_inc(&r1_bio->remaining);
@@ -2818,6 +2821,9 @@ static int run(struct mddev *mddev)
        if (IS_ERR(conf))
                return PTR_ERR(conf);
 
+       if (mddev->queue)
+               blk_queue_max_write_same_sectors(mddev->queue,
+                                                mddev->chunk_sectors);
        rdev_for_each(rdev, mddev) {
                if (!mddev->gendisk)
                        continue;
index 64d48249c03bf09f73580f4465b59192faa005ab..77b562d18a90c4d27d9a5c43e82518e174ed84c7 100644 (file)
  *    near_copies (stored in low byte of layout)
  *    far_copies (stored in second byte of layout)
  *    far_offset (stored in bit 16 of layout )
+ *    use_far_sets (stored in bit 17 of layout )
  *
- * The data to be stored is divided into chunks using chunksize.
- * Each device is divided into far_copies sections.
- * In each section, chunks are laid out in a style similar to raid0, but
- * near_copies copies of each chunk is stored (each on a different drive).
- * The starting device for each section is offset near_copies from the starting
- * device of the previous section.
- * Thus they are (near_copies*far_copies) of each chunk, and each is on a different
- * drive.
- * near_copies and far_copies must be at least one, and their product is at most
- * raid_disks.
+ * The data to be stored is divided into chunks using chunksize.  Each device
+ * is divided into far_copies sections.   In each section, chunks are laid out
+ * in a style similar to raid0, but near_copies copies of each chunk is stored
+ * (each on a different drive).  The starting device for each section is offset
+ * near_copies from the starting device of the previous section.  Thus there
+ * are (near_copies * far_copies) of each chunk, and each is on a different
+ * drive.  near_copies and far_copies must be at least one, and their product
+ * is at most raid_disks.
  *
  * If far_offset is true, then the far_copies are handled a bit differently.
- * The copies are still in different stripes, but instead of be very far apart
- * on disk, there are adjacent stripes.
+ * The copies are still in different stripes, but instead of being very far
+ * apart on disk, there are adjacent stripes.
+ *
+ * The far and offset algorithms are handled slightly differently if
+ * 'use_far_sets' is true.  In this case, the array's devices are grouped into
+ * sets that are (near_copies * far_copies) in size.  The far copied stripes
+ * are still shifted by 'near_copies' devices, but this shifting stays confined
+ * to the set rather than the entire array.  This is done to improve the number
+ * of device combinations that can fail without causing the array to fail.
+ * Example 'far' algorithm w/o 'use_far_sets' (each letter represents a chunk
+ * on a device):
+ *    A B C D    A B C D E
+ *      ...         ...
+ *    D A B C    E A B C D
+ * Example 'far' algorithm w/ 'use_far_sets' enabled (sets illustrated w/ []'s):
+ *    [A B] [C D]    [A B] [C D E]
+ *    |...| |...|    |...| | ... |
+ *    [B A] [D C]    [B A] [E C D]
  */
 
 /*
@@ -535,6 +550,13 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio)
        sector_t stripe;
        int dev;
        int slot = 0;
+       int last_far_set_start, last_far_set_size;
+
+       last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1;
+       last_far_set_start *= geo->far_set_size;
+
+       last_far_set_size = geo->far_set_size;
+       last_far_set_size += (geo->raid_disks % geo->far_set_size);
 
        /* now calculate first sector/dev */
        chunk = r10bio->sector >> geo->chunk_shift;
@@ -551,15 +573,25 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio)
        /* and calculate all the others */
        for (n = 0; n < geo->near_copies; n++) {
                int d = dev;
+               int set;
                sector_t s = sector;
-               r10bio->devs[slot].addr = sector;
                r10bio->devs[slot].devnum = d;
+               r10bio->devs[slot].addr = s;
                slot++;
 
                for (f = 1; f < geo->far_copies; f++) {
+                       set = d / geo->far_set_size;
                        d += geo->near_copies;
-                       if (d >= geo->raid_disks)
-                               d -= geo->raid_disks;
+
+                       if ((geo->raid_disks % geo->far_set_size) &&
+                           (d > last_far_set_start)) {
+                               d -= last_far_set_start;
+                               d %= last_far_set_size;
+                               d += last_far_set_start;
+                       } else {
+                               d %= geo->far_set_size;
+                               d += geo->far_set_size * set;
+                       }
                        s += geo->stride;
                        r10bio->devs[slot].devnum = d;
                        r10bio->devs[slot].addr = s;
@@ -595,6 +627,20 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev)
         * or recovery, so reshape isn't happening
         */
        struct geom *geo = &conf->geo;
+       int far_set_start = (dev / geo->far_set_size) * geo->far_set_size;
+       int far_set_size = geo->far_set_size;
+       int last_far_set_start;
+
+       if (geo->raid_disks % geo->far_set_size) {
+               last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1;
+               last_far_set_start *= geo->far_set_size;
+
+               if (dev >= last_far_set_start) {
+                       far_set_size = geo->far_set_size;
+                       far_set_size += (geo->raid_disks % geo->far_set_size);
+                       far_set_start = last_far_set_start;
+               }
+       }
 
        offset = sector & geo->chunk_mask;
        if (geo->far_offset) {
@@ -602,13 +648,13 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev)
                chunk = sector >> geo->chunk_shift;
                fc = sector_div(chunk, geo->far_copies);
                dev -= fc * geo->near_copies;
-               if (dev < 0)
-                       dev += geo->raid_disks;
+               if (dev < far_set_start)
+                       dev += far_set_size;
        } else {
                while (sector >= geo->stride) {
                        sector -= geo->stride;
-                       if (dev < geo->near_copies)
-                               dev += geo->raid_disks - geo->near_copies;
+                       if (dev < (geo->near_copies + far_set_start))
+                               dev += far_set_size - geo->near_copies;
                        else
                                dev -= geo->near_copies;
                }
@@ -1073,6 +1119,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
                spin_unlock_irq(&conf->device_lock);
+               wake_up(&conf->wait_barrier);
                md_wakeup_thread(mddev->thread);
                kfree(plug);
                return;
@@ -1105,6 +1152,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
        const unsigned long do_discard = (bio->bi_rw
                                          & (REQ_DISCARD | REQ_SECURE));
+       const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
        unsigned long flags;
        struct md_rdev *blocked_rdev;
        struct blk_plug_cb *cb;
@@ -1460,7 +1508,8 @@ retry_write:
                                                              rdev));
                        mbio->bi_bdev = rdev->bdev;
                        mbio->bi_end_io = raid10_end_write_request;
-                       mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+                       mbio->bi_rw =
+                               WRITE | do_sync | do_fua | do_discard | do_same;
                        mbio->bi_private = r10_bio;
 
                        atomic_inc(&r10_bio->remaining);
@@ -1502,7 +1551,8 @@ retry_write:
                                                   r10_bio, rdev));
                        mbio->bi_bdev = rdev->bdev;
                        mbio->bi_end_io = raid10_end_write_request;
-                       mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+                       mbio->bi_rw =
+                               WRITE | do_sync | do_fua | do_discard | do_same;
                        mbio->bi_private = r10_bio;
 
                        atomic_inc(&r10_bio->remaining);
@@ -3436,7 +3486,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
                disks = mddev->raid_disks + mddev->delta_disks;
                break;
        }
-       if (layout >> 17)
+       if (layout >> 18)
                return -1;
        if (chunk < (PAGE_SIZE >> 9) ||
            !is_power_of_2(chunk))
@@ -3448,6 +3498,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
        geo->near_copies = nc;
        geo->far_copies = fc;
        geo->far_offset = fo;
+       geo->far_set_size = (layout & (1<<17)) ? disks / fc : disks;
        geo->chunk_mask = chunk - 1;
        geo->chunk_shift = ffz(~chunk);
        return nc*fc;
@@ -3569,6 +3620,8 @@ static int run(struct mddev *mddev)
        if (mddev->queue) {
                blk_queue_max_discard_sectors(mddev->queue,
                                              mddev->chunk_sectors);
+               blk_queue_max_write_same_sectors(mddev->queue,
+                                                mddev->chunk_sectors);
                blk_queue_io_min(mddev->queue, chunk_size);
                if (conf->geo.raid_disks % conf->geo.near_copies)
                        blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks);
index 1054cf602345250f059ef81fae8bf9ef330cccd1..157d69e83ff401972f395db9bb281faa8df75a65 100644 (file)
@@ -33,6 +33,11 @@ struct r10conf {
                                               * far_offset, in which case it is
                                               * 1 stripe.
                                               */
+               int             far_set_size; /* The number of devices in a set,
+                                              * where a 'set' are devices that
+                                              * contain far/offset copies of
+                                              * each other.
+                                              */
                int             chunk_shift; /* shift from chunks to sectors */
                sector_t        chunk_mask;
        } prev, geo;
index 5af2d270908178b2628a3db42c508417fc4f5579..24909eb13fec1b0bf22e40caa4ff7a76967f80e4 100644 (file)
@@ -671,9 +671,11 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                        bi->bi_next = NULL;
                        if (rrdev)
                                set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
-                       trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
-                                             bi, disk_devt(conf->mddev->gendisk),
-                                             sh->dev[i].sector);
+
+                       if (conf->mddev->gendisk)
+                               trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
+                                                     bi, disk_devt(conf->mddev->gendisk),
+                                                     sh->dev[i].sector);
                        generic_make_request(bi);
                }
                if (rrdev) {
@@ -701,9 +703,10 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                        rbi->bi_io_vec[0].bv_offset = 0;
                        rbi->bi_size = STRIPE_SIZE;
                        rbi->bi_next = NULL;
-                       trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
-                                             rbi, disk_devt(conf->mddev->gendisk),
-                                             sh->dev[i].sector);
+                       if (conf->mddev->gendisk)
+                               trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
+                                                     rbi, disk_devt(conf->mddev->gendisk),
+                                                     sh->dev[i].sector);
                        generic_make_request(rbi);
                }
                if (!rdev && !rrdev) {
@@ -1403,7 +1406,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu
                           &sh->ops.zero_sum_result, percpu->spare_page, &submit);
 }
 
-static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
+static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
 {
        int overlap_clear = 0, i, disks = sh->disks;
        struct dma_async_tx_descriptor *tx = NULL;
@@ -1468,36 +1471,6 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
        put_cpu();
 }
 
-#ifdef CONFIG_MULTICORE_RAID456
-static void async_run_ops(void *param, async_cookie_t cookie)
-{
-       struct stripe_head *sh = param;
-       unsigned long ops_request = sh->ops.request;
-
-       clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state);
-       wake_up(&sh->ops.wait_for_ops);
-
-       __raid_run_ops(sh, ops_request);
-       release_stripe(sh);
-}
-
-static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
-{
-       /* since handle_stripe can be called outside of raid5d context
-        * we need to ensure sh->ops.request is de-staged before another
-        * request arrives
-        */
-       wait_event(sh->ops.wait_for_ops,
-                  !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state));
-       sh->ops.request = ops_request;
-
-       atomic_inc(&sh->count);
-       async_schedule(async_run_ops, sh);
-}
-#else
-#define raid_run_ops __raid_run_ops
-#endif
-
 static int grow_one_stripe(struct r5conf *conf)
 {
        struct stripe_head *sh;
@@ -1506,9 +1479,6 @@ static int grow_one_stripe(struct r5conf *conf)
                return 0;
 
        sh->raid_conf = conf;
-       #ifdef CONFIG_MULTICORE_RAID456
-       init_waitqueue_head(&sh->ops.wait_for_ops);
-       #endif
 
        spin_lock_init(&sh->stripe_lock);
 
@@ -1627,9 +1597,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                        break;
 
                nsh->raid_conf = conf;
-               #ifdef CONFIG_MULTICORE_RAID456
-               init_waitqueue_head(&nsh->ops.wait_for_ops);
-               #endif
                spin_lock_init(&nsh->stripe_lock);
 
                list_add(&nsh->lru, &newstripes);
@@ -2316,17 +2283,6 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
        int level = conf->level;
 
        if (rcw) {
-               /* if we are not expanding this is a proper write request, and
-                * there will be bios with new data to be drained into the
-                * stripe cache
-                */
-               if (!expand) {
-                       sh->reconstruct_state = reconstruct_state_drain_run;
-                       set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
-               } else
-                       sh->reconstruct_state = reconstruct_state_run;
-
-               set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
 
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
@@ -2339,6 +2295,21 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
                                s->locked++;
                        }
                }
+               /* if we are not expanding this is a proper write request, and
+                * there will be bios with new data to be drained into the
+                * stripe cache
+                */
+               if (!expand) {
+                       if (!s->locked)
+                               /* False alarm, nothing to do */
+                               return;
+                       sh->reconstruct_state = reconstruct_state_drain_run;
+                       set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+               } else
+                       sh->reconstruct_state = reconstruct_state_run;
+
+               set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
+
                if (s->locked + conf->max_degraded == disks)
                        if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state))
                                atomic_inc(&conf->pending_full_writes);
@@ -2347,11 +2318,6 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
                BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) ||
                        test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags)));
 
-               sh->reconstruct_state = reconstruct_state_prexor_drain_run;
-               set_bit(STRIPE_OP_PREXOR, &s->ops_request);
-               set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
-               set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
-
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
                        if (i == pd_idx)
@@ -2366,6 +2332,13 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
                                s->locked++;
                        }
                }
+               if (!s->locked)
+                       /* False alarm - nothing to do */
+                       return;
+               sh->reconstruct_state = reconstruct_state_prexor_drain_run;
+               set_bit(STRIPE_OP_PREXOR, &s->ops_request);
+               set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+               set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
        }
 
        /* keep the parity disk(s) locked while asynchronous operations
@@ -2600,6 +2573,8 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh,
        int i;
 
        clear_bit(STRIPE_SYNCING, &sh->state);
+       if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags))
+               wake_up(&conf->wait_for_overlap);
        s->syncing = 0;
        s->replacing = 0;
        /* There is nothing more to do for sync/check/repair.
@@ -2773,6 +2748,7 @@ static void handle_stripe_clean_event(struct r5conf *conf,
 {
        int i;
        struct r5dev *dev;
+       int discard_pending = 0;
 
        for (i = disks; i--; )
                if (sh->dev[i].written) {
@@ -2801,9 +2777,23 @@ static void handle_stripe_clean_event(struct r5conf *conf,
                                                STRIPE_SECTORS,
                                         !test_bit(STRIPE_DEGRADED, &sh->state),
                                                0);
-                       }
-               } else if (test_bit(R5_Discard, &sh->dev[i].flags))
-                       clear_bit(R5_Discard, &sh->dev[i].flags);
+                       } else if (test_bit(R5_Discard, &dev->flags))
+                               discard_pending = 1;
+               }
+       if (!discard_pending &&
+           test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) {
+               clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags);
+               clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
+               if (sh->qd_idx >= 0) {
+                       clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags);
+                       clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags);
+               }
+               /* now that discard is done we can proceed with any sync */
+               clear_bit(STRIPE_DISCARD, &sh->state);
+               if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
+                       set_bit(STRIPE_HANDLE, &sh->state);
+
+       }
 
        if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
                if (atomic_dec_and_test(&conf->pending_full_writes))
@@ -2862,8 +2852,10 @@ static void handle_stripe_dirtying(struct r5conf *conf,
        set_bit(STRIPE_HANDLE, &sh->state);
        if (rmw < rcw && rmw > 0) {
                /* prefer read-modify-write, but need to get some data */
-               blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d",
-                                 (unsigned long long)sh->sector, rmw);
+               if (conf->mddev->queue)
+                       blk_add_trace_msg(conf->mddev->queue,
+                                         "raid5 rmw %llu %d",
+                                         (unsigned long long)sh->sector, rmw);
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
                        if ((dev->towrite || i == sh->pd_idx) &&
@@ -2913,7 +2905,7 @@ static void handle_stripe_dirtying(struct r5conf *conf,
                                }
                        }
                }
-               if (rcw)
+               if (rcw && conf->mddev->queue)
                        blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d",
                                          (unsigned long long)sh->sector,
                                          rcw, qread, test_bit(STRIPE_DELAYED, &sh->state));
@@ -3453,9 +3445,15 @@ static void handle_stripe(struct stripe_head *sh)
                return;
        }
 
-       if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
-               set_bit(STRIPE_SYNCING, &sh->state);
-               clear_bit(STRIPE_INSYNC, &sh->state);
+       if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
+               spin_lock(&sh->stripe_lock);
+               /* Cannot process 'sync' concurrently with 'discard' */
+               if (!test_bit(STRIPE_DISCARD, &sh->state) &&
+                   test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
+                       set_bit(STRIPE_SYNCING, &sh->state);
+                       clear_bit(STRIPE_INSYNC, &sh->state);
+               }
+               spin_unlock(&sh->stripe_lock);
        }
        clear_bit(STRIPE_DELAYED, &sh->state);
 
@@ -3615,6 +3613,8 @@ static void handle_stripe(struct stripe_head *sh)
            test_bit(STRIPE_INSYNC, &sh->state)) {
                md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
                clear_bit(STRIPE_SYNCING, &sh->state);
+               if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags))
+                       wake_up(&conf->wait_for_overlap);
        }
 
        /* If the failed drives are just a ReadError, then we might need
@@ -4018,9 +4018,10 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
                atomic_inc(&conf->active_aligned_reads);
                spin_unlock_irq(&conf->device_lock);
 
-               trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
-                                     align_bi, disk_devt(mddev->gendisk),
-                                     raid_bio->bi_sector);
+               if (mddev->gendisk)
+                       trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
+                                             align_bi, disk_devt(mddev->gendisk),
+                                             raid_bio->bi_sector);
                generic_make_request(align_bi);
                return 1;
        } else {
@@ -4114,7 +4115,8 @@ static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule)
                }
                spin_unlock_irq(&conf->device_lock);
        }
-       trace_block_unplug(mddev->queue, cnt, !from_schedule);
+       if (mddev->queue)
+               trace_block_unplug(mddev->queue, cnt, !from_schedule);
        kfree(cb);
 }
 
@@ -4177,6 +4179,13 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
                sh = get_active_stripe(conf, logical_sector, 0, 0, 0);
                prepare_to_wait(&conf->wait_for_overlap, &w,
                                TASK_UNINTERRUPTIBLE);
+               set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
+               if (test_bit(STRIPE_SYNCING, &sh->state)) {
+                       release_stripe(sh);
+                       schedule();
+                       goto again;
+               }
+               clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
                spin_lock_irq(&sh->stripe_lock);
                for (d = 0; d < conf->raid_disks; d++) {
                        if (d == sh->pd_idx || d == sh->qd_idx)
@@ -4189,6 +4198,7 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
                                goto again;
                        }
                }
+               set_bit(STRIPE_DISCARD, &sh->state);
                finish_wait(&conf->wait_for_overlap, &w);
                for (d = 0; d < conf->raid_disks; d++) {
                        if (d == sh->pd_idx || d == sh->qd_idx)
index 18b2c4a8a1fdf55af4af03ccd5ca71d2e84db1cb..b0b663b119a8f324ba7fa3b58953b42c81030fa4 100644 (file)
@@ -221,10 +221,6 @@ struct stripe_head {
        struct stripe_operations {
                int                  target, target2;
                enum sum_check_flags zero_sum_result;
-               #ifdef CONFIG_MULTICORE_RAID456
-               unsigned long        request;
-               wait_queue_head_t    wait_for_ops;
-               #endif
        } ops;
        struct r5dev {
                /* rreq and rvec are used for the replacement device when
@@ -323,6 +319,7 @@ enum {
        STRIPE_COMPUTE_RUN,
        STRIPE_OPS_REQ_PENDING,
        STRIPE_ON_UNPLUG_LIST,
+       STRIPE_DISCARD,
 };
 
 /*
index 6e50a758156817834e314bd7ca6222a8c9c8f2e2..73fc7fe007511e722cf905fc4fc6202bc9d4dad9 100644 (file)
@@ -2492,11 +2492,8 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 
        if (dvbdev->users == -1) {
                wake_up(&fepriv->wait_queue);
-               if (fepriv->exit != DVB_FE_NO_EXIT) {
-                       fops_put(file->f_op);
-                       file->f_op = NULL;
+               if (fepriv->exit != DVB_FE_NO_EXIT)
                        wake_up(&dvbdev->wait_queue);
-               }
                if (fe->ops.ts_bus_ctrl)
                        fe->ops.ts_bus_ctrl(fe, 0);
        }
index 44225b186f6df4a42945a8f9998361558d470451..59ba60659a3e7b38f182bdcdc581fbb58855af75 100644 (file)
@@ -1479,11 +1479,8 @@ static int dvb_net_close(struct inode *inode, struct file *file)
 
        dvb_generic_release(inode, file);
 
-       if(dvbdev->users == 1 && dvbnet->exit == 1) {
-               fops_put(file->f_op);
-               file->f_op = NULL;
+       if(dvbdev->users == 1 && dvbnet->exit == 1)
                wake_up(&dvbdev->wait_queue);
-       }
        return 0;
 }
 
index 87491ca05ee556fc9b7b4fc4c2112684fc997604..d6dfb5765d0ba3006fef715cde707b455b89b11e 100644 (file)
@@ -259,79 +259,46 @@ void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
 static int cx25821_get_audio_data(struct cx25821_dev *dev,
                           struct sram_channel *sram_ch)
 {
-       struct file *myfile;
+       struct file *file;
        int frame_index_temp = dev->_audioframe_index;
        int i = 0;
-       int line_size = AUDIO_LINE_SIZE;
        int frame_size = AUDIO_DATA_BUF_SZ;
        int frame_offset = frame_size * frame_index_temp;
-       ssize_t vfs_read_retval = 0;
-       char mybuf[line_size];
+       char mybuf[AUDIO_LINE_SIZE];
        loff_t file_offset = dev->_audioframe_count * frame_size;
-       loff_t pos;
-       mm_segment_t old_fs;
+       char *p = NULL;
 
        if (dev->_audiofile_status == END_OF_FILE)
                return 0;
 
-       myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+       file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+       if (IS_ERR(file)) {
+               pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n",
+                      __func__, dev->_audiofilename, -PTR_ERR(file));
+               return PTR_ERR(file);
+       }
 
-       if (IS_ERR(myfile)) {
-               const int open_errno = -PTR_ERR(myfile);
-               pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
-                      __func__, dev->_audiofilename, open_errno);
-               return PTR_ERR(myfile);
-       } else {
-               if (!(myfile->f_op)) {
-                       pr_err("%s(): File has no file operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
+       if (dev->_audiodata_buf_virt_addr)
+               p = (char *)dev->_audiodata_buf_virt_addr + frame_offset;
 
-               if (!myfile->f_op->read) {
-                       pr_err("%s(): File has no READ operations registered!\n",
+       for (i = 0; i < dev->_audio_lines_count; i++) {
+               int n = kernel_read(file, file_offset, mybuf, AUDIO_LINE_SIZE);
+               if (n < AUDIO_LINE_SIZE) {
+                       pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
                                __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
+                       dev->_audiofile_status = END_OF_FILE;
+                       fput(file);
+                       return 0;
                }
-
-               pos = myfile->f_pos;
-               old_fs = get_fs();
-               set_fs(KERNEL_DS);
-
-               for (i = 0; i < dev->_audio_lines_count; i++) {
-                       pos = file_offset;
-
-                       vfs_read_retval = vfs_read(myfile, mybuf, line_size,
-                                                                       &pos);
-
-                       if (vfs_read_retval > 0 && vfs_read_retval == line_size
-                           && dev->_audiodata_buf_virt_addr != NULL) {
-                               memcpy((void *)(dev->_audiodata_buf_virt_addr +
-                                               frame_offset / 4), mybuf,
-                                       vfs_read_retval);
-                       }
-
-                       file_offset += vfs_read_retval;
-                       frame_offset += vfs_read_retval;
-
-                       if (vfs_read_retval < line_size) {
-                               pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
-                                       __func__);
-                               break;
-                       }
+               dev->_audiofile_status = IN_PROGRESS;
+               if (p) {
+                       memcpy(p, mybuf, n);
+                       p += n;
                }
-
-               if (i > 0)
-                       dev->_audioframe_count++;
-
-               dev->_audiofile_status = (vfs_read_retval == line_size) ?
-                                               IN_PROGRESS : END_OF_FILE;
-
-               set_fs(old_fs);
-               filp_close(myfile, NULL);
+               file_offset += n;
        }
+       dev->_audioframe_count++;
+       fput(file);
 
        return 0;
 }
@@ -354,81 +321,41 @@ static void cx25821_audioups_handler(struct work_struct *work)
 static int cx25821_openfile_audio(struct cx25821_dev *dev,
                           struct sram_channel *sram_ch)
 {
-       struct file *myfile;
-       int i = 0, j = 0;
-       int line_size = AUDIO_LINE_SIZE;
-       ssize_t vfs_read_retval = 0;
-       char mybuf[line_size];
-       loff_t pos;
-       loff_t offset = (unsigned long)0;
-       mm_segment_t old_fs;
-
-       myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
-
-       if (IS_ERR(myfile)) {
-               const int open_errno = -PTR_ERR(myfile);
-               pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
-                       __func__, dev->_audiofilename, open_errno);
-               return PTR_ERR(myfile);
-       } else {
-               if (!(myfile->f_op)) {
-                       pr_err("%s(): File has no file operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
-
-               if (!myfile->f_op->read) {
-                       pr_err("%s(): File has no READ operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
-
-               pos = myfile->f_pos;
-               old_fs = get_fs();
-               set_fs(KERNEL_DS);
-
-               for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
-                       for (i = 0; i < dev->_audio_lines_count; i++) {
-                               pos = offset;
-
-                               vfs_read_retval = vfs_read(myfile, mybuf,
-                                               line_size, &pos);
-
-                               if (vfs_read_retval > 0 &&
-                                   vfs_read_retval == line_size &&
-                                   dev->_audiodata_buf_virt_addr != NULL) {
-                                       memcpy((void *)(dev->
-                                                       _audiodata_buf_virt_addr
-                                                       + offset / 4), mybuf,
-                                              vfs_read_retval);
-                               }
+       char *p = (void *)dev->_audiodata_buf_virt_addr;
+       struct file *file;
+       loff_t offset;
+       int i, j;
+
+       file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+       if (IS_ERR(file)) {
+               pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n",
+                       __func__, dev->_audiofilename, PTR_ERR(file));
+               return PTR_ERR(file);
+       }
 
-                               offset += vfs_read_retval;
+       for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) {
+               for (i = 0; i < dev->_audio_lines_count; i++) {
+                       char buf[AUDIO_LINE_SIZE];
+                       int n = kernel_read(file, offset, buf,
+                                               AUDIO_LINE_SIZE);
 
-                               if (vfs_read_retval < line_size) {
-                                       pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
-                                               __func__);
-                                       break;
-                               }
+                       if (n < AUDIO_LINE_SIZE) {
+                               pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+                                       __func__);
+                               dev->_audiofile_status = END_OF_FILE;
+                               fput(file);
+                               return 0;
                        }
 
-                       if (i > 0)
-                               dev->_audioframe_count++;
+                       if (p)
+                               memcpy(p + offset, buf, n);
 
-                       if (vfs_read_retval < line_size)
-                               break;
+                       offset += n;
                }
-
-               dev->_audiofile_status = (vfs_read_retval == line_size) ?
-                                               IN_PROGRESS : END_OF_FILE;
-
-               set_fs(old_fs);
-               myfile->f_pos = 0;
-               filp_close(myfile, NULL);
+               dev->_audioframe_count++;
        }
-
+       dev->_audiofile_status = IN_PROGRESS;
+       fput(file);
        return 0;
 }
 
index eb822862a6467fdc096fd9f992d8c6b863045cb2..0e763a784e2b44d6d12c78d83cc2be5cbc7918ab 100644 (file)
@@ -375,7 +375,7 @@ int av7110_ir_init(struct av7110 *av7110)
        if (av_cnt == 1) {
                e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
                if (e)
-                       e->size = 4 + 256 * sizeof(u16);
+                       proc_set_size(e, 4 + 256 * sizeof(u16));
        }
 
        tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
index e084b0a21b1b2dfd3b616ed7449d782e7b43dd89..f7ceee0cdefdee4d5ef1b64429bc02d309a8c5e8 100644 (file)
@@ -130,14 +130,14 @@ static int zoran_show(struct seq_file *p, void *v)
 
 static int zoran_open(struct inode *inode, struct file *file)
 {
-       struct zoran *data = PDE(inode)->data;
+       struct zoran *data = PDE_DATA(inode);
        return single_open(file, zoran_show, data);
 }
 
 static ssize_t zoran_write(struct file *file, const char __user *buffer,
                        size_t count, loff_t *ppos)
 {
-       struct zoran *zr = PDE(file_inode(file))->data;
+       struct zoran *zr = PDE_DATA(file_inode(file));
        char *string, *sp;
        char *line, *ldelim, *varname, *svar, *tdelim;
 
@@ -201,7 +201,7 @@ zoran_proc_init (struct zoran *zr)
                dprintk(2,
                        KERN_INFO
                        "%s: procfs entry /proc/%s allocated. data=%p\n",
-                       ZR_DEVNAME(zr), name, zr->zoran_proc->data);
+                       ZR_DEVNAME(zr), name, zr);
        } else {
                dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",
                        ZR_DEVNAME(zr), name);
index 9945e5e7f61a6d58d94105c6f5a6a3c9555d93fb..8ee080ef2f2c636cc743f1c28c0f978b0871fc4c 100644 (file)
@@ -307,7 +307,7 @@ static void ir_lirc_close(void *data)
        return;
 }
 
-static struct file_operations lirc_fops = {
+static const struct file_operations lirc_fops = {
        .owner          = THIS_MODULE,
        .write          = ir_lirc_transmit_ir,
        .unlocked_ioctl = ir_lirc_ioctl,
index 5247d94fea29f354a351333a0d0d3020e94ca684..8dc057b273f25b49f7f4960896828c9437e3b489 100644 (file)
@@ -152,7 +152,7 @@ static int lirc_thread(void *irctl)
 }
 
 
-static struct file_operations lirc_dev_fops = {
+static const struct file_operations lirc_dev_fops = {
        .owner          = THIS_MODULE,
        .read           = lirc_dev_fop_read,
        .write          = lirc_dev_fop_write,
index fb69baa06ca88f8b0cdd60b6ac79fc6fbc7ba118..767ff4d839f448168e475ba3e506350977490ac6 100644 (file)
@@ -6656,7 +6656,7 @@ static int mpt_summary_proc_show(struct seq_file *m, void *v)
 
 static int mpt_summary_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, mpt_summary_proc_show, PDE(inode)->data);
+       return single_open(file, mpt_summary_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations mpt_summary_proc_fops = {
@@ -6805,7 +6805,7 @@ static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
 
 static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data);
+       return single_open(file, mpt_iocinfo_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations mpt_iocinfo_proc_fops = {
index b383b6961e59549c8075b197d89adb6417b252cf..dcc8385adeb3b8b830a58cfad62f19604122a52b 100644 (file)
@@ -596,13 +596,6 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
        return 1;
 }
 
-static int
-mptctl_release(struct inode *inode, struct file *filep)
-{
-       fasync_helper(-1, filep, 0, &async_queue);
-       return 0;
-}
-
 static int
 mptctl_fasync(int fd, struct file *filep, int mode)
 {
@@ -2822,7 +2815,6 @@ static const struct file_operations mptctl_fops = {
        .llseek =       no_llseek,
        .fasync =       mptctl_fasync,
        .unlocked_ioctl = mptctl_ioctl,
-       .release =      mptctl_release,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = compat_mpctl_ioctl,
 #endif
index c13cd9bc590b91c83a7ab03308acf2bfaa9f7ae7..fd75108c355e49b5c4ea035f60139b6a466c9a2c 100644 (file)
@@ -109,7 +109,7 @@ static int mptfc_host_reset(struct scsi_cmnd *SCpnt);
 static struct scsi_host_template mptfc_driver_template = {
        .module                         = THIS_MODULE,
        .proc_name                      = "mptfc",
-       .proc_info                      = mptscsih_proc_info,
+       .show_info                      = mptscsih_show_info,
        .name                           = "MPT FC Host",
        .info                           = mptscsih_info,
        .queuecommand                   = mptfc_qcmd,
index fa43c391c8ed1072b35200ba671623c933c1df80..ffee6f781e30f6a25537bba1ed44f379aee137fd 100644 (file)
@@ -1977,7 +1977,7 @@ done:
 static struct scsi_host_template mptsas_driver_template = {
        .module                         = THIS_MODULE,
        .proc_name                      = "mptsas",
-       .proc_info                      = mptscsih_proc_info,
+       .show_info                      = mptscsih_show_info,
        .name                           = "MPT SAS Host",
        .info                           = mptscsih_info,
        .queuecommand                   = mptsas_qcmd,
index 164afa71bba7a0bae51aaeb0509237a15d590dbe..727819cc703422578c1f0f71c77efff1333f1c6c 100644 (file)
@@ -1284,101 +1284,17 @@ mptscsih_info(struct Scsi_Host *SChost)
        return h->info_kbuf;
 }
 
-struct info_str {
-       char *buffer;
-       int   length;
-       int   offset;
-       int   pos;
-};
-
-static void
-mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
-{
-       if (info->pos + len > info->length)
-               len = info->length - info->pos;
-
-       if (info->pos + len < info->offset) {
-               info->pos += len;
-               return;
-       }
-
-       if (info->pos < info->offset) {
-               data += (info->offset - info->pos);
-               len  -= (info->offset - info->pos);
-       }
-
-       if (len > 0) {
-                memcpy(info->buffer + info->pos, data, len);
-                info->pos += len;
-       }
-}
-
-static int
-mptscsih_copy_info(struct info_str *info, char *fmt, ...)
-{
-       va_list args;
-       char buf[81];
-       int len;
-
-       va_start(args, fmt);
-       len = vsprintf(buf, fmt, args);
-       va_end(args);
-
-       mptscsih_copy_mem_info(info, buf, len);
-       return len;
-}
-
-static int
-mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
-{
-       struct info_str info;
-
-       info.buffer     = pbuf;
-       info.length     = len;
-       info.offset     = offset;
-       info.pos        = 0;
-
-       mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
-       mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
-       mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
-       mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
-
-       return ((info.pos > info.offset) ? info.pos - info.offset : 0);
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *     mptscsih_proc_info - Return information about MPT adapter
- *     @host:   scsi host struct
- *     @buffer: if write, user data; if read, buffer for user
- *     @start: returns the buffer address
- *     @offset: if write, 0; if read, the current offset into the buffer from
- *              the previous read.
- *     @length: if write, return length;
- *     @func:   write = 1; read = 0
- *
- *     (linux scsi_host_template.info routine)
- */
-int
-mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                       int length, int func)
+int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        MPT_SCSI_HOST   *hd = shost_priv(host);
        MPT_ADAPTER     *ioc = hd->ioc;
-       int size = 0;
 
-       if (func) {
-               /*
-                * write is not supported
-                */
-       } else {
-               if (start)
-                       *start = buffer;
-
-               size = mptscsih_host_info(ioc, buffer, offset, length);
-       }
+       seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
+       seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
+       seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
+       seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
 
-       return size;
+       return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3348,7 +3264,7 @@ EXPORT_SYMBOL(mptscsih_shutdown);
 EXPORT_SYMBOL(mptscsih_suspend);
 EXPORT_SYMBOL(mptscsih_resume);
 #endif
-EXPORT_SYMBOL(mptscsih_proc_info);
+EXPORT_SYMBOL(mptscsih_show_info);
 EXPORT_SYMBOL(mptscsih_info);
 EXPORT_SYMBOL(mptscsih_qcmd);
 EXPORT_SYMBOL(mptscsih_slave_destroy);
index 43e75ff39921b6556e8e2acb36685dc227d4961e..83f503162f7a46846ce4e842362ca83782d49f75 100644 (file)
@@ -111,7 +111,7 @@ extern void mptscsih_shutdown(struct pci_dev *);
 extern int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
 extern int mptscsih_resume(struct pci_dev *pdev);
 #endif
-extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
+extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *);
 extern const char * mptscsih_info(struct Scsi_Host *SChost);
 extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
 extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
index c3aabde2dc4fad50bb0781757bff0605121ba5b0..5653e505f91ff0af540db4e7bb973ef3f03059a4 100644 (file)
@@ -831,7 +831,7 @@ static void mptspi_slave_destroy(struct scsi_device *sdev)
 static struct scsi_host_template mptspi_driver_template = {
        .module                         = THIS_MODULE,
        .proc_name                      = "mptspi",
-       .proc_info                      = mptscsih_proc_info,
+       .show_info                      = mptscsih_show_info,
        .name                           = "MPT SPI Host",
        .info                           = mptscsih_info,
        .queuecommand                   = mptspi_qcmd,
index 8001aa6bfb4809caf35c25ee758330dc3d08751a..b7d87cd227a902b4de1c405dcf726419217b1adc 100644 (file)
@@ -1599,98 +1599,98 @@ static int i2o_seq_show_sensors(struct seq_file *seq, void *v)
 
 static int i2o_seq_open_hrt(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_hrt, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_hrt, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_lct(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_lct, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_lct, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_status(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_status, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_status, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_hw(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_hw, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_hw, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_ddm_table(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_ddm_table, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_ddm_table, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_driver_store(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_driver_store, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_driver_store, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_drivers_stored(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_drivers_stored, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_drivers_stored, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_groups(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_groups, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_groups, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_phys_device(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_phys_device, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_phys_device, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_claimed(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_claimed, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_claimed, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_users(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_users, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_users, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_priv_msgs(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_priv_msgs, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_priv_msgs, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_authorized_users(struct inode *inode, struct file *file)
 {
        return single_open(file, i2o_seq_show_authorized_users,
-                          PDE(inode)->data);
+                          PDE_DATA(inode));
 };
 
 static int i2o_seq_open_dev_identity(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_dev_identity, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_dev_identity, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_ddm_identity(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_ddm_identity, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_ddm_identity, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_uinfo(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_uinfo, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_uinfo, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_sgl_limits(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_sgl_limits, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_sgl_limits, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_sensors(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_sensors, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_sensors, PDE_DATA(inode));
 };
 
 static int i2o_seq_open_dev_name(struct inode *inode, struct file *file)
 {
-       return single_open(file, i2o_seq_show_dev_name, PDE(inode)->data);
+       return single_open(file, i2o_seq_show_dev_name, PDE_DATA(inode));
 };
 
 static const struct file_operations i2o_seq_fops_lct = {
@@ -1894,25 +1894,6 @@ static int i2o_proc_create_entries(struct proc_dir_entry *dir,
        return 0;
 }
 
-/**
- *     i2o_proc_subdir_remove - Remove child entries from a proc entry
- *     @dir: proc dir entry from which the childs should be removed
- *
- *     Iterate over each i2o proc entry under dir and remove it. If the child
- *     also has entries, remove them too.
- */
-static void i2o_proc_subdir_remove(struct proc_dir_entry *dir)
-{
-       struct proc_dir_entry *pe, *tmp;
-       pe = dir->subdir;
-       while (pe) {
-               tmp = pe->next;
-               i2o_proc_subdir_remove(pe);
-               remove_proc_entry(pe->name, dir);
-               pe = tmp;
-       }
-};
-
 /**
  *     i2o_proc_device_add - Add an I2O device to the proc dir
  *     @dir: proc dir entry to which the device should be added
@@ -1932,14 +1913,12 @@ static void i2o_proc_device_add(struct proc_dir_entry *dir,
 
        osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff);
 
-       devdir = proc_mkdir(buff, dir);
+       devdir = proc_mkdir_data(buff, 0, dir, dev);
        if (!devdir) {
                osm_warn("Could not allocate procdir!\n");
                return;
        }
 
-       devdir->data = dev;
-
        i2o_proc_create_entries(devdir, generic_dev_entries, dev);
 
        /* Inform core that we want updates about this device's status */
@@ -1973,12 +1952,10 @@ static int i2o_proc_iop_add(struct proc_dir_entry *dir,
 
        osm_debug("adding IOP /proc/i2o/%s\n", c->name);
 
-       iopdir = proc_mkdir(c->name, dir);
+       iopdir = proc_mkdir_data(c->name, 0, dir, c);
        if (!iopdir)
                return -1;
 
-       iopdir->data = c;
-
        i2o_proc_create_entries(iopdir, i2o_proc_generic_iop_entries, c);
 
        list_for_each_entry(dev, &c->devices, list)
@@ -1987,31 +1964,6 @@ static int i2o_proc_iop_add(struct proc_dir_entry *dir,
        return 0;
 }
 
-/**
- *     i2o_proc_iop_remove - Removes an I2O controller from the i2o proc tree
- *     @dir: parent proc dir entry
- *     @c: I2O controller which should be removed
- *
- *     Iterate over each i2o proc entry and search controller c. If it is found
- *     remove it from the tree.
- */
-static void i2o_proc_iop_remove(struct proc_dir_entry *dir,
-                               struct i2o_controller *c)
-{
-       struct proc_dir_entry *pe, *tmp;
-
-       pe = dir->subdir;
-       while (pe) {
-               tmp = pe->next;
-               if (pe->data == c) {
-                       i2o_proc_subdir_remove(pe);
-                       remove_proc_entry(pe->name, dir);
-               }
-               osm_debug("removing IOP /proc/i2o/%s\n", c->name);
-               pe = tmp;
-       }
-}
-
 /**
  *     i2o_proc_fs_create - Create the i2o proc fs.
  *
@@ -2042,12 +1994,7 @@ static int __init i2o_proc_fs_create(void)
  */
 static int __exit i2o_proc_fs_destroy(void)
 {
-       struct i2o_controller *c;
-
-       list_for_each_entry(c, &i2o_controllers, list)
-           i2o_proc_iop_remove(i2o_proc_dir_root, c);
-
-       remove_proc_entry("i2o", NULL);
+       remove_proc_subtree("i2o", NULL);
 
        return 0;
 };
index 671f5b171c737d78c9659d2afe3a68e02fd3981f..c346941a251593bbe42bd8f3d3171acc6a93c2cf 100644 (file)
@@ -858,6 +858,7 @@ config EZX_PCAP
 config AB8500_CORE
        bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
        depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU
+       select POWER_SUPPLY
        select MFD_CORE
        select IRQ_DOMAIN
        help
index b1f3561b023f0aaa4939bc469e3c0a40a718d0db..5f341a50ee5a5783e6e84118124e9efcfe177bd3 100644 (file)
@@ -594,9 +594,12 @@ static int ab8500_gpadc_runtime_suspend(struct device *dev)
 static int ab8500_gpadc_runtime_resume(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
+       int ret;
 
-       regulator_enable(gpadc->regu);
-       return 0;
+       ret = regulator_enable(gpadc->regu);
+       if (ret)
+               dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
+       return ret;
 }
 
 static int ab8500_gpadc_runtime_idle(struct device *dev)
@@ -643,7 +646,7 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
        }
 
        /* VTVout LDO used to power up ab8500-GPADC */
-       gpadc->regu = regulator_get(&pdev->dev, "vddadc");
+       gpadc->regu = devm_regulator_get(&pdev->dev, "vddadc");
        if (IS_ERR(gpadc->regu)) {
                ret = PTR_ERR(gpadc->regu);
                dev_err(gpadc->dev, "failed to get vtvout LDO\n");
@@ -652,7 +655,11 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, gpadc);
 
-       regulator_enable(gpadc->regu);
+       ret = regulator_enable(gpadc->regu);
+       if (ret) {
+               dev_err(gpadc->dev, "Failed to enable vtvout LDO: %d\n", ret);
+               goto fail_enable;
+       }
 
        pm_runtime_set_autosuspend_delay(gpadc->dev, GPADC_AUDOSUSPEND_DELAY);
        pm_runtime_use_autosuspend(gpadc->dev);
@@ -663,6 +670,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
        list_add_tail(&gpadc->node, &ab8500_gpadc_list);
        dev_dbg(gpadc->dev, "probe success\n");
        return 0;
+
+fail_enable:
 fail_irq:
        free_irq(gpadc->irq, gpadc);
 fail:
index 6b5edf64de2b3a4eafbdc0ace93a5a4bd2d4caea..4febc5c7fdeece4a87be9c2dca0eb642357d4cc7 100644 (file)
@@ -460,15 +460,15 @@ static void omap_usbhs_init(struct device *dev)
 
        switch (omap->usbhs_rev) {
        case OMAP_USBHS_REV1:
-               omap_usbhs_rev1_hostconfig(omap, reg);
+               reg = omap_usbhs_rev1_hostconfig(omap, reg);
                break;
 
        case OMAP_USBHS_REV2:
-               omap_usbhs_rev2_hostconfig(omap, reg);
+               reg = omap_usbhs_rev2_hostconfig(omap, reg);
                break;
 
        default:        /* newer revisions */
-               omap_usbhs_rev2_hostconfig(omap, reg);
+               reg = omap_usbhs_rev2_hostconfig(omap, reg);
                break;
        }
 
index bbdbc50a3ccadb7ec98d5d6cd6176c36b9d85a50..73bf76df1044cc70b04bc383d2ad7ec9384a7fcc 100644 (file)
@@ -257,9 +257,24 @@ static struct regmap_irq_chip palmas_irq_chip = {
                        PALMAS_INT1_MASK),
 };
 
-static void palmas_dt_to_pdata(struct device_node *node,
+static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
                struct palmas_platform_data *pdata)
 {
+       struct irq_data *irq_data = irq_get_irq_data(i2c->irq);
+       if (!irq_data) {
+               dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
+               return -EINVAL;
+       }
+
+       pdata->irq_flags = irqd_get_trigger_type(irq_data);
+       dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags);
+       return 0;
+}
+
+static void palmas_dt_to_pdata(struct i2c_client *i2c,
+               struct palmas_platform_data *pdata)
+{
+       struct device_node *node = i2c->dev.of_node;
        int ret;
        u32 prop;
 
@@ -283,6 +298,8 @@ static void palmas_dt_to_pdata(struct device_node *node,
                pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
                                        PALMAS_POWER_CTRL_ENABLE1_MASK |
                                        PALMAS_POWER_CTRL_ENABLE2_MASK;
+       if (i2c->irq)
+               palmas_set_pdata_irq_flag(i2c, pdata);
 }
 
 static int palmas_i2c_probe(struct i2c_client *i2c,
@@ -304,7 +321,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
                if (!pdata)
                        return -ENOMEM;
 
-               palmas_dt_to_pdata(node, pdata);
+               palmas_dt_to_pdata(i2c, pdata);
        }
 
        if (!pdata)
@@ -344,6 +361,19 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
                }
        }
 
+       /* Change interrupt line output polarity */
+       if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH)
+               reg = PALMAS_POLARITY_CTRL_INT_POLARITY;
+       else
+               reg = 0;
+       ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE,
+                       PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY,
+                       reg);
+       if (ret < 0) {
+               dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
+               goto err;
+       }
+
        /* Change IRQ into clear on read mode for efficiency */
        slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE);
        addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL);
@@ -352,7 +382,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
        regmap_write(palmas->regmap[slave], addr, reg);
 
        ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
-                       IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
+                       IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
                        &palmas->irq_data);
        if (ret < 0)
                goto err;
index 4658b5bdcd84488d3379a2ef4f33e334eb96ea2f..aeb8e40ab4249ac2acdbdb43d7149ca8ca5efde4 100644 (file)
@@ -169,6 +169,7 @@ err:
 void tps65912_device_exit(struct tps65912 *tps65912)
 {
        mfd_remove_devices(tps65912->dev);
+       tps65912_irq_exit(tps65912);
        kfree(tps65912);
 }
 
index e16edca926709bbe501d52dc5fb37f578e9710a4..d2ab222138c29eb24ed8d62247928dda7127b31d 100644 (file)
@@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource);
  * Disable the resource.
  * The function returns with error or the content of the register
  */
-int twl4030_audio_disable_resource(unsigned id)
+int twl4030_audio_disable_resource(enum twl4030_audio_res id)
 {
        struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
        int val;
index 88ff9dc83305e2d2a644c6c049abb35439c2b5ad..942b666a2a07b20ad02f97b864500db0259b8669 100644 (file)
@@ -800,7 +800,7 @@ static int twl4030_madc_remove(struct platform_device *pdev)
 
 static struct platform_driver twl4030_madc_driver = {
        .probe = twl4030_madc_probe,
-       .remove = __exit_p(twl4030_madc_remove),
+       .remove = twl4030_madc_remove,
        .driver = {
                   .name = "twl4030_madc",
                   .owner = THIS_MODULE,
index 6673e578b3e9a00bce4a949cc19495359c66ebda..ce5b75616b453dd49c8fce21cf699fb465b6f4ad 100644 (file)
@@ -110,6 +110,7 @@ static struct file_system_type ibmasmfs_type = {
        .mount          = ibmasmfs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("ibmasmfs");
 
 static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
 {
index 4a87e5c0a3200955e1889edfc441753655bc8b5a..4cd4a3d2a76aa868feba01b1b9a0ad1a7431cc99 100644 (file)
@@ -593,7 +593,6 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
        struct lis3lv02d *lis3 = container_of(file->private_data,
                                              struct lis3lv02d, miscdev);
 
-       fasync_helper(-1, file, 0, &lis3->async_queue);
        clear_bit(0, &lis3->misc_opened); /* release the device */
        if (lis3->pm_dev)
                pm_runtime_put(lis3->pm_dev);
index 950dbe9ecb36540a5eaaffaa63b62ed976360763..797d7962cc8831ce70b3dd852874cd4ab6a02ca0 100644 (file)
@@ -355,7 +355,7 @@ static void delete_proc_files(void)
                for (p = proc_files; p->name; p++)
                        if (p->entry)
                                remove_proc_entry(p->name, proc_gru);
-               remove_proc_entry("gru", proc_gru->parent);
+               proc_remove(proc_gru);
        }
 }
 
index 63feb75cc8e01d2048949343955023b01fc7fadc..9279a9174f84ad9cd3a2ae2c7117c29cc8134e9e 100644 (file)
 /* 10 parts were found on sflash on Netgear WNDR4500 */
 #define BCM47XXPART_MAX_PARTS          12
 
+/*
+ * Amount of bytes we read when analyzing each block of flash memory.
+ * Set it big enough to allow detecting partition and reading important data.
+ */
+#define BCM47XXPART_BYTES_TO_READ      0x404
+
 /* Magics */
 #define BOARD_DATA_MAGIC               0x5246504D      /* MPFR */
 #define POT_MAGIC1                     0x54544f50      /* POTT */
@@ -57,17 +63,15 @@ static int bcm47xxpart_parse(struct mtd_info *master,
        struct trx_header *trx;
        int trx_part = -1;
        int last_trx_part = -1;
-       int max_bytes_to_read = 0x8004;
+       int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
 
        if (blocksize <= 0x10000)
                blocksize = 0x10000;
-       if (blocksize == 0x20000)
-               max_bytes_to_read = 0x18004;
 
        /* Alloc */
        parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
                        GFP_KERNEL);
-       buf = kzalloc(max_bytes_to_read, GFP_KERNEL);
+       buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
 
        /* Parse block by block looking for magics */
        for (offset = 0; offset <= master->size - blocksize;
@@ -82,7 +86,7 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                }
 
                /* Read beginning of the block */
-               if (mtd_read(master, offset, max_bytes_to_read,
+               if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
                             &bytes_read, (uint8_t *)buf) < 0) {
                        pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
                               offset);
@@ -96,20 +100,6 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                        continue;
                }
 
-               /* Standard NVRAM */
-               if (buf[0x000 / 4] == NVRAM_HEADER ||
-                   buf[0x1000 / 4] == NVRAM_HEADER ||
-                   buf[0x8000 / 4] == NVRAM_HEADER ||
-                   (blocksize == 0x20000 && (
-                     buf[0x10000 / 4] == NVRAM_HEADER ||
-                     buf[0x11000 / 4] == NVRAM_HEADER ||
-                     buf[0x18000 / 4] == NVRAM_HEADER))) {
-                       bcm47xxpart_add_part(&parts[curr_part++], "nvram",
-                                            offset, 0);
-                       offset = rounddown(offset, blocksize);
-                       continue;
-               }
-
                /*
                 * board_data starts with board_id which differs across boards,
                 * but we can use 'MPFR' (hopefully) magic at 0x100
@@ -178,6 +168,30 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                        continue;
                }
        }
+
+       /* Look for NVRAM at the end of the last block. */
+       for (i = 0; i < ARRAY_SIZE(possible_nvram_sizes); i++) {
+               if (curr_part > BCM47XXPART_MAX_PARTS) {
+                       pr_warn("Reached maximum number of partitions, scanning stopped!\n");
+                       break;
+               }
+
+               offset = master->size - possible_nvram_sizes[i];
+               if (mtd_read(master, offset, 0x4, &bytes_read,
+                            (uint8_t *)buf) < 0) {
+                       pr_err("mtd_read error while reading at offset 0x%X!\n",
+                              offset);
+                       continue;
+               }
+
+               /* Standard NVRAM */
+               if (buf[0] == NVRAM_HEADER) {
+                       bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+                                            master->size - blocksize, 0);
+                       break;
+               }
+       }
+
        kfree(buf);
 
        /*
index 82c06165d3d27351f3cebf9966b513b6669e96bf..92ab30ab00dcab1d0bc6405a94bbe3aeffcfb128 100644 (file)
@@ -1238,6 +1238,7 @@ static struct file_system_type mtd_inodefs_type = {
        .mount = mtd_inodefs_mount,
        .kill_sb = kill_anon_super,
 };
+MODULE_ALIAS_FS("mtd_inodefs");
 
 static int __init init_mtdchar(void)
 {
index 61d5f56473e11cc32c923d12f0f30f26cee4c557..322ca65b0cc59fe5fd0dcf4c13ce71f9f91e2753 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/idr.h>
 #include <linux/backing-dev.h>
 #include <linux/gfp.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 43214151b882bcf4d2717eb48f20b1b2e0fd9a46..42c63927609dbee8697c691c8e97515cf509b990 100644 (file)
@@ -1523,6 +1523,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                                        oobreadlen -= toread;
                                }
                        }
+
+                       if (chip->options & NAND_NEED_READRDY) {
+                               /* Apply delay or wait for ready/busy pin */
+                               if (!chip->dev_ready)
+                                       udelay(chip->chip_delay);
+                               else
+                                       nand_wait_ready(mtd);
+                       }
                } else {
                        memcpy(buf, chip->buffers->databuf + col, bytes);
                        buf += bytes;
@@ -1787,6 +1795,14 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                len = min(len, readlen);
                buf = nand_transfer_oob(chip, buf, ops, len);
 
+               if (chip->options & NAND_NEED_READRDY) {
+                       /* Apply delay or wait for ready/busy pin */
+                       if (!chip->dev_ready)
+                               udelay(chip->chip_delay);
+                       else
+                               nand_wait_ready(mtd);
+               }
+
                readlen -= len;
                if (!readlen)
                        break;
index e3aa2748a6e7af1cac818aaa170d5f6aff253056..9c612388e5deff15def3bc8014fd1d6408222142 100644 (file)
 *      512     512 Byte page size
 */
 struct nand_flash_dev nand_flash_ids[] = {
+#define SP_OPTIONS NAND_NEED_READRDY
+#define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16)
 
 #ifdef CONFIG_MTD_NAND_MUSEUM_IDS
-       {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, 0},
-       {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, 0},
-       {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, 0},
-       {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, 0},
-       {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, 0},
-       {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, 0},
-       {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, 0},
-       {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, 0},
-       {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, 0},
-       {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, 0},
-
-       {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, 0},
-       {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, 0},
-       {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
-       {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
+       {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, SP_OPTIONS},
+       {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, SP_OPTIONS},
+       {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, SP_OPTIONS},
+       {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, SP_OPTIONS},
+       {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, SP_OPTIONS},
+       {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, SP_OPTIONS},
+       {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, SP_OPTIONS},
+       {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, SP_OPTIONS},
+       {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, SP_OPTIONS},
+       {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, SP_OPTIONS},
+
+       {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, SP_OPTIONS},
+       {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, SP_OPTIONS},
+       {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, SP_OPTIONS16},
+       {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, SP_OPTIONS16},
 #endif
 
-       {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, 0},
-       {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, 0},
-       {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, 0},
-       {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, 0},
-       {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, 0},
-       {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, 0},
-       {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, 0},
-       {"NAND 128MiB 1,8V 8-bit",      0x39, 512, 128, 0x4000, 0},
-       {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, 0},
-       {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 128MiB 1,8V 16-bit",     0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-       {"NAND 128MiB 3,3V 16-bit",     0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-
-       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, 0},
+       {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, SP_OPTIONS},
+       {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, SP_OPTIONS},
+       {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, SP_OPTIONS16},
+       {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, SP_OPTIONS16},
+
+       {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, SP_OPTIONS},
+       {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, SP_OPTIONS},
+       {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, SP_OPTIONS16},
+       {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, SP_OPTIONS16},
+
+       {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, SP_OPTIONS},
+       {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, SP_OPTIONS},
+       {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, SP_OPTIONS16},
+       {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, SP_OPTIONS16},
+
+       {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, SP_OPTIONS},
+       {"NAND 128MiB 1,8V 8-bit",      0x39, 512, 128, 0x4000, SP_OPTIONS},
+       {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, SP_OPTIONS},
+       {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, SP_OPTIONS16},
+       {"NAND 128MiB 1,8V 16-bit",     0x49, 512, 128, 0x4000, SP_OPTIONS16},
+       {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, SP_OPTIONS16},
+       {"NAND 128MiB 3,3V 16-bit",     0x59, 512, 128, 0x4000, SP_OPTIONS16},
+
+       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, SP_OPTIONS},
 
        /*
         * These are the new chips with large page size. The pagesize and the
index 11d01d67b3f510d7e5d159784aee36f6c612cb12..6bbd90e1123c59c58329505537568a2ec2d5b9b0 100644 (file)
@@ -1629,7 +1629,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        /* If this is the first slave, then we need to set the master's hardware
         * address to be the same as the slave's. */
-       if (bond->dev_addr_from_first)
+       if (bond->slave_cnt == 0 && bond->dev_addr_from_first)
                bond_set_dev_addr(bond->dev, slave_dev);
 
        new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
@@ -1746,6 +1746,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        bond_compute_features(bond);
 
+       bond_update_speed_duplex(new_slave);
+
        read_lock(&bond->lock);
 
        new_slave->last_arp_rx = jiffies -
@@ -1798,8 +1800,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                new_slave->link == BOND_LINK_DOWN ? "DOWN" :
                        (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
 
-       bond_update_speed_duplex(new_slave);
-
        if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
                /* if there is a primary slave, remember it */
                if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
@@ -1964,7 +1964,6 @@ static int __bond_release_one(struct net_device *bond_dev,
        }
 
        block_netpoll_tx();
-       call_netdevice_notifiers(NETDEV_RELEASE, bond_dev);
        write_lock_bh(&bond->lock);
 
        slave = bond_get_slave_by_dev(bond, slave_dev);
@@ -2066,8 +2065,10 @@ static int __bond_release_one(struct net_device *bond_dev,
        write_unlock_bh(&bond->lock);
        unblock_netpoll_tx();
 
-       if (bond->slave_cnt == 0)
+       if (bond->slave_cnt == 0) {
                call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+               call_netdevice_notifiers(NETDEV_RELEASE, bond->dev);
+       }
 
        bond_compute_features(bond);
        if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
@@ -2373,8 +2374,6 @@ static void bond_miimon_commit(struct bonding *bond)
                                bond_set_backup_slave(slave);
                        }
 
-                       bond_update_speed_duplex(slave);
-
                        pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
                                bond->dev->name, slave->dev->name,
                                slave->speed, slave->duplex ? "full" : "half");
index 3cea38d373446826b7163974ed8e0b0836d19dc3..94d06f1307b850f927c85b4b7645f49859b4772b 100644 (file)
@@ -218,15 +218,13 @@ static const struct seq_operations bond_info_seq_ops = {
 static int bond_info_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
-       struct proc_dir_entry *proc;
        int res;
 
        res = seq_open(file, &bond_info_seq_ops);
        if (!res) {
                /* recover the pointer buried in proc_dir_entry data */
                seq = file->private_data;
-               proc = PDE(inode);
-               seq->private = proc->data;
+               seq->private = PDE_DATA(inode);
        }
 
        return res;
index 1c9e09fbdff8346e99413e0313d03ed401f463e2..db103e03ba05b4b32b2efbb168a820fe5f71f999 100644 (file)
@@ -183,6 +183,11 @@ int bond_create_slave_symlinks(struct net_device *master,
        sprintf(linkname, "slave_%s", slave->name);
        ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
                                linkname);
+
+       /* free the master link created earlier in case of error */
+       if (ret)
+               sysfs_remove_link(&(slave->dev.kobj), "master");
+
        return ret;
 
 }
index 639049d7e92de5bda8cd901a711f7cc4626d1302..da5f4397f87c2744e13d4cb3bf0c99fb85d4666a 100644 (file)
@@ -301,12 +301,16 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
                        bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
                                  ring->start);
                } else {
+                       /* Omit CRC. */
+                       len -= ETH_FCS_LEN;
+
                        new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len);
                        if (new_skb) {
                                skb_put(new_skb, len);
                                skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET,
                                                                 new_skb->data,
                                                                 len);
+                               skb_checksum_none_assert(skb);
                                new_skb->protocol =
                                        eth_type_trans(new_skb, bgmac->net_dev);
                                netif_receive_skb(new_skb);
index ecac04a3687c6b2967ccc3e8e1ab78bf2107e4e9..4046f97378c29fa737d7123347ba1e940bd8e46d 100644 (file)
@@ -2760,6 +2760,7 @@ load_error2:
        bp->port.pmf = 0;
 load_error1:
        bnx2x_napi_disable(bp);
+       bnx2x_del_all_napi(bp);
 
        /* clear pf_load status, as it was already set */
        if (IS_PF(bp))
@@ -3142,7 +3143,7 @@ static inline __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix)
                tsum = ~csum_fold(csum_add((__force __wsum) csum,
                                  csum_partial(t_header, -fix, 0)));
 
-       return bswab16(csum);
+       return bswab16(tsum);
 }
 
 static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
index 568205436a15f4d5b37528eb155df6e00ee3f07c..91ecd6a00d05a77453e4311eb5741064ba03ded2 100644 (file)
@@ -2139,12 +2139,12 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
                        break;
                default:
                        BNX2X_ERR("Non valid capability ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "DCB disabled\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap);
@@ -2170,12 +2170,12 @@ static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
                        break;
                default:
                        BNX2X_ERR("Non valid TC-ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "DCB disabled\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        return rval;
@@ -2188,7 +2188,7 @@ static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
        return -EINVAL;
 }
 
-static u8  bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
+static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
 {
        struct bnx2x *bp = netdev_priv(netdev);
        DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
@@ -2390,12 +2390,12 @@ static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
                        break;
                default:
                        BNX2X_ERR("Non valid featrue-ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "DCB disabled\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        return rval;
@@ -2431,12 +2431,12 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
                        break;
                default:
                        BNX2X_ERR("Non valid featrue-ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "dcbnl call not valid\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        return rval;
index 9a674b14b403dc605bfb10c448ea8a175a2614ae..edfa67adf2f975d6b5d6dc382e4cf6d5617a2b3b 100644 (file)
@@ -281,6 +281,8 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        cmd->lp_advertising |= ADVERTISED_2500baseX_Full;
                if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE)
                        cmd->lp_advertising |= ADVERTISED_10000baseT_Full;
+               if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE)
+                       cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full;
        }
 
        cmd->maxtxpkt = 0;
@@ -463,6 +465,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                                                ADVERTISED_10000baseKR_Full))
                                bp->link_params.speed_cap_mask[cfg_idx] |=
                                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10G;
+
+                       if (cmd->advertising & ADVERTISED_20000baseKR2_Full)
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_20G;
                }
        } else { /* forced speed */
                /* advertise the requested speed and duplex if supported */
index 1663e0b6b5a01f0baee17e6584dc6b65cf07344c..77ebae0ac64aa9a4e681a506129c5a835d85ef4e 100644 (file)
@@ -8647,7 +8647,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
                                                MDIO_WC_DEVAD,
                                                MDIO_WC_REG_DIGITAL5_MISC6,
                                                &rx_tx_in_reset);
-                               if (!rx_tx_in_reset) {
+                               if ((!rx_tx_in_reset) &&
+                                   (params->link_flags &
+                                    PHY_INITIALIZED)) {
                                        bnx2x_warpcore_reset_lane(bp, phy, 1);
                                        bnx2x_warpcore_config_sfi(phy, params);
                                        bnx2x_warpcore_reset_lane(bp, phy, 0);
@@ -10422,6 +10424,28 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                                         MDIO_PMA_DEVAD,
                                         MDIO_PMA_REG_8481_LED1_MASK,
                                         0x0);
+                       if (phy->type ==
+                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
+                               /* Disable MI_INT interrupt before setting LED4
+                                * source to constant off.
+                                */
+                               if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
+                                          params->port*4) &
+                                   NIG_MASK_MI_INT) {
+                                       params->link_flags |=
+                                       LINK_FLAGS_INT_DISABLED;
+
+                                       bnx2x_bits_dis(
+                                               bp,
+                                               NIG_REG_MASK_INTERRUPT_PORT0 +
+                                               params->port*4,
+                                               NIG_MASK_MI_INT);
+                               }
+                               bnx2x_cl45_write(bp, phy,
+                                                MDIO_PMA_DEVAD,
+                                                MDIO_PMA_REG_8481_SIGNAL_MASK,
+                                                0x0);
+                       }
                }
                break;
        case LED_MODE_ON:
@@ -10468,6 +10492,28 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                                         MDIO_PMA_DEVAD,
                                         MDIO_PMA_REG_8481_LED1_MASK,
                                         0x20);
+                       if (phy->type ==
+                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
+                               /* Disable MI_INT interrupt before setting LED4
+                                * source to constant on.
+                                */
+                               if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
+                                          params->port*4) &
+                                   NIG_MASK_MI_INT) {
+                                       params->link_flags |=
+                                       LINK_FLAGS_INT_DISABLED;
+
+                                       bnx2x_bits_dis(
+                                               bp,
+                                               NIG_REG_MASK_INTERRUPT_PORT0 +
+                                               params->port*4,
+                                               NIG_MASK_MI_INT);
+                               }
+                               bnx2x_cl45_write(bp, phy,
+                                                MDIO_PMA_DEVAD,
+                                                MDIO_PMA_REG_8481_SIGNAL_MASK,
+                                                0x20);
+                       }
                }
                break;
 
@@ -10532,6 +10578,22 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                                         MDIO_PMA_DEVAD,
                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
                                         val);
+                       if (phy->type ==
+                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
+                               /* Restore LED4 source to external link,
+                                * and re-enable interrupts.
+                                */
+                               bnx2x_cl45_write(bp, phy,
+                                                MDIO_PMA_DEVAD,
+                                                MDIO_PMA_REG_8481_SIGNAL_MASK,
+                                                0x40);
+                               if (params->link_flags &
+                                   LINK_FLAGS_INT_DISABLED) {
+                                       bnx2x_link_int_enable(params);
+                                       params->link_flags &=
+                                               ~LINK_FLAGS_INT_DISABLED;
+                               }
+                       }
                }
                break;
        }
@@ -11791,6 +11853,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
                        phy->media_type = ETH_PHY_KR;
                        phy->flags |= FLAGS_WC_DUAL_MODE;
                        phy->supported &= (SUPPORTED_20000baseKR2_Full |
+                                          SUPPORTED_10000baseT_Full |
+                                          SUPPORTED_1000baseT_Full |
                                           SUPPORTED_Autoneg |
                                           SUPPORTED_FIBRE |
                                           SUPPORTED_Pause |
@@ -12465,6 +12529,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
        vars->mac_type = MAC_TYPE_NONE;
        vars->phy_flags = 0;
+       vars->check_kr2_recovery_cnt = 0;
+       params->link_flags = PHY_INITIALIZED;
        /* Driver opens NIG-BRB filters */
        bnx2x_set_rx_filter(params, 1);
        /* Check if link flap can be avoided */
@@ -12629,6 +12695,7 @@ int bnx2x_lfa_reset(struct link_params *params,
        struct bnx2x *bp = params->bp;
        vars->link_up = 0;
        vars->phy_flags = 0;
+       params->link_flags &= ~PHY_INITIALIZED;
        if (!params->lfa_base)
                return bnx2x_link_reset(params, vars, 1);
        /*
@@ -13349,6 +13416,7 @@ static void bnx2x_disable_kr2(struct link_params *params,
        vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
        bnx2x_update_link_attr(params, vars->link_attr_sync);
 
+       vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT;
        /* Restart AN on leading lane */
        bnx2x_warpcore_restart_AN_KR(phy, params);
 }
@@ -13377,6 +13445,15 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
                return;
        }
 
+       /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
+        * since some switches tend to reinit the AN process and clear the
+        * advertised BP/NP after ~2 seconds causing the KR2 to be disabled
+        * and recovered many times
+        */
+       if (vars->check_kr2_recovery_cnt > 0) {
+               vars->check_kr2_recovery_cnt--;
+               return;
+       }
        lane = bnx2x_get_warpcore_lane(phy, params);
        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
                          MDIO_AER_BLOCK_AER_REG, lane);
@@ -13437,7 +13514,7 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
                struct bnx2x_phy *phy = &params->phy[INT_PHY];
                bnx2x_set_aer_mmd(params, phy);
                if ((phy->supported & SUPPORTED_20000baseKR2_Full) &&
-                   (phy->speed_cap_mask & SPEED_20000))
+                   (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
                        bnx2x_check_kr2_wa(params, vars, phy);
                bnx2x_check_over_curr(params, vars);
                if (vars->rx_tx_asic_rst)
index d25c7d79787a1bacdfb0dc526bc9814fdfab8d2d..56c2aae4e2c81b33818d6628cc342e67862d7ebd 100644 (file)
@@ -307,7 +307,9 @@ struct link_params {
        struct bnx2x *bp;
        u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
                                req_flow_ctrl is set to AUTO */
-       u16 rsrv1;
+       u16 link_flags;
+#define LINK_FLAGS_INT_DISABLED                (1<<0)
+#define PHY_INITIALIZED                (1<<1)
        u32 lfa_base;
 };
 
@@ -341,7 +343,8 @@ struct link_vars {
        u32 link_status;
        u32 eee_status;
        u8 fault_detected;
-       u8 rsrv1;
+       u8 check_kr2_recovery_cnt;
+#define CHECK_KR2_RECOVERY_CNT 5
        u16 periodic_flags;
 #define PERIODIC_FLAGS_LINK_EVENT      0x0001
 
index 364e37ecbc5cc013573ab63f5e1125f1e8cd750e..198f6f1c9ad5a342736f0d51528539ee5f22f775 100644 (file)
@@ -459,8 +459,9 @@ struct bnx2x_fw_port_stats_old {
 
 #define UPDATE_QSTAT(s, t) \
        do { \
-               qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \
                qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \
+               qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \
+                       + ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \
        } while (0)
 
 #define UPDATE_QSTAT_OLD(f) \
index fdb9b5655414e77dc6506cdda13642ef16115e27..67d2663b3974aeaf03acfeb9500704ee5659ab8a 100644 (file)
@@ -1869,6 +1869,8 @@ static void tg3_link_report(struct tg3 *tp)
 
                tg3_ump_link_report(tp);
        }
+
+       tp->link_up = netif_carrier_ok(tp->dev);
 }
 
 static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
@@ -2522,12 +2524,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
        return err;
 }
 
-static void tg3_carrier_on(struct tg3 *tp)
-{
-       netif_carrier_on(tp->dev);
-       tp->link_up = true;
-}
-
 static void tg3_carrier_off(struct tg3 *tp)
 {
        netif_carrier_off(tp->dev);
@@ -2553,7 +2549,7 @@ static int tg3_phy_reset(struct tg3 *tp)
                return -EBUSY;
 
        if (netif_running(tp->dev) && tp->link_up) {
-               tg3_carrier_off(tp);
+               netif_carrier_off(tp->dev);
                tg3_link_report(tp);
        }
 
@@ -4134,6 +4130,14 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                tp->link_config.active_speed = tp->link_config.speed;
                tp->link_config.active_duplex = tp->link_config.duplex;
 
+               if (tg3_asic_rev(tp) == ASIC_REV_5714) {
+                       /* With autoneg disabled, 5715 only links up when the
+                        * advertisement register has the configured speed
+                        * enabled.
+                        */
+                       tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL);
+               }
+
                bmcr = 0;
                switch (tp->link_config.speed) {
                default:
@@ -4262,9 +4266,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up)
 {
        if (curr_link_up != tp->link_up) {
                if (curr_link_up) {
-                       tg3_carrier_on(tp);
+                       netif_carrier_on(tp->dev);
                } else {
-                       tg3_carrier_off(tp);
+                       netif_carrier_off(tp->dev);
                        if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
                                tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
                }
index 4ce62031f62fa3a51500d8a571feba701e2fa6ed..8049268ce0f25f50f99a5a0ef7137d0f97c1e763 100644 (file)
@@ -497,8 +497,9 @@ int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
 }
 
 #define EEPROM_STAT_ADDR   0x7bfc
-#define VPD_BASE           0
 #define VPD_LEN            512
+#define VPD_BASE           0x400
+#define VPD_BASE_OLD       0
 
 /**
  *     t4_seeprom_wp - enable/disable EEPROM write protection
@@ -524,7 +525,7 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable)
 int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
 {
        u32 cclk_param, cclk_val;
-       int i, ret;
+       int i, ret, addr;
        int ec, sn;
        u8 *vpd, csum;
        unsigned int vpdr_len, kw_offset, id_len;
@@ -533,7 +534,12 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
        if (!vpd)
                return -ENOMEM;
 
-       ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd);
+       ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd);
+       if (ret < 0)
+               goto out;
+       addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD;
+
+       ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd);
        if (ret < 0)
                goto out;
 
index 0c37fb2cc867530c266902c9d1b79c095a63ba99..1df33c799c0012a9144811c90c39a063e92fb45e 100644 (file)
@@ -108,6 +108,7 @@ config TULIP_DM910X
 config DE4X5
        tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
        depends on (PCI || EISA)
+       depends on VIRT_TO_BUS || ALPHA || PPC || SPARC
        select CRC32
        ---help---
          This is support for the DIGITAL series of PCI/EISA Ethernet cards.
index 28ceb84141851e26e8d49f1175099235a512d54b..29aff55f2eea414bf8dec52d61bee70a034fc12c 100644 (file)
@@ -349,6 +349,7 @@ struct be_adapter {
        struct pci_dev *pdev;
        struct net_device *netdev;
 
+       u8 __iomem *csr;        /* CSR BAR used only for BE2/3 */
        u8 __iomem *db;         /* Door Bell */
 
        struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
index 071aea79d218f01eb166d910a310ef0f49efa470..3c9b4f12e3e516ff8775c208a3b138c9acd5c109 100644 (file)
@@ -473,19 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
        return 0;
 }
 
-static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
+static u16 be_POST_stage_get(struct be_adapter *adapter)
 {
        u32 sem;
-       u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH :
-                                         SLIPORT_SEMAPHORE_OFFSET_BE;
 
-       pci_read_config_dword(adapter->pdev, reg, &sem);
-       *stage = sem & POST_STAGE_MASK;
-
-       if ((sem >> POST_ERR_SHIFT) & POST_ERR_MASK)
-               return -1;
+       if (BEx_chip(adapter))
+               sem  = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
        else
-               return 0;
+               pci_read_config_dword(adapter->pdev,
+                                     SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
+
+       return sem & POST_STAGE_MASK;
 }
 
 int lancer_wait_ready(struct be_adapter *adapter)
@@ -579,19 +577,17 @@ int be_fw_wait_ready(struct be_adapter *adapter)
        }
 
        do {
-               status = be_POST_stage_get(adapter, &stage);
-               if (status) {
-                       dev_err(dev, "POST error; stage=0x%x\n", stage);
-                       return -1;
-               } else if (stage != POST_STAGE_ARMFW_RDY) {
-                       if (msleep_interruptible(2000)) {
-                               dev_err(dev, "Waiting for POST aborted\n");
-                               return -EINTR;
-                       }
-                       timeout += 2;
-               } else {
+               stage = be_POST_stage_get(adapter);
+               if (stage == POST_STAGE_ARMFW_RDY)
                        return 0;
+
+               dev_info(dev, "Waiting for POST, %ds elapsed\n",
+                        timeout);
+               if (msleep_interruptible(2000)) {
+                       dev_err(dev, "Waiting for POST aborted\n");
+                       return -EINTR;
                }
+               timeout += 2;
        } while (timeout < 60);
 
        dev_err(dev, "POST timeout; stage=0x%x\n", stage);
index 541d4530d5bfadb2d038b3aa4e233a069cf9c94a..62dc220695f724999c8df269531274ba38ec0b4a 100644 (file)
@@ -32,8 +32,8 @@
 #define MPU_EP_CONTROL                 0
 
 /********** MPU semphore: used for SH & BE  *************/
-#define SLIPORT_SEMAPHORE_OFFSET_BE            0x7c
-#define SLIPORT_SEMAPHORE_OFFSET_SH            0x94
+#define SLIPORT_SEMAPHORE_OFFSET_BEx           0xac  /* CSR BAR offset */
+#define SLIPORT_SEMAPHORE_OFFSET_SH            0x94  /* PCI-CFG offset */
 #define POST_STAGE_MASK                                0x0000FFFF
 #define POST_ERR_MASK                          0x1
 #define POST_ERR_SHIFT                         31
index 3860888ac711a7fe7630cad2c06bb3819eb1f3a0..08e54f3d288bc9a2e23faa8bb954dcb4bd8cf584 100644 (file)
@@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev)
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
 {
+       if (adapter->csr)
+               pci_iounmap(adapter->pdev, adapter->csr);
        if (adapter->db)
                pci_iounmap(adapter->pdev, adapter->db);
 }
@@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
        adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
                                SLI_INTF_IF_TYPE_SHIFT;
 
+       if (BEx_chip(adapter) && be_physfn(adapter)) {
+               adapter->csr = pci_iomap(adapter->pdev, 2, 0);
+               if (adapter->csr == NULL)
+                       return -ENOMEM;
+       }
+
        addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
        if (addr == NULL)
                goto pci_map_err;
@@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
        pci_restore_state(pdev);
 
        /* Check if card is ok and fw is ready */
+       dev_info(&adapter->pdev->dev,
+                "Waiting for FW to be ready after EEH reset\n");
        status = be_fw_wait_ready(adapter);
        if (status)
                return PCI_ERS_RESULT_DISCONNECT;
index fccc3bf2141d7a757f97ac307a9f3d5678a4b57c..911d0253dbb209d7dc787641cc442c9d12ef370a 100644 (file)
@@ -246,14 +246,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        struct bufdesc *bdp;
        void *bufaddr;
        unsigned short  status;
-       unsigned long flags;
+       unsigned int index;
 
        if (!fep->link) {
                /* Link is down or autonegotiation is in progress. */
                return NETDEV_TX_BUSY;
        }
 
-       spin_lock_irqsave(&fep->hw_lock, flags);
        /* Fill in a Tx ring entry */
        bdp = fep->cur_tx;
 
@@ -264,7 +263,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                 * This should not happen, since ndev->tbusy should be set.
                 */
                printk("%s: tx queue full!.\n", ndev->name);
-               spin_unlock_irqrestore(&fep->hw_lock, flags);
                return NETDEV_TX_BUSY;
        }
 
@@ -280,13 +278,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
         * 4-byte boundaries. Use bounce buffers to copy data
         * and get it aligned. Ugh.
         */
+       if (fep->bufdesc_ex)
+               index = (struct bufdesc_ex *)bdp -
+                       (struct bufdesc_ex *)fep->tx_bd_base;
+       else
+               index = bdp - fep->tx_bd_base;
+
        if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
-               unsigned int index;
-               if (fep->bufdesc_ex)
-                       index = (struct bufdesc_ex *)bdp -
-                               (struct bufdesc_ex *)fep->tx_bd_base;
-               else
-                       index = bdp - fep->tx_bd_base;
                memcpy(fep->tx_bounce[index], skb->data, skb->len);
                bufaddr = fep->tx_bounce[index];
        }
@@ -300,10 +298,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                swap_buffer(bufaddr, skb->len);
 
        /* Save skb pointer */
-       fep->tx_skbuff[fep->skb_cur] = skb;
-
-       ndev->stats.tx_bytes += skb->len;
-       fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
+       fep->tx_skbuff[index] = skb;
 
        /* Push the data cache so the CPM does not get stale memory
         * data.
@@ -331,26 +326,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                        ebdp->cbd_esc = BD_ENET_TX_INT;
                }
        }
-       /* Trigger transmission start */
-       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
-
        /* If this was the last BD in the ring, start at the beginning again. */
        if (status & BD_ENET_TX_WRAP)
                bdp = fep->tx_bd_base;
        else
                bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
 
-       if (bdp == fep->dirty_tx) {
-               fep->tx_full = 1;
+       fep->cur_tx = bdp;
+
+       if (fep->cur_tx == fep->dirty_tx)
                netif_stop_queue(ndev);
-       }
 
-       fep->cur_tx = bdp;
+       /* Trigger transmission start */
+       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
        skb_tx_timestamp(skb);
 
-       spin_unlock_irqrestore(&fep->hw_lock, flags);
-
        return NETDEV_TX_OK;
 }
 
@@ -406,11 +397,8 @@ fec_restart(struct net_device *ndev, int duplex)
                writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
                        * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
 
-       fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
        fep->cur_rx = fep->rx_bd_base;
 
-       /* Reset SKB transmit buffers. */
-       fep->skb_cur = fep->skb_dirty = 0;
        for (i = 0; i <= TX_RING_MOD_MASK; i++) {
                if (fep->tx_skbuff[i]) {
                        dev_kfree_skb_any(fep->tx_skbuff[i]);
@@ -573,20 +561,35 @@ fec_enet_tx(struct net_device *ndev)
        struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
+       int     index = 0;
 
        fep = netdev_priv(ndev);
-       spin_lock(&fep->hw_lock);
        bdp = fep->dirty_tx;
 
+       /* get next bdp of dirty_tx */
+       if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+               bdp = fep->tx_bd_base;
+       else
+               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
-               if (bdp == fep->cur_tx && fep->tx_full == 0)
+
+               /* current queue is empty */
+               if (bdp == fep->cur_tx)
                        break;
 
+               if (fep->bufdesc_ex)
+                       index = (struct bufdesc_ex *)bdp -
+                               (struct bufdesc_ex *)fep->tx_bd_base;
+               else
+                       index = bdp - fep->tx_bd_base;
+
                dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
                                FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
                bdp->cbd_bufaddr = 0;
 
-               skb = fep->tx_skbuff[fep->skb_dirty];
+               skb = fep->tx_skbuff[index];
+
                /* Check for errors. */
                if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
                                   BD_ENET_TX_RL | BD_ENET_TX_UN |
@@ -631,8 +634,9 @@ fec_enet_tx(struct net_device *ndev)
 
                /* Free the sk buffer associated with this last transmit */
                dev_kfree_skb_any(skb);
-               fep->tx_skbuff[fep->skb_dirty] = NULL;
-               fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
+               fep->tx_skbuff[index] = NULL;
+
+               fep->dirty_tx = bdp;
 
                /* Update pointer to next buffer descriptor to be transmitted */
                if (status & BD_ENET_TX_WRAP)
@@ -642,14 +646,12 @@ fec_enet_tx(struct net_device *ndev)
 
                /* Since we have freed up a buffer, the ring is no longer full
                 */
-               if (fep->tx_full) {
-                       fep->tx_full = 0;
+               if (fep->dirty_tx != fep->cur_tx) {
                        if (netif_queue_stopped(ndev))
                                netif_wake_queue(ndev);
                }
        }
-       fep->dirty_tx = bdp;
-       spin_unlock(&fep->hw_lock);
+       return;
 }
 
 
@@ -816,7 +818,7 @@ fec_enet_interrupt(int irq, void *dev_id)
                int_events = readl(fep->hwp + FEC_IEVENT);
                writel(int_events, fep->hwp + FEC_IEVENT);
 
-               if (int_events & FEC_ENET_RXF) {
+               if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
                        ret = IRQ_HANDLED;
 
                        /* Disable the RX interrupt */
@@ -827,15 +829,6 @@ fec_enet_interrupt(int irq, void *dev_id)
                        }
                }
 
-               /* Transmit OK, or non-fatal error. Update the buffer
-                * descriptors. FEC handles all errors, we just discover
-                * them as part of the transmit process.
-                */
-               if (int_events & FEC_ENET_TXF) {
-                       ret = IRQ_HANDLED;
-                       fec_enet_tx(ndev);
-               }
-
                if (int_events & FEC_ENET_MII) {
                        ret = IRQ_HANDLED;
                        complete(&fep->mdio_done);
@@ -851,6 +844,8 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
        int pkts = fec_enet_rx(ndev, budget);
        struct fec_enet_private *fep = netdev_priv(ndev);
 
+       fec_enet_tx(ndev);
+
        if (pkts < budget) {
                napi_complete(napi);
                writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
@@ -939,24 +934,28 @@ static void fec_enet_adjust_link(struct net_device *ndev)
                goto spin_unlock;
        }
 
-       /* Duplex link change */
        if (phy_dev->link) {
-               if (fep->full_duplex != phy_dev->duplex) {
-                       fec_restart(ndev, phy_dev->duplex);
-                       /* prevent unnecessary second fec_restart() below */
+               if (!fep->link) {
                        fep->link = phy_dev->link;
                        status_change = 1;
                }
-       }
 
-       /* Link on or off change */
-       if (phy_dev->link != fep->link) {
-               fep->link = phy_dev->link;
-               if (phy_dev->link)
+               if (fep->full_duplex != phy_dev->duplex)
+                       status_change = 1;
+
+               if (phy_dev->speed != fep->speed) {
+                       fep->speed = phy_dev->speed;
+                       status_change = 1;
+               }
+
+               /* if any of the above changed restart the FEC */
+               if (status_change)
                        fec_restart(ndev, phy_dev->duplex);
-               else
+       } else {
+               if (fep->link) {
                        fec_stop(ndev);
-               status_change = 1;
+                       status_change = 1;
+               }
        }
 
 spin_unlock:
@@ -1333,7 +1332,7 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 static void fec_enet_free_buffers(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
-       int i;
+       unsigned int i;
        struct sk_buff *skb;
        struct bufdesc  *bdp;
 
@@ -1357,7 +1356,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 static int fec_enet_alloc_buffers(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
-       int i;
+       unsigned int i;
        struct sk_buff *skb;
        struct bufdesc  *bdp;
 
@@ -1442,6 +1441,7 @@ fec_enet_close(struct net_device *ndev)
        struct fec_enet_private *fep = netdev_priv(ndev);
 
        /* Don't know what to do yet. */
+       napi_disable(&fep->napi);
        fep->opened = 0;
        netif_stop_queue(ndev);
        fec_stop(ndev);
@@ -1598,7 +1598,7 @@ static int fec_enet_init(struct net_device *ndev)
        struct fec_enet_private *fep = netdev_priv(ndev);
        struct bufdesc *cbd_base;
        struct bufdesc *bdp;
-       int i;
+       unsigned int i;
 
        /* Allocate memory for buffer descriptors. */
        cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
@@ -1646,6 +1646,7 @@ static int fec_enet_init(struct net_device *ndev)
 
        /* ...and the same for transmit */
        bdp = fep->tx_bd_base;
+       fep->cur_tx = bdp;
        for (i = 0; i < TX_RING_SIZE; i++) {
 
                /* Initialize the BD for every fragment in the page. */
@@ -1657,6 +1658,7 @@ static int fec_enet_init(struct net_device *ndev)
        /* Set the last buffer to wrap */
        bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
        bdp->cbd_sc |= BD_SC_WRAP;
+       fep->dirty_tx = bdp;
 
        fec_restart(ndev, 0);
 
index 01579b8e37c4f979ea668b28538be4e22e255baa..eb4372962839c216ed1ad68e29ba09a7aaf487ea 100644 (file)
@@ -97,6 +97,13 @@ struct bufdesc {
        unsigned short cbd_sc;  /* Control and status info */
        unsigned long cbd_bufaddr;      /* Buffer address */
 };
+#else
+struct bufdesc {
+       unsigned short  cbd_sc;                 /* Control and status info */
+       unsigned short  cbd_datlen;             /* Data length */
+       unsigned long   cbd_bufaddr;            /* Buffer address */
+};
+#endif
 
 struct bufdesc_ex {
        struct bufdesc desc;
@@ -107,14 +114,6 @@ struct bufdesc_ex {
        unsigned short res0[4];
 };
 
-#else
-struct bufdesc {
-       unsigned short  cbd_sc;                 /* Control and status info */
-       unsigned short  cbd_datlen;             /* Data length */
-       unsigned long   cbd_bufaddr;            /* Buffer address */
-};
-#endif
-
 /*
  *     The following definitions courtesy of commproc.h, which where
  *     Copyright (c) 1997 Dan Malek (dmalek@jlc.net).
@@ -214,8 +213,6 @@ struct fec_enet_private {
        unsigned char *tx_bounce[TX_RING_SIZE];
        struct  sk_buff *tx_skbuff[TX_RING_SIZE];
        struct  sk_buff *rx_skbuff[RX_RING_SIZE];
-       ushort  skb_cur;
-       ushort  skb_dirty;
 
        /* CPM dual port RAM relative addresses */
        dma_addr_t      bd_dma;
@@ -227,7 +224,6 @@ struct fec_enet_private {
        /* The ring entries to be free()ed */
        struct bufdesc  *dirty_tx;
 
-       uint    tx_full;
        /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
        spinlock_t hw_lock;
 
@@ -244,6 +240,7 @@ struct fec_enet_private {
        phy_interface_t phy_interface;
        int     link;
        int     full_duplex;
+       int     speed;
        struct  completion mdio_done;
        int     irq[FEC_IRQ_NUM];
        int     bufdesc_ex;
index 1f17ca0f22019d8350af2affdcc6b00739ce966f..0d8df400a4798c06a1345773b9a0f821b4ab7cb2 100644 (file)
@@ -128,6 +128,7 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
 
        spin_unlock_irqrestore(&fep->tmreg_lock, flags);
 }
+EXPORT_SYMBOL(fec_ptp_start_cyclecounter);
 
 /**
  * fec_ptp_adjfreq - adjust ptp cycle frequency
@@ -318,6 +319,7 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
        return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
            -EFAULT : 0;
 }
+EXPORT_SYMBOL(fec_ptp_ioctl);
 
 /**
  * fec_time_keep - call timecounter_read every second to avoid timer overrun
@@ -383,3 +385,4 @@ void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev)
                pr_info("registered PHC device on %s\n", ndev->name);
        }
 }
+EXPORT_SYMBOL(fec_ptp_init);
index 2c1813737f6d2562189065d945a5002750d8e10c..f91a8f3f9d48beff868f0e9e567ec1779273c877 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/mdio.h>
+#include <linux/pm_runtime.h>
 
 #include "e1000.h"
 
@@ -2229,7 +2230,19 @@ static int e1000e_get_ts_info(struct net_device *netdev,
        return 0;
 }
 
+static int e1000e_ethtool_begin(struct net_device *netdev)
+{
+       return pm_runtime_get_sync(netdev->dev.parent);
+}
+
+static void e1000e_ethtool_complete(struct net_device *netdev)
+{
+       pm_runtime_put_sync(netdev->dev.parent);
+}
+
 static const struct ethtool_ops e1000_ethtool_ops = {
+       .begin                  = e1000e_ethtool_begin,
+       .complete               = e1000e_ethtool_complete,
        .get_settings           = e1000_get_settings,
        .set_settings           = e1000_set_settings,
        .get_drvinfo            = e1000_get_drvinfo,
index dff7bff8b8e0f1d5ee4e6ca4af510516b3d7fd49..121a865c7fbd12855b32b5dff2883332f3b9485b 100644 (file)
@@ -781,6 +781,59 @@ release:
        return ret_val;
 }
 
+/**
+ *  e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP
+ *  @hw:   pointer to the HW structure
+ *  @link: link up bool flag
+ *
+ *  When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications
+ *  preventing further DMA write requests.  Workaround the issue by disabling
+ *  the de-assertion of the clock request when in 1Gpbs mode.
+ **/
+static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
+{
+       u32 fextnvm6 = er32(FEXTNVM6);
+       s32 ret_val = 0;
+
+       if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) {
+               u16 kmrn_reg;
+
+               ret_val = hw->phy.ops.acquire(hw);
+               if (ret_val)
+                       return ret_val;
+
+               ret_val =
+                   e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
+                                               &kmrn_reg);
+               if (ret_val)
+                       goto release;
+
+               ret_val =
+                   e1000e_write_kmrn_reg_locked(hw,
+                                                E1000_KMRNCTRLSTA_K1_CONFIG,
+                                                kmrn_reg &
+                                                ~E1000_KMRNCTRLSTA_K1_ENABLE);
+               if (ret_val)
+                       goto release;
+
+               usleep_range(10, 20);
+
+               ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK);
+
+               ret_val =
+                   e1000e_write_kmrn_reg_locked(hw,
+                                                E1000_KMRNCTRLSTA_K1_CONFIG,
+                                                kmrn_reg);
+release:
+               hw->phy.ops.release(hw);
+       } else {
+               /* clear FEXTNVM6 bit 8 on link down or 10/100 */
+               ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+       }
+
+       return ret_val;
+}
+
 /**
  *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
  *  @hw: pointer to the HW structure
@@ -818,6 +871,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                        return ret_val;
        }
 
+       /* Work-around I218 hang issue */
+       if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
+           (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+               ret_val = e1000_k1_workaround_lpt_lp(hw, link);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /* Clear link partner's EEE ability */
        hw->dev_spec.ich8lan.eee_lp_ability = 0;
 
@@ -3954,8 +4015,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
 
        phy_ctrl = er32(PHY_CTRL);
        phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE;
+
        if (hw->phy.type == e1000_phy_i217) {
-               u16 phy_reg;
+               u16 phy_reg, device_id = hw->adapter->pdev->device;
+
+               if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
+                   (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+                       u32 fextnvm6 = er32(FEXTNVM6);
+
+                       ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+               }
 
                ret_val = hw->phy.ops.acquire(hw);
                if (ret_val)
index b6d3174d7d2d737ff599b2f3f17d6bb7bb1b7cc6..8bf4655c2e17f25a26b70bb6c0ad268034bf8c04 100644 (file)
@@ -92,6 +92,8 @@
 #define E1000_FEXTNVM4_BEACON_DURATION_8USEC   0x7
 #define E1000_FEXTNVM4_BEACON_DURATION_16USEC  0x3
 
+#define E1000_FEXTNVM6_REQ_PLL_CLK     0x00000100
+
 #define PCIE_ICH8_SNOOP_ALL    PCIE_NO_SNOOP_ALL
 
 #define E1000_ICH_RAR_ENTRIES  7
index a177b8b65c44c615271b85840c18bd217f959212..948b86ffa4f027753eec3f5b57b45b90277947ab 100644 (file)
@@ -4303,6 +4303,7 @@ static int e1000_open(struct net_device *netdev)
        netif_start_queue(netdev);
 
        adapter->idle_check = true;
+       hw->mac.get_link_status = true;
        pm_runtime_put(&pdev->dev);
 
        /* fire a link status change interrupt to start the watchdog */
@@ -4662,6 +4663,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
            (adapter->hw.phy.media_type == e1000_media_type_copper)) {
                int ret_val;
 
+               pm_runtime_get_sync(&adapter->pdev->dev);
                ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);
                ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);
                ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise);
@@ -4672,6 +4674,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
                ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);
                if (ret_val)
                        e_warn("Error reading PHY register\n");
+               pm_runtime_put_sync(&adapter->pdev->dev);
        } else {
                /* Do not read PHY registers if link is not up
                 * Set values to typical power-on defaults
@@ -5887,8 +5890,7 @@ release:
        return retval;
 }
 
-static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
-                           bool runtime)
+static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -5912,10 +5914,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
        }
        e1000e_reset_interrupt_capability(adapter);
 
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
-
        status = er32(STATUS);
        if (status & E1000_STATUS_LU)
                wufc &= ~E1000_WUFC_LNKC;
@@ -5971,13 +5969,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
                ew32(WUFC, 0);
        }
 
-       *enable_wake = !!wufc;
-
-       /* make sure adapter isn't asleep if manageability is enabled */
-       if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
-           (hw->mac.ops.check_mng_mode(hw)))
-               *enable_wake = true;
-
        if (adapter->hw.phy.type == e1000_phy_igp_3)
                e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
 
@@ -5986,27 +5977,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
         */
        e1000e_release_hw_control(adapter);
 
-       pci_disable_device(pdev);
-
-       return 0;
-}
-
-static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
-{
-       if (sleep && wake) {
-               pci_prepare_to_sleep(pdev);
-               return;
-       }
-
-       pci_wake_from_d3(pdev, wake);
-       pci_set_power_state(pdev, PCI_D3hot);
-}
-
-static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
-                                    bool wake)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct e1000_adapter *adapter = netdev_priv(netdev);
+       pci_clear_master(pdev);
 
        /* The pci-e switch on some quad port adapters will report a
         * correctable error when the MAC transitions from D0 to D3.  To
@@ -6021,12 +5992,13 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
                pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
                                           (devctl & ~PCI_EXP_DEVCTL_CERE));
 
-               e1000_power_off(pdev, sleep, wake);
+               pci_save_state(pdev);
+               pci_prepare_to_sleep(pdev);
 
                pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
-       } else {
-               e1000_power_off(pdev, sleep, wake);
        }
+
+       return 0;
 }
 
 #ifdef CONFIG_PCIEASPM
@@ -6084,9 +6056,7 @@ static int __e1000_resume(struct pci_dev *pdev)
        if (aspm_disable_flag)
                e1000e_disable_aspm(pdev, aspm_disable_flag);
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_save_state(pdev);
+       pci_set_master(pdev);
 
        e1000e_set_interrupt_capability(adapter);
        if (netif_running(netdev)) {
@@ -6152,14 +6122,8 @@ static int __e1000_resume(struct pci_dev *pdev)
 static int e1000_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       int retval;
-       bool wake;
-
-       retval = __e1000_shutdown(pdev, &wake, false);
-       if (!retval)
-               e1000_complete_shutdown(pdev, true, wake);
 
-       return retval;
+       return __e1000_shutdown(pdev, false);
 }
 
 static int e1000_resume(struct device *dev)
@@ -6182,13 +6146,10 @@ static int e1000_runtime_suspend(struct device *dev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
 
-       if (e1000e_pm_ready(adapter)) {
-               bool wake;
-
-               __e1000_shutdown(pdev, &wake, true);
-       }
+       if (!e1000e_pm_ready(adapter))
+               return 0;
 
-       return 0;
+       return __e1000_shutdown(pdev, true);
 }
 
 static int e1000_idle(struct device *dev)
@@ -6226,12 +6187,7 @@ static int e1000_runtime_resume(struct device *dev)
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-       bool wake = false;
-
-       __e1000_shutdown(pdev, &wake, false);
-
-       if (system_state == SYSTEM_POWER_OFF)
-               e1000_complete_shutdown(pdev, false, wake);
+       __e1000_shutdown(pdev, false);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -6352,9 +6308,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
                        "Cannot re-enable PCI device after reset.\n");
                result = PCI_ERS_RESULT_DISCONNECT;
        } else {
-               pci_set_master(pdev);
                pdev->state_saved = true;
                pci_restore_state(pdev);
+               pci_set_master(pdev);
 
                pci_enable_wake(pdev, PCI_D3hot, 0);
                pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -6783,7 +6739,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* initialize the wol settings based on the eeprom settings */
        adapter->wol = adapter->eeprom_wol;
-       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+       /* make sure adapter isn't asleep if manageability is enabled */
+       if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
+           (hw->mac.ops.check_mng_mode(hw)))
+               device_wakeup_enable(&pdev->dev);
 
        /* save off EEPROM version number */
        e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
index 794fe14976667059b3cb33924f49dec84cde2aef..a7e6a3e37257b34f200ba01c3525fd3269964943 100644 (file)
@@ -42,6 +42,7 @@
 #define E1000_FEXTNVM  0x00028 /* Future Extended NVM - RW */
 #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
 #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
+#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
 #define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
 #define E1000_FCT      0x00030 /* Flow Control Type - RW */
 #define E1000_VET      0x00038 /* VLAN Ether Type - RW */
index 84e7e0909def4bb866411851b2a8ceecffeb1212..12b1d84808084269971e5f83f55bd8b0f3fb8240 100644 (file)
@@ -1361,11 +1361,16 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
        switch (hw->phy.type) {
        case e1000_phy_i210:
        case e1000_phy_m88:
-               if (hw->phy.id == I347AT4_E_PHY_ID ||
-                   hw->phy.id == M88E1112_E_PHY_ID)
+               switch (hw->phy.id) {
+               case I347AT4_E_PHY_ID:
+               case M88E1112_E_PHY_ID:
+               case I210_I_PHY_ID:
                        ret_val = igb_copper_link_setup_m88_gen2(hw);
-               else
+                       break;
+               default:
                        ret_val = igb_copper_link_setup_m88(hw);
+                       break;
+               }
                break;
        case e1000_phy_igp_3:
                ret_val = igb_copper_link_setup_igp(hw);
@@ -1813,27 +1818,32 @@ out:
  **/
 void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
 {
-       u32 dtxswc;
+       u32 reg_val, reg_offset;
 
        switch (hw->mac.type) {
        case e1000_82576:
+               reg_offset = E1000_DTXSWC;
+               break;
        case e1000_i350:
-               dtxswc = rd32(E1000_DTXSWC);
-               if (enable) {
-                       dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
-                                  E1000_DTXSWC_VLAN_SPOOF_MASK);
-                       /* The PF can spoof - it has to in order to
-                        * support emulation mode NICs */
-                       dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
-               } else {
-                       dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
-                                   E1000_DTXSWC_VLAN_SPOOF_MASK);
-               }
-               wr32(E1000_DTXSWC, dtxswc);
+               reg_offset = E1000_TXSWC;
                break;
        default:
-               break;
+               return;
+       }
+
+       reg_val = rd32(reg_offset);
+       if (enable) {
+               reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
+                            E1000_DTXSWC_VLAN_SPOOF_MASK);
+               /* The PF can spoof - it has to in order to
+                * support emulation mode NICs
+                */
+               reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
+       } else {
+               reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
+                            E1000_DTXSWC_VLAN_SPOOF_MASK);
        }
+       wr32(reg_offset, reg_val);
 }
 
 /**
index d27edbc63923a2f2429ef85d3e7713c50f8e8469..25151401c2abe54dcec7fe1fe6f48791e0660a64 100644 (file)
@@ -447,7 +447,7 @@ struct igb_adapter {
 #endif
        struct i2c_algo_bit_data i2c_algo;
        struct i2c_adapter i2c_adap;
-       struct igb_i2c_client_list *i2c_clients;
+       struct i2c_client *i2c_client;
 };
 
 #define IGB_FLAG_HAS_MSI               (1 << 0)
index 0a9b073d0b033ea7e03f745e4983e048804daf1f..0478a1abe54110d1374c6d77d950f6a4d7bf0327 100644 (file)
 #include <linux/pci.h>
 
 #ifdef CONFIG_IGB_HWMON
+static struct i2c_board_info i350_sensor_info = {
+       I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)),
+};
+
 /* hwmon callback functions */
 static ssize_t igb_hwmon_show_location(struct device *dev,
                                         struct device_attribute *attr,
@@ -188,6 +192,7 @@ int igb_sysfs_init(struct igb_adapter *adapter)
        unsigned int i;
        int n_attrs;
        int rc = 0;
+       struct i2c_client *client = NULL;
 
        /* If this method isn't defined we don't support thermals */
        if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
@@ -198,6 +203,15 @@ int igb_sysfs_init(struct igb_adapter *adapter)
                if (rc)
                        goto exit;
 
+       /* init i2c_client */
+       client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info);
+       if (client == NULL) {
+               dev_info(&adapter->pdev->dev,
+                       "Failed to create new i2c device..\n");
+               goto exit;
+       }
+       adapter->i2c_client = client;
+
        /* Allocation space for max attributes
         * max num sensors * values (loc, temp, max, caution)
         */
index ed79a1c53b59b0c101f1e5a2c2363f67f1fe0b04..8496adfc6a685580f6ec1c50b86f0fed62b2b121 100644 (file)
@@ -1923,10 +1923,6 @@ void igb_set_fw_version(struct igb_adapter *adapter)
        return;
 }
 
-static const struct i2c_board_info i350_sensor_info = {
-       I2C_BOARD_INFO("i350bb", 0Xf8),
-};
-
 /*  igb_init_i2c - Init I2C interface
  *  @adapter: pointer to adapter structure
  *
@@ -2546,8 +2542,8 @@ static void igb_probe_vfs(struct igb_adapter *adapter)
        if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
                return;
 
-       igb_enable_sriov(pdev, max_vfs);
        pci_sriov_set_totalvfs(pdev, 7);
+       igb_enable_sriov(pdev, max_vfs);
 
 #endif /* CONFIG_PCI_IOV */
 }
@@ -2656,7 +2652,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
                if (max_vfs > 7) {
                        dev_warn(&pdev->dev,
                                 "Maximum of 7 VFs per PF, using max\n");
-                       adapter->vfs_allocated_count = 7;
+                       max_vfs = adapter->vfs_allocated_count = 7;
                } else
                        adapter->vfs_allocated_count = max_vfs;
                if (adapter->vfs_allocated_count)
@@ -6227,13 +6223,6 @@ static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring,
        /* If we spanned a buffer we have a huge mess so test for it */
        BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)));
 
-       /* Guarantee this function can be used by verifying buffer sizes */
-       BUILD_BUG_ON(SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) < (NET_SKB_PAD +
-                                                       NET_IP_ALIGN +
-                                                       IGB_TS_HDR_LEN +
-                                                       ETH_FRAME_LEN +
-                                                       ETH_FCS_LEN));
-
        rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
        page = rx_buffer->page;
        prefetchw(page);
@@ -7724,67 +7713,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
        }
 }
 
-static DEFINE_SPINLOCK(i2c_clients_lock);
-
-/*  igb_get_i2c_client - returns matching client
- *  in adapters's client list.
- *  @adapter: adapter struct
- *  @dev_addr: device address of i2c needed.
- */
-static struct i2c_client *
-igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr)
-{
-       ulong flags;
-       struct igb_i2c_client_list *client_list;
-       struct i2c_client *client = NULL;
-       struct i2c_board_info client_info = {
-               I2C_BOARD_INFO("igb", 0x00),
-       };
-
-       spin_lock_irqsave(&i2c_clients_lock, flags);
-       client_list = adapter->i2c_clients;
-
-       /* See if we already have an i2c_client */
-       while (client_list) {
-               if (client_list->client->addr == (dev_addr >> 1)) {
-                       client = client_list->client;
-                       goto exit;
-               } else {
-                       client_list = client_list->next;
-               }
-       }
-
-       /* no client_list found, create a new one */
-       client_list = kzalloc(sizeof(*client_list), GFP_ATOMIC);
-       if (client_list == NULL)
-               goto exit;
-
-       /* dev_addr passed to us is left-shifted by 1 bit
-        * i2c_new_device call expects it to be flush to the right.
-        */
-       client_info.addr = dev_addr >> 1;
-       client_info.platform_data = adapter;
-       client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info);
-       if (client_list->client == NULL) {
-               dev_info(&adapter->pdev->dev,
-                       "Failed to create new i2c device..\n");
-               goto err_no_client;
-       }
-
-       /* insert new client at head of list */
-       client_list->next = adapter->i2c_clients;
-       adapter->i2c_clients = client_list;
-
-       client = client_list->client;
-       goto exit;
-
-err_no_client:
-       kfree(client_list);
-exit:
-       spin_unlock_irqrestore(&i2c_clients_lock, flags);
-       return client;
-}
-
 /*  igb_read_i2c_byte - Reads 8 bit word over I2C
  *  @hw: pointer to hardware structure
  *  @byte_offset: byte offset to read
@@ -7798,7 +7726,7 @@ s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
                                u8 dev_addr, u8 *data)
 {
        struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
-       struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr);
+       struct i2c_client *this_client = adapter->i2c_client;
        s32 status;
        u16 swfw_mask = 0;
 
@@ -7835,7 +7763,7 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
                                 u8 dev_addr, u8 data)
 {
        struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
-       struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr);
+       struct i2c_client *this_client = adapter->i2c_client;
        s32 status;
        u16 swfw_mask = E1000_SWFW_PHY0_SM;
 
index 0987822359f00590d7f36bc5e126c8a4f20ee1ac..0a237507ee85008e9e11c703b07f58730202e072 100644 (file)
@@ -740,7 +740,7 @@ void igb_ptp_init(struct igb_adapter *adapter)
        case e1000_82576:
                snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
                adapter->ptp_caps.owner = THIS_MODULE;
-               adapter->ptp_caps.max_adj = 1000000000;
+               adapter->ptp_caps.max_adj = 999999881;
                adapter->ptp_caps.n_ext_ts = 0;
                adapter->ptp_caps.pps = 0;
                adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82576;
index c3db6cd69b68b0135f42908fd738bd7c9fd4fddc..2b6cb5ca48eefe8f0a075b1166f24dff7aaaaa83 100644 (file)
@@ -944,9 +944,17 @@ free_queue_irqs:
                free_irq(adapter->msix_entries[vector].vector,
                         adapter->q_vector[vector]);
        }
-       pci_disable_msix(adapter->pdev);
-       kfree(adapter->msix_entries);
-       adapter->msix_entries = NULL;
+       /* This failure is non-recoverable - it indicates the system is
+        * out of MSIX vector resources and the VF driver cannot run
+        * without them.  Set the number of msix vectors to zero
+        * indicating that not enough can be allocated.  The error
+        * will be returned to the user indicating device open failed.
+        * Any further attempts to force the driver to open will also
+        * fail.  The only way to recover is to unload the driver and
+        * reload it again.  If the system has recovered some MSIX
+        * vectors then it may succeed.
+        */
+       adapter->num_msix_vectors = 0;
        return err;
 }
 
@@ -2572,6 +2580,15 @@ static int ixgbevf_open(struct net_device *netdev)
        struct ixgbe_hw *hw = &adapter->hw;
        int err;
 
+       /* A previous failure to open the device because of a lack of
+        * available MSIX vector resources may have reset the number
+        * of msix vectors variable to zero.  The only way to recover
+        * is to unload/reload the driver and hope that the system has
+        * been able to recover some MSIX vector resources.
+        */
+       if (!adapter->num_msix_vectors)
+               return -ENOMEM;
+
        /* disallow open during test */
        if (test_bit(__IXGBEVF_TESTING, &adapter->state))
                return -EBUSY;
@@ -2628,7 +2645,6 @@ static int ixgbevf_open(struct net_device *netdev)
 
 err_req_irq:
        ixgbevf_down(adapter);
-       ixgbevf_free_irq(adapter);
 err_setup_rx:
        ixgbevf_free_all_rx_resources(adapter);
 err_setup_tx:
index 6a2127489af78e718264f202737ba0667770ba1b..bfdb06860397e720a848d6e8cab7b324ded6ea1c 100644 (file)
@@ -769,7 +769,7 @@ ltq_etop_probe(struct platform_device *pdev)
        return 0;
 
 err_free:
-       kfree(dev);
+       free_netdev(dev);
 err_out:
        return err;
 }
index 29140502b71aea8765a917f2b68e34d8d645b249..6562c736a1d83df96a8feb249a289268b014a854 100644 (file)
@@ -1081,6 +1081,45 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
 
 
 /* mii management interface *************************************************/
+static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp)
+{
+       u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL);
+       u32 autoneg_disable = FORCE_LINK_PASS |
+                    DISABLE_AUTO_NEG_SPEED_GMII |
+                    DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
+                    DISABLE_AUTO_NEG_FOR_DUPLEX;
+
+       if (mp->phy->autoneg == AUTONEG_ENABLE) {
+               /* enable auto negotiation */
+               pscr &= ~autoneg_disable;
+               goto out_write;
+       }
+
+       pscr |= autoneg_disable;
+
+       if (mp->phy->speed == SPEED_1000) {
+               /* force gigabit, half duplex not supported */
+               pscr |= SET_GMII_SPEED_TO_1000;
+               pscr |= SET_FULL_DUPLEX_MODE;
+               goto out_write;
+       }
+
+       pscr &= ~SET_GMII_SPEED_TO_1000;
+
+       if (mp->phy->speed == SPEED_100)
+               pscr |= SET_MII_SPEED_TO_100;
+       else
+               pscr &= ~SET_MII_SPEED_TO_100;
+
+       if (mp->phy->duplex == DUPLEX_FULL)
+               pscr |= SET_FULL_DUPLEX_MODE;
+       else
+               pscr &= ~SET_FULL_DUPLEX_MODE;
+
+out_write:
+       wrlp(mp, PORT_SERIAL_CONTROL, pscr);
+}
+
 static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
 {
        struct mv643xx_eth_shared_private *msp = dev_id;
@@ -1499,6 +1538,7 @@ static int
 mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
+       int ret;
 
        if (mp->phy == NULL)
                return -EINVAL;
@@ -1508,7 +1548,10 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
         */
        cmd->advertising &= ~ADVERTISED_1000baseT_Half;
 
-       return phy_ethtool_sset(mp->phy, cmd);
+       ret = phy_ethtool_sset(mp->phy, cmd);
+       if (!ret)
+               mv643xx_adjust_pscr(mp);
+       return ret;
 }
 
 static void mv643xx_eth_get_drvinfo(struct net_device *dev,
@@ -2442,11 +2485,15 @@ static int mv643xx_eth_stop(struct net_device *dev)
 static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
+       int ret;
 
-       if (mp->phy != NULL)
-               return phy_mii_ioctl(mp->phy, ifr, cmd);
+       if (mp->phy == NULL)
+               return -ENOTSUPP;
 
-       return -EOPNOTSUPP;
+       ret = phy_mii_ioctl(mp->phy, ifr, cmd);
+       if (!ret)
+               mv643xx_adjust_pscr(mp);
+       return ret;
 }
 
 static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
index 7e64033d7de39ed7723c162c75e24cf49cd3d6fa..0706623cfb96abf74b2d6ebb15d15f05d18504f5 100644 (file)
@@ -226,7 +226,7 @@ void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
 
 static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
index bb4d8d99f36d2d69060a534e4e39ca07a69187a8..f278b10ef7140a6e195056e11a12075de02afabc 100644 (file)
@@ -565,34 +565,38 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv)
        struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_dev *dev = mdev->dev;
        int qpn = priv->base_qpn;
-       u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
-
-       en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
-              priv->dev->dev_addr);
-       mlx4_unregister_mac(dev, priv->port, mac);
+       u64 mac;
 
-       if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) {
+       if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) {
+               mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
+               en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
+                      priv->dev->dev_addr);
+               mlx4_unregister_mac(dev, priv->port, mac);
+       } else {
                struct mlx4_mac_entry *entry;
                struct hlist_node *tmp;
                struct hlist_head *bucket;
-               unsigned int mac_hash;
+               unsigned int i;
 
-               mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX];
-               bucket = &priv->mac_hash[mac_hash];
-               hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
-                       if (ether_addr_equal_64bits(entry->mac,
-                                                   priv->dev->dev_addr)) {
-                               en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n",
-                                      priv->port, priv->dev->dev_addr, qpn);
+               for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) {
+                       bucket = &priv->mac_hash[i];
+                       hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
+                               mac = mlx4_en_mac_to_u64(entry->mac);
+                               en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
+                                      entry->mac);
                                mlx4_en_uc_steer_release(priv, entry->mac,
                                                         qpn, entry->reg_id);
-                               mlx4_qp_release_range(dev, qpn, 1);
 
+                               mlx4_unregister_mac(dev, priv->port, mac);
                                hlist_del_rcu(&entry->hlist);
                                kfree_rcu(entry, rcu);
-                               break;
                        }
                }
+
+               en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n",
+                      priv->port, qpn);
+               mlx4_qp_release_range(dev, qpn, 1);
+               priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC;
        }
 }
 
@@ -650,28 +654,10 @@ u64 mlx4_en_mac_to_u64(u8 *addr)
        return mac;
 }
 
-static int mlx4_en_set_mac(struct net_device *dev, void *addr)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-       struct sockaddr *saddr = addr;
-
-       if (!is_valid_ether_addr(saddr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
-       queue_work(mdev->workqueue, &priv->mac_task);
-       return 0;
-}
-
-static void mlx4_en_do_set_mac(struct work_struct *work)
+static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv)
 {
-       struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
-                                                mac_task);
-       struct mlx4_en_dev *mdev = priv->mdev;
        int err = 0;
 
-       mutex_lock(&mdev->state_lock);
        if (priv->port_up) {
                /* Remove old MAC and insert the new one */
                err = mlx4_en_replace_mac(priv, priv->base_qpn,
@@ -683,7 +669,26 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
        } else
                en_dbg(HW, priv, "Port is down while registering mac, exiting...\n");
 
+       return err;
+}
+
+static int mlx4_en_set_mac(struct net_device *dev, void *addr)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct sockaddr *saddr = addr;
+       int err;
+
+       if (!is_valid_ether_addr(saddr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
+
+       mutex_lock(&mdev->state_lock);
+       err = mlx4_en_do_set_mac(priv);
        mutex_unlock(&mdev->state_lock);
+
+       return err;
 }
 
 static void mlx4_en_clear_list(struct net_device *dev)
@@ -1348,7 +1353,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
                queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        }
        if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
-               queue_work(mdev->workqueue, &priv->mac_task);
+               mlx4_en_do_set_mac(priv);
                mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
        }
        mutex_unlock(&mdev->state_lock);
@@ -1632,6 +1637,17 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
        /* Flush multicast filter */
        mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);
 
+       /* Remove flow steering rules for the port*/
+       if (mdev->dev->caps.steering_mode ==
+           MLX4_STEERING_MODE_DEVICE_MANAGED) {
+               ASSERT_RTNL();
+               list_for_each_entry_safe(flow, tmp_flow,
+                                        &priv->ethtool_list, list) {
+                       mlx4_flow_detach(mdev->dev, flow->id);
+                       list_del(&flow->list);
+               }
+       }
+
        mlx4_en_destroy_drop_qp(priv);
 
        /* Free TX Rings */
@@ -1652,17 +1668,6 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
        if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN))
                mdev->mac_removed[priv->port] = 1;
 
-       /* Remove flow steering rules for the port*/
-       if (mdev->dev->caps.steering_mode ==
-           MLX4_STEERING_MODE_DEVICE_MANAGED) {
-               ASSERT_RTNL();
-               list_for_each_entry_safe(flow, tmp_flow,
-                                        &priv->ethtool_list, list) {
-                       mlx4_flow_detach(mdev->dev, flow->id);
-                       list_del(&flow->list);
-               }
-       }
-
        /* Free RX Rings */
        for (i = 0; i < priv->rx_ring_num; i++) {
                mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
@@ -1828,9 +1833,11 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
        }
 
 #ifdef CONFIG_RFS_ACCEL
-       priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
-       if (!priv->dev->rx_cpu_rmap)
-               goto err;
+       if (priv->mdev->dev->caps.comp_pool) {
+               priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
+               if (!priv->dev->rx_cpu_rmap)
+                       goto err;
+       }
 #endif
 
        return 0;
@@ -2078,7 +2085,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        priv->msg_enable = MLX4_EN_MSG_LEVEL;
        spin_lock_init(&priv->stats_lock);
        INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
-       INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac);
        INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
        INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
        INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
index 251ae2f9311680cb69eaada07cf3ad8a3cf58354..8e3123a1df886de6b0afb2c60397ecd28be3e4b9 100644 (file)
@@ -771,7 +771,7 @@ int mlx4_MAP_EQ_wrapper(struct mlx4_dev *dev, int slave,
        struct mlx4_slave_event_eq_info *event_eq =
                priv->mfunc.master.slave_state[slave].event_eq;
        u32 in_modifier = vhcr->in_modifier;
-       u32 eqn = in_modifier & 0x1FF;
+       u32 eqn = in_modifier & 0x3FF;
        u64 in_param =  vhcr->in_param;
        int err = 0;
        int i;
index 50917eb3013e1bad3aef4a572a006002d5ba61f0..f6245579962d5f0c1a81e31f757a52d16c7cd3de 100644 (file)
@@ -787,6 +787,14 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
        MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
 
+       /* turn off device-managed steering capability if not enabled */
+       if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) {
+               MLX4_GET(field, outbox->buf,
+                        QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
+               field &= 0x7f;
+               MLX4_PUT(outbox->buf, field,
+                        QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
+       }
        return 0;
 }
 
index d180bc46826afd0189eb7aa0360baf598615c02b..16abde20e1fcd2daaefc6b9a671b4c6c1a4313bb 100644 (file)
@@ -1555,7 +1555,7 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 
 void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, idx);
index cf883345af8887eeac97eb5b7278b98a98ffe4bb..d738454116a088db7a098c88f2ef5fc9b7eb1698 100644 (file)
@@ -1235,7 +1235,7 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
 
 static inline void set_param_l(u64 *arg, u32 val)
 {
-       *((u32 *)arg) = val;
+       *arg = (*arg & 0xffffffff00000000ULL) | (u64) val;
 }
 
 static inline void set_param_h(u64 *arg, u32 val)
index c313d7e943a95cbd049d2ed000dc76ab8c4e0009..f710b7ce0dcbbf9ef740d0661add1bb744921b9f 100644 (file)
@@ -509,7 +509,6 @@ struct mlx4_en_priv {
        struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
        struct mlx4_qp drop_qp;
        struct work_struct rx_mode_task;
-       struct work_struct mac_task;
        struct work_struct watchdog_task;
        struct work_struct linkstate_task;
        struct delayed_work stats_task;
index 602ca9bf78e46b22ec921140c4539105b8597454..f91719a08cbac000dc34f68f7d40252aa652ac58 100644 (file)
@@ -183,7 +183,7 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
 
 static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
 {
-       u64 in_param;
+       u64 in_param = 0;
        u64 out_param;
        int err;
 
@@ -240,7 +240,7 @@ void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
 
 static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -351,7 +351,7 @@ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
 
 static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, index);
@@ -374,7 +374,7 @@ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
 
 static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
 {
-       u64 param;
+       u64 param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&param, index);
@@ -395,7 +395,7 @@ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
 
 static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, index);
index 1ac88637ad9de145f81d9e4851fda2387da12158..00f223acada79a8f0bf6b52ae21e75afbfb60ce0 100644 (file)
@@ -101,7 +101,7 @@ void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
 
 void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
index 719ead15e49181f1fc419b0c18310db521280eff..10c57c86388baed3626cc803fc8acadf605ca855 100644 (file)
@@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac);
 
 int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 {
-       u64 out_param;
+       u64 out_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
 
 void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 {
-       u64 out_param;
+       u64 out_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&out_param, port);
@@ -361,7 +361,7 @@ out:
 
 int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
 {
-       u64 out_param;
+       u64 out_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -406,7 +406,7 @@ out:
 
 void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
index 81e2abe07bbbf656689ba327ab0d4d22368961df..e891b058c1befdc09927ea1ab49aa70e282d4278 100644 (file)
@@ -222,7 +222,7 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
 
 int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
 {
-       u64 in_param;
+       u64 in_param = 0;
        u64 out_param;
        int err;
 
@@ -255,7 +255,7 @@ void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 
 void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -319,7 +319,7 @@ err_out:
 
 static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
 {
-       u64 param;
+       u64 param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&param, qpn);
@@ -344,7 +344,7 @@ void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
 
 static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, qpn);
index 083fb48dc3d7bd7bfa014f8ddc9a7eed81dffca5..1391b52f443aa5489ec31ee7e155b087f0372b0c 100644 (file)
@@ -99,6 +99,7 @@ struct res_qp {
        struct list_head        mcg_list;
        spinlock_t              mcg_spl;
        int                     local_qpn;
+       atomic_t                ref_count;
 };
 
 enum res_mtt_states {
@@ -197,6 +198,7 @@ enum res_fs_rule_states {
 
 struct res_fs_rule {
        struct res_common       com;
+       int                     qpn;
 };
 
 static void *res_tracker_lookup(struct rb_root *root, u64 res_id)
@@ -355,7 +357,7 @@ static int mpt_mask(struct mlx4_dev *dev)
        return dev->caps.num_mpts - 1;
 }
 
-static void *find_res(struct mlx4_dev *dev, int res_id,
+static void *find_res(struct mlx4_dev *dev, u64 res_id,
                      enum mlx4_resource type)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
@@ -447,6 +449,7 @@ static struct res_common *alloc_qp_tr(int id)
        ret->local_qpn = id;
        INIT_LIST_HEAD(&ret->mcg_list);
        spin_lock_init(&ret->mcg_spl);
+       atomic_set(&ret->ref_count, 0);
 
        return &ret->com;
 }
@@ -554,7 +557,7 @@ static struct res_common *alloc_xrcdn_tr(int id)
        return &ret->com;
 }
 
-static struct res_common *alloc_fs_rule_tr(u64 id)
+static struct res_common *alloc_fs_rule_tr(u64 id, int qpn)
 {
        struct res_fs_rule *ret;
 
@@ -564,7 +567,7 @@ static struct res_common *alloc_fs_rule_tr(u64 id)
 
        ret->com.res_id = id;
        ret->com.state = RES_FS_RULE_ALLOCATED;
-
+       ret->qpn = qpn;
        return &ret->com;
 }
 
@@ -602,7 +605,7 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
                ret = alloc_xrcdn_tr(id);
                break;
        case RES_FS_RULE:
-               ret = alloc_fs_rule_tr(id);
+               ret = alloc_fs_rule_tr(id, extra);
                break;
        default:
                return NULL;
@@ -671,10 +674,14 @@ undo:
 
 static int remove_qp_ok(struct res_qp *res)
 {
-       if (res->com.state == RES_QP_BUSY)
+       if (res->com.state == RES_QP_BUSY || atomic_read(&res->ref_count) ||
+           !list_empty(&res->mcg_list)) {
+               pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n",
+                      res->com.state, atomic_read(&res->ref_count));
                return -EBUSY;
-       else if (res->com.state != RES_QP_RESERVED)
+       } else if (res->com.state != RES_QP_RESERVED) {
                return -EPERM;
+       }
 
        return 0;
 }
@@ -2990,6 +2997,9 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
        u8 steer_type_mask = 2;
        enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
 
+       if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0)
+               return -EINVAL;
+
        qpn = vhcr->in_modifier & 0xffffff;
        err = get_res(dev, slave, qpn, RES_QP, &rqp);
        if (err)
@@ -3121,6 +3131,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
        struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];
        int err;
        int qpn;
+       struct res_qp *rqp;
        struct mlx4_net_trans_rule_hw_ctrl *ctrl;
        struct _rule_hw  *rule_header;
        int header_id;
@@ -3131,7 +3142,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
 
        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
        qpn = be32_to_cpu(ctrl->qpn) & 0xffffff;
-       err = get_res(dev, slave, qpn, RES_QP, NULL);
+       err = get_res(dev, slave, qpn, RES_QP, &rqp);
        if (err) {
                pr_err("Steering rule with qpn 0x%x rejected.\n", qpn);
                return err;
@@ -3172,14 +3183,16 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
        if (err)
                goto err_put;
 
-       err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0);
+       err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, qpn);
        if (err) {
                mlx4_err(dev, "Fail to add flow steering resources.\n ");
                /* detach rule*/
                mlx4_cmd(dev, vhcr->out_param, 0, 0,
                         MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
                         MLX4_CMD_NATIVE);
+               goto err_put;
        }
+       atomic_inc(&rqp->ref_count);
 err_put:
        put_res(dev, slave, qpn, RES_QP);
        return err;
@@ -3192,20 +3205,35 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
                                         struct mlx4_cmd_info *cmd)
 {
        int err;
+       struct res_qp *rqp;
+       struct res_fs_rule *rrule;
 
        if (dev->caps.steering_mode !=
            MLX4_STEERING_MODE_DEVICE_MANAGED)
                return -EOPNOTSUPP;
 
+       err = get_res(dev, slave, vhcr->in_param, RES_FS_RULE, &rrule);
+       if (err)
+               return err;
+       /* Release the rule form busy state before removal */
+       put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
+       err = get_res(dev, slave, rrule->qpn, RES_QP, &rqp);
+       if (err)
+               return err;
+
        err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0);
        if (err) {
                mlx4_err(dev, "Fail to remove flow steering resources.\n ");
-               return err;
+               goto out;
        }
 
        err = mlx4_cmd(dev, vhcr->in_param, 0, 0,
                       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
                       MLX4_CMD_NATIVE);
+       if (!err)
+               atomic_dec(&rqp->ref_count);
+out:
+       put_res(dev, slave, rrule->qpn, RES_QP);
        return err;
 }
 
@@ -3803,6 +3831,7 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
        mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
        /*VLAN*/
        rem_slave_macs(dev, slave);
+       rem_slave_fs_rule(dev, slave);
        rem_slave_qps(dev, slave);
        rem_slave_srqs(dev, slave);
        rem_slave_cqs(dev, slave);
@@ -3811,6 +3840,5 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
        rem_slave_mtts(dev, slave);
        rem_slave_counters(dev, slave);
        rem_slave_xrcdns(dev, slave);
-       rem_slave_fs_rule(dev, slave);
        mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
 }
index feda6c00829f391e0d5bd822db970c5d6a2f7ca2..e329fe1f11b736d8e717880c7e6e7e092db2a14c 100644 (file)
@@ -149,7 +149,7 @@ void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
 
 static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, srqn);
index c4122c86f829293cc60d6dd48c72602d7dded49f..efa29b712d5f1bdc9793648ebd76f9201cc3f99a 100644 (file)
@@ -1472,7 +1472,8 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        }
        platform_set_drvdata(pdev, ndev);
 
-       if (lpc_mii_init(pldat) != 0)
+       ret = lpc_mii_init(pldat);
+       if (ret)
                goto err_out_unregister_netdev;
 
        netdev_info(ndev, "LPC mac at 0x%08x irq %d\n",
index 39ab4d09faaa2eb500748466ba6ab0fbe4074ac9..73ce7dd6b9544d470a6e14b163f7ae751d3d749d 100644 (file)
@@ -1726,9 +1726,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
 
                        skb->protocol = eth_type_trans(skb, netdev);
                        if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK)
-                               skb->ip_summed = CHECKSUM_NONE;
-                       else
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       else
+                               skb->ip_summed = CHECKSUM_NONE;
 
                        napi_gro_receive(&adapter->napi, skb);
                        (*work_done)++;
index 8900398ba103929135278c1046e50126d627eabd..28fb50a1e9c350851b3844592bf85adea877f604 100644 (file)
@@ -4765,8 +4765,10 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 
-       rtl_tx_performance_tweak(pdev,
-               (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
+       if (tp->dev->mtu <= ETH_DATA_LEN) {
+               rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) |
+                                        PCI_EXP_DEVCTL_NOSNOOP_EN);
+       }
 }
 
 static void rtl_hw_start_8168bef(struct rtl8169_private *tp)
@@ -4789,7 +4791,8 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
 
        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        rtl_disable_clock_request(pdev);
 
@@ -4822,7 +4825,8 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp)
 
        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
@@ -4841,7 +4845,8 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp)
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
@@ -4901,7 +4906,8 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp)
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
@@ -4913,7 +4919,8 @@ static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
 
        rtl_csi_access_enable_1(tp);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
@@ -4972,7 +4979,8 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
 
        rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
@@ -4998,7 +5006,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
 
        rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
        rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
index 33e96176e4d82167a2d62a51f1f1eb5d711f7375..bf5e3cf97c4d89d55b92b66a46ee37787acb934c 100644 (file)
@@ -2220,6 +2220,7 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
 /* MDIO bus release function */
 static int sh_mdio_release(struct net_device *ndev)
 {
+       struct sh_eth_private *mdp = netdev_priv(ndev);
        struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
 
        /* unregister mdio bus */
@@ -2234,6 +2235,9 @@ static int sh_mdio_release(struct net_device *ndev)
        /* free bitbang info */
        free_mdio_bitbang(bus);
 
+       /* free bitbang memory */
+       kfree(mdp->bitbang);
+
        return 0;
 }
 
@@ -2262,6 +2266,7 @@ static int sh_mdio_init(struct net_device *ndev, int id,
        bitbang->ctrl.ops = &bb_ops;
 
        /* MII controller setting */
+       mdp->bitbang = bitbang;
        mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
        if (!mdp->mii_bus) {
                ret = -ENOMEM;
@@ -2441,6 +2446,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
                }
                mdp->tsu_addr = ioremap(rtsu->start,
                                        resource_size(rtsu));
+               if (mdp->tsu_addr == NULL) {
+                       ret = -ENOMEM;
+                       dev_err(&pdev->dev, "TSU ioremap failed.\n");
+                       goto out_release;
+               }
                mdp->port = devno % 2;
                ndev->features = NETIF_F_HW_VLAN_FILTER;
        }
index bae84fd2e73a7419504d8b29b195c0a118711b8a..e6655678458e5984fee032c6593e719a631d9c42 100644 (file)
@@ -705,6 +705,7 @@ struct sh_eth_private {
        const u16 *reg_offset;
        void __iomem *addr;
        void __iomem *tsu_addr;
+       struct bb_info *bitbang;
        u32 num_rx_ring;
        u32 num_tx_ring;
        dma_addr_t rx_desc_dma;
index bf57b3cb16abdbc1e89e8aaa83c99a9c47888552..0bc00991d31010cf1ec4efd95ec95afba8aa5d53 100644 (file)
@@ -779,6 +779,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
                                                tx_queue->txd.entries);
        }
 
+       efx_device_detach_sync(efx);
        efx_stop_all(efx);
        efx_stop_interrupts(efx, true);
 
@@ -832,6 +833,7 @@ out:
 
        efx_start_interrupts(efx, true);
        efx_start_all(efx);
+       netif_device_attach(efx->net_dev);
        return rc;
 
 rollback:
@@ -1641,8 +1643,12 @@ static void efx_stop_all(struct efx_nic *efx)
        /* Flush efx_mac_work(), refill_workqueue, monitor_work */
        efx_flush_all(efx);
 
-       /* Stop the kernel transmit interface late, so the watchdog
-        * timer isn't ticking over the flush */
+       /* Stop the kernel transmit interface.  This is only valid if
+        * the device is stopped or detached; otherwise the watchdog
+        * may fire immediately.
+        */
+       WARN_ON(netif_running(efx->net_dev) &&
+               netif_device_present(efx->net_dev));
        netif_tx_disable(efx->net_dev);
 
        efx_stop_datapath(efx);
@@ -1963,16 +1969,18 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
        if (new_mtu > EFX_MAX_MTU)
                return -EINVAL;
 
-       efx_stop_all(efx);
-
        netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
 
+       efx_device_detach_sync(efx);
+       efx_stop_all(efx);
+
        mutex_lock(&efx->mac_lock);
        net_dev->mtu = new_mtu;
        efx->type->reconfigure_mac(efx);
        mutex_unlock(&efx->mac_lock);
 
        efx_start_all(efx);
+       netif_device_attach(efx->net_dev);
        return 0;
 }
 
index 50247dfe8f574d2a7184c8ea675b5ecabdcc37cc..d2f790df6dcbf6872084c49d74a8a63efb58f569 100644 (file)
@@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
         * TX scheduler is stopped when we're done and before
         * netif_device_present() becomes false.
         */
-       netif_tx_lock(dev);
+       netif_tx_lock_bh(dev);
        netif_device_detach(dev);
-       netif_tx_unlock(dev);
+       netif_tx_unlock_bh(dev);
 }
 
 #endif /* EFX_EFX_H */
index 2d756c1d71425823100f572065e224a59ca16813..0a90abd2421b62540d7e2fb2888caa0a4a3abf3a 100644 (file)
@@ -210,6 +210,7 @@ struct efx_tx_queue {
  *     Will be %NULL if the buffer slot is currently free.
  * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE.
  *     Will be %NULL if the buffer slot is currently free.
+ * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE.
  * @len: Buffer length, in bytes.
  * @flags: Flags for buffer and packet state.
  */
@@ -219,7 +220,8 @@ struct efx_rx_buffer {
                struct sk_buff *skb;
                struct page *page;
        } u;
-       unsigned int len;
+       u16 page_offset;
+       u16 len;
        u16 flags;
 };
 #define EFX_RX_BUF_PAGE                0x0001
index 0ad790cc473cb1697e71bd422af0e0086c0242a9..eaa8e874a3cb0580cbe68ca40ba5004942a91e5f 100644 (file)
@@ -376,7 +376,8 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count)
                return false;
 
        tx_queue->empty_read_count = 0;
-       return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
+       return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
+               && tx_queue->write_count - write_count == 1;
 }
 
 /* For each entry inserted into the software descriptor ring, create a
index d780a0d096b4c5b0b87036c6404089309592d43b..bb579a6128c8ce883ac7156ea24ac541d4901e38 100644 (file)
@@ -90,11 +90,7 @@ static unsigned int rx_refill_threshold;
 static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
                                             struct efx_rx_buffer *buf)
 {
-       /* Offset is always within one page, so we don't need to consider
-        * the page order.
-        */
-       return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) +
-               efx->type->rx_buffer_hash_size;
+       return buf->page_offset + efx->type->rx_buffer_hash_size;
 }
 static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
 {
@@ -187,6 +183,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
        struct efx_nic *efx = rx_queue->efx;
        struct efx_rx_buffer *rx_buf;
        struct page *page;
+       unsigned int page_offset;
        struct efx_rx_page_state *state;
        dma_addr_t dma_addr;
        unsigned index, count;
@@ -211,12 +208,14 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
                state->dma_addr = dma_addr;
 
                dma_addr += sizeof(struct efx_rx_page_state);
+               page_offset = sizeof(struct efx_rx_page_state);
 
        split:
                index = rx_queue->added_count & rx_queue->ptr_mask;
                rx_buf = efx_rx_buffer(rx_queue, index);
                rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
                rx_buf->u.page = page;
+               rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
                rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
                rx_buf->flags = EFX_RX_BUF_PAGE;
                ++rx_queue->added_count;
@@ -227,6 +226,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
                        /* Use the second half of the page */
                        get_page(page);
                        dma_addr += (PAGE_SIZE >> 1);
+                       page_offset += (PAGE_SIZE >> 1);
                        ++count;
                        goto split;
                }
@@ -236,7 +236,8 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
 }
 
 static void efx_unmap_rx_buffer(struct efx_nic *efx,
-                               struct efx_rx_buffer *rx_buf)
+                               struct efx_rx_buffer *rx_buf,
+                               unsigned int used_len)
 {
        if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) {
                struct efx_rx_page_state *state;
@@ -247,6 +248,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
                                       state->dma_addr,
                                       efx_rx_buf_size(efx),
                                       DMA_FROM_DEVICE);
+               } else if (used_len) {
+                       dma_sync_single_for_cpu(&efx->pci_dev->dev,
+                                               rx_buf->dma_addr, used_len,
+                                               DMA_FROM_DEVICE);
                }
        } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) {
                dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr,
@@ -269,7 +274,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx,
 static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
                               struct efx_rx_buffer *rx_buf)
 {
-       efx_unmap_rx_buffer(rx_queue->efx, rx_buf);
+       efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0);
        efx_free_rx_buffer(rx_queue->efx, rx_buf);
 }
 
@@ -535,10 +540,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
                goto out;
        }
 
-       /* Release card resources - assumes all RX buffers consumed in-order
-        * per RX queue
+       /* Release and/or sync DMA mapping - assumes all RX buffers
+        * consumed in-order per RX queue
         */
-       efx_unmap_rx_buffer(efx, rx_buf);
+       efx_unmap_rx_buffer(efx, rx_buf, len);
 
        /* Prefetch nice and early so data will (hopefully) be in cache by
         * the time we look at it.
index 7e93df6585e7fd7cce9db2ba3f9ed3187f2b699c..df32a090d08e0c96841a9958b1c1319eb6cbbc19 100644 (file)
@@ -731,7 +731,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
 
        writel(vlan, &priv->host_port_regs->port_vlan);
 
-       for (i = 0; i < 2; i++)
+       for (i = 0; i < priv->data.slaves; i++)
                slave_write(priv->slaves + i, vlan, reg);
 
        cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port,
@@ -905,7 +905,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
        /* If there is no more tx desc left free then we need to
         * tell the kernel to stop sending us tx frames.
         */
-       if (unlikely(cpdma_check_free_tx_desc(priv->txch)))
+       if (unlikely(!cpdma_check_free_tx_desc(priv->txch)))
                netif_stop_queue(ndev);
 
        return NETDEV_TX_OK;
@@ -1364,7 +1364,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
                struct platform_device *mdio;
 
                parp = of_get_property(slave_node, "phy_id", &lenp);
-               if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
+               if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
                        pr_err("Missing slave[%d] phy_id property\n", i);
                        ret = -EINVAL;
                        goto error_ret;
index 52c05366599aca9338267d013ca814abe5b61e78..ae1b77aa199f87ab947c185b552d9274266dac91 100644 (file)
@@ -1102,7 +1102,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
        /* If there is no more tx desc left free then we need to
         * tell the kernel to stop sending us tx frames.
         */
-       if (unlikely(cpdma_check_free_tx_desc(priv->txchan)))
+       if (unlikely(!cpdma_check_free_tx_desc(priv->txchan)))
                netif_stop_queue(ndev);
 
        return NETDEV_TX_OK;
index e5b19b05690967ed93f9ac50be4d1548911bf38a..3c4d6274bb9b25527aa2af7e1daf4f07fe3a84d0 100644 (file)
@@ -202,6 +202,9 @@ static int rr_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 
  out:
+       if (rrpriv->evt_ring)
+               pci_free_consistent(pdev, EVT_RING_SIZE, rrpriv->evt_ring,
+                                   rrpriv->evt_ring_dma);
        if (rrpriv->rx_ring)
                pci_free_consistent(pdev, RX_TOTAL_SIZE, rrpriv->rx_ring,
                                    rrpriv->rx_ring_dma);
index 2f99f8881dfc4c53eb209e888f2f496f97450989..5f4758492e4c0ca1efb1b7e4c4ab063ba98bf7aa 100644 (file)
@@ -383,7 +383,7 @@ static int vlsi_seq_show(struct seq_file *seq, void *v)
 
 static int vlsi_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, vlsi_seq_show, PDE(inode)->data);
+       return single_open(file, vlsi_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations vlsi_proc_fops = {
@@ -1678,7 +1678,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                        IRDA_WARNING("%s: failed to create proc entry\n",
                                     __func__);
                } else {
-                       ent->size = 0;
+                       proc_set_size(ent, 0);
                }
                idev->proc_entry = ent;
        }
index 417b2af1aa8097fd3e158e8b9e09b59885d8c723..73abbc1655d5c7b793601f93027dad37d2923150 100644 (file)
@@ -660,6 +660,7 @@ void macvlan_common_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->priv_flags        &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+       dev->priv_flags        |= IFF_UNICAST_FLT;
        dev->netdev_ops         = &macvlan_netdev_ops;
        dev->destructor         = free_netdev;
        dev->header_ops         = &macvlan_hard_header_ops,
index 37add21a3d7d630d2a989312deab132017eb5fcf..59ac143dec2576a697d9f383ef4d5d7372eef93c 100644 (file)
@@ -666,6 +666,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
                goto done;
 
        spin_lock_irqsave(&target_list_lock, flags);
+restart:
        list_for_each_entry(nt, &target_list, list) {
                netconsole_target_get(nt);
                if (nt->np.dev == dev) {
@@ -678,15 +679,17 @@ static int netconsole_netdev_event(struct notifier_block *this,
                        case NETDEV_UNREGISTER:
                                /*
                                 * rtnl_lock already held
+                                * we might sleep in __netpoll_cleanup()
                                 */
-                               if (nt->np.dev) {
-                                       __netpoll_cleanup(&nt->np);
-                                       dev_put(nt->np.dev);
-                                       nt->np.dev = NULL;
-                               }
+                               spin_unlock_irqrestore(&target_list_lock, flags);
+                               __netpoll_cleanup(&nt->np);
+                               spin_lock_irqsave(&target_list_lock, flags);
+                               dev_put(nt->np.dev);
+                               nt->np.dev = NULL;
                                nt->enabled = 0;
                                stopped = true;
-                               break;
+                               netconsole_target_put(nt);
+                               goto restart;
                        }
                }
                netconsole_target_put(nt);
index 29934446436ac0e6dd7df8d80797a3b4351d77ac..abf7b6153d00b8527b997e4e947b48a63449af4b 100644 (file)
@@ -257,8 +257,7 @@ static struct phy_driver ksphy_driver[] = {
        .phy_id         = PHY_ID_KSZ9021,
        .phy_id_mask    = 0x000ffffe,
        .name           = "Micrel KSZ9021 Gigabit PHY",
-       .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause
-                               | SUPPORTED_Asym_Pause),
+       .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = kszphy_config_init,
        .config_aneg    = genphy_config_aneg,
index 9930f999956172fa20ad5e5a34d3db5297fe9c12..3657b4a29124b57bc335417a1389f792aaf2ce79 100644 (file)
@@ -44,13 +44,13 @@ MODULE_LICENSE("GPL");
 
 void phy_device_free(struct phy_device *phydev)
 {
-       kfree(phydev);
+       put_device(&phydev->dev);
 }
 EXPORT_SYMBOL(phy_device_free);
 
 static void phy_device_release(struct device *dev)
 {
-       phy_device_free(to_phy_device(dev));
+       kfree(to_phy_device(dev));
 }
 
 static struct phy_driver genphy_driver;
@@ -201,6 +201,8 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
           there's no driver _already_ loaded. */
        request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id));
 
+       device_initialize(&dev->dev);
+
        return dev;
 }
 EXPORT_SYMBOL(phy_device_create);
@@ -363,9 +365,9 @@ int phy_device_register(struct phy_device *phydev)
        /* Run all of the fixups for this PHY */
        phy_scan_fixups(phydev);
 
-       err = device_register(&phydev->dev);
+       err = device_add(&phydev->dev);
        if (err) {
-               pr_err("phy %d failed to register\n", phydev->addr);
+               pr_err("PHY %d failed to add\n", phydev->addr);
                goto out;
        }
 
index 05c5efe8459148be152db604da421fe35e95ba41..bf3419297875b102da599162c0852ecfd9eb71eb 100644 (file)
@@ -1138,6 +1138,8 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
        netdev_upper_dev_unlink(port_dev, dev);
        team_port_disable_netpoll(port);
        vlan_vids_del_by_dev(port_dev, dev);
+       dev_uc_unsync(port_dev, dev);
+       dev_mc_unsync(port_dev, dev);
        dev_close(port_dev);
        team_port_leave(team, port);
 
index 2c6a22e278ea15843b7fb4500749304aad0a1444..b7c457adc0dc7439cc2a842409ed3871207f079b 100644 (file)
@@ -747,6 +747,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                goto drop;
        skb_orphan(skb);
 
+       nf_reset(skb);
+
        /* Enqueue packet */
        skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb);
 
index da92ed3797aa32e763c1496a5dce9cca4a273bd5..7c769d8e25ad835440321d9840822b3484f0d08b 100644 (file)
@@ -156,6 +156,24 @@ config USB_NET_AX8817X
          This driver creates an interface named "ethX", where X depends on
          what other networking devices you have in use.
 
+config USB_NET_AX88179_178A
+       tristate "ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet"
+       depends on USB_USBNET
+       select CRC32
+       select PHYLIB
+       default y
+       help
+         This option adds support for ASIX AX88179 based USB 3.0/2.0
+         to Gigabit Ethernet adapters.
+
+         This driver should work with at least the following devices:
+           * ASIX AX88179
+           * ASIX AX88178A
+           * Sitcomm LN-032
+
+         This driver creates an interface named "ethX", where X depends on
+         what other networking devices you have in use.
+
 config USB_NET_CDCETHER
        tristate "CDC Ethernet support (smart devices such as cable modems)"
        depends on USB_USBNET
@@ -250,7 +268,7 @@ config USB_NET_SMSC75XX
        select CRC16
        select CRC32
        help
-         This option adds support for SMSC LAN95XX based USB 2.0
+         This option adds support for SMSC LAN75XX based USB 2.0
          Gigabit Ethernet adapters.
 
 config USB_NET_SMSC95XX
index 478691326f37fc3303199a07dd9e83ae087615be..119b06c9aa167235571ccc8649e25191497e505d 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_RTL8150)       += rtl8150.o
 obj-$(CONFIG_USB_HSO)          += hso.o
 obj-$(CONFIG_USB_NET_AX8817X)  += asix.o
 asix-y := asix_devices.o asix_common.o ax88172a.o
+obj-$(CONFIG_USB_NET_AX88179_178A)      += ax88179_178a.o
 obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
index 2205dbc8d32fc2bbcb74e5c82047913edc3fdd24..709753469099c032aad55c3b98da120a0f930b2e 100644 (file)
@@ -924,6 +924,29 @@ static const struct driver_info ax88178_info = {
        .tx_fixup = asix_tx_fixup,
 };
 
+/*
+ * USBLINK 20F9 "USB 2.0 LAN" USB ethernet adapter, typically found in
+ * no-name packaging.
+ * USB device strings are:
+ *   1: Manufacturer: USBLINK
+ *   2: Product: HG20F9 USB2.0
+ *   3: Serial: 000003
+ * Appears to be compatible with Asix 88772B.
+ */
+static const struct driver_info hg20f9_info = {
+       .description = "HG20F9 USB 2.0 Ethernet",
+       .bind = ax88772_bind,
+       .unbind = ax88772_unbind,
+       .status = asix_status,
+       .link_reset = ax88772_link_reset,
+       .reset = ax88772_reset,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
+                FLAG_MULTI_PACKET,
+       .rx_fixup = asix_rx_fixup_common,
+       .tx_fixup = asix_tx_fixup,
+       .data = FLAG_EEPROM_MAC,
+};
+
 extern const struct driver_info ax88172a_info;
 
 static const struct usb_device_id      products [] = {
@@ -1063,6 +1086,14 @@ static const struct usb_device_id        products [] = {
        /* ASIX 88172a demo board */
        USB_DEVICE(0x0b95, 0x172a),
        .driver_info = (unsigned long) &ax88172a_info,
+}, {
+       /*
+        * USBLINK HG20F9 "USB 2.0 LAN"
+        * Appears to have gazumped Linksys's manufacturer ID but
+        * doesn't (yet) conflict with any known Linksys product.
+        */
+       USB_DEVICE(0x066b, 0x20f9),
+       .driver_info = (unsigned long) &hg20f9_info,
 },
        { },            // END
 };
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
new file mode 100644 (file)
index 0000000..71c27d8
--- /dev/null
@@ -0,0 +1,1448 @@
+/*
+ * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices
+ *
+ * Copyright (C) 2011-2013 ASIX
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+
+#define AX88179_PHY_ID                         0x03
+#define AX_EEPROM_LEN                          0x100
+#define AX88179_EEPROM_MAGIC                   0x17900b95
+#define AX_MCAST_FLTSIZE                       8
+#define AX_MAX_MCAST                           64
+#define AX_INT_PPLS_LINK                       ((u32)BIT(16))
+#define AX_RXHDR_L4_TYPE_MASK                  0x1c
+#define AX_RXHDR_L4_TYPE_UDP                   4
+#define AX_RXHDR_L4_TYPE_TCP                   16
+#define AX_RXHDR_L3CSUM_ERR                    2
+#define AX_RXHDR_L4CSUM_ERR                    1
+#define AX_RXHDR_CRC_ERR                       ((u32)BIT(31))
+#define AX_RXHDR_DROP_ERR                      ((u32)BIT(30))
+#define AX_ACCESS_MAC                          0x01
+#define AX_ACCESS_PHY                          0x02
+#define AX_ACCESS_EEPROM                       0x04
+#define AX_ACCESS_EFUS                         0x05
+#define AX_PAUSE_WATERLVL_HIGH                 0x54
+#define AX_PAUSE_WATERLVL_LOW                  0x55
+
+#define PHYSICAL_LINK_STATUS                   0x02
+       #define AX_USB_SS               0x04
+       #define AX_USB_HS               0x02
+
+#define GENERAL_STATUS                         0x03
+/* Check AX88179 version. UA1:Bit2 = 0,  UA2:Bit2 = 1 */
+       #define AX_SECLD                0x04
+
+#define AX_SROM_ADDR                           0x07
+#define AX_SROM_CMD                            0x0a
+       #define EEP_RD                  0x04
+       #define EEP_BUSY                0x10
+
+#define AX_SROM_DATA_LOW                       0x08
+#define AX_SROM_DATA_HIGH                      0x09
+
+#define AX_RX_CTL                              0x0b
+       #define AX_RX_CTL_DROPCRCERR    0x0100
+       #define AX_RX_CTL_IPE           0x0200
+       #define AX_RX_CTL_START         0x0080
+       #define AX_RX_CTL_AP            0x0020
+       #define AX_RX_CTL_AM            0x0010
+       #define AX_RX_CTL_AB            0x0008
+       #define AX_RX_CTL_AMALL         0x0002
+       #define AX_RX_CTL_PRO           0x0001
+       #define AX_RX_CTL_STOP          0x0000
+
+#define AX_NODE_ID                             0x10
+#define AX_MULFLTARY                           0x16
+
+#define AX_MEDIUM_STATUS_MODE                  0x22
+       #define AX_MEDIUM_GIGAMODE      0x01
+       #define AX_MEDIUM_FULL_DUPLEX   0x02
+       #define AX_MEDIUM_ALWAYS_ONE    0x04
+       #define AX_MEDIUM_EN_125MHZ     0x08
+       #define AX_MEDIUM_RXFLOW_CTRLEN 0x10
+       #define AX_MEDIUM_TXFLOW_CTRLEN 0x20
+       #define AX_MEDIUM_RECEIVE_EN    0x100
+       #define AX_MEDIUM_PS            0x200
+       #define AX_MEDIUM_JUMBO_EN      0x8040
+
+#define AX_MONITOR_MOD                         0x24
+       #define AX_MONITOR_MODE_RWLC    0x02
+       #define AX_MONITOR_MODE_RWMP    0x04
+       #define AX_MONITOR_MODE_PMEPOL  0x20
+       #define AX_MONITOR_MODE_PMETYPE 0x40
+
+#define AX_GPIO_CTRL                           0x25
+       #define AX_GPIO_CTRL_GPIO3EN    0x80
+       #define AX_GPIO_CTRL_GPIO2EN    0x40
+       #define AX_GPIO_CTRL_GPIO1EN    0x20
+
+#define AX_PHYPWR_RSTCTL                       0x26
+       #define AX_PHYPWR_RSTCTL_BZ     0x0010
+       #define AX_PHYPWR_RSTCTL_IPRL   0x0020
+       #define AX_PHYPWR_RSTCTL_AT     0x1000
+
+#define AX_RX_BULKIN_QCTRL                     0x2e
+#define AX_CLK_SELECT                          0x33
+       #define AX_CLK_SELECT_BCS       0x01
+       #define AX_CLK_SELECT_ACS       0x02
+       #define AX_CLK_SELECT_ULR       0x08
+
+#define AX_RXCOE_CTL                           0x34
+       #define AX_RXCOE_IP             0x01
+       #define AX_RXCOE_TCP            0x02
+       #define AX_RXCOE_UDP            0x04
+       #define AX_RXCOE_TCPV6          0x20
+       #define AX_RXCOE_UDPV6          0x40
+
+#define AX_TXCOE_CTL                           0x35
+       #define AX_TXCOE_IP             0x01
+       #define AX_TXCOE_TCP            0x02
+       #define AX_TXCOE_UDP            0x04
+       #define AX_TXCOE_TCPV6          0x20
+       #define AX_TXCOE_UDPV6          0x40
+
+#define AX_LEDCTRL                             0x73
+
+#define GMII_PHY_PHYSR                         0x11
+       #define GMII_PHY_PHYSR_SMASK    0xc000
+       #define GMII_PHY_PHYSR_GIGA     0x8000
+       #define GMII_PHY_PHYSR_100      0x4000
+       #define GMII_PHY_PHYSR_FULL     0x2000
+       #define GMII_PHY_PHYSR_LINK     0x400
+
+#define GMII_LED_ACT                           0x1a
+       #define GMII_LED_ACTIVE_MASK    0xff8f
+       #define GMII_LED0_ACTIVE        BIT(4)
+       #define GMII_LED1_ACTIVE        BIT(5)
+       #define GMII_LED2_ACTIVE        BIT(6)
+
+#define GMII_LED_LINK                          0x1c
+       #define GMII_LED_LINK_MASK      0xf888
+       #define GMII_LED0_LINK_10       BIT(0)
+       #define GMII_LED0_LINK_100      BIT(1)
+       #define GMII_LED0_LINK_1000     BIT(2)
+       #define GMII_LED1_LINK_10       BIT(4)
+       #define GMII_LED1_LINK_100      BIT(5)
+       #define GMII_LED1_LINK_1000     BIT(6)
+       #define GMII_LED2_LINK_10       BIT(8)
+       #define GMII_LED2_LINK_100      BIT(9)
+       #define GMII_LED2_LINK_1000     BIT(10)
+       #define LED0_ACTIVE             BIT(0)
+       #define LED0_LINK_10            BIT(1)
+       #define LED0_LINK_100           BIT(2)
+       #define LED0_LINK_1000          BIT(3)
+       #define LED0_FD                 BIT(4)
+       #define LED0_USB3_MASK          0x001f
+       #define LED1_ACTIVE             BIT(5)
+       #define LED1_LINK_10            BIT(6)
+       #define LED1_LINK_100           BIT(7)
+       #define LED1_LINK_1000          BIT(8)
+       #define LED1_FD                 BIT(9)
+       #define LED1_USB3_MASK          0x03e0
+       #define LED2_ACTIVE             BIT(10)
+       #define LED2_LINK_1000          BIT(13)
+       #define LED2_LINK_100           BIT(12)
+       #define LED2_LINK_10            BIT(11)
+       #define LED2_FD                 BIT(14)
+       #define LED_VALID               BIT(15)
+       #define LED2_USB3_MASK          0x7c00
+
+#define GMII_PHYPAGE                           0x1e
+#define GMII_PHY_PAGE_SELECT                   0x1f
+       #define GMII_PHY_PGSEL_EXT      0x0007
+       #define GMII_PHY_PGSEL_PAGE0    0x0000
+
+struct ax88179_data {
+       u16 rxctl;
+       u16 reserved;
+};
+
+struct ax88179_int_data {
+       __le32 intdata1;
+       __le32 intdata2;
+};
+
+static const struct {
+       unsigned char ctrl, timer_l, timer_h, size, ifg;
+} AX88179_BULKIN_SIZE[] =      {
+       {7, 0x4f, 0,    0x12, 0xff},
+       {7, 0x20, 3,    0x16, 0xff},
+       {7, 0xae, 7,    0x18, 0xff},
+       {7, 0xcc, 0x4c, 0x18, 8},
+};
+
+static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                             u16 size, void *data, int in_pm)
+{
+       int ret;
+       int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
+
+       BUG_ON(!dev);
+
+       if (!in_pm)
+               fn = usbnet_read_cmd;
+       else
+               fn = usbnet_read_cmd_nopm;
+
+       ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                value, index, data, size);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n",
+                           index, ret);
+
+       return ret;
+}
+
+static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                              u16 size, void *data, int in_pm)
+{
+       int ret;
+       int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
+
+       BUG_ON(!dev);
+
+       if (!in_pm)
+               fn = usbnet_write_cmd;
+       else
+               fn = usbnet_write_cmd_nopm;
+
+       ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                value, index, data, size);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n",
+                           index, ret);
+
+       return ret;
+}
+
+static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
+                                   u16 index, u16 size, void *data)
+{
+       u16 buf;
+
+       if (2 == size) {
+               buf = *((u16 *)data);
+               cpu_to_le16s(&buf);
+               usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+                                      USB_RECIP_DEVICE, value, index, &buf,
+                                      size);
+       } else {
+               usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+                                      USB_RECIP_DEVICE, value, index, data,
+                                      size);
+       }
+}
+
+static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+                                u16 index, u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
+               le16_to_cpus(&buf);
+               *((u16 *)data) = buf;
+       } else if (4 == size) {
+               u32 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
+               le32_to_cpus(&buf);
+               *((u32 *)data) = buf;
+       } else {
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1);
+       }
+
+       return ret;
+}
+
+static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+                                 u16 index, u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               buf = *((u16 *)data);
+               cpu_to_le16s(&buf);
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, &buf, 1);
+       } else {
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, data, 1);
+       }
+
+       return ret;
+}
+
+static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                           u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
+               le16_to_cpus(&buf);
+               *((u16 *)data) = buf;
+       } else if (4 == size) {
+               u32 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
+               le32_to_cpus(&buf);
+               *((u32 *)data) = buf;
+       } else {
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0);
+       }
+
+       return ret;
+}
+
+static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                            u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               buf = *((u16 *)data);
+               cpu_to_le16s(&buf);
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, &buf, 0);
+       } else {
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, data, 0);
+       }
+
+       return ret;
+}
+
+static void ax88179_status(struct usbnet *dev, struct urb *urb)
+{
+       struct ax88179_int_data *event;
+       u32 link;
+
+       if (urb->actual_length < 8)
+               return;
+
+       event = urb->transfer_buffer;
+       le32_to_cpus((void *)&event->intdata1);
+
+       link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16;
+
+       if (netif_carrier_ok(dev->net) != link) {
+               if (link)
+                       usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+               else
+                       netif_carrier_off(dev->net);
+
+               netdev_info(dev->net, "ax88179 - Link status is: %d\n", link);
+       }
+}
+
+static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res;
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
+       return res;
+}
+
+static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,
+                              int val)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res = (u16) val;
+
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
+}
+
+static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usbnet *dev = usb_get_intfdata(intf);
+       u16 tmp16;
+       u8 tmp8;
+
+       usbnet_suspend(intf, message);
+
+       /* Disable RX path */
+       ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                             2, 2, &tmp16);
+       tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                              2, 2, &tmp16);
+
+       /* Force bulk-in zero length */
+       ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                             2, 2, &tmp16);
+
+       tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                              2, 2, &tmp16);
+
+       /* change clock */
+       tmp8 = 0;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+
+       /* Configure RX control register => stop operation */
+       tmp16 = AX_RX_CTL_STOP;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+       return 0;
+}
+
+/* This function is used to enable the autodetach function. */
+/* This function is determined by offset 0x43 of EEPROM */
+static int ax88179_auto_detach(struct usbnet *dev, int in_pm)
+{
+       u16 tmp16;
+       u8 tmp8;
+       int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *);
+       int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *);
+
+       if (!in_pm) {
+               fnr = ax88179_read_cmd;
+               fnw = ax88179_write_cmd;
+       } else {
+               fnr = ax88179_read_cmd_nopm;
+               fnw = ax88179_write_cmd_nopm;
+       }
+
+       if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0)
+               return 0;
+
+       if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100)))
+               return 0;
+
+       /* Enable Auto Detach bit */
+       tmp8 = 0;
+       fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+       tmp8 |= AX_CLK_SELECT_ULR;
+       fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+
+       fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+       tmp16 |= AX_PHYPWR_RSTCTL_AT;
+       fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+
+       return 0;
+}
+
+static int ax88179_resume(struct usb_interface *intf)
+{
+       struct usbnet *dev = usb_get_intfdata(intf);
+       u16 tmp16;
+       u8 tmp8;
+
+       netif_carrier_off(dev->net);
+
+       /* Power up ethernet PHY */
+       tmp16 = 0;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                              2, 2, &tmp16);
+       udelay(1000);
+
+       tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                              2, 2, &tmp16);
+       msleep(200);
+
+       /* Ethernet PHY Auto Detach*/
+       ax88179_auto_detach(dev, 1);
+
+       /* Enable clock */
+       ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC,  AX_CLK_SELECT, 1, 1, &tmp8);
+       tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+       msleep(100);
+
+       /* Configure RX control register => start operation */
+       tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+               AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+       return usbnet_resume(intf);
+}
+
+static void
+ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u8 opt;
+
+       if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
+                            1, 1, &opt) < 0) {
+               wolinfo->supported = 0;
+               wolinfo->wolopts = 0;
+               return;
+       }
+
+       wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
+       wolinfo->wolopts = 0;
+       if (opt & AX_MONITOR_MODE_RWLC)
+               wolinfo->wolopts |= WAKE_PHY;
+       if (opt & AX_MONITOR_MODE_RWMP)
+               wolinfo->wolopts |= WAKE_MAGIC;
+}
+
+static int
+ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u8 opt = 0;
+
+       if (wolinfo->wolopts & WAKE_PHY)
+               opt |= AX_MONITOR_MODE_RWLC;
+       if (wolinfo->wolopts & WAKE_MAGIC)
+               opt |= AX_MONITOR_MODE_RWMP;
+
+       if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
+                             1, 1, &opt) < 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ax88179_get_eeprom_len(struct net_device *net)
+{
+       return AX_EEPROM_LEN;
+}
+
+static int
+ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
+                  u8 *data)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u16 *eeprom_buff;
+       int first_word, last_word;
+       int i, ret;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       eeprom->magic = AX88179_EEPROM_MAGIC;
+
+       first_word = eeprom->offset >> 1;
+       last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+       eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1),
+                             GFP_KERNEL);
+       if (!eeprom_buff)
+               return -ENOMEM;
+
+       /* ax88179/178A returns 2 bytes from eeprom on read */
+       for (i = first_word; i <= last_word; i++) {
+               ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2,
+                                        &eeprom_buff[i - first_word],
+                                        0);
+               if (ret < 0) {
+                       kfree(eeprom_buff);
+                       return -EIO;
+               }
+       }
+
+       memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
+       kfree(eeprom_buff);
+       return 0;
+}
+
+static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return mii_ethtool_gset(&dev->mii, cmd);
+}
+
+static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return mii_ethtool_sset(&dev->mii, cmd);
+}
+
+
+static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static const struct ethtool_ops ax88179_ethtool_ops = {
+       .get_link               = ethtool_op_get_link,
+       .get_msglevel           = usbnet_get_msglevel,
+       .set_msglevel           = usbnet_set_msglevel,
+       .get_wol                = ax88179_get_wol,
+       .set_wol                = ax88179_set_wol,
+       .get_eeprom_len         = ax88179_get_eeprom_len,
+       .get_eeprom             = ax88179_get_eeprom,
+       .get_settings           = ax88179_get_settings,
+       .set_settings           = ax88179_set_settings,
+       .nway_reset             = usbnet_nway_reset,
+};
+
+static void ax88179_set_multicast(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct ax88179_data *data = (struct ax88179_data *)dev->data;
+       u8 *m_filter = ((u8 *)dev->data) + 12;
+
+       data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
+
+       if (net->flags & IFF_PROMISC) {
+               data->rxctl |= AX_RX_CTL_PRO;
+       } else if (net->flags & IFF_ALLMULTI ||
+                  netdev_mc_count(net) > AX_MAX_MCAST) {
+               data->rxctl |= AX_RX_CTL_AMALL;
+       } else if (netdev_mc_empty(net)) {
+               /* just broadcast and directed */
+       } else {
+               /* We use the 20 byte dev->data for our 8 byte filter buffer
+                * to avoid allocating memory that is tricky to free later
+                */
+               u32 crc_bits;
+               struct netdev_hw_addr *ha;
+
+               memset(m_filter, 0, AX_MCAST_FLTSIZE);
+
+               netdev_for_each_mc_addr(ha, net) {
+                       crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
+                       *(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7));
+               }
+
+               ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY,
+                                       AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE,
+                                       m_filter);
+
+               data->rxctl |= AX_RX_CTL_AM;
+       }
+
+       ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL,
+                               2, 2, &data->rxctl);
+}
+
+static int
+ax88179_set_features(struct net_device *net, netdev_features_t features)
+{
+       u8 tmp;
+       struct usbnet *dev = netdev_priv(net);
+       netdev_features_t changed = net->features ^ features;
+
+       if (changed & NETIF_F_IP_CSUM) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+               tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+       }
+
+       if (changed & NETIF_F_IPV6_CSUM) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+               tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+       }
+
+       if (changed & NETIF_F_RXCSUM) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
+               tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+                      AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
+       }
+
+       return 0;
+}
+
+static int ax88179_change_mtu(struct net_device *net, int new_mtu)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u16 tmp16;
+
+       if (new_mtu <= 0 || new_mtu > 4088)
+               return -EINVAL;
+
+       net->mtu = new_mtu;
+       dev->hard_mtu = net->mtu + net->hard_header_len;
+
+       if (net->mtu > 1500) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                2, 2, &tmp16);
+               tmp16 |= AX_MEDIUM_JUMBO_EN;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                 2, 2, &tmp16);
+       } else {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                2, 2, &tmp16);
+               tmp16 &= ~AX_MEDIUM_JUMBO_EN;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                 2, 2, &tmp16);
+       }
+
+       return 0;
+}
+
+static int ax88179_set_mac_addr(struct net_device *net, void *p)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct sockaddr *addr = p;
+
+       if (netif_running(net))
+               return -EBUSY;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
+
+       /* Set the MAC address */
+       return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+                                ETH_ALEN, net->dev_addr);
+}
+
+static const struct net_device_ops ax88179_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = ax88179_change_mtu,
+       .ndo_set_mac_address    = ax88179_set_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = ax88179_ioctl,
+       .ndo_set_rx_mode        = ax88179_set_multicast,
+       .ndo_set_features       = ax88179_set_features,
+};
+
+static int ax88179_check_eeprom(struct usbnet *dev)
+{
+       u8 i, buf, eeprom[20];
+       u16 csum, delay = HZ / 10;
+       unsigned long jtimeout;
+
+       /* Read EEPROM content */
+       for (i = 0; i < 6; i++) {
+               buf = i;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
+                                     1, 1, &buf) < 0)
+                       return -EINVAL;
+
+               buf = EEP_RD;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                     1, 1, &buf) < 0)
+                       return -EINVAL;
+
+               jtimeout = jiffies + delay;
+               do {
+                       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                        1, 1, &buf);
+
+                       if (time_after(jiffies, jtimeout))
+                               return -EINVAL;
+
+               } while (buf & EEP_BUSY);
+
+               __ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+                                  2, 2, &eeprom[i * 2], 0);
+
+               if ((i == 0) && (eeprom[0] == 0xFF))
+                       return -EINVAL;
+       }
+
+       csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9];
+       csum = (csum >> 8) + (csum & 0xff);
+       if ((csum + eeprom[10]) != 0xff)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode)
+{
+       u8      i;
+       u8      efuse[64];
+       u16     csum = 0;
+
+       if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0)
+               return -EINVAL;
+
+       if (*efuse == 0xFF)
+               return -EINVAL;
+
+       for (i = 0; i < 64; i++)
+               csum = csum + efuse[i];
+
+       while (csum > 255)
+               csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF);
+
+       if (csum != 0xFF)
+               return -EINVAL;
+
+       *ledmode = (efuse[51] << 8) | efuse[52];
+
+       return 0;
+}
+
+static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue)
+{
+       u16 led;
+
+       /* Loaded the old eFuse LED Mode */
+       if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0)
+               return -EINVAL;
+
+       led >>= 8;
+       switch (led) {
+       case 0xFF:
+               led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+                     LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+                     LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+               break;
+       case 0xFE:
+               led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID;
+               break;
+       case 0xFD:
+               led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 |
+                     LED2_LINK_10 | LED_VALID;
+               break;
+       case 0xFC:
+               led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE |
+                     LED2_LINK_100 | LED2_LINK_10 | LED_VALID;
+               break;
+       default:
+               led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+                     LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+                     LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+               break;
+       }
+
+       *ledvalue = led;
+
+       return 0;
+}
+
+static int ax88179_led_setting(struct usbnet *dev)
+{
+       u8 ledfd, value = 0;
+       u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10;
+       unsigned long jtimeout;
+
+       /* Check AX88179 version. UA1 or UA2*/
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value);
+
+       if (!(value & AX_SECLD)) {      /* UA1 */
+               value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN |
+                       AX_GPIO_CTRL_GPIO1EN;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL,
+                                     1, 1, &value) < 0)
+                       return -EINVAL;
+       }
+
+       /* Check EEPROM */
+       if (!ax88179_check_eeprom(dev)) {
+               value = 0x42;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
+                                     1, 1, &value) < 0)
+                       return -EINVAL;
+
+               value = EEP_RD;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                     1, 1, &value) < 0)
+                       return -EINVAL;
+
+               jtimeout = jiffies + delay;
+               do {
+                       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                        1, 1, &value);
+
+                       if (time_after(jiffies, jtimeout))
+                               return -EINVAL;
+
+               } while (value & EEP_BUSY);
+
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH,
+                                1, 1, &value);
+               ledvalue = (value << 8);
+
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+                                1, 1, &value);
+               ledvalue |= value;
+
+               /* load internal ROM for defaule setting */
+               if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+                       ax88179_convert_old_led(dev, &ledvalue);
+
+       } else if (!ax88179_check_efuse(dev, &ledvalue)) {
+               if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+                       ax88179_convert_old_led(dev, &ledvalue);
+       } else {
+               ax88179_convert_old_led(dev, &ledvalue);
+       }
+
+       tmp = GMII_PHY_PGSEL_EXT;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_PHY_PAGE_SELECT, 2, &tmp);
+
+       tmp = 0x2c;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_PHYPAGE, 2, &tmp);
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                        GMII_LED_ACT, 2, &ledact);
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                        GMII_LED_LINK, 2, &ledlink);
+
+       ledact &= GMII_LED_ACTIVE_MASK;
+       ledlink &= GMII_LED_LINK_MASK;
+
+       if (ledvalue & LED0_ACTIVE)
+               ledact |= GMII_LED0_ACTIVE;
+
+       if (ledvalue & LED1_ACTIVE)
+               ledact |= GMII_LED1_ACTIVE;
+
+       if (ledvalue & LED2_ACTIVE)
+               ledact |= GMII_LED2_ACTIVE;
+
+       if (ledvalue & LED0_LINK_10)
+               ledlink |= GMII_LED0_LINK_10;
+
+       if (ledvalue & LED1_LINK_10)
+               ledlink |= GMII_LED1_LINK_10;
+
+       if (ledvalue & LED2_LINK_10)
+               ledlink |= GMII_LED2_LINK_10;
+
+       if (ledvalue & LED0_LINK_100)
+               ledlink |= GMII_LED0_LINK_100;
+
+       if (ledvalue & LED1_LINK_100)
+               ledlink |= GMII_LED1_LINK_100;
+
+       if (ledvalue & LED2_LINK_100)
+               ledlink |= GMII_LED2_LINK_100;
+
+       if (ledvalue & LED0_LINK_1000)
+               ledlink |= GMII_LED0_LINK_1000;
+
+       if (ledvalue & LED1_LINK_1000)
+               ledlink |= GMII_LED1_LINK_1000;
+
+       if (ledvalue & LED2_LINK_1000)
+               ledlink |= GMII_LED2_LINK_1000;
+
+       tmp = ledact;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_LED_ACT, 2, &tmp);
+
+       tmp = ledlink;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_LED_LINK, 2, &tmp);
+
+       tmp = GMII_PHY_PGSEL_PAGE0;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_PHY_PAGE_SELECT, 2, &tmp);
+
+       /* LED full duplex setting */
+       ledfd = 0;
+       if (ledvalue & LED0_FD)
+               ledfd |= 0x01;
+       else if ((ledvalue & LED0_USB3_MASK) == 0)
+               ledfd |= 0x02;
+
+       if (ledvalue & LED1_FD)
+               ledfd |= 0x04;
+       else if ((ledvalue & LED1_USB3_MASK) == 0)
+               ledfd |= 0x08;
+
+       if (ledvalue & LED2_FD)
+               ledfd |= 0x10;
+       else if ((ledvalue & LED2_USB3_MASK) == 0)
+               ledfd |= 0x20;
+
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd);
+
+       return 0;
+}
+
+static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u8 buf[5];
+       u16 *tmp16;
+       u8 *tmp;
+       struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+
+       usbnet_get_endpoints(dev, intf);
+
+       tmp16 = (u16 *)buf;
+       tmp = (u8 *)buf;
+
+       memset(ax179_data, 0, sizeof(*ax179_data));
+
+       /* Power up ethernet PHY */
+       *tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+       *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+       msleep(200);
+
+       *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+       msleep(100);
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+                        ETH_ALEN, dev->net->dev_addr);
+       memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+
+       /* RX bulk configuration */
+       memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+       dev->rx_urb_size = 1024 * 20;
+
+       *tmp = 0x34;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+
+       *tmp = 0x52;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+                         1, 1, tmp);
+
+       dev->net->netdev_ops = &ax88179_netdev_ops;
+       dev->net->ethtool_ops = &ax88179_ethtool_ops;
+       dev->net->needed_headroom = 8;
+
+       /* Initialize MII structure */
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = ax88179_mdio_read;
+       dev->mii.mdio_write = ax88179_mdio_write;
+       dev->mii.phy_id_mask = 0xff;
+       dev->mii.reg_num_mask = 0xff;
+       dev->mii.phy_id = 0x03;
+       dev->mii.supports_gmii = 1;
+
+       dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                             NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                                NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       /* Enable checksum offload */
+       *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+              AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
+
+       *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+              AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
+
+       /* Configure RX control register => start operation */
+       *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+                AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
+
+       *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+              AX_MONITOR_MODE_RWMP;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
+
+       /* Configure default medium type => giga */
+       *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
+                AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, tmp16);
+
+       ax88179_led_setting(dev);
+
+       /* Restart autoneg */
+       mii_nway_restart(&dev->mii);
+
+       netif_carrier_off(dev->net);
+
+       return 0;
+}
+
+static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u16 tmp16;
+
+       /* Configure RX control register => stop operation */
+       tmp16 = AX_RX_CTL_STOP;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+       tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16);
+
+       /* Power down ethernet PHY */
+       tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+}
+
+static void
+ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr)
+{
+       skb->ip_summed = CHECKSUM_NONE;
+
+       /* checksum error bit is set */
+       if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) ||
+           (*pkt_hdr & AX_RXHDR_L4CSUM_ERR))
+               return;
+
+       /* It must be a TCP or UDP packet with a valid checksum */
+       if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) ||
+           ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP))
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
+static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct sk_buff *ax_skb;
+       int pkt_cnt;
+       u32 rx_hdr;
+       u16 hdr_off;
+       u32 *pkt_hdr;
+
+       skb_trim(skb, skb->len - 4);
+       memcpy(&rx_hdr, skb_tail_pointer(skb), 4);
+       le32_to_cpus(&rx_hdr);
+
+       pkt_cnt = (u16)rx_hdr;
+       hdr_off = (u16)(rx_hdr >> 16);
+       pkt_hdr = (u32 *)(skb->data + hdr_off);
+
+       while (pkt_cnt--) {
+               u16 pkt_len;
+
+               le32_to_cpus(pkt_hdr);
+               pkt_len = (*pkt_hdr >> 16) & 0x1fff;
+
+               /* Check CRC or runt packet */
+               if ((*pkt_hdr & AX_RXHDR_CRC_ERR) ||
+                   (*pkt_hdr & AX_RXHDR_DROP_ERR)) {
+                       skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+                       pkt_hdr++;
+                       continue;
+               }
+
+               if (pkt_cnt == 0) {
+                       /* Skip IP alignment psudo header */
+                       skb_pull(skb, 2);
+                       skb->len = pkt_len;
+                       skb_set_tail_pointer(skb, pkt_len);
+                       skb->truesize = pkt_len + sizeof(struct sk_buff);
+                       ax88179_rx_checksum(skb, pkt_hdr);
+                       return 1;
+               }
+
+               ax_skb = skb_clone(skb, GFP_ATOMIC);
+               if (ax_skb) {
+                       ax_skb->len = pkt_len;
+                       ax_skb->data = skb->data + 2;
+                       skb_set_tail_pointer(ax_skb, pkt_len);
+                       ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
+                       ax88179_rx_checksum(ax_skb, pkt_hdr);
+                       usbnet_skb_return(dev, ax_skb);
+               } else {
+                       return 0;
+               }
+
+               skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+               pkt_hdr++;
+       }
+       return 1;
+}
+
+static struct sk_buff *
+ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+       u32 tx_hdr1, tx_hdr2;
+       int frame_size = dev->maxpacket;
+       int mss = skb_shinfo(skb)->gso_size;
+       int headroom;
+       int tailroom;
+
+       tx_hdr1 = skb->len;
+       tx_hdr2 = mss;
+       if (((skb->len + 8) % frame_size) == 0)
+               tx_hdr2 |= 0x80008000;  /* Enable padding */
+
+       skb_linearize(skb);
+       headroom = skb_headroom(skb);
+       tailroom = skb_tailroom(skb);
+
+       if (!skb_header_cloned(skb) &&
+           !skb_cloned(skb) &&
+           (headroom + tailroom) >= 8) {
+               if (headroom < 8) {
+                       skb->data = memmove(skb->head + 8, skb->data, skb->len);
+                       skb_set_tail_pointer(skb, skb->len);
+               }
+       } else {
+               struct sk_buff *skb2;
+
+               skb2 = skb_copy_expand(skb, 8, 0, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_hdr2);
+       skb_copy_to_linear_data(skb, &tx_hdr2, 4);
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_hdr1);
+       skb_copy_to_linear_data(skb, &tx_hdr1, 4);
+
+       return skb;
+}
+
+static int ax88179_link_reset(struct usbnet *dev)
+{
+       struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+       u8 tmp[5], link_sts;
+       u16 mode, tmp16, delay = HZ / 10;
+       u32 tmp32 = 0x40000000;
+       unsigned long jtimeout;
+
+       jtimeout = jiffies + delay;
+       while (tmp32 & 0x40000000) {
+               mode = 0;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode);
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2,
+                                 &ax179_data->rxctl);
+
+               /*link up, check the usb device control TX FIFO full or empty*/
+               ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32);
+
+               if (time_after(jiffies, jtimeout))
+                       return 0;
+       }
+
+       mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+              AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE;
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
+                        1, 1, &link_sts);
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                        GMII_PHY_PHYSR, 2, &tmp16);
+
+       if (!(tmp16 & GMII_PHY_PHYSR_LINK)) {
+               return 0;
+       } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
+               mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ;
+               if (dev->net->mtu > 1500)
+                       mode |= AX_MEDIUM_JUMBO_EN;
+
+               if (link_sts & AX_USB_SS)
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+               else if (link_sts & AX_USB_HS)
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5);
+               else
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+       } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
+               mode |= AX_MEDIUM_PS;
+
+               if (link_sts & (AX_USB_SS | AX_USB_HS))
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5);
+               else
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+       } else {
+               memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+       }
+
+       /* RX bulk configuration */
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+       dev->rx_urb_size = (1024 * (tmp[3] + 2));
+
+       if (tmp16 & GMII_PHY_PHYSR_FULL)
+               mode |= AX_MEDIUM_FULL_DUPLEX;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, &mode);
+
+       netif_carrier_on(dev->net);
+
+       return 0;
+}
+
+static int ax88179_reset(struct usbnet *dev)
+{
+       u8 buf[5];
+       u16 *tmp16;
+       u8 *tmp;
+
+       tmp16 = (u16 *)buf;
+       tmp = (u8 *)buf;
+
+       /* Power up ethernet PHY */
+       *tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+
+       *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+       msleep(200);
+
+       *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+       msleep(100);
+
+       /* Ethernet PHY Auto Detach*/
+       ax88179_auto_detach(dev, 0);
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
+                        dev->net->dev_addr);
+       memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+
+       /* RX bulk configuration */
+       memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+       dev->rx_urb_size = 1024 * 20;
+
+       *tmp = 0x34;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+
+       *tmp = 0x52;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+                         1, 1, tmp);
+
+       dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                             NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                                NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       /* Enable checksum offload */
+       *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+              AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
+
+       *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+              AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
+
+       /* Configure RX control register => start operation */
+       *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+                AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
+
+       *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+              AX_MONITOR_MODE_RWMP;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
+
+       /* Configure default medium type => giga */
+       *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
+                AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, tmp16);
+
+       ax88179_led_setting(dev);
+
+       /* Restart autoneg */
+       mii_nway_restart(&dev->mii);
+
+       netif_carrier_off(dev->net);
+
+       return 0;
+}
+
+static int ax88179_stop(struct usbnet *dev)
+{
+       u16 tmp16;
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                        2, 2, &tmp16);
+       tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, &tmp16);
+
+       return 0;
+}
+
+static const struct driver_info ax88179_info = {
+       .description = "ASIX AX88179 USB 3.0 Gigibit Ethernet",
+       .bind = ax88179_bind,
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct driver_info ax88178a_info = {
+       .description = "ASIX AX88178A USB 2.0 Gigibit Ethernet",
+       .bind = ax88179_bind,
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct driver_info sitecom_info = {
+       .description = "Sitecom USB 3.0 to Gigabit Adapter",
+       .bind = ax88179_bind,
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+{
+       /* ASIX AX88179 10/100/1000 */
+       USB_DEVICE(0x0b95, 0x1790),
+       .driver_info = (unsigned long)&ax88179_info,
+}, {
+       /* ASIX AX88178A 10/100/1000 */
+       USB_DEVICE(0x0b95, 0x178a),
+       .driver_info = (unsigned long)&ax88178a_info,
+}, {
+       /* Sitecom USB 3.0 to Gigabit Adapter */
+       USB_DEVICE(0x0df6, 0x0072),
+       .driver_info = (unsigned long) &sitecom_info,
+},
+       { },
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver ax88179_178a_driver = {
+       .name =         "ax88179_178a",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .suspend =      ax88179_suspend,
+       .resume =       ax88179_resume,
+       .disconnect =   usbnet_disconnect,
+       .supports_autosuspend = 1,
+       .disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(ax88179_178a_driver);
+
+MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
index 248d2dc765a5c06c64ab3c27c47f38d36bf14c20..16c842997291483eb12306d9ccf0a638772f18f0 100644 (file)
@@ -68,18 +68,9 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
        struct cdc_ncm_ctx *ctx;
        struct usb_driver *subdriver = ERR_PTR(-ENODEV);
        int ret = -ENODEV;
-       u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM;
+       u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf);
        struct cdc_mbim_state *info = (void *)&dev->data;
 
-       /* see if interface supports MBIM alternate setting */
-       if (intf->num_altsetting == 2) {
-               if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
-                       usb_set_interface(dev->udev,
-                                         intf->cur_altsetting->desc.bInterfaceNumber,
-                                         CDC_NCM_COMM_ALTSETTING_MBIM);
-               data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
-       }
-
        /* Probably NCM, defer for cdc_ncm_bind */
        if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
                goto err;
index 4a8c25a222940d3061b61336976db5f1e80aef58..4709fa3497cf2efcada053ccdefc06f7061971bc 100644 (file)
 
 #define        DRIVER_VERSION                          "14-Mar-2012"
 
+#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
+static bool prefer_mbim = true;
+#else
+static bool prefer_mbim;
+#endif
+module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions");
+
 static void cdc_ncm_txpath_bh(unsigned long param);
 static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
 static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
@@ -550,9 +558,12 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(cdc_ncm_unbind);
 
-static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
+/* Select the MBIM altsetting iff it is preferred and available,
+ * returning the number of the corresponding data interface altsetting
+ */
+u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf)
 {
-       int ret;
+       struct usb_host_interface *alt;
 
        /* The MBIM spec defines a NCM compatible default altsetting,
         * which we may have matched:
@@ -568,23 +579,27 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
         *   endpoint descriptors, shall be constructed according to
         *   the rules given in section 6 (USB Device Model) of this
         *   specification."
-        *
-        * Do not bind to such interfaces, allowing cdc_mbim to handle
-        * them
         */
-#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
-       if ((intf->num_altsetting == 2) &&
-           !usb_set_interface(dev->udev,
-                              intf->cur_altsetting->desc.bInterfaceNumber,
-                              CDC_NCM_COMM_ALTSETTING_MBIM)) {
-               if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
-                       return -ENODEV;
-               else
-                       usb_set_interface(dev->udev,
-                                         intf->cur_altsetting->desc.bInterfaceNumber,
-                                         CDC_NCM_COMM_ALTSETTING_NCM);
+       if (prefer_mbim && intf->num_altsetting == 2) {
+               alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM);
+               if (alt && cdc_ncm_comm_intf_is_mbim(alt) &&
+                   !usb_set_interface(dev->udev,
+                                      intf->cur_altsetting->desc.bInterfaceNumber,
+                                      CDC_NCM_COMM_ALTSETTING_MBIM))
+                       return CDC_NCM_DATA_ALTSETTING_MBIM;
        }
-#endif
+       return CDC_NCM_DATA_ALTSETTING_NCM;
+}
+EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting);
+
+static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int ret;
+
+       /* MBIM backwards compatible function? */
+       cdc_ncm_select_altsetting(dev, intf);
+       if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+               return -ENODEV;
 
        /* NCM data altsetting is always 1 */
        ret = cdc_ncm_bind_common(dev, intf, 1);
@@ -1213,6 +1228,14 @@ static const struct usb_device_id cdc_devs[] = {
          .driver_info = (unsigned long) &wwan_info,
        },
 
+       /* tag Huawei devices as wwan */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x12d1,
+                                       USB_CLASS_COMM,
+                                       USB_CDC_SUBCLASS_NCM,
+                                       USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&wwan_info,
+       },
+
        /* Huawei NCM devices disguised as vendor specific */
        { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
          .driver_info = (unsigned long)&wwan_info,
index efb5c7c33a28c946c7ca44a0b8a05aeeb8048345..968d5d50751dc120b406f54fffca49b46eafa230 100644 (file)
@@ -139,16 +139,9 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
 
        BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
 
-       /* control and data is shared? */
-       if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
-               info->control = intf;
-               info->data = intf;
-               goto shared;
-       }
-
-       /* else require a single interrupt status endpoint on control intf */
-       if (intf->cur_altsetting->desc.bNumEndpoints != 1)
-               goto err;
+       /* set up initial state */
+       info->control = intf;
+       info->data = intf;
 
        /* and a number of CDC descriptors */
        while (len > 3) {
@@ -207,25 +200,14 @@ next_desc:
                buf += h->bLength;
        }
 
-       /* did we find all the required ones? */
-       if (!(found & (1 << USB_CDC_HEADER_TYPE)) ||
-           !(found & (1 << USB_CDC_UNION_TYPE))) {
-               dev_err(&intf->dev, "CDC functional descriptors missing\n");
-               goto err;
-       }
-
-       /* verify CDC Union */
-       if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) {
-               dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0);
-               goto err;
-       }
-
-       /* need to save these for unbind */
-       info->control = intf;
-       info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
-       if (!info->data) {
-               dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0);
-               goto err;
+       /* Use separate control and data interfaces if we found a CDC Union */
+       if (cdc_union) {
+               info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
+               if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) {
+                       dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n",
+                               cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0);
+                       goto err;
+               }
        }
 
        /* errors aren't fatal - we can live with the dynamic address */
@@ -235,11 +217,12 @@ next_desc:
        }
 
        /* claim data interface and set it up */
-       status = usb_driver_claim_interface(driver, info->data, dev);
-       if (status < 0)
-               goto err;
+       if (info->control != info->data) {
+               status = usb_driver_claim_interface(driver, info->data, dev);
+               if (status < 0)
+                       goto err;
+       }
 
-shared:
        status = qmi_wwan_register_subdriver(dev);
        if (status < 0 && info->control != info->data) {
                usb_set_intfdata(info->data, NULL);
index 4aad350e4daec8e5c252052153688b19ae51996d..eae7a03d4f9bb7a5b69414d9c161bb7b0f777b77 100644 (file)
@@ -2958,6 +2958,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
 
        adapter->num_rx_queues = num_rx_queues;
        adapter->num_tx_queues = num_tx_queues;
+       adapter->rx_buf_per_pkt = 1;
 
        size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues;
        size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues;
index a0feb17a023844fac5840e8c92998f46d119464e..63a124340cbecb19f3ad0d5f9b43f6fcfed6b4e0 100644 (file)
@@ -472,6 +472,12 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                                                VMXNET3_RX_RING_MAX_SIZE)
                return -EINVAL;
 
+       /* if adapter not yet initialized, do nothing */
+       if (adapter->rx_buf_per_pkt == 0) {
+               netdev_err(netdev, "adapter not completely initialized, "
+                          "ring size cannot be changed yet\n");
+               return -EOPNOTSUPP;
+       }
 
        /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
        new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
index 3198384689d9fbcb5119c029706844b7d8bc86bc..35418146fa170100ec1f8aef59c123e6a5b908df 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.1.29.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.1.30.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01011D00
+#define VMXNET3_DRIVER_VERSION_NUM      0x01011E00
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index f10e58ac9c1b6078527ecbc88b2c59fe54d4ea66..7cee7a3068ec11ae9a7f91efa612748dfdd0463e 100644 (file)
@@ -961,6 +961,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
        iph->ttl        = ttl ? : ip4_dst_hoplimit(&rt->dst);
        tunnel_ip_select_ident(skb, old_iph, &rt->dst);
 
+       nf_reset(skb);
+
        vxlan_set_owner(dev, skb);
 
        /* See iptunnel_xmit() */
@@ -1504,6 +1506,14 @@ static __net_init int vxlan_init_net(struct net *net)
 static __net_exit void vxlan_exit_net(struct net *net)
 {
        struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+       struct vxlan_dev *vxlan;
+       unsigned h;
+
+       rtnl_lock();
+       for (h = 0; h < VNI_HASH_SIZE; ++h)
+               hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist)
+                       dev_close(vxlan->dev);
+       rtnl_unlock();
 
        if (vn->sock) {
                sk_release_kernel(vn->sock->sk);
index 53295418f57616e3d1c891ae8bdf5446a40c9e2e..6125adb520a3ee08a20acb2c6c43ef97418b11b9 100644 (file)
@@ -4506,108 +4506,75 @@ static int setup_proc_entry( struct net_device *dev,
        apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
                                            airo_entry);
        if (!apriv->proc_entry)
-               goto fail;
-       apriv->proc_entry->uid = proc_kuid;
-       apriv->proc_entry->gid = proc_kgid;
+               return -ENOMEM;
+       proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
 
        /* Setup the StatsDelta */
        entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
                                 apriv->proc_entry, &proc_statsdelta_ops, dev);
        if (!entry)
-               goto fail_stats_delta;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the Stats */
        entry = proc_create_data("Stats", S_IRUGO & proc_perm,
                                 apriv->proc_entry, &proc_stats_ops, dev);
        if (!entry)
-               goto fail_stats;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the Status */
        entry = proc_create_data("Status", S_IRUGO & proc_perm,
                                 apriv->proc_entry, &proc_status_ops, dev);
        if (!entry)
-               goto fail_status;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the Config */
        entry = proc_create_data("Config", proc_perm,
                                 apriv->proc_entry, &proc_config_ops, dev);
        if (!entry)
-               goto fail_config;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the SSID */
        entry = proc_create_data("SSID", proc_perm,
                                 apriv->proc_entry, &proc_SSID_ops, dev);
        if (!entry)
-               goto fail_ssid;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the APList */
        entry = proc_create_data("APList", proc_perm,
                                 apriv->proc_entry, &proc_APList_ops, dev);
        if (!entry)
-               goto fail_aplist;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the BSSList */
        entry = proc_create_data("BSSList", proc_perm,
                                 apriv->proc_entry, &proc_BSSList_ops, dev);
        if (!entry)
-               goto fail_bsslist;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
 
        /* Setup the WepKey */
        entry = proc_create_data("WepKey", proc_perm,
                                 apriv->proc_entry, &proc_wepkey_ops, dev);
        if (!entry)
-               goto fail_wepkey;
-       entry->uid = proc_kuid;
-       entry->gid = proc_kgid;
-
+               goto fail;
+       proc_set_user(entry, proc_kuid, proc_kgid);
        return 0;
 
-fail_wepkey:
-       remove_proc_entry("BSSList", apriv->proc_entry);
-fail_bsslist:
-       remove_proc_entry("APList", apriv->proc_entry);
-fail_aplist:
-       remove_proc_entry("SSID", apriv->proc_entry);
-fail_ssid:
-       remove_proc_entry("Config", apriv->proc_entry);
-fail_config:
-       remove_proc_entry("Status", apriv->proc_entry);
-fail_status:
-       remove_proc_entry("Stats", apriv->proc_entry);
-fail_stats:
-       remove_proc_entry("StatsDelta", apriv->proc_entry);
-fail_stats_delta:
-       remove_proc_entry(apriv->proc_name, airo_entry);
 fail:
+       remove_proc_subtree(apriv->proc_name, airo_entry);
        return -ENOMEM;
 }
 
 static int takedown_proc_entry( struct net_device *dev,
-                               struct airo_info *apriv ) {
-       if ( !apriv->proc_entry->namelen ) return 0;
-       remove_proc_entry("Stats",apriv->proc_entry);
-       remove_proc_entry("StatsDelta",apriv->proc_entry);
-       remove_proc_entry("Status",apriv->proc_entry);
-       remove_proc_entry("Config",apriv->proc_entry);
-       remove_proc_entry("SSID",apriv->proc_entry);
-       remove_proc_entry("APList",apriv->proc_entry);
-       remove_proc_entry("BSSList",apriv->proc_entry);
-       remove_proc_entry("WepKey",apriv->proc_entry);
-       remove_proc_entry(apriv->proc_name,airo_entry);
+                               struct airo_info *apriv )
+{
+       remove_proc_subtree(apriv->proc_name, airo_entry);
        return 0;
 }
 
@@ -4663,8 +4630,7 @@ static ssize_t proc_write( struct file *file,
 static int proc_status_open(struct inode *inode, struct file *file)
 {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *apriv = dev->ml_priv;
        CapabilityRid cap_rid;
        StatusRid status_rid;
@@ -4746,8 +4712,7 @@ static int proc_stats_rid_open( struct inode *inode,
                                u16 rid )
 {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *apriv = dev->ml_priv;
        StatsRid stats;
        int i, j;
@@ -4809,8 +4774,7 @@ static inline int sniffing_mode(struct airo_info *ai)
 static void proc_config_on_close(struct inode *inode, struct file *file)
 {
        struct proc_data *data = file->private_data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        char *line;
 
@@ -5021,8 +4985,7 @@ static const char *get_rmode(__le16 mode)
 static int proc_config_open(struct inode *inode, struct file *file)
 {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        int i;
        __le16 mode;
@@ -5112,8 +5075,7 @@ static int proc_config_open(struct inode *inode, struct file *file)
 static void proc_SSID_on_close(struct inode *inode, struct file *file)
 {
        struct proc_data *data = file->private_data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        SsidRid SSID_rid;
        int i;
@@ -5148,8 +5110,7 @@ static void proc_SSID_on_close(struct inode *inode, struct file *file)
 
 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
        struct proc_data *data = file->private_data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        APListRid APList_rid;
        int i;
@@ -5283,8 +5244,7 @@ static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
 
 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        int i, rc;
        char key[16];
@@ -5335,8 +5295,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
 static int proc_wepkey_open( struct inode *inode, struct file *file )
 {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        char *ptr;
        WepKeyRid wkr;
@@ -5384,8 +5343,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file )
 static int proc_SSID_open(struct inode *inode, struct file *file)
 {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        int i;
        char *ptr;
@@ -5428,8 +5386,7 @@ static int proc_SSID_open(struct inode *inode, struct file *file)
 
 static int proc_APList_open( struct inode *inode, struct file *file ) {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        int i;
        char *ptr;
@@ -5468,8 +5425,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
 
 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
        struct proc_data *data;
-       struct proc_dir_entry *dp = PDE(inode);
-       struct net_device *dev = dp->data;
+       struct net_device *dev = PDE_DATA(inode);
        struct airo_info *ai = dev->ml_priv;
        char *ptr;
        BSSListRid BSSList_rid;
@@ -5706,10 +5662,8 @@ static int __init airo_init_module( void )
 
        airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
 
-       if (airo_entry) {
-               airo_entry->uid = proc_kuid;
-               airo_entry->gid = proc_kgid;
-       }
+       if (airo_entry)
+               proc_set_user(airo_entry, proc_kuid, proc_kgid);
 
        for (i = 0; i < 4 && io[i] && irq[i]; i++) {
                airo_print_info("", "Trying to configure ISA adapter at irq=%d "
index 4cc13940c8950d2a7ad2a3fdf1a092ac3736a7d5..f76c3ca07a4501603883bbcbe9feb901d4eca390 100644 (file)
@@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                                          AR_PHY_AGC_CONTROL_FLTR_CAL   |
                                          AR_PHY_AGC_CONTROL_PKDET_CAL;
 
+       /* Use chip chainmask only for calibration */
        ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
 
        if (rtt) {
@@ -1150,6 +1151,9 @@ skip_tx_iqcal:
                ar9003_hw_rtt_disable(ah);
        }
 
+       /* Revert chainmask to runtime parameters */
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
        /* Initialize list pointers */
        ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
 
index 5f845beeb18b86210d3aebf9f52fdcfff87e1462..050ca4a4850d9b874ef1ddd271a2c2abd4fd9644 100644 (file)
@@ -27,7 +27,7 @@
 #define WME_MAX_BA              WME_BA_BMP_SIZE
 #define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
 
-#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RSSI_DUMMY_MARKER   127
 #define ATH_RSSI_LPF_LEN               10
 #define RSSI_LPF_THRESHOLD             -20
 #define ATH_RSSI_EP_MULTIPLIER     (1<<7)
index 96bfb18078fa14b0013d4b3e93e7544b16639746..d3b099d7898b692b181029c808d41969554035ee 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/firmware.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
 #include <net/mac80211.h>
index 3ad1fd05c5e769fc429325377470c888edb354a2..bd8251c1c7494fe69a140d4089d6d2d586c0eaae 100644 (file)
@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
 
        last_rssi = priv->rx.last_rssi;
 
-       if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-               rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
-                                                    ATH_RSSI_EP_MULTIPLIER);
+       if (ieee80211_is_beacon(hdr->frame_control) &&
+           !is_zero_ether_addr(common->curbssid) &&
+           ether_addr_equal(hdr->addr3, common->curbssid)) {
+               s8 rssi = rxbuf->rxstatus.rs_rssi;
 
-       if (rxbuf->rxstatus.rs_rssi < 0)
-               rxbuf->rxstatus.rs_rssi = 0;
+               if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+                       rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
 
-       if (ieee80211_is_beacon(fc))
-               priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
+               if (rssi < 0)
+                       rssi = 0;
+
+               priv->ah->stats.avgbrssi = rssi;
+       }
 
        rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
        rx_status->band = hw->conf.channel->band;
index 2a2ae403e0e5202a996fab3e1a7cf9ebecfa2c0a..07e25260c31d85084c8c680f69cda6ac85264e21 100644 (file)
@@ -1463,7 +1463,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
                        reset_type = ATH9K_RESET_POWER_ON;
                else
                        reset_type = ATH9K_RESET_COLD;
-       }
+       } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
+                  (REG_READ(ah, AR_CR) & AR_CR_RXE))
+               reset_type = ATH9K_RESET_COLD;
 
        if (!ath9k_hw_set_reset_reg(ah, reset_type))
                return false;
index ade3afb21f911e86589e325c2e99b49b7fe91289..39c84ecf6a42b345dc67d9cb52c7d3b45957525a 100644 (file)
@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work)
        int i;
        bool needreset = false;
 
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i)) {
-                       txq = &sc->tx.txq[i];
-                       ath_txq_lock(sc, txq);
-                       if (txq->axq_depth) {
-                               if (txq->axq_tx_inprogress) {
-                                       needreset = true;
-                                       ath_txq_unlock(sc, txq);
-                                       break;
-                               } else {
-                                       txq->axq_tx_inprogress = true;
-                               }
+       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+               txq = sc->tx.txq_map[i];
+
+               ath_txq_lock(sc, txq);
+               if (txq->axq_depth) {
+                       if (txq->axq_tx_inprogress) {
+                               needreset = true;
+                               ath_txq_unlock(sc, txq);
+                               break;
+                       } else {
+                               txq->axq_tx_inprogress = true;
                        }
-                       ath_txq_unlock_complete(sc, txq);
                }
+               ath_txq_unlock_complete(sc, txq);
+       }
 
        if (needreset) {
                ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
index 65fc9683bfd8e2751f3a80ca16605ae6d89e86e1..76c7694518d9303ebcf6590c149b91db86fd5af2 100644 (file)
@@ -216,7 +216,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get,
                        wil_debugfs_iomem_x32_set, "0x%08llx\n");
 
 static struct dentry *wil_debugfs_create_iomem_x32(const char *name,
-                                                  mode_t mode,
+                                                  umode_t mode,
                                                   struct dentry *parent,
                                                   void __iomem *value)
 {
@@ -367,7 +367,7 @@ static const struct file_operations fops_ioblob = {
 
 static
 struct dentry *wil_debugfs_create_ioblob(const char *name,
-                                        mode_t mode,
+                                        umode_t mode,
                                         struct dentry *parent,
                                         struct debugfs_blob_wrapper *blob)
 {
index 4374079dfc2a031d6faa0a2819c69e1b9c49885f..23a3498f14d4a60d81f6e8cc4cfd4472d3f5baf2 100644 (file)
@@ -63,6 +63,7 @@
 #include <net/iw_handler.h>
 #include <linux/crc32.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
@@ -1409,30 +1410,28 @@ static int atmel_validate_channel(struct atmel_private *priv, int channel)
        return 0;
 }
 
-static int atmel_proc_output (char *buf, struct atmel_private *priv)
+static int atmel_proc_show(struct seq_file *m, void *v)
 {
+       struct atmel_private *priv = m->private;
        int i;
-       char *p = buf;
        char *s, *r, *c;
 
-       p += sprintf(p, "Driver version:\t\t%d.%d\n",
-                    DRIVER_MAJOR, DRIVER_MINOR);
+       seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
 
        if (priv->station_state != STATION_STATE_DOWN) {
-               p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
-                               "Firmware location:\t",
-                            priv->host_info.major_version,
-                            priv->host_info.minor_version,
-                            priv->host_info.build_version);
+               seq_printf(m,
+                          "Firmware version:\t%d.%d build %d\n"
+                          "Firmware location:\t",
+                          priv->host_info.major_version,
+                          priv->host_info.minor_version,
+                          priv->host_info.build_version);
 
                if (priv->card_type != CARD_TYPE_EEPROM)
-                       p += sprintf(p, "on card\n");
+                       seq_puts(m, "on card\n");
                else if (priv->firmware)
-                       p += sprintf(p, "%s loaded by host\n",
-                                    priv->firmware_id);
+                       seq_printf(m, "%s loaded by host\n", priv->firmware_id);
                else
-                       p += sprintf(p, "%s loaded by hotplug\n",
-                                    priv->firmware_id);
+                       seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
 
                switch (priv->card_type) {
                case CARD_TYPE_PARALLEL_FLASH:
@@ -1453,12 +1452,12 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
                        if (priv->reg_domain == channel_table[i].reg_domain)
                                r = channel_table[i].name;
 
-               p += sprintf(p, "MAC memory type:\t%s\n", c);
-               p += sprintf(p, "Regulatory domain:\t%s\n", r);
-               p += sprintf(p, "Host CRC checking:\t%s\n",
-                            priv->do_rx_crc ? "On" : "Off");
-               p += sprintf(p, "WPA-capable firmware:\t%s\n",
-                            priv->use_wpa ? "Yes" : "No");
+               seq_printf(m, "MAC memory type:\t%s\n", c);
+               seq_printf(m, "Regulatory domain:\t%s\n", r);
+               seq_printf(m, "Host CRC checking:\t%s\n",
+                        priv->do_rx_crc ? "On" : "Off");
+               seq_printf(m, "WPA-capable firmware:\t%s\n",
+                        priv->use_wpa ? "Yes" : "No");
        }
 
        switch (priv->station_state) {
@@ -1490,26 +1489,22 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
                s = "<unknown>";
        }
 
-       p += sprintf(p, "Current state:\t\t%s\n", s);
-       return p - buf;
+       seq_printf(m, "Current state:\t\t%s\n", s);
+       return 0;
 }
 
-static int atmel_read_proc(char *page, char **start, off_t off,
-                          int count, int *eof, void *data)
+static int atmel_proc_open(struct inode *inode, struct file *file)
 {
-       struct atmel_private *priv = data;
-       int len = atmel_proc_output (page, priv);
-       if (len <= off+count)
-               *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
-       return len;
+       return single_open(file, atmel_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations atmel_proc_fops = {
+       .open           = atmel_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static const struct net_device_ops atmel_netdev_ops = {
        .ndo_open               = atmel_open,
        .ndo_stop               = atmel_close,
@@ -1525,7 +1520,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
                                   struct device *sys_dev,
                                   int (*card_present)(void *), void *card)
 {
-       struct proc_dir_entry *ent;
        struct net_device *dev;
        struct atmel_private *priv;
        int rc;
@@ -1630,8 +1624,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
 
        netif_carrier_off(dev);
 
-       ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
-       if (!ent)
+       if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv));
                printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
 
        printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
index dd9a18f8dbcae411bfda2bedb6f762afd2010185..19c45e363aa7bba64a6ad35163c762b18a73e7c8 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/delay.h>
 #include <linux/random.h>
 #include <linux/if_arp.h>
@@ -64,28 +65,32 @@ static void prism2_send_mgmt(struct net_device *dev,
 
 
 #ifndef PRISM2_NO_PROCFS_DEBUG
-static int ap_debug_proc_read(char *page, char **start, off_t off,
-                             int count, int *eof, void *data)
-{
-       char *p = page;
-       struct ap_data *ap = (struct ap_data *) data;
-
-       if (off != 0) {
-               *eof = 1;
-               return 0;
-       }
-
-       p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
-       p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
-       p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ);
-       p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets);
-       p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack);
-       p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds);
-       p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs);
-       p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
+static int ap_debug_proc_show(struct seq_file *m, void *v)
+{
+       struct ap_data *ap = m->private;
+
+       seq_printf(m, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
+       seq_printf(m, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
+       seq_printf(m, "max_inactivity=%u\n", ap->max_inactivity / HZ);
+       seq_printf(m, "bridge_packets=%u\n", ap->bridge_packets);
+       seq_printf(m, "nullfunc_ack=%u\n", ap->nullfunc_ack);
+       seq_printf(m, "autom_ap_wds=%u\n", ap->autom_ap_wds);
+       seq_printf(m, "auth_algs=%u\n", ap->local->auth_algs);
+       seq_printf(m, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
+       return 0;
+}
 
-       return (p - page);
+static int ap_debug_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ap_debug_proc_show, PDE_DATA(inode));
 }
+
+static const struct file_operations ap_debug_proc_fops = {
+       .open           = ap_debug_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif /* PRISM2_NO_PROCFS_DEBUG */
 
 
@@ -325,50 +330,81 @@ void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
 }
 
 
-static int ap_control_proc_read(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+static int ap_control_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       struct ap_data *ap = (struct ap_data *) data;
+       struct ap_data *ap = m->private;
        char *policy_txt;
        struct mac_entry *entry;
 
-       if (off != 0) {
-               *eof = 1;
+       if (v == SEQ_START_TOKEN) {
+               switch (ap->mac_restrictions.policy) {
+               case MAC_POLICY_OPEN:
+                       policy_txt = "open";
+                       break;
+               case MAC_POLICY_ALLOW:
+                       policy_txt = "allow";
+                       break;
+               case MAC_POLICY_DENY:
+                       policy_txt = "deny";
+                       break;
+               default:
+                       policy_txt = "unknown";
+                       break;
+               }
+               seq_printf(m, "MAC policy: %s\n", policy_txt);
+               seq_printf(m, "MAC entries: %u\n", ap->mac_restrictions.entries);
+               seq_puts(m, "MAC list:\n");
                return 0;
        }
 
-       switch (ap->mac_restrictions.policy) {
-       case MAC_POLICY_OPEN:
-               policy_txt = "open";
-               break;
-       case MAC_POLICY_ALLOW:
-               policy_txt = "allow";
-               break;
-       case MAC_POLICY_DENY:
-               policy_txt = "deny";
-               break;
-       default:
-               policy_txt = "unknown";
-               break;
-       }
-       p += sprintf(p, "MAC policy: %s\n", policy_txt);
-       p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
-       p += sprintf(p, "MAC list:\n");
+       entry = v;
+       seq_printf(m, "%pM\n", entry->addr);
+       return 0;
+}
+
+static void *ap_control_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       struct ap_data *ap = m->private;
        spin_lock_bh(&ap->mac_restrictions.lock);
-       list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) {
-               if (p - page > PAGE_SIZE - 80) {
-                       p += sprintf(p, "All entries did not fit one page.\n");
-                       break;
-               }
+       return seq_list_start_head(&ap->mac_restrictions.mac_list, *_pos);
+}
 
-               p += sprintf(p, "%pM\n", entry->addr);
-       }
+static void *ap_control_proc_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       struct ap_data *ap = m->private;
+       return seq_list_next(v, &ap->mac_restrictions.mac_list, _pos);
+}
+
+static void ap_control_proc_stop(struct seq_file *m, void *v)
+{
+       struct ap_data *ap = m->private;
        spin_unlock_bh(&ap->mac_restrictions.lock);
+}
 
-       return (p - page);
+static const struct seq_operations ap_control_proc_seqops = {
+       .start  = ap_control_proc_start,
+       .next   = ap_control_proc_next,
+       .stop   = ap_control_proc_stop,
+       .show   = ap_control_proc_show,
+};
+
+static int ap_control_proc_open(struct inode *inode, struct file *file)
+{
+       int ret = seq_open(file, &ap_control_proc_seqops);
+       if (ret == 0) {
+               struct seq_file *m = file->private_data;
+               m->private = PDE_DATA(inode);
+       }
+       return ret;
 }
 
+static const struct file_operations ap_control_proc_fops = {
+       .open           = ap_control_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 
 int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
 {
@@ -510,61 +546,84 @@ void ap_control_kickall(struct ap_data *ap)
 
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
 
-#define PROC_LIMIT (PAGE_SIZE - 80)
-
-static int prism2_ap_proc_read(char *page, char **start, off_t off,
-                              int count, int *eof, void *data)
+static int prism2_ap_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       struct ap_data *ap = (struct ap_data *) data;
-       struct sta_info *sta;
+       struct sta_info *sta = v;
        int i;
 
-       if (off > PROC_LIMIT) {
-               *eof = 1;
+       if (v == SEQ_START_TOKEN) {
+               seq_printf(m, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
                return 0;
        }
 
-       p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
-       spin_lock_bh(&ap->sta_table_lock);
-       list_for_each_entry(sta, &ap->sta_list, list) {
-               if (!sta->ap)
-                       continue;
+       if (!sta->ap)
+               return 0;
 
-               p += sprintf(p, "%pM %d %d %d %d '",
-                            sta->addr,
-                            sta->u.ap.channel, sta->last_rx_signal,
-                            sta->last_rx_silence, sta->last_rx_rate);
-               for (i = 0; i < sta->u.ap.ssid_len; i++)
-                       p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
-                                         sta->u.ap.ssid[i] < 127) ?
-                                        "%c" : "<%02x>"),
-                                    sta->u.ap.ssid[i]);
-               p += sprintf(p, "'");
-               if (sta->capability & WLAN_CAPABILITY_ESS)
-                       p += sprintf(p, " [ESS]");
-               if (sta->capability & WLAN_CAPABILITY_IBSS)
-                       p += sprintf(p, " [IBSS]");
-               if (sta->capability & WLAN_CAPABILITY_PRIVACY)
-                       p += sprintf(p, " [WEP]");
-               p += sprintf(p, "\n");
-
-               if ((p - page) > PROC_LIMIT) {
-                       printk(KERN_DEBUG "hostap: ap proc did not fit\n");
-                       break;
-               }
-       }
-       spin_unlock_bh(&ap->sta_table_lock);
+       seq_printf(m, "%pM %d %d %d %d '",
+                  sta->addr,
+                  sta->u.ap.channel, sta->last_rx_signal,
+                  sta->last_rx_silence, sta->last_rx_rate);
 
-       if ((p - page) <= off) {
-               *eof = 1;
-               return 0;
+       for (i = 0; i < sta->u.ap.ssid_len; i++) {
+               if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127)
+                       seq_putc(m, sta->u.ap.ssid[i]);
+               else
+                       seq_printf(m, "<%02x>", sta->u.ap.ssid[i]);
        }
 
-       *start = page + off;
+       seq_putc(m, '\'');
+       if (sta->capability & WLAN_CAPABILITY_ESS)
+               seq_puts(m, " [ESS]");
+       if (sta->capability & WLAN_CAPABILITY_IBSS)
+               seq_puts(m, " [IBSS]");
+       if (sta->capability & WLAN_CAPABILITY_PRIVACY)
+               seq_puts(m, " [WEP]");
+       seq_putc(m, '\n');
+       return 0;
+}
+
+static void *prism2_ap_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       struct ap_data *ap = m->private;
+       spin_lock_bh(&ap->sta_table_lock);
+       return seq_list_start_head(&ap->sta_list, *_pos);
+}
 
-       return (p - page - off);
+static void *prism2_ap_proc_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       struct ap_data *ap = m->private;
+       return seq_list_next(v, &ap->sta_list, _pos);
 }
+
+static void prism2_ap_proc_stop(struct seq_file *m, void *v)
+{
+       struct ap_data *ap = m->private;
+       spin_unlock_bh(&ap->sta_table_lock);
+}
+
+static const struct seq_operations prism2_ap_proc_seqops = {
+       .start  = prism2_ap_proc_start,
+       .next   = prism2_ap_proc_next,
+       .stop   = prism2_ap_proc_stop,
+       .show   = prism2_ap_proc_show,
+};
+
+static int prism2_ap_proc_open(struct inode *inode, struct file *file)
+{
+       int ret = seq_open(file, &prism2_ap_proc_seqops);
+       if (ret == 0) {
+               struct seq_file *m = file->private_data;
+               m->private = PDE_DATA(inode);
+       }
+       return ret;
+}
+
+static const struct file_operations prism2_ap_proc_fops = {
+       .open           = prism2_ap_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
 
@@ -836,15 +895,12 @@ void hostap_init_ap_proc(local_info_t *local)
                return;
 
 #ifndef PRISM2_NO_PROCFS_DEBUG
-       create_proc_read_entry("ap_debug", 0, ap->proc,
-                              ap_debug_proc_read, ap);
+       proc_create_data("ap_debug", 0, ap->proc, &ap_debug_proc_fops, ap);
 #endif /* PRISM2_NO_PROCFS_DEBUG */
 
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
-       create_proc_read_entry("ap_control", 0, ap->proc,
-                              ap_control_proc_read, ap);
-       create_proc_read_entry("ap", 0, ap->proc,
-                              prism2_ap_proc_read, ap);
+       proc_create_data("ap_control", 0, ap->proc, &ap_control_proc_fops, ap);
+       proc_create_data("ap", 0, ap->proc, &prism2_ap_proc_fops, ap);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
 }
@@ -982,79 +1038,86 @@ static void prism2_send_mgmt(struct net_device *dev,
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
 
-static int prism2_sta_proc_read(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+static int prism2_sta_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       struct sta_info *sta = (struct sta_info *) data;
+       struct sta_info *sta = m->private;
        int i;
 
        /* FIX: possible race condition.. the STA data could have just expired,
         * but proc entry was still here so that the read could have started;
         * some locking should be done here.. */
 
-       if (off != 0) {
-               *eof = 1;
-               return 0;
-       }
-
-       p += sprintf(p, "%s=%pM\nusers=%d\naid=%d\n"
-                    "flags=0x%04x%s%s%s%s%s%s%s\n"
-                    "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
-                    sta->ap ? "AP" : "STA",
-                    sta->addr, atomic_read(&sta->users), sta->aid,
-                    sta->flags,
-                    sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
-                    sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
-                    sta->flags & WLAN_STA_PS ? " PS" : "",
-                    sta->flags & WLAN_STA_TIM ? " TIM" : "",
-                    sta->flags & WLAN_STA_PERM ? " PERM" : "",
-                    sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
-                    sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
-                    sta->capability, sta->listen_interval);
+       seq_printf(m,
+                  "%s=%pM\nusers=%d\naid=%d\n"
+                  "flags=0x%04x%s%s%s%s%s%s%s\n"
+                  "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
+                  sta->ap ? "AP" : "STA",
+                  sta->addr, atomic_read(&sta->users), sta->aid,
+                  sta->flags,
+                  sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
+                  sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
+                  sta->flags & WLAN_STA_PS ? " PS" : "",
+                  sta->flags & WLAN_STA_TIM ? " TIM" : "",
+                  sta->flags & WLAN_STA_PERM ? " PERM" : "",
+                  sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
+                  sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
+                  sta->capability, sta->listen_interval);
        /* supported_rates: 500 kbit/s units with msb ignored */
        for (i = 0; i < sizeof(sta->supported_rates); i++)
                if (sta->supported_rates[i] != 0)
-                       p += sprintf(p, "%d%sMbps ",
-                                    (sta->supported_rates[i] & 0x7f) / 2,
-                                    sta->supported_rates[i] & 1 ? ".5" : "");
-       p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
-                    "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
-                    "tx_packets=%lu\n"
-                    "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
-                    "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
-                    "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
-                    "tx[11M]=%d\n"
-                    "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
-                    jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
-                    sta->last_tx,
-                    sta->rx_packets, sta->tx_packets, sta->rx_bytes,
-                    sta->tx_bytes, skb_queue_len(&sta->tx_buf),
-                    sta->last_rx_silence,
-                    sta->last_rx_signal, sta->last_rx_rate / 10,
-                    sta->last_rx_rate % 10 ? ".5" : "",
-                    sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
-                    sta->tx_count[2], sta->tx_count[3],  sta->rx_count[0],
-                    sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
+                       seq_printf(m, "%d%sMbps ",
+                                  (sta->supported_rates[i] & 0x7f) / 2,
+                                  sta->supported_rates[i] & 1 ? ".5" : "");
+       seq_printf(m,
+                  "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
+                  "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
+                  "tx_packets=%lu\n"
+                  "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
+                  "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
+                  "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
+                  "tx[11M]=%d\n"
+                  "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
+                  jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
+                  sta->last_tx,
+                  sta->rx_packets, sta->tx_packets, sta->rx_bytes,
+                  sta->tx_bytes, skb_queue_len(&sta->tx_buf),
+                  sta->last_rx_silence,
+                  sta->last_rx_signal, sta->last_rx_rate / 10,
+                  sta->last_rx_rate % 10 ? ".5" : "",
+                  sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
+                  sta->tx_count[2], sta->tx_count[3],  sta->rx_count[0],
+                  sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
        if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats)
-               p = sta->crypt->ops->print_stats(p, sta->crypt->priv);
+               sta->crypt->ops->print_stats(m, sta->crypt->priv);
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
        if (sta->ap) {
                if (sta->u.ap.channel >= 0)
-                       p += sprintf(p, "channel=%d\n", sta->u.ap.channel);
-               p += sprintf(p, "ssid=");
-               for (i = 0; i < sta->u.ap.ssid_len; i++)
-                       p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
-                                         sta->u.ap.ssid[i] < 127) ?
-                                        "%c" : "<%02x>"),
-                                    sta->u.ap.ssid[i]);
-               p += sprintf(p, "\n");
+                       seq_printf(m, "channel=%d\n", sta->u.ap.channel);
+               seq_puts(m, "ssid=");
+               for (i = 0; i < sta->u.ap.ssid_len; i++) {
+                       if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127)
+                               seq_putc(m, sta->u.ap.ssid[i]);
+                       else
+                               seq_printf(m, "<%02x>", sta->u.ap.ssid[i]);
+               }
+               seq_putc(m, '\n');
        }
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-       return (p - page);
+       return 0;
+}
+
+static int prism2_sta_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, prism2_sta_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations prism2_sta_proc_fops = {
+       .open           = prism2_sta_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
 static void handle_add_proc_queue(struct work_struct *work)
 {
@@ -1076,9 +1139,9 @@ static void handle_add_proc_queue(struct work_struct *work)
 
                if (sta) {
                        sprintf(name, "%pM", sta->addr);
-                       sta->proc = create_proc_read_entry(
+                       sta->proc = proc_create_data(
                                name, 0, ap->proc,
-                               prism2_sta_proc_read, sta);
+                               &prism2_sta_proc_fops, sta);
 
                        atomic_dec(&sta->users);
                }
index e73bf739fd9bd56871c7b6ef902c3622ba71c003..705fe668b969819761584dbd25276eed403f756d 100644 (file)
@@ -174,20 +174,70 @@ static int prism2_pda_ok(u8 *buf)
 }
 
 
-static int prism2_download_aux_dump(struct net_device *dev,
-                                    unsigned int addr, int len, u8 *buf)
-{
-       int res;
+#define prism2_download_aux_dump_npages 65536
 
-       prism2_enable_aux_port(dev, 1);
-       res = hfa384x_from_aux(dev, addr, len, buf);
-       prism2_enable_aux_port(dev, 0);
-       if (res)
-               return -1;
+struct prism2_download_aux_dump {
+       local_info_t *local;
+       u16 page[0x80];
+};
+
+static int prism2_download_aux_dump_proc_show(struct seq_file *m, void *v)
+{
+       struct prism2_download_aux_dump *ctx = m->private;
 
+       hfa384x_from_aux(ctx->local->dev, (unsigned long)v - 1, 0x80, ctx->page);
+       seq_write(m, ctx->page, 0x80);
        return 0;
 }
 
+static void *prism2_download_aux_dump_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       struct prism2_download_aux_dump *ctx = m->private;
+       prism2_enable_aux_port(ctx->local->dev, 1);
+       if (*_pos >= prism2_download_aux_dump_npages)
+               return NULL;
+       return (void *)((unsigned long)*_pos + 1);
+}
+
+static void *prism2_download_aux_dump_proc_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       ++*_pos;
+       if (*_pos >= prism2_download_aux_dump_npages)
+               return NULL;
+       return (void *)((unsigned long)*_pos + 1);
+}
+
+static void prism2_download_aux_dump_proc_stop(struct seq_file *m, void *v)
+{
+       struct prism2_download_aux_dump *ctx = m->private;
+       prism2_enable_aux_port(ctx->local->dev, 0);
+}
+
+static const struct seq_operations prism2_download_aux_dump_proc_seqops = {
+       .start  = prism2_download_aux_dump_proc_start,
+       .next   = prism2_download_aux_dump_proc_next,
+       .stop   = prism2_download_aux_dump_proc_stop,
+       .show   = prism2_download_aux_dump_proc_show,
+};
+
+static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file *file)
+{
+       int ret = seq_open_private(file, &prism2_download_aux_dump_proc_seqops,
+                                  sizeof(struct prism2_download_aux_dump));
+       if (ret == 0) {
+               struct seq_file *m = file->private_data;
+               m->private = PDE_DATA(inode);
+       }
+       return ret;
+}
+
+static const struct file_operations prism2_download_aux_dump_proc_fops = {
+       .open           = prism2_download_aux_dump_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release_private,
+};
+
 
 static u8 * prism2_read_pda(struct net_device *dev)
 {
index 8e7000fd4414fa4c52ff8218a7c61963d6c215bb..507ab99eef4e86a241996ae546810093f7a7b0ae 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/if_arp.h>
 #include <linux/delay.h>
 #include <linux/random.h>
@@ -129,8 +130,7 @@ static void prism2_check_sta_fw_version(local_info_t *local);
 
 #ifdef PRISM2_DOWNLOAD_SUPPORT
 /* hostap_download.c */
-static int prism2_download_aux_dump(struct net_device *dev,
-                                   unsigned int addr, int len, u8 *buf);
+static const struct file_operations prism2_download_aux_dump_proc_fops;
 static u8 * prism2_read_pda(struct net_device *dev);
 static int prism2_download(local_info_t *local,
                           struct prism2_download_param *param);
@@ -2894,19 +2894,12 @@ static void hostap_tick_timer(unsigned long data)
 
 
 #ifndef PRISM2_NO_PROCFS_DEBUG
-static int prism2_registers_proc_read(char *page, char **start, off_t off,
-                                     int count, int *eof, void *data)
+static int prism2_registers_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
-
-       if (off != 0) {
-               *eof = 1;
-               return 0;
-       }
+       local_info_t *local = m->private;
 
 #define SHOW_REG(n) \
-p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF))
+  seq_printf(m, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF))
 
        SHOW_REG(CMD);
        SHOW_REG(PARAM0);
@@ -2952,8 +2945,21 @@ p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF))
        SHOW_REG(PCI_M1_CTL);
 #endif /* PRISM2_PCI */
 
-       return (p - page);
+       return 0;
 }
+
+static int prism2_registers_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, prism2_registers_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations prism2_registers_proc_fops = {
+       .open           = prism2_registers_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 #endif /* PRISM2_NO_PROCFS_DEBUG */
 
 
@@ -3128,7 +3134,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
        local->func->reset_port = prism2_reset_port;
        local->func->schedule_reset = prism2_schedule_reset;
 #ifdef PRISM2_DOWNLOAD_SUPPORT
-       local->func->read_aux = prism2_download_aux_dump;
+       local->func->read_aux_fops = &prism2_download_aux_dump_proc_fops;
        local->func->download = prism2_download;
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
        local->func->tx = prism2_tx_80211;
@@ -3274,8 +3280,8 @@ static int hostap_hw_ready(struct net_device *dev)
                }
                hostap_init_proc(local);
 #ifndef PRISM2_NO_PROCFS_DEBUG
-               create_proc_read_entry("registers", 0, local->proc,
-                                      prism2_registers_proc_read, local);
+               proc_create_data("registers", 0, local->proc,
+                                &prism2_registers_proc_fops, local);
 #endif /* PRISM2_NO_PROCFS_DEBUG */
                hostap_init_ap_proc(local);
                return 0;
index dc447c1b5abebbb2b7116182821888cf6ac96b5a..7491dab2c105a26d93317b98539388f59a5a663d 100644 (file)
 
 
 #ifndef PRISM2_NO_PROCFS_DEBUG
-static int prism2_debug_proc_read(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
+static int prism2_debug_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
+       local_info_t *local = m->private;
        int i;
 
-       if (off != 0) {
-               *eof = 1;
-               return 0;
-       }
-
-       p += sprintf(p, "next_txfid=%d next_alloc=%d\n",
-                    local->next_txfid, local->next_alloc);
+       seq_printf(m, "next_txfid=%d next_alloc=%d\n",
+                  local->next_txfid, local->next_alloc);
        for (i = 0; i < PRISM2_TXFID_COUNT; i++)
-               p += sprintf(p, "FID: tx=%04X intransmit=%04X\n",
-                            local->txfid[i], local->intransmitfid[i]);
-       p += sprintf(p, "FW TX rate control: %d\n", local->fw_tx_rate_control);
-       p += sprintf(p, "beacon_int=%d\n", local->beacon_int);
-       p += sprintf(p, "dtim_period=%d\n", local->dtim_period);
-       p += sprintf(p, "wds_max_connections=%d\n",
-                    local->wds_max_connections);
-       p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
-       p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
+               seq_printf(m, "FID: tx=%04X intransmit=%04X\n",
+                          local->txfid[i], local->intransmitfid[i]);
+       seq_printf(m, "FW TX rate control: %d\n", local->fw_tx_rate_control);
+       seq_printf(m, "beacon_int=%d\n", local->beacon_int);
+       seq_printf(m, "dtim_period=%d\n", local->dtim_period);
+       seq_printf(m, "wds_max_connections=%d\n", local->wds_max_connections);
+       seq_printf(m, "dev_enabled=%d\n", local->dev_enabled);
+       seq_printf(m, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
        for (i = 0; i < WEP_KEYS; i++) {
                if (local->crypt_info.crypt[i] &&
                    local->crypt_info.crypt[i]->ops) {
-                       p += sprintf(p, "crypt[%d]=%s\n", i,
-                                    local->crypt_info.crypt[i]->ops->name);
+                       seq_printf(m, "crypt[%d]=%s\n", i,
+                                  local->crypt_info.crypt[i]->ops->name);
                }
        }
-       p += sprintf(p, "pri_only=%d\n", local->pri_only);
-       p += sprintf(p, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI);
-       p += sprintf(p, "sram_type=%d\n", local->sram_type);
-       p += sprintf(p, "no_pri=%d\n", local->no_pri);
+       seq_printf(m, "pri_only=%d\n", local->pri_only);
+       seq_printf(m, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI);
+       seq_printf(m, "sram_type=%d\n", local->sram_type);
+       seq_printf(m, "no_pri=%d\n", local->no_pri);
 
-       return (p - page);
+       return 0;
 }
+
+static int prism2_debug_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, prism2_debug_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations prism2_debug_proc_fops = {
+       .open           = prism2_debug_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif /* PRISM2_NO_PROCFS_DEBUG */
 
 
-static int prism2_stats_proc_read(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
+static int prism2_stats_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
+       local_info_t *local = m->private;
        struct comm_tallies_sums *sums = &local->comm_tallies;
 
-       if (off != 0) {
-               *eof = 1;
-               return 0;
-       }
-
-       p += sprintf(p, "TxUnicastFrames=%u\n", sums->tx_unicast_frames);
-       p += sprintf(p, "TxMulticastframes=%u\n", sums->tx_multicast_frames);
-       p += sprintf(p, "TxFragments=%u\n", sums->tx_fragments);
-       p += sprintf(p, "TxUnicastOctets=%u\n", sums->tx_unicast_octets);
-       p += sprintf(p, "TxMulticastOctets=%u\n", sums->tx_multicast_octets);
-       p += sprintf(p, "TxDeferredTransmissions=%u\n",
-                    sums->tx_deferred_transmissions);
-       p += sprintf(p, "TxSingleRetryFrames=%u\n",
-                    sums->tx_single_retry_frames);
-       p += sprintf(p, "TxMultipleRetryFrames=%u\n",
-                    sums->tx_multiple_retry_frames);
-       p += sprintf(p, "TxRetryLimitExceeded=%u\n",
-                    sums->tx_retry_limit_exceeded);
-       p += sprintf(p, "TxDiscards=%u\n", sums->tx_discards);
-       p += sprintf(p, "RxUnicastFrames=%u\n", sums->rx_unicast_frames);
-       p += sprintf(p, "RxMulticastFrames=%u\n", sums->rx_multicast_frames);
-       p += sprintf(p, "RxFragments=%u\n", sums->rx_fragments);
-       p += sprintf(p, "RxUnicastOctets=%u\n", sums->rx_unicast_octets);
-       p += sprintf(p, "RxMulticastOctets=%u\n", sums->rx_multicast_octets);
-       p += sprintf(p, "RxFCSErrors=%u\n", sums->rx_fcs_errors);
-       p += sprintf(p, "RxDiscardsNoBuffer=%u\n",
-                    sums->rx_discards_no_buffer);
-       p += sprintf(p, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa);
-       p += sprintf(p, "RxDiscardsWEPUndecryptable=%u\n",
-                    sums->rx_discards_wep_undecryptable);
-       p += sprintf(p, "RxMessageInMsgFragments=%u\n",
-                    sums->rx_message_in_msg_fragments);
-       p += sprintf(p, "RxMessageInBadMsgFragments=%u\n",
-                    sums->rx_message_in_bad_msg_fragments);
+       seq_printf(m, "TxUnicastFrames=%u\n", sums->tx_unicast_frames);
+       seq_printf(m, "TxMulticastframes=%u\n", sums->tx_multicast_frames);
+       seq_printf(m, "TxFragments=%u\n", sums->tx_fragments);
+       seq_printf(m, "TxUnicastOctets=%u\n", sums->tx_unicast_octets);
+       seq_printf(m, "TxMulticastOctets=%u\n", sums->tx_multicast_octets);
+       seq_printf(m, "TxDeferredTransmissions=%u\n",
+                  sums->tx_deferred_transmissions);
+       seq_printf(m, "TxSingleRetryFrames=%u\n", sums->tx_single_retry_frames);
+       seq_printf(m, "TxMultipleRetryFrames=%u\n",
+                  sums->tx_multiple_retry_frames);
+       seq_printf(m, "TxRetryLimitExceeded=%u\n",
+                  sums->tx_retry_limit_exceeded);
+       seq_printf(m, "TxDiscards=%u\n", sums->tx_discards);
+       seq_printf(m, "RxUnicastFrames=%u\n", sums->rx_unicast_frames);
+       seq_printf(m, "RxMulticastFrames=%u\n", sums->rx_multicast_frames);
+       seq_printf(m, "RxFragments=%u\n", sums->rx_fragments);
+       seq_printf(m, "RxUnicastOctets=%u\n", sums->rx_unicast_octets);
+       seq_printf(m, "RxMulticastOctets=%u\n", sums->rx_multicast_octets);
+       seq_printf(m, "RxFCSErrors=%u\n", sums->rx_fcs_errors);
+       seq_printf(m, "RxDiscardsNoBuffer=%u\n", sums->rx_discards_no_buffer);
+       seq_printf(m, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa);
+       seq_printf(m, "RxDiscardsWEPUndecryptable=%u\n",
+                  sums->rx_discards_wep_undecryptable);
+       seq_printf(m, "RxMessageInMsgFragments=%u\n",
+                  sums->rx_message_in_msg_fragments);
+       seq_printf(m, "RxMessageInBadMsgFragments=%u\n",
+                  sums->rx_message_in_bad_msg_fragments);
        /* FIX: this may grow too long for one page(?) */
 
-       return (p - page);
+       return 0;
+}
+
+static int prism2_stats_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, prism2_stats_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations prism2_stats_proc_fops = {
+       .open           = prism2_stats_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-static int prism2_wds_proc_read(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+
+static int prism2_wds_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
-       struct list_head *ptr;
+       struct list_head *ptr = v;
        struct hostap_interface *iface;
 
-       if (off > PROC_LIMIT) {
-               *eof = 1;
-               return 0;
-       }
+       iface = list_entry(ptr, struct hostap_interface, list);
+       if (iface->type == HOSTAP_INTERFACE_WDS)
+               seq_printf(m, "%s\t%pM\n",
+                          iface->dev->name, iface->u.wds.remote_addr);
+       return 0;
+}
 
+static void *prism2_wds_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       local_info_t *local = m->private;
        read_lock_bh(&local->iface_lock);
-       list_for_each(ptr, &local->hostap_interfaces) {
-               iface = list_entry(ptr, struct hostap_interface, list);
-               if (iface->type != HOSTAP_INTERFACE_WDS)
-                       continue;
-               p += sprintf(p, "%s\t%pM\n",
-                            iface->dev->name,
-                            iface->u.wds.remote_addr);
-               if ((p - page) > PROC_LIMIT) {
-                       printk(KERN_DEBUG "%s: wds proc did not fit\n",
-                              local->dev->name);
-                       break;
-               }
-       }
-       read_unlock_bh(&local->iface_lock);
+       return seq_list_start(&local->hostap_interfaces, *_pos);
+}
 
-       if ((p - page) <= off) {
-               *eof = 1;
-               return 0;
-       }
+static void *prism2_wds_proc_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       local_info_t *local = m->private;
+       return seq_list_next(v, &local->hostap_interfaces, _pos);
+}
 
-       *start = page + off;
+static void prism2_wds_proc_stop(struct seq_file *m, void *v)
+{
+       local_info_t *local = m->private;
+       read_unlock_bh(&local->iface_lock);
+}
 
-       return (p - page - off);
+static const struct seq_operations prism2_wds_proc_seqops = {
+       .start  = prism2_wds_proc_start,
+       .next   = prism2_wds_proc_next,
+       .stop   = prism2_wds_proc_stop,
+       .show   = prism2_wds_proc_show,
+};
+
+static int prism2_wds_proc_open(struct inode *inode, struct file *file)
+{
+       int ret = seq_open(file, &prism2_wds_proc_seqops);
+       if (ret == 0) {
+               struct seq_file *m = file->private_data;
+               m->private = PDE_DATA(inode);
+       }
+       return ret;
 }
 
+static const struct file_operations prism2_wds_proc_fops = {
+       .open           = prism2_wds_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-static int prism2_bss_list_proc_read(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data)
+
+static int prism2_bss_list_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
-       struct list_head *ptr;
+       local_info_t *local = m->private;
+       struct list_head *ptr = v;
        struct hostap_bss_info *bss;
        int i;
 
-       if (off > PROC_LIMIT) {
-               *eof = 1;
+       if (ptr == &local->bss_list) {
+               seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t"
+                          "SSID(hex)\tWPA IE\n");
                return 0;
        }
 
-       p += sprintf(p, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t"
-                    "SSID(hex)\tWPA IE\n");
+       bss = list_entry(ptr, struct hostap_bss_info, list);
+       seq_printf(m, "%pM\t%lu\t%u\t0x%x\t",
+                  bss->bssid, bss->last_update,
+                  bss->count, bss->capab_info);
+
+       for (i = 0; i < bss->ssid_len; i++)
+               seq_putc(m,bss->ssid[i] >= 32 && bss->ssid[i] < 127 ?
+                          bss->ssid[i] : '_');
+
+       seq_putc(m, '\t');
+       for (i = 0; i < bss->ssid_len; i++)
+               seq_printf(m, "%02x", bss->ssid[i]);
+       seq_putc(m, '\t');
+       for (i = 0; i < bss->wpa_ie_len; i++)
+               seq_printf(m, "%02x", bss->wpa_ie[i]);
+       seq_putc(m, '\n');
+       return 0;
+}
+
+static void *prism2_bss_list_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       local_info_t *local = m->private;
        spin_lock_bh(&local->lock);
-       list_for_each(ptr, &local->bss_list) {
-               bss = list_entry(ptr, struct hostap_bss_info, list);
-               p += sprintf(p, "%pM\t%lu\t%u\t0x%x\t",
-                            bss->bssid, bss->last_update,
-                            bss->count, bss->capab_info);
-               for (i = 0; i < bss->ssid_len; i++) {
-                       p += sprintf(p, "%c",
-                                    bss->ssid[i] >= 32 && bss->ssid[i] < 127 ?
-                                    bss->ssid[i] : '_');
-               }
-               p += sprintf(p, "\t");
-               for (i = 0; i < bss->ssid_len; i++) {
-                       p += sprintf(p, "%02x", bss->ssid[i]);
-               }
-               p += sprintf(p, "\t");
-               for (i = 0; i < bss->wpa_ie_len; i++) {
-                       p += sprintf(p, "%02x", bss->wpa_ie[i]);
-               }
-               p += sprintf(p, "\n");
-               if ((p - page) > PROC_LIMIT) {
-                       printk(KERN_DEBUG "%s: BSS proc did not fit\n",
-                              local->dev->name);
-                       break;
-               }
-       }
-       spin_unlock_bh(&local->lock);
+       return seq_list_start_head(&local->bss_list, *_pos);
+}
 
-       if ((p - page) <= off) {
-               *eof = 1;
-               return 0;
-       }
+static void *prism2_bss_list_proc_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       local_info_t *local = m->private;
+       return seq_list_next(v, &local->bss_list, _pos);
+}
 
-       *start = page + off;
+static void prism2_bss_list_proc_stop(struct seq_file *m, void *v)
+{
+       local_info_t *local = m->private;
+       spin_unlock_bh(&local->lock);
+}
+
+static const struct seq_operations prism2_bss_list_proc_seqops = {
+       .start  = prism2_bss_list_proc_start,
+       .next   = prism2_bss_list_proc_next,
+       .stop   = prism2_bss_list_proc_stop,
+       .show   = prism2_bss_list_proc_show,
+};
 
-       return (p - page - off);
+static int prism2_bss_list_proc_open(struct inode *inode, struct file *file)
+{
+       int ret = seq_open(file, &prism2_bss_list_proc_seqops);
+       if (ret == 0) {
+               struct seq_file *m = file->private_data;
+               m->private = PDE_DATA(inode);
+       }
+       return ret;
 }
 
+static const struct file_operations prism2_bss_list_proc_fops = {
+       .open           = prism2_bss_list_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-static int prism2_crypt_proc_read(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
+
+static int prism2_crypt_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
+       local_info_t *local = m->private;
        int i;
 
-       if (off > PROC_LIMIT) {
-               *eof = 1;
-               return 0;
-       }
-
-       p += sprintf(p, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx);
+       seq_printf(m, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx);
        for (i = 0; i < WEP_KEYS; i++) {
                if (local->crypt_info.crypt[i] &&
                    local->crypt_info.crypt[i]->ops &&
                    local->crypt_info.crypt[i]->ops->print_stats) {
-                       p = local->crypt_info.crypt[i]->ops->print_stats(
-                               p, local->crypt_info.crypt[i]->priv);
+                       local->crypt_info.crypt[i]->ops->print_stats(
+                               m, local->crypt_info.crypt[i]->priv);
                }
        }
+       return 0;
+}
 
-       if ((p - page) <= off) {
-               *eof = 1;
-               return 0;
-       }
-
-       *start = page + off;
-
-       return (p - page - off);
+static int prism2_crypt_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, prism2_crypt_proc_show, PDE_DATA(inode));
 }
 
+static const struct file_operations prism2_crypt_proc_fops = {
+       .open           = prism2_crypt_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-static int prism2_pda_proc_read(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+
+static ssize_t prism2_pda_proc_read(struct file *file, char __user *buf,
+                                   size_t count, loff_t *_pos)
 {
-       local_info_t *local = (local_info_t *) data;
+       local_info_t *local = PDE_DATA(file_inode(file));
+       size_t off;
 
-       if (local->pda == NULL || off >= PRISM2_PDA_SIZE) {
-               *eof = 1;
+       if (local->pda == NULL || *_pos >= PRISM2_PDA_SIZE)
                return 0;
-       }
 
-       if (off + count > PRISM2_PDA_SIZE)
+       off = *_pos;
+       if (count > PRISM2_PDA_SIZE - off)
                count = PRISM2_PDA_SIZE - off;
-
-       memcpy(page, local->pda + off, count);
+       if (copy_to_user(buf, local->pda + off, count) != 0)
+               return -EFAULT;
+       *_pos += count;
        return count;
 }
 
+static const struct file_operations prism2_pda_proc_fops = {
+       .read           = prism2_pda_proc_read,
+       .llseek         = generic_file_llseek,
+};
 
-static int prism2_aux_dump_proc_read(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data)
-{
-       local_info_t *local = (local_info_t *) data;
-
-       if (local->func->read_aux == NULL) {
-               *eof = 1;
-               return 0;
-       }
 
-       if (local->func->read_aux(local->dev, off, count, page)) {
-               *eof = 1;
-               return 0;
-       }
-       *start = page;
-
-       return count;
+static ssize_t prism2_aux_dump_proc_no_read(struct file *file, char __user *buf,
+                                           size_t bufsize, loff_t *_pos)
+{
+       return 0;
 }
 
+static const struct file_operations prism2_aux_dump_proc_fops = {
+       .read           = prism2_aux_dump_proc_no_read,
+};
+
 
 #ifdef PRISM2_IO_DEBUG
 static int prism2_io_debug_proc_read(char *page, char **start, off_t off,
@@ -306,82 +344,108 @@ static int prism2_io_debug_proc_read(char *page, char **start, off_t off,
 
 
 #ifndef PRISM2_NO_STATION_MODES
-static int prism2_scan_results_proc_read(char *page, char **start, off_t off,
-                                        int count, int *eof, void *data)
+static int prism2_scan_results_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       local_info_t *local = (local_info_t *) data;
-       int entry, i, len, total = 0;
+       local_info_t *local = m->private;
+       unsigned long entry;
+       int i, len;
        struct hfa384x_hostscan_result *scanres;
-       u8 *pos;
+       u8 *p;
 
-       p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates "
-                    "SSID\n");
+       if (v == SEQ_START_TOKEN) {
+               seq_printf(m,
+                          "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates SSID\n");
+               return 0;
+       }
 
+       entry = (unsigned long)v - 2;
+       scanres = &local->last_scan_results[entry];
+
+       seq_printf(m, "%d %d %d %d 0x%02x %d %pM %d ",
+                  le16_to_cpu(scanres->chid),
+                  (s16) le16_to_cpu(scanres->anl),
+                  (s16) le16_to_cpu(scanres->sl),
+                  le16_to_cpu(scanres->beacon_interval),
+                  le16_to_cpu(scanres->capability),
+                  le16_to_cpu(scanres->rate),
+                  scanres->bssid,
+                  le16_to_cpu(scanres->atim));
+
+       p = scanres->sup_rates;
+       for (i = 0; i < sizeof(scanres->sup_rates); i++) {
+               if (p[i] == 0)
+                       break;
+               seq_printf(m, "<%02x>", p[i]);
+       }
+       seq_putc(m, ' ');
+
+       p = scanres->ssid;
+       len = le16_to_cpu(scanres->ssid_len);
+       if (len > 32)
+               len = 32;
+       for (i = 0; i < len; i++) {
+               unsigned char c = p[i];
+               if (c >= 32 && c < 127)
+                       seq_putc(m, c);
+               else
+                       seq_printf(m, "<%02x>", c);
+       }
+       seq_putc(m, '\n');
+       return 0;
+}
+
+static void *prism2_scan_results_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       local_info_t *local = m->private;
        spin_lock_bh(&local->lock);
-       for (entry = 0; entry < local->last_scan_results_count; entry++) {
-               scanres = &local->last_scan_results[entry];
 
-               if (total + (p - page) <= off) {
-                       total += p - page;
-                       p = page;
-               }
-               if (total + (p - page) > off + count)
-                       break;
-               if ((p - page) > (PAGE_SIZE - 200))
-                       break;
+       /* We have a header (pos 0) + N results to show (pos 1...N) */
+       if (*_pos > local->last_scan_results_count)
+               return NULL;
+       return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */
+}
 
-               p += sprintf(p, "%d %d %d %d 0x%02x %d %pM %d ",
-                            le16_to_cpu(scanres->chid),
-                            (s16) le16_to_cpu(scanres->anl),
-                            (s16) le16_to_cpu(scanres->sl),
-                            le16_to_cpu(scanres->beacon_interval),
-                            le16_to_cpu(scanres->capability),
-                            le16_to_cpu(scanres->rate),
-                            scanres->bssid,
-                            le16_to_cpu(scanres->atim));
-
-               pos = scanres->sup_rates;
-               for (i = 0; i < sizeof(scanres->sup_rates); i++) {
-                       if (pos[i] == 0)
-                               break;
-                       p += sprintf(p, "<%02x>", pos[i]);
-               }
-               p += sprintf(p, " ");
-
-               pos = scanres->ssid;
-               len = le16_to_cpu(scanres->ssid_len);
-               if (len > 32)
-                       len = 32;
-               for (i = 0; i < len; i++) {
-                       unsigned char c = pos[i];
-                       if (c >= 32 && c < 127)
-                               p += sprintf(p, "%c", c);
-                       else
-                               p += sprintf(p, "<%02x>", c);
-               }
-               p += sprintf(p, "\n");
-       }
+static void *prism2_scan_results_proc_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       local_info_t *local = m->private;
+
+       ++*_pos;
+       if (*_pos > local->last_scan_results_count)
+               return NULL;
+       return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */
+}
+
+static void prism2_scan_results_proc_stop(struct seq_file *m, void *v)
+{
+       local_info_t *local = m->private;
        spin_unlock_bh(&local->lock);
+}
 
-       total += (p - page);
-       if (total >= off + count)
-               *eof = 1;
+static const struct seq_operations prism2_scan_results_proc_seqops = {
+       .start  = prism2_scan_results_proc_start,
+       .next   = prism2_scan_results_proc_next,
+       .stop   = prism2_scan_results_proc_stop,
+       .show   = prism2_scan_results_proc_show,
+};
 
-       if (total < off) {
-               *eof = 1;
-               return 0;
+static int prism2_scan_results_proc_open(struct inode *inode, struct file *file)
+{
+       int ret = seq_open(file, &prism2_scan_results_proc_seqops);
+       if (ret == 0) {
+               struct seq_file *m = file->private_data;
+               m->private = PDE_DATA(inode);
        }
+       return ret;
+}
+
+static const struct file_operations prism2_scan_results_proc_fops = {
+       .open           = prism2_scan_results_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-       len = total - off;
-       if (len > (p - page))
-               len = p - page;
-       *start = p - len;
-       if (len > count)
-               len = count;
 
-       return len;
-}
 #endif /* PRISM2_NO_STATION_MODES */
 
 
@@ -403,53 +467,36 @@ void hostap_init_proc(local_info_t *local)
        }
 
 #ifndef PRISM2_NO_PROCFS_DEBUG
-       create_proc_read_entry("debug", 0, local->proc,
-                              prism2_debug_proc_read, local);
+       proc_create_data("debug", 0, local->proc,
+                        &prism2_debug_proc_fops, local);
 #endif /* PRISM2_NO_PROCFS_DEBUG */
-       create_proc_read_entry("stats", 0, local->proc,
-                              prism2_stats_proc_read, local);
-       create_proc_read_entry("wds", 0, local->proc,
-                              prism2_wds_proc_read, local);
-       create_proc_read_entry("pda", 0, local->proc,
-                              prism2_pda_proc_read, local);
-       create_proc_read_entry("aux_dump", 0, local->proc,
-                              prism2_aux_dump_proc_read, local);
-       create_proc_read_entry("bss_list", 0, local->proc,
-                              prism2_bss_list_proc_read, local);
-       create_proc_read_entry("crypt", 0, local->proc,
-                              prism2_crypt_proc_read, local);
+       proc_create_data("stats", 0, local->proc,
+                        &prism2_stats_proc_fops, local);
+       proc_create_data("wds", 0, local->proc,
+                        &prism2_wds_proc_fops, local);
+       proc_create_data("pda", 0, local->proc,
+                        &prism2_pda_proc_fops, local);
+       proc_create_data("aux_dump", 0, local->proc,
+                        local->func->read_aux_fops ?: &prism2_aux_dump_proc_fops,
+                        local);
+       proc_create_data("bss_list", 0, local->proc,
+                        &prism2_bss_list_proc_fops, local);
+       proc_create_data("crypt", 0, local->proc,
+                        &prism2_crypt_proc_fops, local);
 #ifdef PRISM2_IO_DEBUG
-       create_proc_read_entry("io_debug", 0, local->proc,
-                              prism2_io_debug_proc_read, local);
+       proc_create_data("io_debug", 0, local->proc,
+                        &prism2_io_debug_proc_fops, local);
 #endif /* PRISM2_IO_DEBUG */
 #ifndef PRISM2_NO_STATION_MODES
-       create_proc_read_entry("scan_results", 0, local->proc,
-                              prism2_scan_results_proc_read, local);
+       proc_create_data("scan_results", 0, local->proc,
+                        &prism2_scan_results_proc_fops, local);
 #endif /* PRISM2_NO_STATION_MODES */
 }
 
 
 void hostap_remove_proc(local_info_t *local)
 {
-       if (local->proc != NULL) {
-#ifndef PRISM2_NO_STATION_MODES
-               remove_proc_entry("scan_results", local->proc);
-#endif /* PRISM2_NO_STATION_MODES */
-#ifdef PRISM2_IO_DEBUG
-               remove_proc_entry("io_debug", local->proc);
-#endif /* PRISM2_IO_DEBUG */
-               remove_proc_entry("pda", local->proc);
-               remove_proc_entry("aux_dump", local->proc);
-               remove_proc_entry("wds", local->proc);
-               remove_proc_entry("stats", local->proc);
-               remove_proc_entry("bss_list", local->proc);
-               remove_proc_entry("crypt", local->proc);
-#ifndef PRISM2_NO_PROCFS_DEBUG
-               remove_proc_entry("debug", local->proc);
-#endif /* PRISM2_NO_PROCFS_DEBUG */
-               if (hostap_proc != NULL)
-                       remove_proc_entry(local->proc->name, hostap_proc);
-       }
+       remove_proc_subtree(local->ddev->name, hostap_proc);
 }
 
 
index 7bb0b4b3f2cbce894b0b22d27f9c336c7f9935bf..57904015380f05f28f5b555a8322caef59ab699d 100644 (file)
@@ -596,8 +596,7 @@ struct prism2_helper_functions {
                        struct prism2_download_param *param);
        int (*tx)(struct sk_buff *skb, struct net_device *dev);
        int (*set_tim)(struct net_device *dev, int aid, int set);
-       int (*read_aux)(struct net_device *dev, unsigned addr, int len,
-                       u8 *buf);
+       const struct file_operations *read_aux_fops;
 
        int need_tx_headroom; /* number of bytes of headroom needed before
                               * IEEE 802.11 header */
index 3630a41df50d7c64815abae048696ea04329a703..c353b5f19c8c639480be47121f06c166dfc9f71c 100644 (file)
@@ -475,6 +475,7 @@ il3945_tx_skb(struct il_priv *il,
        dma_addr_t txcmd_phys;
        int txq_id = skb_get_queue_mapping(skb);
        u16 len, idx, hdr_len;
+       u16 firstlen, secondlen;
        u8 id;
        u8 unicast;
        u8 sta_id;
@@ -589,21 +590,22 @@ il3945_tx_skb(struct il_priv *il,
        len =
            sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) +
            hdr_len;
-       len = (len + 3) & ~3;
+       firstlen = (len + 3) & ~3;
 
        /* Physical address of this Tx command's header (not MAC header!),
         * within command buffer array. */
        txcmd_phys =
-           pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE);
+           pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen,
+                          PCI_DMA_TODEVICE);
        if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys)))
                goto drop_unlock;
 
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
         * if any (802.11 null frames have no payload). */
-       len = skb->len - hdr_len;
-       if (len) {
+       secondlen = skb->len - hdr_len;
+       if (secondlen > 0) {
                phys_addr =
-                   pci_map_single(il->pci_dev, skb->data + hdr_len, len,
+                   pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
                                   PCI_DMA_TODEVICE);
                if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr)))
                        goto drop_unlock;
@@ -611,12 +613,12 @@ il3945_tx_skb(struct il_priv *il,
 
        /* Add buffer containing Tx command and MAC(!) header to TFD's
         * first entry */
-       il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0);
+       il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
        dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
-       dma_unmap_len_set(out_meta, len, len);
-       if (len)
-               il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
-                                              U32_PAD(len));
+       dma_unmap_len_set(out_meta, len, firstlen);
+       if (secondlen > 0)
+               il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0,
+                                              U32_PAD(secondlen));
 
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
index 94ef33838bc69b615f8f47140922bf0d13eb2453..b775769f8322c437558712af955332296e95db89 100644 (file)
@@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
                       sta_id, sta->sta.addr, flags & CMD_ASYNC ?  "a" : "");
 
        if (!(flags & CMD_ASYNC)) {
-               cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD;
+               cmd.flags |= CMD_WANT_SKB;
                might_sleep();
        }
 
index 9a0f45ec9e01e2456610e28d0f760ce7d890451e..81aa91fab5aafcc1dc7fa597c85878d01ab83685 100644 (file)
@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
 TRACE_EVENT(iwlwifi_dev_hcmd,
        TP_PROTO(const struct device *dev,
                 struct iwl_host_cmd *cmd, u16 total_size,
-                const void *hdr, size_t hdr_len),
-       TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
+                struct iwl_cmd_header *hdr),
+       TP_ARGS(dev, cmd, total_size, hdr),
        TP_STRUCT__entry(
                DEV_ENTRY
                __dynamic_array(u8, hcmd, total_size)
                __field(u32, flags)
        ),
        TP_fast_assign(
-               int i, offset = hdr_len;
+               int i, offset = sizeof(*hdr);
 
                DEV_ASSIGN;
                __entry->flags = cmd->flags;
-               memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
+               memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
 
-               for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+               for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
                        if (!cmd->len[i])
                                continue;
-                       if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
-                               continue;
                        memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
                               cmd->data[i], cmd->len[i]);
                        offset += cmd->len[i];
index 6f228bb2b84431e61cd8292d1563f81faa91efc6..fbfd2d1371176e247a22e5fca00ee5809088c306 100644 (file)
@@ -1102,7 +1102,6 @@ void iwl_drv_stop(struct iwl_drv *drv)
 
 /* shared module parameters */
 struct iwl_mod_params iwlwifi_mod_params = {
-       .amsdu_size_8K = 1,
        .restart_fw = 1,
        .plcp_check = true,
        .bt_coex_active = true,
@@ -1207,7 +1206,7 @@ MODULE_PARM_DESC(11n_disable,
        "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
 module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
                   int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
+MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
 module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO);
 MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
 
index e5e3a79eae2fbd5e8f544db2cc9605522770dddb..2c2a729092f5e894013c39f1eccb0a739a5e56d4 100644 (file)
@@ -91,7 +91,7 @@ enum iwl_power_level {
  * @sw_crypto: using hardware encryption, default = 0
  * @disable_11n: disable 11n capabilities, default = 0,
  *     use IWL_DISABLE_HT_* constants
- * @amsdu_size_8K: enable 8K amsdu size, default = 1
+ * @amsdu_size_8K: enable 8K amsdu size, default = 0
  * @restart_fw: restart firmware, default = 1
  * @plcp_check: enable plcp health check, default = true
  * @wd_disable: enable stuck queue check, default = 0
index 14fc8d39fc28e81c1cb11487b3820374c5807848..3392011a876841bae6ac4d75eb11fa4a764cc07b 100644 (file)
@@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db {
        u8 data[];
 } __packed;
 
-#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
-static inline void iwl_phy_db_test_pic(__le32 pic)
-{
-       WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);
-}
-
 struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
 {
        struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
@@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
                        (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
        }
 
-       /* Test PIC */
-       if (type != IWL_PHY_DB_CFG)
-               iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +
-                                     (size / sizeof(__le32)) - 1));
-
        IWL_DEBUG_INFO(phy_db->trans,
                       "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
                       __func__, __LINE__, type, size);
@@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
                *size = entry->size;
        }
 
-       /* Test PIC */
-       if (type != IWL_PHY_DB_CFG)
-               iwl_phy_db_test_pic(*(((__le32 *)*data) +
-                                     (*size / sizeof(__le32)) - 1));
-
        IWL_DEBUG_INFO(phy_db->trans,
                       "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
                       __func__, __LINE__, type, *size);
index 8c7bec6b9a0be92d29136a47fc20f920a5ce7a6d..0cac2b7af78b99eb1e8c8951a9638c12033e382c 100644 (file)
@@ -186,19 +186,13 @@ struct iwl_rx_packet {
  * @CMD_ASYNC: Return right away and don't want for the response
  * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
  *     response. The caller needs to call iwl_free_resp when done.
- * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the
- *     response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be
- *     copied. The pointer passed to the response handler is in the transport
- *     ownership and don't need to be freed by the op_mode. This also means
- *     that the pointer is invalidated after the op_mode's handler returns.
  * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
  */
 enum CMD_MODE {
        CMD_SYNC                = 0,
        CMD_ASYNC               = BIT(0),
        CMD_WANT_SKB            = BIT(1),
-       CMD_WANT_HCMD           = BIT(2),
-       CMD_ON_DEMAND           = BIT(3),
+       CMD_ON_DEMAND           = BIT(2),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -217,7 +211,11 @@ struct iwl_device_cmd {
 
 #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
 
-#define IWL_MAX_CMD_TFDS       2
+/*
+ * number of transfer buffers (fragments) per transmit frame descriptor;
+ * this is just the driver's idea, the hardware supports 20
+ */
+#define IWL_MAX_CMD_TBS_PER_TFD        2
 
 /**
  * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
@@ -254,15 +252,15 @@ enum iwl_hcmd_dataflag {
  * @id: id of the host command
  */
 struct iwl_host_cmd {
-       const void *data[IWL_MAX_CMD_TFDS];
+       const void *data[IWL_MAX_CMD_TBS_PER_TFD];
        struct iwl_rx_packet *resp_pkt;
        unsigned long _rx_page_addr;
        u32 _rx_page_order;
        int handler_status;
 
        u32 flags;
-       u16 len[IWL_MAX_CMD_TFDS];
-       u8 dataflags[IWL_MAX_CMD_TFDS];
+       u16 len[IWL_MAX_CMD_TBS_PER_TFD];
+       u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];
        u8 id;
 };
 
index c64d864799cd49659acf6c2498aba7b62ca35891..994c8c263dc0e6744afa176e0be5ef4e89d6638d 100644 (file)
@@ -61,6 +61,7 @@
  *
  *****************************************************************************/
 
+#include <linux/etherdevice.h>
 #include <net/cfg80211.h>
 #include <net/ipv6.h>
 #include "iwl-modparams.h"
@@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                                           sizeof(wkc), &wkc);
                data->error = ret != 0;
 
+               mvm->ptk_ivlen = key->iv_len;
+               mvm->ptk_icvlen = key->icv_len;
+               mvm->gtk_ivlen = key->iv_len;
+               mvm->gtk_icvlen = key->icv_len;
+
                /* don't upload key again */
                goto out_unlock;
        }
@@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
         */
        if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
                key->hw_key_idx = 0;
+               mvm->ptk_ivlen = key->iv_len;
+               mvm->ptk_icvlen = key->icv_len;
        } else {
                data->gtk_key_idx++;
                key->hw_key_idx = data->gtk_key_idx;
+               mvm->gtk_ivlen = key->iv_len;
+               mvm->gtk_icvlen = key->icv_len;
        }
 
        ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
@@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        /* We reprogram keys and shouldn't allocate new key indices */
        memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
 
+       mvm->ptk_ivlen = 0;
+       mvm->ptk_icvlen = 0;
+       mvm->ptk_ivlen = 0;
+       mvm->ptk_icvlen = 0;
+
        /*
         * The D3 firmware still hardcodes the AP station ID for the
         * BSS we're associated with as 0. As a result, we have to move
@@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
        struct iwl_wowlan_status *status;
        u32 reasons;
        int ret, len;
-       bool pkt8023 = false;
        struct sk_buff *pkt = NULL;
 
        iwl_trans_read_mem_bytes(mvm->trans, base,
@@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
        status = (void *)cmd.resp_pkt->data;
 
        if (len - sizeof(struct iwl_cmd_header) !=
-           sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) {
+           sizeof(*status) +
+           ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
                IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
                goto out;
        }
@@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
                goto report;
        }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
                wakeup.magic_pkt = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
                wakeup.pattern_idx =
                        le16_to_cpu(status->pattern_number);
-               pkt8023 = true;
-       }
 
        if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
                       IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
                wakeup.disconnect = true;
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
                wakeup.gtk_rekey_failure = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
                wakeup.rfkill_release = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
                wakeup.eap_identity_req = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
                wakeup.four_way_handshake = true;
-               pkt8023 = true;
-       }
 
        if (status->wake_packet_bufsize) {
-               u32 pktsize = le32_to_cpu(status->wake_packet_bufsize);
-               u32 pktlen = le32_to_cpu(status->wake_packet_length);
+               int pktsize = le32_to_cpu(status->wake_packet_bufsize);
+               int pktlen = le32_to_cpu(status->wake_packet_length);
+               const u8 *pktdata = status->wake_packet;
+               struct ieee80211_hdr *hdr = (void *)pktdata;
+               int truncated = pktlen - pktsize;
+
+               /* this would be a firmware bug */
+               if (WARN_ON_ONCE(truncated < 0))
+                       truncated = 0;
+
+               if (ieee80211_is_data(hdr->frame_control)) {
+                       int hdrlen = ieee80211_hdrlen(hdr->frame_control);
+                       int ivlen = 0, icvlen = 4; /* also FCS */
 
-               if (pkt8023) {
                        pkt = alloc_skb(pktsize, GFP_KERNEL);
                        if (!pkt)
                                goto report;
-                       memcpy(skb_put(pkt, pktsize), status->wake_packet,
-                              pktsize);
+
+                       memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);
+                       pktdata += hdrlen;
+                       pktsize -= hdrlen;
+
+                       if (ieee80211_has_protected(hdr->frame_control)) {
+                               if (is_multicast_ether_addr(hdr->addr1)) {
+                                       ivlen = mvm->gtk_ivlen;
+                                       icvlen += mvm->gtk_icvlen;
+                               } else {
+                                       ivlen = mvm->ptk_ivlen;
+                                       icvlen += mvm->ptk_icvlen;
+                               }
+                       }
+
+                       /* if truncated, FCS/ICV is (partially) gone */
+                       if (truncated >= icvlen) {
+                               icvlen = 0;
+                               truncated -= icvlen;
+                       } else {
+                               icvlen -= truncated;
+                               truncated = 0;
+                       }
+
+                       pktsize -= ivlen + icvlen;
+                       pktdata += ivlen;
+
+                       memcpy(skb_put(pkt, pktsize), pktdata, pktsize);
+
                        if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
                                goto report;
                        wakeup.packet = pkt->data;
                        wakeup.packet_present_len = pkt->len;
-                       wakeup.packet_len = pkt->len - (pktlen - pktsize);
+                       wakeup.packet_len = pkt->len - truncated;
                        wakeup.packet_80211 = false;
                } else {
+                       int fcslen = 4;
+
+                       if (truncated >= 4) {
+                               truncated -= 4;
+                               fcslen = 0;
+                       } else {
+                               fcslen -= truncated;
+                               truncated = 0;
+                       }
+                       pktsize -= fcslen;
                        wakeup.packet = status->wake_packet;
                        wakeup.packet_present_len = pktsize;
-                       wakeup.packet_len = pktlen;
+                       wakeup.packet_len = pktlen - truncated;
                        wakeup.packet_80211 = true;
                }
        }
index 23eebda848b05ae64f9ae8dfb6ce5647dded4b19..2adb61f103f4cd310ae654fdd83ff466a843dda5 100644 (file)
@@ -762,18 +762,20 @@ struct iwl_phy_context_cmd {
 #define IWL_RX_INFO_PHY_CNT 8
 #define IWL_RX_INFO_AGC_IDX 1
 #define IWL_RX_INFO_RSSI_AB_IDX 2
-#define IWL_RX_INFO_RSSI_C_IDX 3
-#define IWL_OFDM_AGC_DB_MSK 0xfe00
-#define IWL_OFDM_AGC_DB_POS 9
+#define IWL_OFDM_AGC_A_MSK 0x0000007f
+#define IWL_OFDM_AGC_A_POS 0
+#define IWL_OFDM_AGC_B_MSK 0x00003f80
+#define IWL_OFDM_AGC_B_POS 7
+#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000
+#define IWL_OFDM_AGC_CODE_POS 20
 #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
-#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
 #define IWL_OFDM_RSSI_A_POS 0
+#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
+#define IWL_OFDM_RSSI_ALLBAND_A_POS 8
 #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
-#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
 #define IWL_OFDM_RSSI_B_POS 16
-#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff
-#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00
-#define IWL_OFDM_RSSI_C_POS 0
+#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
+#define IWL_OFDM_RSSI_ALLBAND_B_POS 24
 
 /**
  * struct iwl_rx_phy_info - phy info
index d3d959db03a9727e7033a871fc4717654dc3ec10..500f818dba0412df8e5a76d018ddaec761529820 100644 (file)
 #define UCODE_VALID_OK cpu_to_le32(0x1)
 
 /* Default calibration values for WkP - set to INIT image w/o running */
-static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
-                                                0x00, 0x18, 0x00 };
-static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-                                            0x7f, 0x7f, 0x7f };
-static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
-static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
-                                            0x00 };
-static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
 static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
 static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
-static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
 
 struct iwl_calib_default_data {
        u16 size;
@@ -99,12 +90,7 @@ struct iwl_calib_default_data {
 #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
 
 static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
-       [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
-       [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
-       [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
-       [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
        [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
-       [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
        [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
 };
 
@@ -241,20 +227,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
 
        return 0;
 }
-#define IWL_HW_REV_ID_RAINBOW  0x2
-#define IWL_PROJ_TYPE_LHP      0x5
-
-static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
-{
-       struct iwl_nvm_data *data = mvm->nvm_data;
-       /* Temp calls to static definitions, will be changed to CSR calls */
-       u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
-       u8 project_type = IWL_PROJ_TYPE_LHP;
-
-       return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
-               (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
-               (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
-}
 
 static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
 {
@@ -262,7 +234,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
        enum iwl_ucode_type ucode_type = mvm->cur_ucode;
 
        /* Set parameters */
-       phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm));
+       phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
        phy_cfg_cmd.calib_control.event_trigger =
                mvm->fw->default_calib[ucode_type].event_trigger;
        phy_cfg_cmd.calib_control.flow_trigger =
@@ -275,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
                                    sizeof(phy_cfg_cmd), &phy_cfg_cmd);
 }
 
-/* Starting with the new PHY DB implementation - New calibs are enabled */
-/* Value - 0x405e7 */
-#define IWL_CALIB_DEFAULT_FLOW_INIT    (IWL_CALIB_CFG_XTAL_IDX         |\
-                                        IWL_CALIB_CFG_TEMPERATURE_IDX  |\
-                                        IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
-                                        IWL_CALIB_CFG_DC_IDX           |\
-                                        IWL_CALIB_CFG_BB_FILTER_IDX    |\
-                                        IWL_CALIB_CFG_LO_LEAKAGE_IDX   |\
-                                        IWL_CALIB_CFG_TX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_RX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_AGC_IDX)
-
-#define IWL_CALIB_DEFAULT_EVENT_INIT   0x0
-
-/* Value 0x41567 */
-#define IWL_CALIB_DEFAULT_FLOW_RUN     (IWL_CALIB_CFG_XTAL_IDX         |\
-                                        IWL_CALIB_CFG_TEMPERATURE_IDX  |\
-                                        IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
-                                        IWL_CALIB_CFG_BB_FILTER_IDX    |\
-                                        IWL_CALIB_CFG_DC_IDX           |\
-                                        IWL_CALIB_CFG_TX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_RX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_SENSITIVITY_IDX  |\
-                                        IWL_CALIB_CFG_AGC_IDX)
-
-#define IWL_CALIB_DEFAULT_EVENT_RUN    (IWL_CALIB_CFG_XTAL_IDX         |\
-                                        IWL_CALIB_CFG_TEMPERATURE_IDX  |\
-                                        IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
-                                        IWL_CALIB_CFG_TX_PWR_IDX       |\
-                                        IWL_CALIB_CFG_DC_IDX           |\
-                                        IWL_CALIB_CFG_TX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_SENSITIVITY_IDX)
-
-/*
- * Sets the calibrations trigger values that will be sent to the FW for runtime
- * and init calibrations.
- * The ones given in the FW TLV are not correct.
- */
-static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
-{
-       struct iwl_tlv_calib_ctrl default_calib;
-
-       /*
-        * WkP FW TLV calib bits are wrong, overwrite them.
-        * This defines the dynamic calibrations which are implemented in the
-        * uCode both for init(flow) calculation and event driven calibs.
-        */
-
-       /* Init Image */
-       default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
-       default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
-
-       if (default_calib.event_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
-               IWL_ERR(mvm,
-                       "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
-                       default_calib.event_trigger);
-       if (default_calib.flow_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
-               IWL_ERR(mvm,
-                       "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
-                       default_calib.flow_trigger);
-
-       memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
-              &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
-       IWL_ERR(mvm,
-               "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
-               default_calib.event_trigger,
-               default_calib.flow_trigger);
-
-       /* Run time image */
-       default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
-       default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
-
-       if (default_calib.event_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
-               IWL_ERR(mvm,
-                       "Updating the event calib for RT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
-                       default_calib.event_trigger);
-       if (default_calib.flow_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
-               IWL_ERR(mvm,
-                       "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
-                       default_calib.flow_trigger);
-
-       memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
-              &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
-       IWL_ERR(mvm,
-               "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
-               default_calib.event_trigger,
-               default_calib.flow_trigger);
-}
-
 static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
 {
        u8 cmd_raw[16]; /* holds the variable size commands */
@@ -446,8 +321,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
        ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
        WARN_ON(ret);
 
-       /* Override the calibrations from TLV and the const of fw */
-       iwl_set_default_calib_trigger(mvm);
+       /* Send TX valid antennas before triggering calibrations */
+       ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
+       if (ret)
+               goto error;
 
        /* WkP doesn't have all calibrations, need to set default values */
        if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
index e8264e11b12da0d2ab33108ff2cf8676ecd61825..7e169b085afe05f1c4c5a17804e864d8bc15e9f2 100644 (file)
@@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
        return ret;
 }
 
-static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
-                                        struct ieee80211_vif *vif)
+static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
+                                       struct ieee80211_vif *vif)
 {
-       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        u32 tfd_msk = 0, ac;
 
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
                 */
                flush_work(&mvm->sta_drained_wk);
        }
+}
+
+static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif)
+{
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       iwl_mvm_prepare_mac_removal(mvm, vif);
 
        mutex_lock(&mvm->mutex);
 
        /*
         * For AP/GO interface, the tear down of the resources allocated to the
-        * interface should be handled as part of the bss_info_changed flow.
+        * interface is be handled as part of the stop_ap flow.
         */
        if (vif->type == NL80211_IFTYPE_AP) {
                iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
@@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
+       iwl_mvm_prepare_mac_removal(mvm, vif);
+
        mutex_lock(&mvm->mutex);
 
        mvmvif->ap_active = false;
index 4e339ccfa8005e6afd5f7d549982906cff9004aa..bdae700c769eb292223d8871b1789a46f6f13610 100644 (file)
@@ -80,7 +80,8 @@
 
 #define IWL_INVALID_MAC80211_QUEUE     0xff
 #define IWL_MVM_MAX_ADDRESSES          2
-#define IWL_RSSI_OFFSET 44
+/* RSSI offset for WkP */
+#define IWL_RSSI_OFFSET 50
 
 enum iwl_mvm_tx_fifo {
        IWL_MVM_TX_FIFO_BK = 0,
@@ -327,6 +328,10 @@ struct iwl_mvm {
        struct led_classdev led;
 
        struct ieee80211_vif *p2p_device_vif;
+
+#ifdef CONFIG_PM_SLEEP
+       int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
+#endif
 };
 
 /* Extract MVM priv from op_mode and _hw */
index aa59adf87db333f66b0a2e925ddd66afd574ae60..d0f9c1e0475e71659576b609b8f3365196435f02 100644 (file)
@@ -624,12 +624,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
        ieee80211_free_txskb(mvm->hw, skb);
 }
 
-static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
 {
-       struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
-       iwl_mvm_dump_nic_error_log(mvm);
-
        iwl_abort_notification_waits(&mvm->notif_wait);
 
        /*
@@ -663,9 +659,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
        }
 }
 
+static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+{
+       struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
+       iwl_mvm_dump_nic_error_log(mvm);
+
+       iwl_mvm_nic_restart(mvm);
+}
+
 static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
 {
+       struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
        WARN_ON(1);
+       iwl_mvm_nic_restart(mvm);
 }
 
 static const struct iwl_op_mode_ops iwl_mvm_ops = {
index 3f40ab05bbd8181d55d4e1999ebc77f5f977b6f9..b0b190d0ec23659279f9a33e7d57b21428114f30 100644 (file)
@@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
 static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
                             struct iwl_rx_phy_info *phy_info)
 {
-       u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db;
+       int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
+       int rssi_all_band_a, rssi_all_band_b;
+       u32 agc_a, agc_b, max_agc;
        u32 val;
 
-       /* Find max rssi among 3 possible receivers.
+       /* Find max rssi among 2 possible receivers.
         * These values are measured by the Digital Signal Processor (DSP).
         * They should stay fairly constant even as the signal strength varies,
         * if the radio's Automatic Gain Control (AGC) is working right.
         * AGC value (see below) will provide the "interesting" info.
         */
+       val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
+       agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
+       agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
+       max_agc = max_t(u32, agc_a, agc_b);
+
        val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
        rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
        rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
-       val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]);
-       rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS;
-
-       val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
-       agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
+       rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
+                               IWL_OFDM_RSSI_ALLBAND_A_POS;
+       rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
+                               IWL_OFDM_RSSI_ALLBAND_B_POS;
 
-       max_rssi = max_t(u32, rssi_a, rssi_b);
-       max_rssi = max_t(u32, max_rssi, rssi_c);
+       /*
+        * dBm = rssi dB - agc dB - constant.
+        * Higher AGC (higher radio gain) means lower signal.
+        */
+       rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
+       rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
+       max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);
 
-       IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
-                       rssi_a, rssi_b, rssi_c, max_rssi, agc_db);
+       IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
+                       rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
 
-       /* dBm = max_rssi dB - agc dB - constant.
-        * Higher AGC (higher radio gain) means lower signal. */
-       return max_rssi - agc_db - IWL_RSSI_OFFSET;
+       return max_rssi_dbm;
 }
 
 /*
index 861a7f9f8e7f4c0a932e4ce71e607bdc8a3b94fa..274f44e2ef60e52d1fb39f66735c98563036449e 100644 (file)
@@ -770,6 +770,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        u16 txq_id;
        int err;
 
+
+       /*
+        * If mac80211 is cleaning its state, then say that we finished since
+        * our state has been cleared anyway.
+        */
+       if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+               ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               return 0;
+       }
+
        spin_lock_bh(&mvmsta->lock);
 
        txq_id = tid_data->txq_id;
index 6b67ce3f679ceb8ad4907c14c32926d0828f9f75..6645efe5c03edfdc3c4523f0c06ab1d7bc0c7629 100644 (file)
@@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
 
                /* Single frame failure in an AMPDU queue => send BAR */
                if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&
-                   !(info->flags & IEEE80211_TX_STAT_ACK)) {
-                       /* there must be only one skb in the skb_list */
-                       WARN_ON_ONCE(skb_freed > 1 ||
-                                    !skb_queue_empty(&skbs));
+                   !(info->flags & IEEE80211_TX_STAT_ACK))
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-               }
 
                /* W/A FW bug: seq_ctl is wrong when the queue is flushed */
                if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
index aa2a39a637ddebb15e2b1f390eaa84c839af3dda..148843e7f34f26f9ea98d8ae269e366765cba115 100644 (file)
@@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
 struct iwl_cmd_meta {
        /* only for SYNC commands, iff the reply skb is wanted */
        struct iwl_host_cmd *source;
-
-       DEFINE_DMA_UNMAP_ADDR(mapping);
-       DEFINE_DMA_UNMAP_LEN(len);
-
        u32 flags;
 };
 
@@ -182,19 +178,39 @@ struct iwl_queue {
 #define TFD_TX_CMD_SLOTS 256
 #define TFD_CMD_SLOTS 32
 
+/*
+ * The FH will write back to the first TB only, so we need
+ * to copy some data into the buffer regardless of whether
+ * it should be mapped or not. This indicates how big the
+ * first TB must be to include the scratch buffer. Since
+ * the scratch is 4 bytes at offset 12, it's 16 now. If we
+ * make it bigger then allocations will be bigger and copy
+ * slower, so that's probably not useful.
+ */
+#define IWL_HCMD_SCRATCHBUF_SIZE       16
+
 struct iwl_pcie_txq_entry {
        struct iwl_device_cmd *cmd;
-       struct iwl_device_cmd *copy_cmd;
        struct sk_buff *skb;
        /* buffer to free after command completes */
        const void *free_buf;
        struct iwl_cmd_meta meta;
 };
 
+struct iwl_pcie_txq_scratch_buf {
+       struct iwl_cmd_header hdr;
+       u8 buf[8];
+       __le32 scratch;
+};
+
 /**
  * struct iwl_txq - Tx Queue for DMA
  * @q: generic Rx/Tx queue descriptor
  * @tfds: transmit frame descriptors (DMA memory)
+ * @scratchbufs: start of command headers, including scratch buffers, for
+ *     the writeback -- this is DMA memory and an array holding one buffer
+ *     for each command on the queue
+ * @scratchbufs_dma: DMA address for the scratchbufs start
  * @entries: transmit entries (driver state)
  * @lock: queue lock
  * @stuck_timer: timer that fires if queue gets stuck
@@ -208,6 +224,8 @@ struct iwl_pcie_txq_entry {
 struct iwl_txq {
        struct iwl_queue q;
        struct iwl_tfd *tfds;
+       struct iwl_pcie_txq_scratch_buf *scratchbufs;
+       dma_addr_t scratchbufs_dma;
        struct iwl_pcie_txq_entry *entries;
        spinlock_t lock;
        struct timer_list stuck_timer;
@@ -216,6 +234,13 @@ struct iwl_txq {
        u8 active;
 };
 
+static inline dma_addr_t
+iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
+{
+       return txq->scratchbufs_dma +
+              sizeof(struct iwl_pcie_txq_scratch_buf) * idx;
+}
+
 /**
  * struct iwl_trans_pcie - PCIe transport specific data
  * @rxq: all the RX queue data
index b0ae06d2456f1c388ba47fcdbb88f74063ea1162..567e67ad1f617682cbba7a90f2ca95e53eb07eea 100644 (file)
@@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
                index = SEQ_TO_INDEX(sequence);
                cmd_index = get_cmd_index(&txq->q, index);
 
-               if (reclaim) {
-                       struct iwl_pcie_txq_entry *ent;
-                       ent = &txq->entries[cmd_index];
-                       cmd = ent->copy_cmd;
-                       WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
-               } else {
+               if (reclaim)
+                       cmd = txq->entries[cmd_index].cmd;
+               else
                        cmd = NULL;
-               }
 
                err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
 
                if (reclaim) {
-                       /* The original command isn't needed any more */
-                       kfree(txq->entries[cmd_index].copy_cmd);
-                       txq->entries[cmd_index].copy_cmd = NULL;
-                       /* nor is the duplicated part of the command */
                        kfree(txq->entries[cmd_index].free_buf);
                        txq->entries[cmd_index].free_buf = NULL;
                }
index 8e9e3212fe784bcc8c3aea8007111669bee2441b..8595c16f74deb8bdcf531725e3c65c0986d58745 100644 (file)
@@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
        }
 
        for (i = q->read_ptr; i != q->write_ptr;
-            i = iwl_queue_inc_wrap(i, q->n_bd)) {
-               struct iwl_tx_cmd *tx_cmd =
-                       (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
+            i = iwl_queue_inc_wrap(i, q->n_bd))
                IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
-                       get_unaligned_le32(&tx_cmd->scratch));
-       }
+                       le32_to_cpu(txq->scratchbufs[i].scratch));
 
        iwl_op_mode_nic_error(trans->op_mode);
 }
@@ -367,8 +364,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd)
 }
 
 static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
-                              struct iwl_cmd_meta *meta, struct iwl_tfd *tfd,
-                              enum dma_data_direction dma_dir)
+                              struct iwl_cmd_meta *meta,
+                              struct iwl_tfd *tfd)
 {
        int i;
        int num_tbs;
@@ -382,17 +379,12 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
                return;
        }
 
-       /* Unmap tx_cmd */
-       if (num_tbs)
-               dma_unmap_single(trans->dev,
-                               dma_unmap_addr(meta, mapping),
-                               dma_unmap_len(meta, len),
-                               DMA_BIDIRECTIONAL);
+       /* first TB is never freed - it's the scratchbuf data */
 
-       /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
                dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),
-                                iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir);
+                                iwl_pcie_tfd_tb_get_len(tfd, i),
+                                DMA_TO_DEVICE);
 
        tfd->num_tbs = 0;
 }
@@ -406,8 +398,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
  * Does NOT advance any TFD circular buffer read/write indexes
  * Does NOT free the TFD itself (which is within circular buffer)
  */
-static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
-                                 enum dma_data_direction dma_dir)
+static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
 {
        struct iwl_tfd *tfd_tmp = txq->tfds;
 
@@ -418,8 +409,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
        lockdep_assert_held(&txq->lock);
 
        /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
-       iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr],
-                          dma_dir);
+       iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);
 
        /* free SKB */
        if (txq->entries) {
@@ -479,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
+       size_t scratchbuf_sz;
        int i;
 
        if (WARN_ON(txq->entries || txq->tfds))
@@ -514,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
                IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
                goto error;
        }
+
+       BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs));
+       BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) !=
+                       sizeof(struct iwl_cmd_header) +
+                       offsetof(struct iwl_tx_cmd, scratch));
+
+       scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num;
+
+       txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz,
+                                             &txq->scratchbufs_dma,
+                                             GFP_KERNEL);
+       if (!txq->scratchbufs)
+               goto err_free_tfds;
+
        txq->q.id = txq_id;
 
        return 0;
+err_free_tfds:
+       dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr);
 error:
        if (txq->entries && txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < slots_num; i++)
@@ -565,22 +572,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_txq *txq = &trans_pcie->txq[txq_id];
        struct iwl_queue *q = &txq->q;
-       enum dma_data_direction dma_dir;
 
        if (!q->n_bd)
                return;
 
-       /* In the command queue, all the TBs are mapped as BIDI
-        * so unmap them as such.
-        */
-       if (txq_id == trans_pcie->cmd_queue)
-               dma_dir = DMA_BIDIRECTIONAL;
-       else
-               dma_dir = DMA_TO_DEVICE;
-
        spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
-               iwl_pcie_txq_free_tfd(trans, txq, dma_dir);
+               iwl_pcie_txq_free_tfd(trans, txq);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
        spin_unlock_bh(&txq->lock);
@@ -610,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
        if (txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < txq->q.n_window; i++) {
                        kfree(txq->entries[i].cmd);
-                       kfree(txq->entries[i].copy_cmd);
                        kfree(txq->entries[i].free_buf);
                }
 
@@ -619,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
                dma_free_coherent(dev, sizeof(struct iwl_tfd) *
                                  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
                txq->q.dma_addr = 0;
+
+               dma_free_coherent(dev,
+                                 sizeof(*txq->scratchbufs) * txq->q.n_window,
+                                 txq->scratchbufs, txq->scratchbufs_dma);
        }
 
        kfree(txq->entries);
@@ -962,7 +963,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
 
                iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
 
-               iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE);
+               iwl_pcie_txq_free_tfd(trans, txq);
        }
 
        iwl_pcie_txq_progress(trans_pcie, txq);
@@ -1152,20 +1153,37 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
        void *dup_buf = NULL;
        dma_addr_t phys_addr;
        int idx;
-       u16 copy_size, cmd_size;
+       u16 copy_size, cmd_size, scratch_size;
        bool had_nocopy = false;
        int i;
        u32 cmd_pos;
+       const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
+       u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
 
        copy_size = sizeof(out_cmd->hdr);
        cmd_size = sizeof(out_cmd->hdr);
 
        /* need one for the header if the first is NOCOPY */
-       BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
+       BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);
+
+       for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
+               cmddata[i] = cmd->data[i];
+               cmdlen[i] = cmd->len[i];
 
-       for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
                if (!cmd->len[i])
                        continue;
+
+               /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
+               if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
+                       int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
+
+                       if (copy > cmdlen[i])
+                               copy = cmdlen[i];
+                       cmdlen[i] -= copy;
+                       cmddata[i] += copy;
+                       copy_size += copy;
+               }
+
                if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
                        had_nocopy = true;
                        if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
@@ -1185,7 +1203,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                                goto free_dup_buf;
                        }
 
-                       dup_buf = kmemdup(cmd->data[i], cmd->len[i],
+                       dup_buf = kmemdup(cmddata[i], cmdlen[i],
                                          GFP_ATOMIC);
                        if (!dup_buf)
                                return -ENOMEM;
@@ -1195,7 +1213,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                                idx = -EINVAL;
                                goto free_dup_buf;
                        }
-                       copy_size += cmd->len[i];
+                       copy_size += cmdlen[i];
                }
                cmd_size += cmd->len[i];
        }
@@ -1242,30 +1260,30 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
 
        /* and copy the data that needs to be copied */
        cmd_pos = offsetof(struct iwl_device_cmd, payload);
-       for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
-               if (!cmd->len[i])
+       copy_size = sizeof(out_cmd->hdr);
+       for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
+               int copy = 0;
+
+               if (!cmd->len)
                        continue;
-               if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
-                                        IWL_HCMD_DFL_DUP))
-                       break;
-               memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
-               cmd_pos += cmd->len[i];
-       }
 
-       WARN_ON_ONCE(txq->entries[idx].copy_cmd);
+               /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
+               if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
+                       copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
 
-       /*
-        * since out_cmd will be the source address of the FH, it will write
-        * the retry count there. So when the user needs to receivce the HCMD
-        * that corresponds to the response in the response handler, it needs
-        * to set CMD_WANT_HCMD.
-        */
-       if (cmd->flags & CMD_WANT_HCMD) {
-               txq->entries[idx].copy_cmd =
-                       kmemdup(out_cmd, cmd_pos, GFP_ATOMIC);
-               if (unlikely(!txq->entries[idx].copy_cmd)) {
-                       idx = -ENOMEM;
-                       goto out;
+                       if (copy > cmd->len[i])
+                               copy = cmd->len[i];
+               }
+
+               /* copy everything if not nocopy/dup */
+               if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+                                          IWL_HCMD_DFL_DUP)))
+                       copy = cmd->len[i];
+
+               if (copy) {
+                       memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
+                       cmd_pos += copy;
+                       copy_size += copy;
                }
        }
 
@@ -1275,22 +1293,35 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                     out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
                     cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
 
-       phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
-                                  DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
-               idx = -ENOMEM;
-               goto out;
-       }
-
-       dma_unmap_addr_set(out_meta, mapping, phys_addr);
-       dma_unmap_len_set(out_meta, len, copy_size);
+       /* start the TFD with the scratchbuf */
+       scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);
+       memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
+       iwl_pcie_txq_build_tfd(trans, txq,
+                              iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
+                              scratch_size, 1);
+
+       /* map first command fragment, if any remains */
+       if (copy_size > scratch_size) {
+               phys_addr = dma_map_single(trans->dev,
+                                          ((u8 *)&out_cmd->hdr) + scratch_size,
+                                          copy_size - scratch_size,
+                                          DMA_TO_DEVICE);
+               if (dma_mapping_error(trans->dev, phys_addr)) {
+                       iwl_pcie_tfd_unmap(trans, out_meta,
+                                          &txq->tfds[q->write_ptr]);
+                       idx = -ENOMEM;
+                       goto out;
+               }
 
-       iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
+               iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
+                                      copy_size - scratch_size, 0);
+       }
 
-       for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
-               const void *data = cmd->data[i];
+       /* map the remaining (adjusted) nocopy/dup fragments */
+       for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
+               const void *data = cmddata[i];
 
-               if (!cmd->len[i])
+               if (!cmdlen[i])
                        continue;
                if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
                                           IWL_HCMD_DFL_DUP)))
@@ -1298,16 +1329,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
                        data = dup_buf;
                phys_addr = dma_map_single(trans->dev, (void *)data,
-                                          cmd->len[i], DMA_BIDIRECTIONAL);
+                                          cmdlen[i], DMA_TO_DEVICE);
                if (dma_mapping_error(trans->dev, phys_addr)) {
                        iwl_pcie_tfd_unmap(trans, out_meta,
-                                          &txq->tfds[q->write_ptr],
-                                          DMA_BIDIRECTIONAL);
+                                          &txq->tfds[q->write_ptr]);
                        idx = -ENOMEM;
                        goto out;
                }
 
-               iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
+               iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
        }
 
        out_meta->flags = cmd->flags;
@@ -1317,8 +1347,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
 
        txq->need_update = 1;
 
-       trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
-                              &out_cmd->hdr, copy_size);
+       trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
 
        /* start timer if queue currently empty */
        if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
@@ -1377,7 +1406,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
        cmd = txq->entries[cmd_index].cmd;
        meta = &txq->entries[cmd_index].meta;
 
-       iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
+       iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]);
 
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
@@ -1556,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        struct iwl_cmd_meta *out_meta;
        struct iwl_txq *txq;
        struct iwl_queue *q;
-       dma_addr_t phys_addr = 0;
-       dma_addr_t txcmd_phys;
-       dma_addr_t scratch_phys;
-       u16 len, firstlen, secondlen;
+       dma_addr_t tb0_phys, tb1_phys, scratch_phys;
+       void *tb1_addr;
+       u16 len, tb1_len, tb2_len;
        u8 wait_write_ptr = 0;
        __le16 fc = hdr->frame_control;
        u8 hdr_len = ieee80211_hdrlen(fc);
@@ -1597,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
                            INDEX_TO_SEQ(q->write_ptr)));
 
+       tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);
+       scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
+                      offsetof(struct iwl_tx_cmd, scratch);
+
+       tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
+       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
+
        /* Set up first empty entry in queue's array of Tx/cmd buffers */
        out_meta = &txq->entries[q->write_ptr].meta;
 
        /*
-        * Use the first empty entry in this queue's command buffer array
-        * to contain the Tx command and MAC header concatenated together
-        * (payload data will be in another buffer).
-        * Size of this varies, due to varying MAC header length.
-        * If end is not dword aligned, we'll have 2 extra bytes at the end
-        * of the MAC header (device reads on dword boundaries).
-        * We'll tell device about this padding later.
+        * The second TB (tb1) points to the remainder of the TX command
+        * and the 802.11 header - dword aligned size
+        * (This calculation modifies the TX command, so do it before the
+        * setup of the first TB)
         */
-       len = sizeof(struct iwl_tx_cmd) +
-               sizeof(struct iwl_cmd_header) + hdr_len;
-       firstlen = (len + 3) & ~3;
+       len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
+             hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
+       tb1_len = (len + 3) & ~3;
 
        /* Tell NIC about any 2-byte padding after MAC header */
-       if (firstlen != len)
+       if (tb1_len != len)
                tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
 
-       /* Physical address of this Tx command's header (not MAC header!),
-        * within command buffer array. */
-       txcmd_phys = dma_map_single(trans->dev,
-                                   &dev_cmd->hdr, firstlen,
-                                   DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
-               goto out_err;
-       dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
-       dma_unmap_len_set(out_meta, len, firstlen);
+       /* The first TB points to the scratchbuf data - min_copy bytes */
+       memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
+              IWL_HCMD_SCRATCHBUF_SIZE);
+       iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
+                              IWL_HCMD_SCRATCHBUF_SIZE, 1);
 
-       if (!ieee80211_has_morefrags(fc)) {
-               txq->need_update = 1;
-       } else {
-               wait_write_ptr = 1;
-               txq->need_update = 0;
-       }
+       /* there must be data left over for TB1 or this code must be changed */
+       BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
+
+       /* map the data for TB1 */
+       tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;
+       tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
+               goto out_err;
+       iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);
 
-       /* Set up TFD's 2nd entry to point directly to remainder of skb,
-        * if any (802.11 null frames have no payload). */
-       secondlen = skb->len - hdr_len;
-       if (secondlen > 0) {
-               phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
-                                          secondlen, DMA_TO_DEVICE);
-               if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
-                       dma_unmap_single(trans->dev,
-                                        dma_unmap_addr(out_meta, mapping),
-                                        dma_unmap_len(out_meta, len),
-                                        DMA_BIDIRECTIONAL);
+       /*
+        * Set up TFD's third entry to point directly to remainder
+        * of skb, if any (802.11 null frames have no payload).
+        */
+       tb2_len = skb->len - hdr_len;
+       if (tb2_len > 0) {
+               dma_addr_t tb2_phys = dma_map_single(trans->dev,
+                                                    skb->data + hdr_len,
+                                                    tb2_len, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {
+                       iwl_pcie_tfd_unmap(trans, out_meta,
+                                          &txq->tfds[q->write_ptr]);
                        goto out_err;
                }
+               iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);
        }
 
-       /* Attach buffers to TFD */
-       iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);
-       if (secondlen > 0)
-               iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);
-
-       scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
-                               offsetof(struct iwl_tx_cmd, scratch);
-
-       /* take back ownership of DMA buffer to enable update */
-       dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
-                               DMA_BIDIRECTIONAL);
-       tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
-       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
-
        /* Set up entry for this TFD in Tx byte-count array */
        iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
 
-       dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
-                                  DMA_BIDIRECTIONAL);
-
        trace_iwlwifi_dev_tx(trans->dev, skb,
                             &txq->tfds[txq->q.write_ptr],
                             sizeof(struct iwl_tfd),
-                            &dev_cmd->hdr, firstlen,
-                            skb->data + hdr_len, secondlen);
+                            &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
+                            skb->data + hdr_len, tb2_len);
        trace_iwlwifi_dev_tx_data(trans->dev, skb,
-                                 skb->data + hdr_len, secondlen);
+                                 skb->data + hdr_len, tb2_len);
+
+       if (!ieee80211_has_morefrags(fc)) {
+               txq->need_update = 1;
+       } else {
+               wait_write_ptr = 1;
+               txq->need_update = 0;
+       }
 
        /* start timer if queue currently empty */
        if (txq->need_update && q->read_ptr == q->write_ptr &&
index 739309e70d8be7872e9272c9e25dcb7e3a5b2a4a..45578335e4200f2f47a3fc8284f9bd09127209ee 100644 (file)
@@ -825,6 +825,11 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
 
        sdio_release_host(func);
 
+       /* Set fw_ready before queuing any commands so that
+        * lbs_thread won't block from sending them to firmware.
+        */
+       priv->fw_ready = 1;
+
        /*
         * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
         */
@@ -839,7 +844,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
                        netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
        }
 
-       priv->fw_ready = 1;
        wake_up(&card->pwron_waitq);
 
        if (!card->started) {
index 20a6c55558737b3bc3e3968856c5fe827780c688..b5c8b962ce12f74077fb6159b3e8558f521f10a5 100644 (file)
@@ -157,6 +157,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
                return -1;
        }
 
+       cmd_code = le16_to_cpu(host_cmd->command);
+       cmd_size = le16_to_cpu(host_cmd->size);
+
+       if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET &&
+           cmd_code != HostCmd_CMD_FUNC_SHUTDOWN &&
+           cmd_code != HostCmd_CMD_FUNC_INIT) {
+               dev_err(adapter->dev,
+                       "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
+                       cmd_code);
+               mwifiex_complete_cmd(adapter, cmd_node);
+               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+               return -1;
+       }
+
        /* Set command sequence number */
        adapter->seq_num++;
        host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
@@ -168,9 +182,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
        adapter->curr_cmd = cmd_node;
        spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
 
-       cmd_code = le16_to_cpu(host_cmd->command);
-       cmd_size = le16_to_cpu(host_cmd->size);
-
        /* Adjust skb length */
        if (cmd_node->cmd_skb->len > cmd_size)
                /*
@@ -484,8 +495,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
 
        ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
                                     data_buf);
-       if (!ret)
-               ret = mwifiex_wait_queue_complete(adapter);
 
        return ret;
 }
@@ -588,9 +597,10 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
        if (cmd_no == HostCmd_CMD_802_11_SCAN) {
                mwifiex_queue_scan_cmd(priv, cmd_node);
        } else {
-               adapter->cmd_queued = cmd_node;
                mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
                queue_work(adapter->workqueue, &adapter->main_work);
+               if (cmd_node->wait_q_enabled)
+                       ret = mwifiex_wait_queue_complete(adapter, cmd_node);
        }
 
        return ret;
index e38aa9b3663d0a76c0cfe1c7f0698f923fc58587..0ff4c37ab42ae6853dbe6c85f8bb33f476b531e1 100644 (file)
@@ -709,6 +709,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
                return ret;
        }
 
+       /* cancel current command */
+       if (adapter->curr_cmd) {
+               dev_warn(adapter->dev, "curr_cmd is still in processing\n");
+               del_timer(&adapter->cmd_timer);
+               mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+               adapter->curr_cmd = NULL;
+       }
+
        /* shut down mwifiex */
        dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
 
index 246aa62a48172d849cff8bd3d42947b28d7803a0..2fe0ceba4400ad017d99ca5324707aa96093d6be 100644 (file)
@@ -1117,10 +1117,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
                adhoc_join->bss_descriptor.bssid,
                adhoc_join->bss_descriptor.ssid);
 
-       for (i = 0; bss_desc->supported_rates[i] &&
-                       i < MWIFIEX_SUPPORTED_RATES;
-                       i++)
-                       ;
+       for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
+                   bss_desc->supported_rates[i]; i++)
+               ;
        rates_size = i;
 
        /* Copy Data Rates from the Rates recorded in scan response */
index 553adfb0aa81a35c468e44a07943b3f8fdf6e79e..7035ade9af74aeb08ceeea6b1545b28bd8e105d9 100644 (file)
@@ -723,7 +723,6 @@ struct mwifiex_adapter {
        u16 cmd_wait_q_required;
        struct mwifiex_wait_queue cmd_wait_q;
        u8 scan_wait_q_woken;
-       struct cmd_ctrl_node *cmd_queued;
        spinlock_t queue_lock;          /* lock for tx queues */
        struct completion fw_load;
        u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
@@ -1018,7 +1017,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
                        struct mwifiex_multicast_list *mcast_list);
 int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
                            struct net_device *dev);
-int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
+                               struct cmd_ctrl_node *cmd_queued);
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                      struct cfg80211_ssid *req_ssid);
 int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
index 35c79722c361f0e6165071e986af4c5e3f3b8ea3..5c395e2e6a2b874fb0257424663a73cb7abf0c17 100644 (file)
@@ -302,7 +302,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
                i++;
                usleep_range(10, 20);
                /* 50ms max wait */
-               if (i == 50000)
+               if (i == 5000)
                        break;
        }
 
index bb60c2754a97ea54cc8c709206ba31a861e05d2e..d215b4d3c51b57db90eee2293f6c153059fe037b 100644 (file)
@@ -1388,10 +1388,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
                        list_del(&cmd_node->list);
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
-                       adapter->cmd_queued = cmd_node;
                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
                                                        true);
                        queue_work(adapter->workqueue, &adapter->main_work);
+
+                       /* Perform internal scan synchronously */
+                       if (!priv->scan_request)
+                               mwifiex_wait_queue_complete(adapter, cmd_node);
                } else {
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
@@ -1946,9 +1949,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
                /* Normal scan */
                ret = mwifiex_scan_networks(priv, NULL);
 
-       if (!ret)
-               ret = mwifiex_wait_queue_complete(priv->adapter);
-
        up(&priv->async_sem);
 
        return ret;
index 9f33c92c90f5b8dc32bf9685bd3b708171b66acc..13100f8de3db1729b613333f16d21438104cd2e0 100644 (file)
@@ -54,16 +54,10 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
  * This function waits on a cmd wait queue. It also cancels the pending
  * request after waking up, in case of errors.
  */
-int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
+                               struct cmd_ctrl_node *cmd_queued)
 {
        int status;
-       struct cmd_ctrl_node *cmd_queued;
-
-       if (!adapter->cmd_queued)
-               return 0;
-
-       cmd_queued = adapter->cmd_queued;
-       adapter->cmd_queued = NULL;
 
        dev_dbg(adapter->dev, "cmd pending\n");
        atomic_inc(&adapter->cmd_pending);
index 3109c0db66e1167e8dffa94582a0c594a7c608da..a6f660c0190248a0095053b6a04087f138a1a325 100644 (file)
@@ -2778,7 +2778,7 @@ static ssize_t int_proc_write(struct file *file, const char __user *buffer,
                nr = nr * 10 + c;
                p++;
        } while (--len);
-       *(int *)PDE(file_inode(file))->data = nr;
+       *(int *)PDE_DATA(file_inode(file)) = nr;
        return count;
 }
 
index 44d6ead433411eeddc801dc8e1eea0cce40d67e4..2bf4efa331867acaea139bb81dcca75a66532ef4 100644 (file)
@@ -55,10 +55,10 @@ config RT61PCI
 
 config RT2800PCI
        tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
-       depends on PCI || RALINK_RT288X || RALINK_RT305X
+       depends on PCI || SOC_RT288X || SOC_RT305X
        select RT2800_LIB
        select RT2X00_LIB_PCI if PCI
-       select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
+       select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
        select RT2X00_LIB_FIRMWARE
        select RT2X00_LIB_CRYPTO
        select CRC_CCITT
index 48a01aa21f1c94039d9485d5e635926d58a17750..ded73da4de0b0d52cd6331d837c8c68e86b87749 100644 (file)
@@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
        rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 }
 
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 {
        void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
@@ -107,7 +107,7 @@ static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 {
        return -ENOMEM;
 }
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
+#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
 
 #ifdef CONFIG_PCI
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -1177,7 +1177,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 #endif /* CONFIG_PCI */
 MODULE_LICENSE("GPL");
 
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 static int rt2800soc_probe(struct platform_device *pdev)
 {
        return rt2x00soc_probe(pdev, &rt2800pci_ops);
@@ -1194,7 +1194,7 @@ static struct platform_driver rt2800soc_driver = {
        .suspend        = rt2x00soc_suspend,
        .resume         = rt2x00soc_resume,
 };
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
+#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
 
 #ifdef CONFIG_PCI
 static int rt2800pci_probe(struct pci_dev *pci_dev,
@@ -1217,7 +1217,7 @@ static int __init rt2800pci_init(void)
 {
        int ret = 0;
 
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
        ret = platform_driver_register(&rt2800soc_driver);
        if (ret)
                return ret;
@@ -1225,7 +1225,7 @@ static int __init rt2800pci_init(void)
 #ifdef CONFIG_PCI
        ret = pci_register_driver(&rt2800pci_driver);
        if (ret) {
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
                platform_driver_unregister(&rt2800soc_driver);
 #endif
                return ret;
@@ -1240,7 +1240,7 @@ static void __exit rt2800pci_exit(void)
 #ifdef CONFIG_PCI
        pci_unregister_driver(&rt2800pci_driver);
 #endif
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
        platform_driver_unregister(&rt2800soc_driver);
 #endif
 }
index 1031db66474a6403e67ab5a8f5789820343ac1a6..189744db65e073ec96ff396d7ae8fee46a3c3fcd 100644 (file)
@@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
         */
        if_limit = &rt2x00dev->if_limits_ap;
        if_limit->max = rt2x00dev->ops->max_ap_intf;
-       if_limit->types = BIT(NL80211_IFTYPE_AP) |
-                       BIT(NL80211_IFTYPE_MESH_POINT);
+       if_limit->types = BIT(NL80211_IFTYPE_AP);
+#ifdef CONFIG_MAC80211_MESH
+       if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
+#endif
 
        /*
         * Build up AP interface combinations structure.
@@ -1309,7 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
                rt2x00dev->hw->wiphy->interface_modes |=
                    BIT(NL80211_IFTYPE_ADHOC) |
                    BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
                    BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
                    BIT(NL80211_IFTYPE_WDS);
 
        rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
index b1ccff474c7953f2431cb2cd0390f2e0ebf89591..c08d0f4c5f3d3fe8416195951ea6547a80429030 100644 (file)
@@ -1376,75 +1376,58 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw)
 }
 
 void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
-{
-       /* dummy routine needed for callback from rtl_op_configure_filter() */
-}
-
-/*========================================================================== */
-
-static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw,
-                             enum nl80211_iftype type)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
-       struct rtl_phy *rtlphy = &(rtlpriv->phy);
-       u8 filterout_non_associated_bssid = false;
+       u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
 
-       switch (type) {
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_STATION:
-               filterout_non_associated_bssid = true;
-               break;
-       case NL80211_IFTYPE_UNSPECIFIED:
-       case NL80211_IFTYPE_AP:
-       default:
-               break;
-       }
-       if (filterout_non_associated_bssid) {
+       if (rtlpriv->psc.rfpwr_state != ERFON)
+               return;
+
+       if (check_bssid) {
+               u8 tmp;
                if (IS_NORMAL_CHIP(rtlhal->version)) {
-                       switch (rtlphy->current_io_type) {
-                       case IO_CMD_RESUME_DM_BY_SCAN:
-                               reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
-                               rtlpriv->cfg->ops->set_hw_reg(hw,
-                                                HW_VAR_RCR, (u8 *)(&reg_rcr));
-                               /* enable update TSF */
-                               _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
-                               break;
-                       case IO_CMD_PAUSE_DM_BY_SCAN:
-                               reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
-                               rtlpriv->cfg->ops->set_hw_reg(hw,
-                                                HW_VAR_RCR, (u8 *)(&reg_rcr));
-                               /* disable update TSF */
-                               _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
-                               break;
-                       }
+                       reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+                       tmp = BIT(4);
                } else {
-                       reg_rcr |= (RCR_CBSSID);
-                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
-                                                     (u8 *)(&reg_rcr));
-                       _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5)));
+                       reg_rcr |= RCR_CBSSID;
+                       tmp = BIT(4) | BIT(5);
                }
-       } else if (filterout_non_associated_bssid == false) {
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+                                             (u8 *) (&reg_rcr));
+               _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
+       } else {
+               u8 tmp;
                if (IS_NORMAL_CHIP(rtlhal->version)) {
-                       reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
-                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
-                                                     (u8 *)(&reg_rcr));
-                       _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
+                       reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+                       tmp = BIT(4);
                } else {
-                       reg_rcr &= (~RCR_CBSSID);
-                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
-                                                     (u8 *)(&reg_rcr));
-                       _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0);
+                       reg_rcr &= ~RCR_CBSSID;
+                       tmp = BIT(4) | BIT(5);
                }
+               reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                                             HW_VAR_RCR, (u8 *) (&reg_rcr));
+               _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
        }
 }
 
+/*========================================================================== */
+
 int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 {
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
        if (_rtl92cu_set_media_status(hw, type))
                return -EOPNOTSUPP;
-       _rtl92cu_set_check_bssid(hw, type);
+
+       if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+               if (type != NL80211_IFTYPE_AP)
+                       rtl92cu_set_check_bssid(hw, true);
+       } else {
+               rtl92cu_set_check_bssid(hw, false);
+       }
+
        return 0;
 }
 
@@ -2058,8 +2041,6 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
                               (shortgi_rate << 4) | (shortgi_rate);
        }
        rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
-                rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
index 156b52732f3d576cb458bc3f6b3e2eb2818f2d90..5847d6d0881e7ce30180d26cc275425c55eda76b 100644 (file)
@@ -851,6 +851,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
        if (unlikely(!_urb)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                         "Can't allocate urb. Drop skb!\n");
+               kfree_skb(skb);
                return;
        }
        _rtl_submit_tx_urb(hw, _urb);
index 44d01afafe9c2633e1008b8c4d9be9a2a979cf48..43926cd25ae81fbef6ea0d72e10b95466621ee5b 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/hwtest.h>
-#include <linux/proc_fs.h>
 #include <asm/mac_via.h>
 #include <asm/mac_oss.h>
 
@@ -954,56 +953,6 @@ void __init nubus_probe_slot(int slot)
        }
 }
 
-#if defined(CONFIG_PROC_FS)
-
-/* /proc/nubus stuff */
-
-static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len)
-{
-       if(len < 100)
-               return -1;
-       
-       sprintf(ptr, "Slot %X: %s\n",
-               board->slot, board->name);
-       
-       return strlen(ptr);
-}
-
-static int nubus_read_proc(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
-{
-       int nprinted, len, begin = 0;
-       int size = PAGE_SIZE;
-       struct nubus_board* board;
-       
-       len   = sprintf(page, "Nubus devices found:\n");
-       /* Walk the list of NuBus boards */
-       for (board = nubus_boards; board != NULL; board = board->next)
-       {
-               nprinted = sprint_nubus_board(board, page + len, size - len);
-               if (nprinted < 0)
-                       break;
-               len += nprinted;
-               if (len+begin < off) {
-                       begin += len;
-                       len = 0;
-               }
-               if (len+begin >= off+count)
-                       break;
-       }
-       if (len+begin < off)
-               *eof = 1;
-       off -= begin;
-       *start = page + off;
-       len -= off;
-       if (len>count)
-               len = count;
-       if (len<0)
-               len = 0;
-       return len;
-}
-#endif
-
 void __init nubus_scan_bus(void)
 {
        int slot;
@@ -1041,11 +990,7 @@ static int __init nubus_init(void)
        nubus_devices = NULL;
        nubus_boards  = NULL;
        nubus_scan_bus();
-
-#ifdef CONFIG_PROC_FS
-       create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
        nubus_proc_init();
-#endif
        return 0;
 }
 
index 208dd12825bc4314be4bbba70a9c898d8b99ae92..b8286ed65919304c8960488c2c0c3a457bbfcf40 100644 (file)
@@ -52,7 +52,6 @@ static int nubus_devices_proc_open(struct inode *inode, struct file *file)
 }
 
 static const struct file_operations nubus_devices_proc_fops = {
-       .owner          = THIS_MODULE,
        .open           = nubus_devices_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -61,6 +60,10 @@ static const struct file_operations nubus_devices_proc_fops = {
 
 static struct proc_dir_entry *proc_bus_nubus_dir;
 
+static const struct file_operations nubus_proc_subdir_fops = {
+#warning Need to set some I/O handlers here
+};
+
 static void nubus_proc_subdir(struct nubus_dev* dev,
                              struct proc_dir_entry* parent,
                              struct nubus_dir* dir)
@@ -73,9 +76,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev,
                struct proc_dir_entry* e;
                
                sprintf(name, "%x", ent.type);
-               e = create_proc_entry(name, S_IFREG | S_IRUGO |
-                                     S_IWUSR, parent);
-               if (!e) return;
+               e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent,
+                               &nubus_proc_subdir_fops);
+               if (!e)
+                       return;
        }
 }
 
@@ -158,6 +162,73 @@ int nubus_proc_detach_device(struct nubus_dev *dev)
 }
 EXPORT_SYMBOL(nubus_proc_detach_device);
 
+/*
+ * /proc/nubus stuff
+ */
+static int nubus_proc_show(struct seq_file *m, void *v)
+{
+       const struct nubus_board *board = v;
+
+       /* Display header on line 1 */
+       if (v == SEQ_START_TOKEN)
+               seq_puts(m, "Nubus devices found:\n");
+       else
+               seq_printf(m, "Slot %X: %s\n", board->slot, board->name);
+       return 0;
+}
+
+static void *nubus_proc_start(struct seq_file *m, loff_t *_pos)
+{
+       struct nubus_board *board;
+       unsigned pos;
+
+       if (*_pos > LONG_MAX)
+               return NULL;
+       pos = *_pos;
+       if (pos == 0)
+               return SEQ_START_TOKEN;
+       for (board = nubus_boards; board; board = board->next)
+               if (--pos == 0)
+                       break;
+       return board;
+}
+
+static void *nubus_proc_next(struct seq_file *p, void *v, loff_t *_pos)
+{
+       /* Walk the list of NuBus boards */
+       struct nubus_board *board = v;
+
+       ++*_pos;
+       if (v == SEQ_START_TOKEN)
+               board = nubus_boards;
+       else if (board)
+               board = board->next;
+       return board;
+}
+
+static void nubus_proc_stop(struct seq_file *p, void *v)
+{
+}
+
+static const struct seq_operations nubus_proc_seqops = {
+       .start  = nubus_proc_start,
+       .next   = nubus_proc_next,
+       .stop   = nubus_proc_stop,
+       .show   = nubus_proc_show,
+};
+
+static int nubus_proc_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &nubus_proc_seqops);
+}
+
+static const struct file_operations nubus_proc_fops = {
+       .open           = nubus_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 void __init proc_bus_nubus_add_devices(void)
 {
        struct nubus_dev *dev;
@@ -168,6 +239,7 @@ void __init proc_bus_nubus_add_devices(void)
 
 void __init nubus_proc_init(void)
 {
+       proc_create("nubus", 0, NULL, &nubus_proc_fops);
        if (!MACH_IS_MAC)
                return;
        proc_bus_nubus_dir = proc_mkdir("bus/nubus", NULL);
index 321d3ef050065e12b2d639e02fada00ec6b9e658..9c704369eda858644b49d39166205883bb0789a6 100644 (file)
@@ -1452,16 +1452,7 @@ int of_attach_node(struct device_node *np)
 #ifdef CONFIG_PROC_DEVICETREE
 static void of_remove_proc_dt_entry(struct device_node *dn)
 {
-       struct device_node *parent = dn->parent;
-       struct property *prop = dn->properties;
-
-       while (prop) {
-               remove_proc_entry(prop->name, dn->pde);
-               prop = prop->next;
-       }
-
-       if (dn->pde)
-               remove_proc_entry(dn->pde->name, parent->pde);
+       proc_remove(dn->pde);
 }
 #else
 static void of_remove_proc_dt_entry(struct device_node *dn)
index 445ffda715ade70884bf52dda1bd3e0391b6bd5a..7c12d9c2b23010a54c2752a0abac70b1bcf17735 100644 (file)
@@ -276,6 +276,7 @@ static struct file_system_type oprofilefs_type = {
        .mount          = oprofilefs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("oprofilefs");
 
 
 int __init oprofilefs_register(void)
index d4d800c54d862089a0c52ed2e9eb63c69785b1ba..b48243131993a6faddff840551c93a86b53ffec1 100644 (file)
@@ -172,14 +172,14 @@ static int led_proc_show(struct seq_file *m, void *v)
 
 static int led_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, led_proc_show, PDE(inode)->data);
+       return single_open(file, led_proc_show, PDE_DATA(inode));
 }
 
 
 static ssize_t led_proc_write(struct file *file, const char *buf,
        size_t count, loff_t *pos)
 {
-       void *data = PDE(file_inode(file))->data;
+       void *data = PDE_DATA(file_inode(file));
        char *cur, lbuf[32];
        int d;
 
index 39c937f9b426ef392e3820ee2c7f69e128da403e..dee5dddaa292a04ad2200c005ad59b959ed5ad7e 100644 (file)
@@ -331,8 +331,14 @@ static void pci_acpi_cleanup(struct device *dev)
        }
 }
 
+static bool pci_acpi_bus_match(struct device *dev)
+{
+       return dev->bus == &pci_bus_type;
+}
+
 static struct acpi_bus_type acpi_pci_bus = {
-       .bus = &pci_bus_type,
+       .name = "PCI",
+       .match = pci_acpi_bus_match,
        .find_device = acpi_pci_find_device,
        .setup = pci_acpi_setup,
        .cleanup = pci_acpi_cleanup,
index 0b009470e6db548005b6f66539b18e372e8f2261..08126087ec3125c29de84c5b9e5f68d45d2b0328 100644 (file)
@@ -46,9 +46,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
 static ssize_t
 proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
-       const struct inode *ino = file_inode(file);
-       const struct proc_dir_entry *dp = PDE(ino);
-       struct pci_dev *dev = dp->data;
+       struct pci_dev *dev = PDE_DATA(file_inode(file));
        unsigned int pos = *ppos;
        unsigned int cnt, size;
 
@@ -59,7 +57,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
         */
 
        if (capable(CAP_SYS_ADMIN))
-               size = dp->size;
+               size = dev->cfg_size;
        else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
                size = 128;
        else
@@ -133,10 +131,9 @@ static ssize_t
 proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos)
 {
        struct inode *ino = file_inode(file);
-       const struct proc_dir_entry *dp = PDE(ino);
-       struct pci_dev *dev = dp->data;
+       struct pci_dev *dev = PDE_DATA(ino);
        int pos = *ppos;
-       int size = dp->size;
+       int size = dev->cfg_size;
        int cnt;
 
        if (pos >= size)
@@ -200,7 +197,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
        pci_config_pm_runtime_put(dev);
 
        *ppos = pos;
-       i_size_write(ino, dp->size);
+       i_size_write(ino, dev->cfg_size);
        return nbytes;
 }
 
@@ -212,8 +209,7 @@ struct pci_filp_private {
 static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
                               unsigned long arg)
 {
-       const struct proc_dir_entry *dp = PDE(file_inode(file));
-       struct pci_dev *dev = dp->data;
+       struct pci_dev *dev = PDE_DATA(file_inode(file));
 #ifdef HAVE_PCI_MMAP
        struct pci_filp_private *fpriv = file->private_data;
 #endif /* HAVE_PCI_MMAP */
@@ -253,9 +249,7 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
 #ifdef HAVE_PCI_MMAP
 static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct inode *inode = file_inode(file);
-       const struct proc_dir_entry *dp = PDE(inode);
-       struct pci_dev *dev = dp->data;
+       struct pci_dev *dev = PDE_DATA(file_inode(file));
        struct pci_filp_private *fpriv = file->private_data;
        int i, ret;
 
@@ -425,7 +419,7 @@ int pci_proc_attach_device(struct pci_dev *dev)
                             &proc_bus_pci_operations, dev);
        if (!e)
                return -ENOMEM;
-       e->size = dev->cfg_size;
+       proc_set_size(e, dev->cfg_size);
        dev->procent = e;
 
        return 0;
@@ -433,20 +427,14 @@ int pci_proc_attach_device(struct pci_dev *dev)
 
 int pci_proc_detach_device(struct pci_dev *dev)
 {
-       struct proc_dir_entry *e;
-
-       if ((e = dev->procent)) {
-               remove_proc_entry(e->name, dev->bus->procdir);
-               dev->procent = NULL;
-       }
+       proc_remove(dev->procent);
+       dev->procent = NULL;
        return 0;
 }
 
 int pci_proc_detach_bus(struct pci_bus* bus)
 {
-       struct proc_dir_entry *de = bus->procdir;
-       if (de)
-               remove_proc_entry(de->name, proc_bus_pci_dir);
+       proc_remove(bus->procdir);
        return 0;
 }
 
index ab886b7ee327af413f98976382869242fcba679b..b41ac7756a4ba6ff7795804db13db00c6437c662 100644 (file)
@@ -100,6 +100,27 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
        return min((size_t)(image - rom), size);
 }
 
+static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size)
+{
+       struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+       loff_t start;
+
+       /* assign the ROM an address if it doesn't have one */
+       if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE))
+               return 0;
+       start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
+       *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+
+       if (*size == 0)
+               return 0;
+
+       /* Enable ROM space decodes */
+       if (pci_enable_rom(pdev))
+               return 0;
+
+       return start;
+}
+
 /**
  * pci_map_rom - map a PCI ROM to kernel space
  * @pdev: pointer to pci device struct
@@ -114,21 +135,15 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
 {
        struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
-       loff_t start;
+       loff_t start = 0;
        void __iomem *rom;
 
-       /*
-        * Some devices may provide ROMs via a source other than the BAR
-        */
-       if (pdev->rom && pdev->romlen) {
-               *size = pdev->romlen;
-               return phys_to_virt(pdev->rom);
        /*
         * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
         * memory map if the VGA enable bit of the Bridge Control register is
         * set for embedded VGA.
         */
-       } else if (res->flags & IORESOURCE_ROM_SHADOW) {
+       if (res->flags & IORESOURCE_ROM_SHADOW) {
                /* primary video rom always starts here */
                start = (loff_t)0xC0000;
                *size = 0x20000; /* cover C000:0 through E000:0 */
@@ -139,21 +154,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
                        return (void __iomem *)(unsigned long)
                                pci_resource_start(pdev, PCI_ROM_RESOURCE);
                } else {
-                       /* assign the ROM an address if it doesn't have one */
-                       if (res->parent == NULL &&
-                           pci_assign_resource(pdev,PCI_ROM_RESOURCE))
-                               return NULL;
-                       start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
-                       *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-                       if (*size == 0)
-                               return NULL;
-
-                       /* Enable ROM space decodes */
-                       if (pci_enable_rom(pdev))
-                               return NULL;
+                       start = pci_find_rom(pdev, size);
                }
        }
 
+       /*
+        * Some devices may provide ROMs via a source other than the BAR
+        */
+       if (!start && pdev->rom && pdev->romlen) {
+               *size = pdev->romlen;
+               return phys_to_virt(pdev->rom);
+       }
+
+       if (!start)
+               return NULL;
+
        rom = ioremap(start, *size);
        if (!rom) {
                /* restore enable if ioremap fails */
index c689c04a4f523248e9b2712e77d7e041f5b074d7..2d2f0a43d36b409cf287f6d6629b506e517948a9 100644 (file)
@@ -620,7 +620,7 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
 
                /* special soc specific control */
                if (ctrl->mpp_get || ctrl->mpp_set) {
-                       if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) {
+                       if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {
                                dev_err(&pdev->dev, "wrong soc control info\n");
                                return -EINVAL;
                        }
index ac8d382a79bbfe43de8769ea43d1c13ab2fac036..d611ecfcbf70d8401946767f01833069ef60c431 100644 (file)
@@ -622,7 +622,7 @@ static const struct file_operations pinconf_dbg_pinname_fops = {
 static int pinconf_dbg_state_print(struct seq_file *s, void *d)
 {
        if (strlen(dbg_state_name))
-               seq_printf(s, "%s\n", dbg_pinname);
+               seq_printf(s, "%s\n", dbg_state_name);
        else
                seq_printf(s, "No pin state set\n");
        return 0;
index e3ed8cb072a5a4dd410015c66e3202ded90dd49c..bfda73d64eed527b2fce7e0a084b7459943bfb1e 100644 (file)
@@ -90,7 +90,7 @@ static inline void pinconf_init_device_debugfs(struct dentry *devroot,
  * pin config.
  */
 
-#ifdef CONFIG_GENERIC_PINCONF
+#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_DEBUG_FS)
 
 void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
                              struct seq_file *s, unsigned pin);
index caecdd37306126d7352b57365932b00b5e7ac1f2..c542a97c82f37cc743fa9d97e914c13dfe55aaa7 100644 (file)
@@ -422,7 +422,7 @@ static u8 abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
        }
 
        /* check if pin use AlternateFunction register */
-       if ((af.alt_bit1 == UNUSED) && (af.alt_bit1 == UNUSED))
+       if ((af.alt_bit1 == UNUSED) && (af.alt_bit2 == UNUSED))
                return mode;
        /*
         * if pin GPIOSEL bit is set and pin supports alternate function,
index 75933a6aa8284c0cbf466a968ed2c846c7c14d69..efb7f10e902a0e1aa9701ed5506a23d204b1a9df 100644 (file)
@@ -1277,21 +1277,80 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
 }
 
 #ifdef CONFIG_PM
+
+static u32 wakeups[MAX_GPIO_BANKS];
+static u32 backups[MAX_GPIO_BANKS];
+
 static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
 {
        struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
        unsigned        bank = at91_gpio->pioc_idx;
+       unsigned mask = 1 << d->hwirq;
 
        if (unlikely(bank >= MAX_GPIO_BANKS))
                return -EINVAL;
 
+       if (state)
+               wakeups[bank] |= mask;
+       else
+               wakeups[bank] &= ~mask;
+
        irq_set_irq_wake(at91_gpio->pioc_virq, state);
 
        return 0;
 }
+
+void at91_pinctrl_gpio_suspend(void)
+{
+       int i;
+
+       for (i = 0; i < gpio_banks; i++) {
+               void __iomem  *pio;
+
+               if (!gpio_chips[i])
+                       continue;
+
+               pio = gpio_chips[i]->regbase;
+
+               backups[i] = __raw_readl(pio + PIO_IMR);
+               __raw_writel(backups[i], pio + PIO_IDR);
+               __raw_writel(wakeups[i], pio + PIO_IER);
+
+               if (!wakeups[i]) {
+                       clk_unprepare(gpio_chips[i]->clock);
+                       clk_disable(gpio_chips[i]->clock);
+               } else {
+                       printk(KERN_DEBUG "GPIO-%c may wake for %08x\n",
+                              'A'+i, wakeups[i]);
+               }
+       }
+}
+
+void at91_pinctrl_gpio_resume(void)
+{
+       int i;
+
+       for (i = 0; i < gpio_banks; i++) {
+               void __iomem  *pio;
+
+               if (!gpio_chips[i])
+                       continue;
+
+               pio = gpio_chips[i]->regbase;
+
+               if (!wakeups[i]) {
+                       if (clk_prepare(gpio_chips[i]->clock) == 0)
+                               clk_enable(gpio_chips[i]->clock);
+               }
+
+               __raw_writel(wakeups[i], pio + PIO_IDR);
+               __raw_writel(backups[i], pio + PIO_IER);
+       }
+}
+
 #else
 #define gpio_irq_set_wake      NULL
-#endif
+#endif /* CONFIG_PM */
 
 static struct irq_chip gpio_irqchip = {
        .name           = "GPIO",
index 1a00658b3ea070f336333160411f1b01bbc8f96e..bd83c8b01cd102e7c0f194c38389bb4a083c5dec 100644 (file)
@@ -194,6 +194,11 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
        }
 
        if (!gpio_range) {
+               /*
+                * A pin should not be freed more times than allocated.
+                */
+               if (WARN_ON(!desc->mux_usecount))
+                       return NULL;
                desc->mux_usecount--;
                if (desc->mux_usecount)
                        return NULL;
index 93d66809355a203e97b0e4229f5dc2ac932d2e54..3e5b4497a1d02010b4c63bdc939f67127bb19976 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <linux/dmi.h>
 #include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 
 #define ATMEL_TP_I2C_ADDR      0x4b
@@ -67,15 +70,49 @@ static struct i2c_board_info __initdata tsl2563_als_device = {
        I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR),
 };
 
+static struct mxt_platform_data atmel_224s_tp_platform_data = {
+       .x_line                 = 18,
+       .y_line                 = 12,
+       .x_size                 = 102*20,
+       .y_size                 = 68*20,
+       .blen                   = 0x80, /* Gain setting is in upper 4 bits */
+       .threshold              = 0x32,
+       .voltage                = 0,    /* 3.3V */
+       .orient                 = MXT_VERTICAL_FLIP,
+       .irqflags               = IRQF_TRIGGER_FALLING,
+       .is_tp                  = true,
+       .key_map                = { KEY_RESERVED,
+                                   KEY_RESERVED,
+                                   KEY_RESERVED,
+                                   BTN_LEFT },
+       .config                 = NULL,
+       .config_length          = 0,
+};
+
 static struct i2c_board_info __initdata atmel_224s_tp_device = {
        I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR),
-       .platform_data = NULL,
+       .platform_data = &atmel_224s_tp_platform_data,
        .flags          = I2C_CLIENT_WAKE,
 };
 
+static struct mxt_platform_data atmel_1664s_platform_data = {
+       .x_line                 = 32,
+       .y_line                 = 50,
+       .x_size                 = 1700,
+       .y_size                 = 2560,
+       .blen                   = 0x89, /* Gain setting is in upper 4 bits */
+       .threshold              = 0x28,
+       .voltage                = 0,    /* 3.3V */
+       .orient                 = MXT_ROTATED_90_COUNTER,
+       .irqflags               = IRQF_TRIGGER_FALLING,
+       .is_tp                  = false,
+       .config                 = NULL,
+       .config_length          = 0,
+};
+
 static struct i2c_board_info __initdata atmel_1664s_device = {
        I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR),
-       .platform_data = NULL,
+       .platform_data = &atmel_1664s_platform_data,
        .flags          = I2C_CLIENT_WAKE,
 };
 
index 9a907567f41edf495f1c102d906ba63660de082e..05272e676a2813f6cf5ac6ec0ec6ae5388633985 100644 (file)
@@ -844,14 +844,14 @@ static int dispatch_proc_show(struct seq_file *m, void *v)
 
 static int dispatch_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, dispatch_proc_show, PDE(inode)->data);
+       return single_open(file, dispatch_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t dispatch_proc_write(struct file *file,
                        const char __user *userbuf,
                        size_t count, loff_t *pos)
 {
-       struct ibm_struct *ibm = PDE(file_inode(file))->data;
+       struct ibm_struct *ibm = PDE_DATA(file_inode(file));
        char *kernbuf;
        int ret;
 
index 242abac62d8b756547c34ed3bc9793e8edeb9c53..eb3467ea6d860e6c6961f3294922804e0e5776a2 100644 (file)
@@ -553,7 +553,7 @@ static int lcd_proc_show(struct seq_file *m, void *v)
 
 static int lcd_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, lcd_proc_show, PDE(inode)->data);
+       return single_open(file, lcd_proc_show, PDE_DATA(inode));
 }
 
 static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
@@ -583,7 +583,7 @@ static int set_lcd_status(struct backlight_device *bd)
 static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
                              size_t count, loff_t *pos)
 {
-       struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data;
+       struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
        char cmd[42];
        size_t len;
        int value;
@@ -644,13 +644,13 @@ static int video_proc_show(struct seq_file *m, void *v)
 
 static int video_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, video_proc_show, PDE(inode)->data);
+       return single_open(file, video_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t video_proc_write(struct file *file, const char __user *buf,
                                size_t count, loff_t *pos)
 {
-       struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data;
+       struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
        char *cmd, *buffer;
        int ret;
        int value;
@@ -744,13 +744,13 @@ static int fan_proc_show(struct seq_file *m, void *v)
 
 static int fan_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, fan_proc_show, PDE(inode)->data);
+       return single_open(file, fan_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t fan_proc_write(struct file *file, const char __user *buf,
                              size_t count, loff_t *pos)
 {
-       struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data;
+       struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
        char cmd[42];
        size_t len;
        int value;
@@ -816,13 +816,13 @@ static int keys_proc_show(struct seq_file *m, void *v)
 
 static int keys_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, keys_proc_show, PDE(inode)->data);
+       return single_open(file, keys_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t keys_proc_write(struct file *file, const char __user *buf,
                               size_t count, loff_t *pos)
 {
-       struct toshiba_acpi_dev *dev = PDE(file_inode(file))->data;
+       struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
        char cmd[42];
        size_t len;
        int value;
@@ -859,7 +859,7 @@ static int version_proc_show(struct seq_file *m, void *v)
 
 static int version_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, version_proc_show, PDE(inode)->data);
+       return single_open(file, version_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations version_proc_fops = {
index 65f735ac6b3b6115ad0136a48730c0e5ddaa5979..2365ef37ae2466b18620fff5e209c3352a6e08f6 100644 (file)
@@ -55,9 +55,7 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
 static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf,
                                    size_t nbytes, loff_t * ppos)
 {
-       struct inode *ino = file_inode(file);
-       struct proc_dir_entry *dp = PDE(ino);
-       struct pnp_dev *dev = dp->data;
+       struct pnp_dev *dev = PDE_DATA(file_inode(file));
        int pos = *ppos;
        int cnt, size = 256;
 
@@ -107,7 +105,7 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev)
                        &isapnp_proc_bus_file_operations, dev);
        if (!e)
                return -ENOMEM;
-       e->size = 256;
+       proc_set_size(e, 256);
        return 0;
 }
 
index 8813fc03aa099fbb37b3a2321160fef4cdd51ef0..55cd459a39080d6d162074c74772e9850d88c8f1 100644 (file)
@@ -353,8 +353,14 @@ static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle)
 /* complete initialization of a PNPACPI device includes having
  * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
  */
+static bool acpi_pnp_bus_match(struct device *dev)
+{
+       return dev->bus == &pnp_bus_type;
+}
+
 static struct acpi_bus_type __initdata acpi_pnp_bus = {
-       .bus         = &pnp_bus_type,
+       .name        = "PNP",
+       .match       = acpi_pnp_bus_match,
        .find_device = acpi_pnp_find_device,
 };
 
index 63ddb017345631d28ac45b84c764d23a94e5f068..8dafd65d475874ba0d8b8d174cb6abc70fb5c618 100644 (file)
@@ -238,13 +238,13 @@ static int pnpbios_proc_show(struct seq_file *m, void *v)
 
 static int pnpbios_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pnpbios_proc_show, PDE(inode)->data);
+       return single_open(file, pnpbios_proc_show, PDE_DATA(inode));
 }
 
 static ssize_t pnpbios_proc_write(struct file *file, const char __user *buf,
                                  size_t count, loff_t *pos)
 {
-       void *data = PDE(file_inode(file))->data;
+       void *data = PDE_DATA(file_inode(file));
        struct pnp_bios_node *node;
        int boot = (long)data >> 8;
        u8 nodenum = (long)data;
index e1b4705ae3ec83ec1beddfda1dc98d4259bd2a6d..38a8bbe7481008232e7336777850d683afb765be 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 #include <linux/irqnr.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 #include <linux/parport.h>
 #include <linux/pps_kernel.h>
 
index da9782bd27d0a182d32578c4779481072d0657ef..e3661c20cf389fe38bcbb9406f25476aae9d4796 100644 (file)
@@ -2830,7 +2830,7 @@ EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
  * regulator_allow_bypass - allow the regulator to go into bypass mode
  *
  * @regulator: Regulator to configure
- * @allow: enable or disable bypass mode
+ * @enable: enable or disable bypass mode
  *
  * Allow the regulator to go into bypass mode if all other consumers
  * for the regulator also enable bypass mode and the machine
@@ -3057,9 +3057,13 @@ int regulator_bulk_enable(int num_consumers,
        return 0;
 
 err:
-       pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
-       while (--i >= 0)
-               regulator_disable(consumers[i].consumer);
+       for (i = 0; i < num_consumers; i++) {
+               if (consumers[i].ret < 0)
+                       pr_err("Failed to enable %s: %d\n", consumers[i].supply,
+                              consumers[i].ret);
+               else
+                       regulator_disable(consumers[i].consumer);
+       }
 
        return ret;
 }
index 219d162b651e3c75f2077517e5b3e0b69c28100f..a53c11a529d5f65dc55e6790167c4d69f5c68de0 100644 (file)
@@ -528,7 +528,7 @@ static int db8500_regulator_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __exit db8500_regulator_remove(struct platform_device *pdev)
+static int db8500_regulator_remove(struct platform_device *pdev)
 {
        int i;
 
@@ -553,7 +553,7 @@ static struct platform_driver db8500_regulator_driver = {
                .owner = THIS_MODULE,
        },
        .probe = db8500_regulator_probe,
-       .remove = __exit_p(db8500_regulator_remove),
+       .remove = db8500_regulator_remove,
 };
 
 static int __init db8500_regulator_init(void)
index cde13bb5a8fbc4163eb7769b9b7e09e90eaf1d75..39cf14606784bd3571c6aab2d361807d0bdf7c99 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2011-2012 Texas Instruments Inc.
  *
  * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Ian Lartey <ian@slimlogic.co.uk>
  *
  *  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
@@ -156,7 +157,7 @@ static const struct regs_info palmas_regs_info[] = {
  *
  * So they are basically (maxV-minV)/stepV
  */
-#define PALMAS_SMPS_NUM_VOLTAGES       116
+#define PALMAS_SMPS_NUM_VOLTAGES       117
 #define PALMAS_SMPS10_NUM_VOLTAGES     2
 #define PALMAS_LDO_NUM_VOLTAGES                50
 
index 74508cc62d67baafcc39fb3face73f1e7a810d90..f705d25b437ccfc57a144a600d6993ce926869c1 100644 (file)
@@ -471,24 +471,23 @@ twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
                            selector);
 }
 
-static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int             vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
-                                                               VREG_VOLTAGE);
+       int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
 
        if (vsel < 0)
                return vsel;
 
        vsel &= info->table_len - 1;
-       return LDO_MV(info->table[vsel]) * 1000;
+       return vsel;
 }
 
 static struct regulator_ops twl4030ldo_ops = {
        .list_voltage   = twl4030ldo_list_voltage,
 
        .set_voltage_sel = twl4030ldo_set_voltage_sel,
-       .get_voltage    = twl4030ldo_get_voltage,
+       .get_voltage_sel = twl4030ldo_get_voltage_sel,
 
        .enable         = twl4030reg_enable,
        .disable        = twl4030reg_disable,
index 434ebc3a99dc089d10a6d27e5be99faebb28aace..0a9f27e094ea9ea122ec0658c673a3249eb6e04e 100644 (file)
@@ -44,6 +44,7 @@ static DECLARE_COMPLETION(at91_rtc_updated);
 static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
 static void __iomem *at91_rtc_regs;
 static int irq;
+static u32 at91_rtc_imr;
 
 /*
  * Decode time/date into rtc_time structure
@@ -108,9 +109,11 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
        cr = at91_rtc_read(AT91_RTC_CR);
        at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
 
+       at91_rtc_imr |= AT91_RTC_ACKUPD;
        at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD);
        wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */
        at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD);
+       at91_rtc_imr &= ~AT91_RTC_ACKUPD;
 
        at91_rtc_write(AT91_RTC_TIMR,
                          bin2bcd(tm->tm_sec) << 0
@@ -142,7 +145,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
        tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
        tm->tm_year = at91_alarm_year - 1900;
 
-       alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM)
+       alrm->enabled = (at91_rtc_imr & AT91_RTC_ALARM)
                        ? 1 : 0;
 
        dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
@@ -168,6 +171,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
        tm.tm_sec = alrm->time.tm_sec;
 
        at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
+       at91_rtc_imr &= ~AT91_RTC_ALARM;
        at91_rtc_write(AT91_RTC_TIMALR,
                  bin2bcd(tm.tm_sec) << 0
                | bin2bcd(tm.tm_min) << 8
@@ -180,6 +184,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        if (alrm->enabled) {
                at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
+               at91_rtc_imr |= AT91_RTC_ALARM;
                at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
        }
 
@@ -196,9 +201,12 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
        if (enabled) {
                at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
+               at91_rtc_imr |= AT91_RTC_ALARM;
                at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
-       } else
+       } else {
                at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
+               at91_rtc_imr &= ~AT91_RTC_ALARM;
+       }
 
        return 0;
 }
@@ -207,12 +215,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  */
 static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       unsigned long imr = at91_rtc_read(AT91_RTC_IMR);
-
        seq_printf(seq, "update_IRQ\t: %s\n",
-                       (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
+                       (at91_rtc_imr & AT91_RTC_ACKUPD) ? "yes" : "no");
        seq_printf(seq, "periodic_IRQ\t: %s\n",
-                       (imr & AT91_RTC_SECEV) ? "yes" : "no");
+                       (at91_rtc_imr & AT91_RTC_SECEV) ? "yes" : "no");
 
        return 0;
 }
@@ -227,7 +233,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
        unsigned int rtsr;
        unsigned long events = 0;
 
-       rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR);
+       rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_imr;
        if (rtsr) {             /* this interrupt is shared!  Is it ours? */
                if (rtsr & AT91_RTC_ALARM)
                        events |= (RTC_AF | RTC_IRQF);
@@ -291,6 +297,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
        at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
                                        AT91_RTC_SECEV | AT91_RTC_TIMEV |
                                        AT91_RTC_CALEV);
+       at91_rtc_imr = 0;
 
        ret = request_irq(irq, at91_rtc_interrupt,
                                IRQF_SHARED,
@@ -329,6 +336,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
        at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
                                        AT91_RTC_SECEV | AT91_RTC_TIMEV |
                                        AT91_RTC_CALEV);
+       at91_rtc_imr = 0;
        free_irq(irq, pdev);
 
        rtc_device_unregister(rtc);
@@ -341,31 +349,35 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
 
 /* AT91RM9200 RTC Power management control */
 
-static u32 at91_rtc_imr;
+static u32 at91_rtc_bkpimr;
+
 
 static int at91_rtc_suspend(struct device *dev)
 {
        /* this IRQ is shared with DBGU and other hardware which isn't
         * necessarily doing PM like we are...
         */
-       at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR)
-                       & (AT91_RTC_ALARM|AT91_RTC_SECEV);
-       if (at91_rtc_imr) {
-               if (device_may_wakeup(dev))
+       at91_rtc_bkpimr = at91_rtc_imr & (AT91_RTC_ALARM|AT91_RTC_SECEV);
+       if (at91_rtc_bkpimr) {
+               if (device_may_wakeup(dev)) {
                        enable_irq_wake(irq);
-               else
-                       at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr);
-       }
+               } else {
+                       at91_rtc_write(AT91_RTC_IDR, at91_rtc_bkpimr);
+                       at91_rtc_imr &= ~at91_rtc_bkpimr;
+               }
+}
        return 0;
 }
 
 static int at91_rtc_resume(struct device *dev)
 {
-       if (at91_rtc_imr) {
-               if (device_may_wakeup(dev))
+       if (at91_rtc_bkpimr) {
+               if (device_may_wakeup(dev)) {
                        disable_irq_wake(irq);
-               else
-                       at91_rtc_write(AT91_RTC_IER, at91_rtc_imr);
+               } else {
+                       at91_rtc_imr |= at91_rtc_bkpimr;
+                       at91_rtc_write(AT91_RTC_IER, at91_rtc_bkpimr);
+               }
        }
        return 0;
 }
index da1945e5f71449a99dd6ed5baa6a4aec23af7a64..5f940b6844cbfb524de17c1e58cf755f18775bee 100644 (file)
@@ -64,7 +64,6 @@
 #define        AT91_RTC_SCCR           0x1c                    /* Status Clear Command Register */
 #define        AT91_RTC_IER            0x20                    /* Interrupt Enable Register */
 #define        AT91_RTC_IDR            0x24                    /* Interrupt Disable Register */
-#define        AT91_RTC_IMR            0x28                    /* Interrupt Mask Register */
 
 #define        AT91_RTC_VER            0x2c                    /* Valid Entry Register */
 #define                AT91_RTC_NVTIM          (1 <<  0)               /* Non valid Time */
index 0dde688ca09b4785bf6968393f1b1a7579233b8f..969abbad7fe346d0f815c4da6f566b01aeedea45 100644 (file)
@@ -239,11 +239,9 @@ static int da9052_rtc_probe(struct platform_device *pdev)
 
        rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
        platform_set_drvdata(pdev, rtc);
-       rtc->irq = platform_get_irq_byname(pdev, "ALM");
-       ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
-                               da9052_rtc_irq,
-                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                               "ALM", rtc);
+       rtc->irq =  DA9052_IRQ_ALARM;
+       ret = da9052_request_irq(rtc->da9052, rtc->irq, "ALM",
+                               da9052_rtc_irq, rtc);
        if (ret != 0) {
                rtc_err(rtc->da9052, "irq registration failed: %d\n", ret);
                return ret;
index 57233c8859989d15a2a6ce5b041c1363d07374c2..8f87fec27ce78ffa9c191bf104cb9326368f88fc 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 #include <linux/gfp.h>
 #include <linux/module.h>
 
@@ -41,6 +42,7 @@ struct rtc_plat_data {
        struct rtc_device *rtc;
        void __iomem *ioaddr;
        int             irq;
+       struct clk      *clk;
 };
 
 static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -221,6 +223,7 @@ static int mv_rtc_probe(struct platform_device *pdev)
        struct rtc_plat_data *pdata;
        resource_size_t size;
        u32 rtc_time;
+       int ret = 0;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
@@ -239,11 +242,17 @@ static int mv_rtc_probe(struct platform_device *pdev)
        if (!pdata->ioaddr)
                return -ENOMEM;
 
+       pdata->clk = devm_clk_get(&pdev->dev, NULL);
+       /* Not all SoCs require a clock.*/
+       if (!IS_ERR(pdata->clk))
+               clk_prepare_enable(pdata->clk);
+
        /* make sure the 24 hours mode is enabled */
        rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
        if (rtc_time & RTC_HOURS_12H_MODE) {
                dev_err(&pdev->dev, "24 Hours mode not supported.\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        /* make sure it is actually functional */
@@ -252,7 +261,8 @@ static int mv_rtc_probe(struct platform_device *pdev)
                rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
                if (rtc_time == 0x01000000) {
                        dev_err(&pdev->dev, "internal RTC not ticking\n");
-                       return -ENODEV;
+                       ret = -ENODEV;
+                       goto out;
                }
        }
 
@@ -268,8 +278,10 @@ static int mv_rtc_probe(struct platform_device *pdev)
        } else
                pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
                                                 &mv_rtc_ops, THIS_MODULE);
-       if (IS_ERR(pdata->rtc))
-               return PTR_ERR(pdata->rtc);
+       if (IS_ERR(pdata->rtc)) {
+               ret = PTR_ERR(pdata->rtc);
+               goto out;
+       }
 
        if (pdata->irq >= 0) {
                writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
@@ -282,6 +294,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
        }
 
        return 0;
+out:
+       if (!IS_ERR(pdata->clk))
+               clk_disable_unprepare(pdata->clk);
+
+       return ret;
 }
 
 static int __exit mv_rtc_remove(struct platform_device *pdev)
@@ -292,6 +309,9 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
                device_init_wakeup(&pdev->dev, 0);
 
        rtc_device_unregister(pdata->rtc);
+       if (!IS_ERR(pdata->clk))
+               clk_disable_unprepare(pdata->clk);
+
        return 0;
 }
 
index e96236ac2e78a74cc9673f71ef8c07233343277f..ffa69e1c9245446a9d7d2f65eaf81f86a1994633 100644 (file)
@@ -110,7 +110,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
 static int rtc_proc_open(struct inode *inode, struct file *file)
 {
        int ret;
-       struct rtc_device *rtc = PDE(inode)->data;
+       struct rtc_device *rtc = PDE_DATA(inode);
 
        if (!try_module_get(THIS_MODULE))
                return -ENODEV;
index 9978ad4433cb460ea96dcc5f7a4bd0d7e8c5bdd6..5ac9c935c151511a1a9b42cf76dc5efd87c4f71f 100644 (file)
@@ -135,6 +135,11 @@ static const struct block_device_operations scm_blk_devops = {
        .release = scm_release,
 };
 
+static bool scm_permit_request(struct scm_blk_dev *bdev, struct request *req)
+{
+       return rq_data_dir(req) != WRITE || bdev->state != SCM_WR_PROHIBIT;
+}
+
 static void scm_request_prepare(struct scm_request *scmrq)
 {
        struct scm_blk_dev *bdev = scmrq->bdev;
@@ -195,14 +200,18 @@ void scm_request_requeue(struct scm_request *scmrq)
 
        scm_release_cluster(scmrq);
        blk_requeue_request(bdev->rq, scmrq->request);
+       atomic_dec(&bdev->queued_reqs);
        scm_request_done(scmrq);
        scm_ensure_queue_restart(bdev);
 }
 
 void scm_request_finish(struct scm_request *scmrq)
 {
+       struct scm_blk_dev *bdev = scmrq->bdev;
+
        scm_release_cluster(scmrq);
        blk_end_request_all(scmrq->request, scmrq->error);
+       atomic_dec(&bdev->queued_reqs);
        scm_request_done(scmrq);
 }
 
@@ -218,6 +227,10 @@ static void scm_blk_request(struct request_queue *rq)
                if (req->cmd_type != REQ_TYPE_FS)
                        continue;
 
+               if (!scm_permit_request(bdev, req)) {
+                       scm_ensure_queue_restart(bdev);
+                       return;
+               }
                scmrq = scm_request_fetch();
                if (!scmrq) {
                        SCM_LOG(5, "no request");
@@ -231,11 +244,13 @@ static void scm_blk_request(struct request_queue *rq)
                        return;
                }
                if (scm_need_cluster_request(scmrq)) {
+                       atomic_inc(&bdev->queued_reqs);
                        blk_start_request(req);
                        scm_initiate_cluster_request(scmrq);
                        return;
                }
                scm_request_prepare(scmrq);
+               atomic_inc(&bdev->queued_reqs);
                blk_start_request(req);
 
                ret = scm_start_aob(scmrq->aob);
@@ -244,7 +259,6 @@ static void scm_blk_request(struct request_queue *rq)
                        scm_request_requeue(scmrq);
                        return;
                }
-               atomic_inc(&bdev->queued_reqs);
        }
 }
 
@@ -280,6 +294,38 @@ void scm_blk_irq(struct scm_device *scmdev, void *data, int error)
        tasklet_hi_schedule(&bdev->tasklet);
 }
 
+static void scm_blk_handle_error(struct scm_request *scmrq)
+{
+       struct scm_blk_dev *bdev = scmrq->bdev;
+       unsigned long flags;
+
+       if (scmrq->error != -EIO)
+               goto restart;
+
+       /* For -EIO the response block is valid. */
+       switch (scmrq->aob->response.eqc) {
+       case EQC_WR_PROHIBIT:
+               spin_lock_irqsave(&bdev->lock, flags);
+               if (bdev->state != SCM_WR_PROHIBIT)
+                       pr_info("%lu: Write access to the SCM increment is suspended\n",
+                               (unsigned long) bdev->scmdev->address);
+               bdev->state = SCM_WR_PROHIBIT;
+               spin_unlock_irqrestore(&bdev->lock, flags);
+               goto requeue;
+       default:
+               break;
+       }
+
+restart:
+       if (!scm_start_aob(scmrq->aob))
+               return;
+
+requeue:
+       spin_lock_irqsave(&bdev->rq_lock, flags);
+       scm_request_requeue(scmrq);
+       spin_unlock_irqrestore(&bdev->rq_lock, flags);
+}
+
 static void scm_blk_tasklet(struct scm_blk_dev *bdev)
 {
        struct scm_request *scmrq;
@@ -293,11 +339,8 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev)
                spin_unlock_irqrestore(&bdev->lock, flags);
 
                if (scmrq->error && scmrq->retries-- > 0) {
-                       if (scm_start_aob(scmrq->aob)) {
-                               spin_lock_irqsave(&bdev->rq_lock, flags);
-                               scm_request_requeue(scmrq);
-                               spin_unlock_irqrestore(&bdev->rq_lock, flags);
-                       }
+                       scm_blk_handle_error(scmrq);
+
                        /* Request restarted or requeued, handle next. */
                        spin_lock_irqsave(&bdev->lock, flags);
                        continue;
@@ -310,7 +353,6 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev)
                }
 
                scm_request_finish(scmrq);
-               atomic_dec(&bdev->queued_reqs);
                spin_lock_irqsave(&bdev->lock, flags);
        }
        spin_unlock_irqrestore(&bdev->lock, flags);
@@ -332,6 +374,7 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
        }
 
        bdev->scmdev = scmdev;
+       bdev->state = SCM_OPER;
        spin_lock_init(&bdev->rq_lock);
        spin_lock_init(&bdev->lock);
        INIT_LIST_HEAD(&bdev->finished_requests);
@@ -396,6 +439,18 @@ void scm_blk_dev_cleanup(struct scm_blk_dev *bdev)
        put_disk(bdev->gendisk);
 }
 
+void scm_blk_set_available(struct scm_blk_dev *bdev)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&bdev->lock, flags);
+       if (bdev->state == SCM_WR_PROHIBIT)
+               pr_info("%lu: Write access to the SCM increment is restored\n",
+                       (unsigned long) bdev->scmdev->address);
+       bdev->state = SCM_OPER;
+       spin_unlock_irqrestore(&bdev->lock, flags);
+}
+
 static int __init scm_blk_init(void)
 {
        int ret = -EINVAL;
index 3c1ccf4946478dd5817b9a3c0435d89d5f164c06..8b387b32fd622b981a19e951eca1b3fd30c783bf 100644 (file)
@@ -21,6 +21,7 @@ struct scm_blk_dev {
        spinlock_t rq_lock;     /* guard the request queue */
        spinlock_t lock;        /* guard the rest of the blockdev */
        atomic_t queued_reqs;
+       enum {SCM_OPER, SCM_WR_PROHIBIT} state;
        struct list_head finished_requests;
 #ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
        struct list_head cluster_list;
@@ -48,6 +49,7 @@ struct scm_request {
 
 int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
 void scm_blk_dev_cleanup(struct scm_blk_dev *);
+void scm_blk_set_available(struct scm_blk_dev *);
 void scm_blk_irq(struct scm_device *, void *, int);
 
 void scm_request_finish(struct scm_request *);
index 9fa0a908607b013ce3ef0981a323d3b4e9043bde..5f6180d6ff08f50516215c20553f0c1ce5f4da42 100644 (file)
 #include <asm/eadm.h>
 #include "scm_blk.h"
 
-static void notify(struct scm_device *scmdev)
+static void scm_notify(struct scm_device *scmdev, enum scm_event event)
 {
-       pr_info("%lu: The capabilities of the SCM increment changed\n",
-               (unsigned long) scmdev->address);
-       SCM_LOG(2, "State changed");
-       SCM_LOG_STATE(2, scmdev);
+       struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
+
+       switch (event) {
+       case SCM_CHANGE:
+               pr_info("%lu: The capabilities of the SCM increment changed\n",
+                       (unsigned long) scmdev->address);
+               SCM_LOG(2, "State changed");
+               SCM_LOG_STATE(2, scmdev);
+               break;
+       case SCM_AVAIL:
+               SCM_LOG(2, "Increment available");
+               SCM_LOG_STATE(2, scmdev);
+               scm_blk_set_available(bdev);
+               break;
+       }
 }
 
 static int scm_probe(struct scm_device *scmdev)
@@ -64,7 +75,7 @@ static struct scm_driver scm_drv = {
                .name = "scm_block",
                .owner = THIS_MODULE,
        },
-       .notify = notify,
+       .notify = scm_notify,
        .probe = scm_probe,
        .remove = scm_remove,
        .handler = scm_blk_irq,
index 30a2255389e55303934d2e454fbd01fcfe947b2e..cd798386b622173172906cc021306d9cc64941bf 100644 (file)
@@ -627,6 +627,8 @@ static int __init sclp_detect_standby_memory(void)
        struct read_storage_sccb *sccb;
        int i, id, assigned, rc;
 
+       if (OLDMEM_BASE) /* No standby memory in kdump mode */
+               return 0;
        if (!early_read_info_sccb_valid)
                return 0;
        if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL)
index 31ceef1beb8b06715090b9459f879997067896dd..e16c553f65561f453c4eed2a97eb4cda8a539231 100644 (file)
@@ -433,6 +433,20 @@ static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area)
                              " failed (rc=%d).\n", ret);
 }
 
+static void chsc_process_sei_scm_avail(struct chsc_sei_nt0_area *sei_area)
+{
+       int ret;
+
+       CIO_CRW_EVENT(4, "chsc: scm available information\n");
+       if (sei_area->rs != 7)
+               return;
+
+       ret = scm_process_availability_information();
+       if (ret)
+               CIO_CRW_EVENT(0, "chsc: process availability information"
+                             " failed (rc=%d).\n", ret);
+}
+
 static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area)
 {
        switch (sei_area->cc) {
@@ -468,6 +482,9 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
        case 12: /* scm change notification */
                chsc_process_sei_scm_change(sei_area);
                break;
+       case 14: /* scm available notification */
+               chsc_process_sei_scm_avail(sei_area);
+               break;
        default: /* other stuff */
                CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n",
                              sei_area->cc);
index 227e05f674b38a6151a3c3b99534c6700835640f..349d5fc471963a20d7f1dd4fec393ef44877d6a6 100644 (file)
@@ -156,8 +156,10 @@ int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token);
 
 #ifdef CONFIG_SCM_BUS
 int scm_update_information(void);
+int scm_process_availability_information(void);
 #else /* CONFIG_SCM_BUS */
 static inline int scm_update_information(void) { return 0; }
+static inline int scm_process_availability_information(void) { return 0; }
 #endif /* CONFIG_SCM_BUS */
 
 
index ccaae9d63d272581b0610bf4a28505470fda1d0b..4221b02085ad46dc13838461c901abd72c786fca 100644 (file)
@@ -224,7 +224,7 @@ static int qperf_seq_open(struct inode *inode, struct file *filp)
                           file_inode(filp)->i_private);
 }
 
-static struct file_operations debugfs_perf_fops = {
+static const struct file_operations debugfs_perf_fops = {
        .owner   = THIS_MODULE,
        .open    = qperf_seq_open,
        .read    = seq_read,
index bcf20f3aa51b67fd148ae807e0cbc070e09e8b22..46ec25632e8bd4ef8e0be26a3f515697abd7f760 100644 (file)
@@ -211,7 +211,7 @@ static void scmdev_update(struct scm_device *scmdev, struct sale *sale)
                goto out;
        scmdrv = to_scm_drv(scmdev->dev.driver);
        if (changed && scmdrv->notify)
-               scmdrv->notify(scmdev);
+               scmdrv->notify(scmdev, SCM_CHANGE);
 out:
        device_unlock(&scmdev->dev);
        if (changed)
@@ -297,6 +297,22 @@ int scm_update_information(void)
        return ret;
 }
 
+static int scm_dev_avail(struct device *dev, void *unused)
+{
+       struct scm_driver *scmdrv = to_scm_drv(dev->driver);
+       struct scm_device *scmdev = to_scm_dev(dev);
+
+       if (dev->driver && scmdrv->notify)
+               scmdrv->notify(scmdev, SCM_AVAIL);
+
+       return 0;
+}
+
+int scm_process_availability_information(void)
+{
+       return bus_for_each_dev(&scm_bus_type, NULL, NULL, scm_dev_avail);
+}
+
 static int __init scm_init(void)
 {
        int ret;
index d87961d4c0defe7aced66b6430b34cc0c032d886..8c0622399fcd67bd7353b6274a3d370b3d9caaa4 100644 (file)
@@ -916,6 +916,7 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
        void *reply_param);
 int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
 int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
+int qeth_get_elements_for_frags(struct sk_buff *);
 int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
                        struct sk_buff *, struct qeth_hdr *, int, int, int);
 int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
index 0d8cdff818139e8ee267f57df08c78494c1592d0..0d73a999983d90ff632c0dcdcf6d54bedbd5a289 100644 (file)
@@ -3679,6 +3679,25 @@ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
 }
 EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
 
+int qeth_get_elements_for_frags(struct sk_buff *skb)
+{
+       int cnt, length, e, elements = 0;
+       struct skb_frag_struct *frag;
+       char *data;
+
+       for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
+               frag = &skb_shinfo(skb)->frags[cnt];
+               data = (char *)page_to_phys(skb_frag_page(frag)) +
+                       frag->page_offset;
+               length = frag->size;
+               e = PFN_UP((unsigned long)data + length - 1) -
+                       PFN_DOWN((unsigned long)data);
+               elements += e;
+       }
+       return elements;
+}
+EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
+
 int qeth_get_elements_no(struct qeth_card *card, void *hdr,
                     struct sk_buff *skb, int elems)
 {
@@ -3686,7 +3705,8 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr,
        int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
                PFN_DOWN((unsigned long)skb->data);
 
-       elements_needed += skb_shinfo(skb)->nr_frags;
+       elements_needed += qeth_get_elements_for_frags(skb);
+
        if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
                QETH_DBF_MESSAGE(2, "Invalid size of IP packet "
                        "(Number=%d / Length=%d). Discarded.\n",
@@ -3771,12 +3791,23 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
 
        for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
                frag = &skb_shinfo(skb)->frags[cnt];
-               buffer->element[element].addr = (char *)
-                       page_to_phys(skb_frag_page(frag))
-                       + frag->page_offset;
-               buffer->element[element].length = frag->size;
-               buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG;
-               element++;
+               data = (char *)page_to_phys(skb_frag_page(frag)) +
+                       frag->page_offset;
+               length = frag->size;
+               while (length > 0) {
+                       length_here = PAGE_SIZE -
+                               ((unsigned long) data % PAGE_SIZE);
+                       if (length < length_here)
+                               length_here = length;
+
+                       buffer->element[element].addr = data;
+                       buffer->element[element].length = length_here;
+                       buffer->element[element].eflags =
+                               SBAL_EFLAGS_MIDDLE_FRAG;
+                       length -= length_here;
+                       data += length_here;
+                       element++;
+               }
        }
 
        if (buffer->element[element - 1].eflags)
index 091ca0efa1c539e0ca27f57f55a00cb543bfc304..8710337dab3eceb4e5fa692d6a39accd697ba508 100644 (file)
@@ -623,7 +623,7 @@ static int qeth_l3_send_setrouting(struct qeth_card *card,
        return rc;
 }
 
-static void qeth_l3_correct_routing_type(struct qeth_card *card,
+static int qeth_l3_correct_routing_type(struct qeth_card *card,
                enum qeth_routing_types *type, enum qeth_prot_versions prot)
 {
        if (card->info.type == QETH_CARD_TYPE_IQD) {
@@ -632,7 +632,7 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card,
                case PRIMARY_CONNECTOR:
                case SECONDARY_CONNECTOR:
                case MULTICAST_ROUTER:
-                       return;
+                       return 0;
                default:
                        goto out_inval;
                }
@@ -641,17 +641,18 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card,
                case NO_ROUTER:
                case PRIMARY_ROUTER:
                case SECONDARY_ROUTER:
-                       return;
+                       return 0;
                case MULTICAST_ROUTER:
                        if (qeth_is_ipafunc_supported(card, prot,
                                                      IPA_OSA_MC_ROUTER))
-                               return;
+                               return 0;
                default:
                        goto out_inval;
                }
        }
 out_inval:
        *type = NO_ROUTER;
+       return -EINVAL;
 }
 
 int qeth_l3_setrouting_v4(struct qeth_card *card)
@@ -660,8 +661,10 @@ int qeth_l3_setrouting_v4(struct qeth_card *card)
 
        QETH_CARD_TEXT(card, 3, "setrtg4");
 
-       qeth_l3_correct_routing_type(card, &card->options.route4.type,
+       rc = qeth_l3_correct_routing_type(card, &card->options.route4.type,
                                  QETH_PROT_IPV4);
+       if (rc)
+               return rc;
 
        rc = qeth_l3_send_setrouting(card, card->options.route4.type,
                                  QETH_PROT_IPV4);
@@ -683,8 +686,10 @@ int qeth_l3_setrouting_v6(struct qeth_card *card)
 
        if (!qeth_is_supported(card, IPA_IPV6))
                return 0;
-       qeth_l3_correct_routing_type(card, &card->options.route6.type,
+       rc = qeth_l3_correct_routing_type(card, &card->options.route6.type,
                                  QETH_PROT_IPV6);
+       if (rc)
+               return rc;
 
        rc = qeth_l3_send_setrouting(card, card->options.route6.type,
                                  QETH_PROT_IPV6);
@@ -2898,7 +2903,9 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb)
                tcp_hdr(skb)->doff * 4;
        int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
        int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
-       elements += skb_shinfo(skb)->nr_frags;
+
+       elements += qeth_get_elements_for_frags(skb);
+
        return elements;
 }
 
@@ -3348,7 +3355,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
                rc = -ENODEV;
                goto out_remove;
        }
-       qeth_trace_features(card);
 
        if (!card->dev && qeth_l3_setup_netdev(card)) {
                rc = -ENODEV;
@@ -3425,6 +3431,7 @@ contin:
                qeth_l3_set_multicast_list(card->dev);
                rtnl_unlock();
        }
+       qeth_trace_features(card);
        /* let user_space know that device is online */
        kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
        mutex_unlock(&card->conf_mutex);
index ebc3794862675e591b45395f29cc0f6cf4c5e801..e70af2406ff9da388828660bb0bed2b73bf5cb71 100644 (file)
@@ -87,6 +87,8 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
                        rc = qeth_l3_setrouting_v6(card);
        }
 out:
+       if (rc)
+               route->type = old_route_type;
        mutex_unlock(&card->conf_mutex);
        return rc ? rc : count;
 }
index d7ca247efa35b3125fa2f3d0e67b967a600c4d15..344d87599cd2a88734fc2a620518c8a5ff41cb29 100644 (file)
@@ -3201,26 +3201,30 @@ static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_de
   BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
 */
 
-static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
+static int BusLogic_write_info(struct Scsi_Host *shost, char *ProcBuffer, int BytesAvailable)
 {
        struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
        struct BusLogic_TargetStatistics *TargetStatistics;
-       int TargetID, Length;
-       char *Buffer;
 
        TargetStatistics = HostAdapter->TargetStatistics;
-       if (WriteFlag) {
-               HostAdapter->ExternalHostAdapterResets = 0;
-               HostAdapter->HostAdapterInternalErrors = 0;
-               memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
-               return 0;
-       }
-       Buffer = HostAdapter->MessageBuffer;
-       Length = HostAdapter->MessageBufferLength;
-       Length += sprintf(&Buffer[Length], "\n\
+       HostAdapter->ExternalHostAdapterResets = 0;
+       HostAdapter->HostAdapterInternalErrors = 0;
+       memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
+       return 0;
+}
+
+static int BusLogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
+{
+       struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
+       struct BusLogic_TargetStatistics *TargetStatistics;
+       int TargetID;
+
+       TargetStatistics = HostAdapter->TargetStatistics;
+       seq_write(m, HostAdapter->MessageBuffer, HostAdapter->MessageBufferLength);
+       seq_printf(m, "\n\
 Current Driver Queue Depth:    %d\n\
 Currently Allocated CCBs:      %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
-       Length += sprintf(&Buffer[Length], "\n\n\
+       seq_printf(m, "\n\n\
                           DATA TRANSFER STATISTICS\n\
 \n\
 Target Tagged Queuing  Queue Depth  Active  Attempted  Completed\n\
@@ -3229,66 +3233,62 @@ Target  Tagged Queuing  Queue Depth  Active  Attempted  Completed\n\
                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                if (!TargetFlags->TargetExists)
                        continue;
-               Length += sprintf(&Buffer[Length], "  %2d       %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? "    Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
+               seq_printf(m, "  %2d    %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? "    Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
                                                                                                                                                                    ? "  Permitted" : "   Disabled"))
                                                                          : "Not Supported"));
-               Length += sprintf(&Buffer[Length],
+               seq_printf(m,
                                  "         %3d       %3u    %9u        %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
        }
-       Length += sprintf(&Buffer[Length], "\n\
+       seq_printf(m, "\n\
 Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
 ======  =============  ==============  ===================  ===================\n");
        for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                if (!TargetFlags->TargetExists)
                        continue;
-               Length += sprintf(&Buffer[Length], "  %2d         %9u    %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
+               seq_printf(m, "  %2d      %9u    %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
                if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
-                       Length += sprintf(&Buffer[Length], "     %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
+                       seq_printf(m, "     %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
                else
-                       Length += sprintf(&Buffer[Length], "            %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
+                       seq_printf(m, "         %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
                if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
-                       Length += sprintf(&Buffer[Length], "   %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
+                       seq_printf(m, "   %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
                else
-                       Length += sprintf(&Buffer[Length], "         %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
+                       seq_printf(m, "      %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
        }
-       Length += sprintf(&Buffer[Length], "\n\
+       seq_printf(m, "\n\
 Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
 ======  =======  =========  =========  =========  =========  =========\n");
        for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                if (!TargetFlags->TargetExists)
                        continue;
-               Length +=
-                   sprintf(&Buffer[Length],
+               seq_printf(m,
                            "  %2d       Read    %9u  %9u  %9u  %9u  %9u\n", TargetID,
                            TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
                            TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
-               Length +=
-                   sprintf(&Buffer[Length],
+               seq_printf(m,
                            "  %2d       Write   %9u  %9u  %9u  %9u  %9u\n", TargetID,
                            TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
                            TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
        }
-       Length += sprintf(&Buffer[Length], "\n\
+       seq_printf(m, "\n\
 Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
 ======  =======  =========  =========  =========  =========  =========\n");
        for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                if (!TargetFlags->TargetExists)
                        continue;
-               Length +=
-                   sprintf(&Buffer[Length],
+               seq_printf(m,
                            "  %2d       Read    %9u  %9u  %9u  %9u  %9u\n", TargetID,
                            TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
                            TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
-               Length +=
-                   sprintf(&Buffer[Length],
+               seq_printf(m,
                            "  %2d       Write   %9u  %9u  %9u  %9u  %9u\n", TargetID,
                            TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
                            TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
        }
-       Length += sprintf(&Buffer[Length], "\n\n\
+       seq_printf(m, "\n\n\
                           ERROR RECOVERY STATISTICS\n\
 \n\
          Command Aborts      Bus Device Resets   Host Adapter Resets\n\
@@ -3299,20 +3299,12 @@ Target  Requested Completed  Requested Completed  Requested Completed\n\
                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                if (!TargetFlags->TargetExists)
                        continue;
-               Length += sprintf(&Buffer[Length], "\
+               seq_printf(m, "\
   %2d   %5d %5d %5d    %5d %5d %5d        %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted);
        }
-       Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
-       Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
-       if (Length >= BusLogic_MessageBufferSize)
-               BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize);
-       if ((Length -= Offset) <= 0)
-               return 0;
-       if (Length >= BytesAvailable)
-               Length = BytesAvailable;
-       memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
-       *StartPointer = ProcBuffer;
-       return Length;
+       seq_printf(m, "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
+       seq_printf(m, "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
+       return 0;
 }
 
 
@@ -3566,7 +3558,8 @@ static int __init BusLogic_ParseDriverOptions(char *OptionsString)
 static struct scsi_host_template Bus_Logic_template = {
        .module = THIS_MODULE,
        .proc_name = "BusLogic",
-       .proc_info = BusLogic_ProcDirectoryInfo,
+       .write_info = BusLogic_write_info,
+       .show_info = BusLogic_show_info,
        .name = "BusLogic",
        .info = BusLogic_DriverInfo,
        .queuecommand = BusLogic_QueueCommand,
index 649fcb31f26da8e9b5269443574aa82a3dc45fa8..6c6c13c3be1bc1e3197c2d240073b98d884a2887 100644 (file)
@@ -1321,7 +1321,6 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T Co
 static const char *BusLogic_DriverInfo(struct Scsi_Host *);
 static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *);
 static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *);
-static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int BusLogic_SlaveConfigure(struct scsi_device *);
 static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *);
 static irqreturn_t BusLogic_InterruptHandler(int, void *);
index 450353e04dde8b6ed03ad594b57f65705790bd48..1e9d6ad9302b735cf2d124c2c41f053ef4d9f12a 100644 (file)
@@ -695,33 +695,35 @@ static void NCR5380_print_status(struct Scsi_Host *instance)
  * Return the number of bytes read from or written
  */
 
+static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
+       char *buffer, int length)
+{
+#ifdef DTC_PUBLIC_RELEASE
+       dtc_wmaxi = dtc_maxi = 0;
+#endif
+#ifdef PAS16_PUBLIC_RELEASE
+       pas_wmaxi = pas_maxi = 0;
+#endif
+       return (-ENOSYS);       /* Currently this is a no-op */
+}
+
 #undef SPRINTF
-#define SPRINTF(args...) do { if(pos < buffer + length-80) pos += sprintf(pos, ## args); } while(0)
+#define SPRINTF(args...) seq_printf(m, ## args)
 static
-char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length);
+void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m);
 static
-char *lprint_command(unsigned char *cmd, char *pos, char *buffer, int len);
+void lprint_command(unsigned char *cmd, struct seq_file *m);
 static
-char *lprint_opcode(int opcode, char *pos, char *buffer, int length);
+void lprint_opcode(int opcode, struct seq_file *m);
 
-static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
-       char *buffer, char **start, off_t offset, int length, int inout)
+static int __maybe_unused NCR5380_show_info(struct seq_file *m,
+       struct Scsi_Host *instance)
 {
-       char *pos = buffer;
        struct NCR5380_hostdata *hostdata;
        Scsi_Cmnd *ptr;
 
        hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-       if (inout) {            /* Has data been written to the file ? */
-#ifdef DTC_PUBLIC_RELEASE
-               dtc_wmaxi = dtc_maxi = 0;
-#endif
-#ifdef PAS16_PUBLIC_RELEASE
-               pas_wmaxi = pas_maxi = 0;
-#endif
-               return (-ENOSYS);       /* Currently this is a no-op */
-       }
        SPRINTF("NCR5380 core release=%d.   ", NCR5380_PUBLIC_RELEASE);
        if (((struct NCR5380_hostdata *) instance->hostdata)->flags & FLAG_NCR53C400)
                SPRINTF("ncr53c400 release=%d.  ", NCR53C400_PUBLIC_RELEASE);
@@ -755,46 +757,37 @@ static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
        if (!hostdata->connected)
                SPRINTF("scsi%d: no currently connected command\n", instance->host_no);
        else
-               pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, pos, buffer, length);
+               lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m);
        SPRINTF("scsi%d: issue_queue\n", instance->host_no);
        for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
-               pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
+               lprint_Scsi_Cmnd(ptr, m);
 
        SPRINTF("scsi%d: disconnected_queue\n", instance->host_no);
        for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
-               pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
+               lprint_Scsi_Cmnd(ptr, m);
        spin_unlock_irq(instance->host_lock);
-       
-       *start = buffer;
-       if (pos - buffer < offset)
-               return 0;
-       else if (pos - buffer - offset < length)
-               return pos - buffer - offset;
-       return length;
+       return 0;
 }
 
-static char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length)
+static void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m)
 {
        SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
        SPRINTF("        command = ");
-       pos = lprint_command(cmd->cmnd, pos, buffer, length);
-       return (pos);
+       lprint_command(cmd->cmnd, m);
 }
 
-static char *lprint_command(unsigned char *command, char *pos, char *buffer, int length)
+static void lprint_command(unsigned char *command, struct seq_file *m)
 {
        int i, s;
-       pos = lprint_opcode(command[0], pos, buffer, length);
+       lprint_opcode(command[0], m);
        for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
                SPRINTF("%02x ", command[i]);
        SPRINTF("\n");
-       return (pos);
 }
 
-static char *lprint_opcode(int opcode, char *pos, char *buffer, int length)
+static void lprint_opcode(int opcode, struct seq_file *m)
 {
        SPRINTF("%2d (0x%02x)", opcode, opcode);
-       return (pos);
 }
 
 
index fd40a32b1f6f2d3690ac5d63c361cb9ece6a2120..14964d0a0e9dabc2bde55a7e6c8c54fb605bf3d2 100644 (file)
@@ -314,8 +314,10 @@ static void NCR5380_print(struct Scsi_Host *instance);
 static int NCR5380_abort(Scsi_Cmnd * cmd);
 static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
 static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
-static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
-       char *buffer, char **start, off_t offset, int length, int inout);
+static int __maybe_unused NCR5380_show_info(struct seq_file *,
+       struct Scsi_Host *);
+static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
+       char *buffer, int length);
 
 static void NCR5380_reselect(struct Scsi_Host *instance);
 static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
index 3e09aa21c1ca787141aa7f02d08a4aa50dfce7a3..30fa38a0ad39a33102f1cd4656b4d800c498ae07 100644 (file)
@@ -166,7 +166,8 @@ static int a2091_bus_reset(struct scsi_cmnd *cmd)
 static struct scsi_host_template a2091_scsi_template = {
        .module                 = THIS_MODULE,
        .name                   = "Commodore A2091/A590 SCSI",
-       .proc_info              = wd33c93_proc_info,
+       .show_info              = wd33c93_show_info,
+       .write_info             = wd33c93_write_info,
        .proc_name              = "A2901",
        .queuecommand           = wd33c93_queuecommand,
        .eh_abort_handler       = wd33c93_abort,
index e29fe0e708f8f4e63fbcc0f9f20142ce06d6517f..c487916a9d45ecd404c1abdaa12d5d2742aeffe9 100644 (file)
@@ -181,7 +181,8 @@ static int a3000_bus_reset(struct scsi_cmnd *cmd)
 static struct scsi_host_template amiga_a3000_scsi_template = {
        .module                 = THIS_MODULE,
        .name                   = "Amiga 3000 built-in SCSI",
-       .proc_info              = wd33c93_proc_info,
+       .show_info              = wd33c93_show_info,
+       .write_info             = wd33c93_write_info,
        .proc_name              = "A3000",
        .queuecommand           = wd33c93_queuecommand,
        .eh_abort_handler       = wd33c93_abort,
index dcfaee66a8b932eed7457e25b0932cbbad7405f5..c67e401954c542529b617985aa471fef281eb878 100644 (file)
@@ -2178,22 +2178,6 @@ do { \
 
 #define ASC_INFO_SIZE           128    /* advansys_info() line size */
 
-#ifdef CONFIG_PROC_FS
-/* /proc/scsi/advansys/[0...] related definitions */
-#define ASC_PRTBUF_SIZE         2048
-#define ASC_PRTLINE_SIZE        160
-
-#define ASC_PRT_NEXT() \
-    if (cp) { \
-        totlen += len; \
-        leftlen -= len; \
-        if (leftlen == 0) { \
-            return totlen; \
-        } \
-        cp += len; \
-    }
-#endif /* CONFIG_PROC_FS */
-
 /* Asc Library return codes */
 #define ASC_TRUE        1
 #define ASC_FALSE       0
@@ -2384,7 +2368,6 @@ struct asc_board {
        } eep_config;
        ulong last_reset;       /* Saved last reset time */
        /* /proc/scsi/advansys/[0...] */
-       char *prtbuf;           /* /proc print buffer */
 #ifdef ADVANSYS_STATS
        struct asc_stats asc_stats;     /* Board statistics */
 #endif                         /* ADVANSYS_STATS */
@@ -2875,64 +2858,21 @@ static const char *advansys_info(struct Scsi_Host *shost)
 }
 
 #ifdef CONFIG_PROC_FS
-/*
- * asc_prt_line()
- *
- * If 'cp' is NULL print to the console, otherwise print to a buffer.
- *
- * Return 0 if printing to the console, otherwise return the number of
- * bytes written to the buffer.
- *
- * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
- * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
- */
-static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
-{
-       va_list args;
-       int ret;
-       char s[ASC_PRTLINE_SIZE];
-
-       va_start(args, fmt);
-       ret = vsprintf(s, fmt, args);
-       BUG_ON(ret >= ASC_PRTLINE_SIZE);
-       if (buf == NULL) {
-               (void)printk(s);
-               ret = 0;
-       } else {
-               ret = min(buflen, ret);
-               memcpy(buf, s, ret);
-       }
-       va_end(args);
-       return ret;
-}
 
 /*
  * asc_prt_board_devices()
  *
  * Print driver information for devices attached to the board.
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_board_devices(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
-       int leftlen;
-       int totlen;
-       int len;
        int chip_scsi_id;
        int i;
 
-       leftlen = cplen;
-       totlen = len = 0;
-
-       len = asc_prt_line(cp, leftlen,
-                          "\nDevice Information for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  "\nDevice Information for AdvanSys SCSI Host %d:\n",
+                  shost->host_no);
 
        if (ASC_NARROW_BOARD(boardp)) {
                chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
@@ -2940,60 +2880,42 @@ static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
                chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
        }
 
-       len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
-       ASC_PRT_NEXT();
+       seq_printf(m, "Target IDs Detected:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
-               if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
-                       len = asc_prt_line(cp, leftlen, " %X,", i);
-                       ASC_PRT_NEXT();
-               }
+               if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i))
+                       seq_printf(m, " %X,", i);
        }
-       len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
-       ASC_PRT_NEXT();
-
-       return totlen;
+       seq_printf(m, " (%X=Host Adapter)\n", chip_scsi_id);
 }
 
 /*
  * Display Wide Board BIOS Information.
  */
-static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_adv_bios(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
-       int leftlen;
-       int totlen;
-       int len;
        ushort major, minor, letter;
 
-       leftlen = cplen;
-       totlen = len = 0;
-
-       len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\nROM BIOS Version: ");
 
        /*
         * If the BIOS saved a valid signature, then fill in
         * the BIOS code segment base address.
         */
        if (boardp->bios_signature != 0x55AA) {
-               len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
-               ASC_PRT_NEXT();
-               len = asc_prt_line(cp, leftlen,
-                                  "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
-               ASC_PRT_NEXT();
-               len = asc_prt_line(cp, leftlen,
-                                  "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
-               ASC_PRT_NEXT();
+               seq_printf(m, "Disabled or Pre-3.1\n");
+               seq_printf(m,
+                         "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
+               seq_printf(m,
+                         "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
        } else {
                major = (boardp->bios_version >> 12) & 0xF;
                minor = (boardp->bios_version >> 8) & 0xF;
                letter = (boardp->bios_version & 0xFF);
 
-               len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
+               seq_printf(m, "%d.%d%c\n",
                                   major, minor,
                                   letter >= 26 ? '?' : letter + 'A');
-               ASC_PRT_NEXT();
-
                /*
                 * Current available ROM BIOS release is 3.1I for UW
                 * and 3.2I for U2W. This code doesn't differentiate
@@ -3001,16 +2923,12 @@ static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
                 */
                if (major < 3 || (major <= 3 && minor < 1) ||
                    (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
-                       len = asc_prt_line(cp, leftlen,
-                                          "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
-                       ASC_PRT_NEXT();
-                       len = asc_prt_line(cp, leftlen,
-                                          "ftp://ftp.connectcom.net/pub\n");
-                       ASC_PRT_NEXT();
+                       seq_printf(m,
+                                  "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
+                       seq_printf(m,
+                                  "ftp://ftp.connectcom.net/pub\n");
                }
        }
-
-       return totlen;
 }
 
 /*
@@ -3115,20 +3033,11 @@ static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
  * asc_prt_asc_board_eeprom()
  *
  * Print board EEPROM configuration.
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_asc_board_eeprom(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
        ASC_DVC_VAR *asc_dvc_varp;
-       int leftlen;
-       int totlen;
-       int len;
        ASCEEP_CONFIG *ep;
        int i;
 #ifdef CONFIG_ISA
@@ -3139,129 +3048,75 @@ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        ep = &boardp->eep_config.asc_eep;
 
-       leftlen = cplen;
-       totlen = len = 0;
-
-       len = asc_prt_line(cp, leftlen,
-                          "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
+                  shost->host_no);
 
        if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
-           == ASC_TRUE) {
-               len =
-                   asc_prt_line(cp, leftlen, " Serial Number: %s\n",
-                                serialstr);
-               ASC_PRT_NEXT();
-       } else {
-               if (ep->adapter_info[5] == 0xBB) {
-                       len = asc_prt_line(cp, leftlen,
-                                          " Default Settings Used for EEPROM-less Adapter.\n");
-                       ASC_PRT_NEXT();
-               } else {
-                       len = asc_prt_line(cp, leftlen,
-                                          " Serial Number Signature Not Present.\n");
-                       ASC_PRT_NEXT();
-               }
-       }
-
-       len = asc_prt_line(cp, leftlen,
-                          " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-                          ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
-                          ep->max_tag_qng);
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen,
-                          " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " Target ID:           ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ASC_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %d", i);
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " Disconnects:         ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ASC_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (ep->
-                                   disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ASC_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (ep->
-                                   use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " Start Motor:         ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ASC_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (ep->
-                                   start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ASC_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (ep->
-                                   init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+           == ASC_TRUE)
+               seq_printf(m, " Serial Number: %s\n", serialstr);
+       else if (ep->adapter_info[5] == 0xBB)
+               seq_printf(m,
+                          " Default Settings Used for EEPROM-less Adapter.\n");
+       else
+               seq_printf(m,
+                          " Serial Number Signature Not Present.\n");
+
+       seq_printf(m,
+                  " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+                  ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
+                  ep->max_tag_qng);
+
+       seq_printf(m,
+                  " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
+
+       seq_printf(m, " Target ID:           ");
+       for (i = 0; i <= ASC_MAX_TID; i++)
+               seq_printf(m, " %d", i);
+       seq_printf(m, "\n");
+
+       seq_printf(m, " Disconnects:         ");
+       for (i = 0; i <= ASC_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
+
+       seq_printf(m, " Command Queuing:     ");
+       for (i = 0; i <= ASC_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
+
+       seq_printf(m, " Start Motor:         ");
+       for (i = 0; i <= ASC_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
+
+       seq_printf(m, " Synchronous Transfer:");
+       for (i = 0; i <= ASC_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
 
 #ifdef CONFIG_ISA
        if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
-               len = asc_prt_line(cp, leftlen,
-                                  " Host ISA DMA speed:   %d MB/S\n",
-                                  isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
-               ASC_PRT_NEXT();
+               seq_printf(m,
+                          " Host ISA DMA speed:   %d MB/S\n",
+                          isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
        }
 #endif /* CONFIG_ISA */
-
-       return totlen;
 }
 
 /*
  * asc_prt_adv_board_eeprom()
  *
  * Print board EEPROM configuration.
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_adv_board_eeprom(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
        ADV_DVC_VAR *adv_dvc_varp;
-       int leftlen;
-       int totlen;
-       int len;
        int i;
        char *termstr;
        uchar serialstr[13];
@@ -3281,13 +3136,9 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
                ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
        }
 
-       leftlen = cplen;
-       totlen = len = 0;
-
-       len = asc_prt_line(cp, leftlen,
-                          "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
+                  shost->host_no);
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
                wordp = &ep_3550->serial_number_word1;
@@ -3297,38 +3148,28 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
                wordp = &ep_38C1600->serial_number_word1;
        }
 
-       if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
-               len =
-                   asc_prt_line(cp, leftlen, " Serial Number: %s\n",
-                                serialstr);
-               ASC_PRT_NEXT();
-       } else {
-               len = asc_prt_line(cp, leftlen,
-                                  " Serial Number Signature Not Present.\n");
-               ASC_PRT_NEXT();
-       }
+       if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE)
+               seq_printf(m, " Serial Number: %s\n", serialstr);
+       else
+               seq_printf(m, " Serial Number Signature Not Present.\n");
 
-       if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-               len = asc_prt_line(cp, leftlen,
-                                  " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-                                  ep_3550->adapter_scsi_id,
-                                  ep_3550->max_host_qng, ep_3550->max_dvc_qng);
-               ASC_PRT_NEXT();
-       } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
-               len = asc_prt_line(cp, leftlen,
-                                  " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-                                  ep_38C0800->adapter_scsi_id,
-                                  ep_38C0800->max_host_qng,
-                                  ep_38C0800->max_dvc_qng);
-               ASC_PRT_NEXT();
-       } else {
-               len = asc_prt_line(cp, leftlen,
-                                  " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-                                  ep_38C1600->adapter_scsi_id,
-                                  ep_38C1600->max_host_qng,
-                                  ep_38C1600->max_dvc_qng);
-               ASC_PRT_NEXT();
-       }
+       if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+               seq_printf(m,
+                          " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+                          ep_3550->adapter_scsi_id,
+                          ep_3550->max_host_qng, ep_3550->max_dvc_qng);
+       else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
+               seq_printf(m,
+                          " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+                          ep_38C0800->adapter_scsi_id,
+                          ep_38C0800->max_host_qng,
+                          ep_38C0800->max_dvc_qng);
+       else
+               seq_printf(m,
+                          " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+                          ep_38C1600->adapter_scsi_id,
+                          ep_38C1600->max_host_qng,
+                          ep_38C1600->max_dvc_qng);
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
                word = ep_3550->termination;
        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
@@ -3352,34 +3193,26 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
                break;
        }
 
-       if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-               len = asc_prt_line(cp, leftlen,
-                                  " termination: %u (%s), bios_ctrl: 0x%x\n",
-                                  ep_3550->termination, termstr,
-                                  ep_3550->bios_ctrl);
-               ASC_PRT_NEXT();
-       } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
-               len = asc_prt_line(cp, leftlen,
-                                  " termination: %u (%s), bios_ctrl: 0x%x\n",
-                                  ep_38C0800->termination_lvd, termstr,
-                                  ep_38C0800->bios_ctrl);
-               ASC_PRT_NEXT();
-       } else {
-               len = asc_prt_line(cp, leftlen,
-                                  " termination: %u (%s), bios_ctrl: 0x%x\n",
-                                  ep_38C1600->termination_lvd, termstr,
-                                  ep_38C1600->bios_ctrl);
-               ASC_PRT_NEXT();
-       }
+       if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+               seq_printf(m,
+                          " termination: %u (%s), bios_ctrl: 0x%x\n",
+                          ep_3550->termination, termstr,
+                          ep_3550->bios_ctrl);
+       else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
+               seq_printf(m,
+                          " termination: %u (%s), bios_ctrl: 0x%x\n",
+                          ep_38C0800->termination_lvd, termstr,
+                          ep_38C0800->bios_ctrl);
+       else
+               seq_printf(m,
+                          " termination: %u (%s), bios_ctrl: 0x%x\n",
+                          ep_38C1600->termination_lvd, termstr,
+                          ep_38C1600->bios_ctrl);
 
-       len = asc_prt_line(cp, leftlen, " Target ID:           ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ADV_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %X", i);
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Target ID:           ");
+       for (i = 0; i <= ADV_MAX_TID; i++)
+               seq_printf(m, " %X", i);
+       seq_printf(m, "\n");
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
                word = ep_3550->disc_enable;
@@ -3388,15 +3221,11 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
        } else {
                word = ep_38C1600->disc_enable;
        }
-       len = asc_prt_line(cp, leftlen, " Disconnects:         ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ADV_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Disconnects:         ");
+       for (i = 0; i <= ADV_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
                word = ep_3550->tagqng_able;
@@ -3405,15 +3234,11 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
        } else {
                word = ep_38C1600->tagqng_able;
        }
-       len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ADV_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Command Queuing:     ");
+       for (i = 0; i <= ADV_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
                word = ep_3550->start_motor;
@@ -3422,42 +3247,28 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
        } else {
                word = ep_38C1600->start_motor;
        }
-       len = asc_prt_line(cp, leftlen, " Start Motor:         ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ADV_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Start Motor:         ");
+       for (i = 0; i <= ADV_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-               len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
-               ASC_PRT_NEXT();
-               for (i = 0; i <= ADV_MAX_TID; i++) {
-                       len = asc_prt_line(cp, leftlen, " %c",
-                                          (ep_3550->
-                                           sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
-                                          'Y' : 'N');
-                       ASC_PRT_NEXT();
-               }
-               len = asc_prt_line(cp, leftlen, "\n");
-               ASC_PRT_NEXT();
+               seq_printf(m, " Synchronous Transfer:");
+               for (i = 0; i <= ADV_MAX_TID; i++)
+                       seq_printf(m, " %c",
+                                  (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
+                                  'Y' : 'N');
+               seq_printf(m, "\n");
        }
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-               len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
-               ASC_PRT_NEXT();
-               for (i = 0; i <= ADV_MAX_TID; i++) {
-                       len = asc_prt_line(cp, leftlen, " %c",
-                                          (ep_3550->
-                                           ultra_able & ADV_TID_TO_TIDMASK(i))
-                                          ? 'Y' : 'N');
-                       ASC_PRT_NEXT();
-               }
-               len = asc_prt_line(cp, leftlen, "\n");
-               ASC_PRT_NEXT();
+               seq_printf(m, " Ultra Transfer:      ");
+               for (i = 0; i <= ADV_MAX_TID; i++)
+                       seq_printf(m, " %c",
+                                  (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i))
+                                  ? 'Y' : 'N');
+               seq_printf(m, "\n");
        }
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
@@ -3467,21 +3278,16 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
        } else {
                word = ep_38C1600->wdtr_able;
        }
-       len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
-       ASC_PRT_NEXT();
-       for (i = 0; i <= ADV_MAX_TID; i++) {
-               len = asc_prt_line(cp, leftlen, " %c",
-                                  (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
-               ASC_PRT_NEXT();
-       }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Wide Transfer:       ");
+       for (i = 0; i <= ADV_MAX_TID; i++)
+               seq_printf(m, " %c",
+                          (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+       seq_printf(m, "\n");
 
        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
            adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
-               len = asc_prt_line(cp, leftlen,
-                                  " Synchronous Transfer Speed (Mhz):\n  ");
-               ASC_PRT_NEXT();
+               seq_printf(m,
+                          " Synchronous Transfer Speed (Mhz):\n  ");
                for (i = 0; i <= ADV_MAX_TID; i++) {
                        char *speed_str;
 
@@ -3517,99 +3323,64 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen
                                speed_str = "Unk";
                                break;
                        }
-                       len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
-                       ASC_PRT_NEXT();
-                       if (i == 7) {
-                               len = asc_prt_line(cp, leftlen, "\n  ");
-                               ASC_PRT_NEXT();
-                       }
+                       seq_printf(m, "%X:%s ", i, speed_str);
+                       if (i == 7)
+                               seq_printf(m, "\n  ");
                        sdtr_speed >>= 4;
                }
-               len = asc_prt_line(cp, leftlen, "\n");
-               ASC_PRT_NEXT();
+               seq_printf(m, "\n");
        }
-
-       return totlen;
 }
 
 /*
  * asc_prt_driver_conf()
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
-       int leftlen;
-       int totlen;
-       int len;
        int chip_scsi_id;
 
-       leftlen = cplen;
-       totlen = len = 0;
+       seq_printf(m,
+               "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
+               shost->host_no);
 
-       len = asc_prt_line(cp, leftlen,
-                          "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " host_busy %u, last_reset %lu, max_id %u, max_lun %u, max_channel %u\n",
+                  shost->host_busy, shost->last_reset, shost->max_id,
+                  shost->max_lun, shost->max_channel);
 
-       len = asc_prt_line(cp, leftlen,
-                          " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
-                          shost->host_busy, shost->last_reset, shost->max_id,
-                          shost->max_lun, shost->max_channel);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
+                  shost->unique_id, shost->can_queue, shost->this_id,
+                  shost->sg_tablesize, shost->cmd_per_lun);
 
-       len = asc_prt_line(cp, leftlen,
-                          " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
-                          shost->unique_id, shost->can_queue, shost->this_id,
-                          shost->sg_tablesize, shost->cmd_per_lun);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " unchecked_isa_dma %d, use_clustering %d\n",
+                  shost->unchecked_isa_dma, shost->use_clustering);
 
-       len = asc_prt_line(cp, leftlen,
-                          " unchecked_isa_dma %d, use_clustering %d\n",
-                          shost->unchecked_isa_dma, shost->use_clustering);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " flags 0x%x, last_reset 0x%lx, jiffies 0x%lx, asc_n_io_port 0x%x\n",
+                  boardp->flags, boardp->last_reset, jiffies,
+                  boardp->asc_n_io_port);
 
-       len = asc_prt_line(cp, leftlen,
-                          " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
-                          boardp->flags, boardp->last_reset, jiffies,
-                          boardp->asc_n_io_port);
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
-       ASC_PRT_NEXT();
+       seq_printf(m, " io_port 0x%lx\n", shost->io_port);
 
        if (ASC_NARROW_BOARD(boardp)) {
                chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
        } else {
                chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
        }
-
-       return totlen;
 }
 
 /*
  * asc_prt_asc_board_info()
  *
  * Print dynamic board configuration information.
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_asc_board_info(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
        int chip_scsi_id;
-       int leftlen;
-       int totlen;
-       int len;
        ASC_DVC_VAR *v;
        ASC_DVC_CFG *c;
        int i;
@@ -3619,105 +3390,79 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
        c = &boardp->dvc_cfg.asc_dvc_cfg;
        chip_scsi_id = c->chip_scsi_id;
 
-       leftlen = cplen;
-       totlen = len = 0;
+       seq_printf(m,
+                  "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
+                  shost->host_no);
 
-       len = asc_prt_line(cp, leftlen,
-                          "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
-                          "mcode_version 0x%x, err_code %u\n",
-                          c->chip_version, c->mcode_date, c->mcode_version,
-                          v->err_code);
-       ASC_PRT_NEXT();
+       seq_printf(m, " chip_version %u, mcode_date 0x%x, "
+                  "mcode_version 0x%x, err_code %u\n",
+                  c->chip_version, c->mcode_date, c->mcode_version,
+                  v->err_code);
 
        /* Current number of commands waiting for the host. */
-       len = asc_prt_line(cp, leftlen,
-                          " Total Command Pending: %d\n", v->cur_total_qng);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " Total Command Pending: %d\n", v->cur_total_qng);
 
-       len = asc_prt_line(cp, leftlen, " Command Queuing:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Command Queuing:");
        for (i = 0; i <= ASC_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
-               len = asc_prt_line(cp, leftlen, " %X:%c",
-                                  i,
-                                  (v->
-                                   use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
-                                  'Y' : 'N');
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%c",
+                          i,
+                          (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        /* Current number of commands waiting for a device. */
-       len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Command Queue Pending:");
        for (i = 0; i <= ASC_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
-               len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%u", i, v->cur_dvc_qng[i]);
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        /* Current limit on number of commands that can be sent to a device. */
-       len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Command Queue Limit:");
        for (i = 0; i <= ASC_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
-               len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%u", i, v->max_dvc_qng[i]);
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        /* Indicate whether the device has returned queue full status. */
-       len = asc_prt_line(cp, leftlen, " Command Queue Full:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Command Queue Full:");
        for (i = 0; i <= ASC_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
-               if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
-                       len = asc_prt_line(cp, leftlen, " %X:Y-%d",
-                                          i, boardp->queue_full_cnt[i]);
-               } else {
-                       len = asc_prt_line(cp, leftlen, " %X:N", i);
-               }
-               ASC_PRT_NEXT();
+               if (boardp->queue_full & ADV_TID_TO_TIDMASK(i))
+                       seq_printf(m, " %X:Y-%d",
+                                  i, boardp->queue_full_cnt[i]);
+               else
+                       seq_printf(m, " %X:N", i);
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
-       len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Synchronous Transfer:");
        for (i = 0; i <= ASC_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
-               len = asc_prt_line(cp, leftlen, " %X:%c",
-                                  i,
-                                  (v->
-                                   sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%c",
+                          i,
+                          (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        for (i = 0; i <= ASC_MAX_TID; i++) {
                uchar syn_period_ix;
@@ -3728,69 +3473,48 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
                        continue;
                }
 
-               len = asc_prt_line(cp, leftlen, "  %X:", i);
-               ASC_PRT_NEXT();
+               seq_printf(m, "  %X:", i);
 
                if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
-                       len = asc_prt_line(cp, leftlen, " Asynchronous");
-                       ASC_PRT_NEXT();
+                       seq_printf(m, " Asynchronous");
                } else {
                        syn_period_ix =
                            (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
                                                           1);
 
-                       len = asc_prt_line(cp, leftlen,
-                                          " Transfer Period Factor: %d (%d.%d Mhz),",
-                                          v->sdtr_period_tbl[syn_period_ix],
-                                          250 /
-                                          v->sdtr_period_tbl[syn_period_ix],
-                                          ASC_TENTHS(250,
-                                                     v->
-                                                     sdtr_period_tbl
-                                                     [syn_period_ix]));
-                       ASC_PRT_NEXT();
+                       seq_printf(m,
+                                  " Transfer Period Factor: %d (%d.%d Mhz),",
+                                  v->sdtr_period_tbl[syn_period_ix],
+                                  250 / v->sdtr_period_tbl[syn_period_ix],
+                                  ASC_TENTHS(250,
+                                             v->sdtr_period_tbl[syn_period_ix]));
 
-                       len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
-                                          boardp->
-                                          sdtr_data[i] & ASC_SYN_MAX_OFFSET);
-                       ASC_PRT_NEXT();
+                       seq_printf(m, " REQ/ACK Offset: %d",
+                                  boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
                }
 
                if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
-                       len = asc_prt_line(cp, leftlen, "*\n");
+                       seq_printf(m, "*\n");
                        renegotiate = 1;
                } else {
-                       len = asc_prt_line(cp, leftlen, "\n");
+                       seq_printf(m, "\n");
                }
-               ASC_PRT_NEXT();
        }
 
        if (renegotiate) {
-               len = asc_prt_line(cp, leftlen,
-                                  " * = Re-negotiation pending before next command.\n");
-               ASC_PRT_NEXT();
+               seq_printf(m,
+                          " * = Re-negotiation pending before next command.\n");
        }
-
-       return totlen;
 }
 
 /*
  * asc_prt_adv_board_info()
  *
  * Print dynamic board configuration information.
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_adv_board_info(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
-       int leftlen;
-       int totlen;
-       int len;
        int i;
        ADV_DVC_VAR *v;
        ADV_DVC_CFG *c;
@@ -3809,47 +3533,35 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
        iop_base = v->iop_base;
        chip_scsi_id = v->chip_scsi_id;
 
-       leftlen = cplen;
-       totlen = len = 0;
-
-       len = asc_prt_line(cp, leftlen,
-                          "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
+                  shost->host_no);
 
-       len = asc_prt_line(cp, leftlen,
-                          " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
-                          v->iop_base,
-                          AdvReadWordRegister(iop_base,
-                                              IOPW_SCSI_CFG1) & CABLE_DETECT,
-                          v->err_code);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
+                  (unsigned long)v->iop_base,
+                  AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT,
+                  v->err_code);
 
-       len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
-                          "mcode_version 0x%x\n", c->chip_version,
-                          c->mcode_date, c->mcode_version);
-       ASC_PRT_NEXT();
+       seq_printf(m, " chip_version %u, mcode_date 0x%x, "
+                  "mcode_version 0x%x\n", c->chip_version,
+                  c->mcode_date, c->mcode_version);
 
        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
-       len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Queuing Enabled:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
 
-               len = asc_prt_line(cp, leftlen, " %X:%c",
-                                  i,
-                                  (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%c",
+                          i,
+                          (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
-       len = asc_prt_line(cp, leftlen, " Queue Limit:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Queue Limit:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
@@ -3859,14 +3571,11 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
                                lrambyte);
 
-               len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%d", i, lrambyte);
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
-       len = asc_prt_line(cp, leftlen, " Command Pending:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Command Pending:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
@@ -3876,33 +3585,26 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
                                lrambyte);
 
-               len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%d", i, lrambyte);
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
-       len = asc_prt_line(cp, leftlen, " Wide Enabled:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Wide Enabled:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
 
-               len = asc_prt_line(cp, leftlen, " %X:%c",
-                                  i,
-                                  (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%c",
+                          i,
+                          (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
-       len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Transfer Bit Width:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
@@ -3913,37 +3615,30 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
                                ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
                                lramword);
 
-               len = asc_prt_line(cp, leftlen, " %X:%d",
-                                  i, (lramword & 0x8000) ? 16 : 8);
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%d",
+                          i, (lramword & 0x8000) ? 16 : 8);
 
                if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
                    (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
-                       len = asc_prt_line(cp, leftlen, "*");
-                       ASC_PRT_NEXT();
+                       seq_printf(m, "*");
                        renegotiate = 1;
                }
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
-       len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
-       ASC_PRT_NEXT();
+       seq_printf(m, " Synchronous Enabled:");
        for (i = 0; i <= ADV_MAX_TID; i++) {
                if ((chip_scsi_id == i) ||
                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                        continue;
                }
 
-               len = asc_prt_line(cp, leftlen, " %X:%c",
-                                  i,
-                                  (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
-                                  'N');
-               ASC_PRT_NEXT();
+               seq_printf(m, " %X:%c",
+                          i,
+                          (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        }
-       len = asc_prt_line(cp, leftlen, "\n");
-       ASC_PRT_NEXT();
+       seq_printf(m, "\n");
 
        AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
        for (i = 0; i <= ADV_MAX_TID; i++) {
@@ -3959,358 +3654,170 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
                        continue;
                }
 
-               len = asc_prt_line(cp, leftlen, "  %X:", i);
-               ASC_PRT_NEXT();
+               seq_printf(m, "  %X:", i);
 
                if ((lramword & 0x1F) == 0) {   /* Check for REQ/ACK Offset 0. */
-                       len = asc_prt_line(cp, leftlen, " Asynchronous");
-                       ASC_PRT_NEXT();
+                       seq_printf(m, " Asynchronous");
                } else {
-                       len =
-                           asc_prt_line(cp, leftlen,
-                                        " Transfer Period Factor: ");
-                       ASC_PRT_NEXT();
+                       seq_printf(m, " Transfer Period Factor: ");
 
                        if ((lramword & 0x1F00) == 0x1100) {    /* 80 Mhz */
-                               len =
-                                   asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
-                               ASC_PRT_NEXT();
+                               seq_printf(m, "9 (80.0 Mhz),");
                        } else if ((lramword & 0x1F00) == 0x1000) {     /* 40 Mhz */
-                               len =
-                                   asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
-                               ASC_PRT_NEXT();
+                               seq_printf(m, "10 (40.0 Mhz),");
                        } else {        /* 20 Mhz or below. */
 
                                period = (((lramword >> 8) * 25) + 50) / 4;
 
                                if (period == 0) {      /* Should never happen. */
-                                       len =
-                                           asc_prt_line(cp, leftlen,
-                                                        "%d (? Mhz), ");
-                                       ASC_PRT_NEXT();
+                                       seq_printf(m, "%d (? Mhz), ", period);
                                } else {
-                                       len = asc_prt_line(cp, leftlen,
-                                                          "%d (%d.%d Mhz),",
-                                                          period, 250 / period,
-                                                          ASC_TENTHS(250,
-                                                                     period));
-                                       ASC_PRT_NEXT();
+                                       seq_printf(m,
+                                                  "%d (%d.%d Mhz),",
+                                                  period, 250 / period,
+                                                  ASC_TENTHS(250, period));
                                }
                        }
 
-                       len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
-                                          lramword & 0x1F);
-                       ASC_PRT_NEXT();
+                       seq_printf(m, " REQ/ACK Offset: %d",
+                                  lramword & 0x1F);
                }
 
                if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
-                       len = asc_prt_line(cp, leftlen, "*\n");
+                       seq_printf(m, "*\n");
                        renegotiate = 1;
                } else {
-                       len = asc_prt_line(cp, leftlen, "\n");
+                       seq_printf(m, "\n");
                }
-               ASC_PRT_NEXT();
        }
 
        if (renegotiate) {
-               len = asc_prt_line(cp, leftlen,
-                                  " * = Re-negotiation pending before next command.\n");
-               ASC_PRT_NEXT();
+               seq_printf(m,
+                          " * = Re-negotiation pending before next command.\n");
        }
-
-       return totlen;
-}
-
-/*
- * asc_proc_copy()
- *
- * Copy proc information to a read buffer taking into account the current
- * read offset in the file and the remaining space in the read buffer.
- */
-static int
-asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
-             char *cp, int cplen)
-{
-       int cnt = 0;
-
-       ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n",
-                (unsigned)offset, (unsigned)advoffset, cplen);
-       if (offset <= advoffset) {
-               /* Read offset below current offset, copy everything. */
-               cnt = min(cplen, leftlen);
-               ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
-                        (ulong)curbuf, (ulong)cp, cnt);
-               memcpy(curbuf, cp, cnt);
-       } else if (offset < advoffset + cplen) {
-               /* Read offset within current range, partial copy. */
-               cnt = (advoffset + cplen) - offset;
-               cp = (cp + cplen) - cnt;
-               cnt = min(cnt, leftlen);
-               ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
-                        (ulong)curbuf, (ulong)cp, cnt);
-               memcpy(curbuf, cp, cnt);
-       }
-       return cnt;
 }
 
 #ifdef ADVANSYS_STATS
 /*
  * asc_prt_board_stats()
- *
- * Note: no single line should be greater than ASC_PRTLINE_SIZE,
- * cf. asc_prt_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
  */
-static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
+static void asc_prt_board_stats(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
        struct asc_stats *s = &boardp->asc_stats;
 
-       int leftlen = cplen;
-       int len, totlen = 0;
+       seq_printf(m,
+                  "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
+                  shost->host_no);
 
-       len = asc_prt_line(cp, leftlen,
-                          "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
-                          shost->host_no);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " queuecommand %u, reset %u, biosparam %u, interrupt %u\n",
+                  s->queuecommand, s->reset, s->biosparam,
+                  s->interrupt);
 
-       len = asc_prt_line(cp, leftlen,
-                          " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
-                          s->queuecommand, s->reset, s->biosparam,
-                          s->interrupt);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " callback %u, done %u, build_error %u, build_noreq %u, build_nosg %u\n",
+                  s->callback, s->done, s->build_error,
+                  s->adv_build_noreq, s->adv_build_nosg);
 
-       len = asc_prt_line(cp, leftlen,
-                          " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
-                          s->callback, s->done, s->build_error,
-                          s->adv_build_noreq, s->adv_build_nosg);
-       ASC_PRT_NEXT();
-
-       len = asc_prt_line(cp, leftlen,
-                          " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
-                          s->exe_noerror, s->exe_busy, s->exe_error,
-                          s->exe_unknown);
-       ASC_PRT_NEXT();
+       seq_printf(m,
+                  " exe_noerror %u, exe_busy %u, exe_error %u, exe_unknown %u\n",
+                  s->exe_noerror, s->exe_busy, s->exe_error,
+                  s->exe_unknown);
 
        /*
         * Display data transfer statistics.
         */
        if (s->xfer_cnt > 0) {
-               len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ",
-                                  s->xfer_cnt, s->xfer_elem);
-               ASC_PRT_NEXT();
+               seq_printf(m, " xfer_cnt %u, xfer_elem %u, ",
+                          s->xfer_cnt, s->xfer_elem);
 
-               len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n",
-                                  s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
-               ASC_PRT_NEXT();
+               seq_printf(m, "xfer_bytes %u.%01u kb\n",
+                          s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
 
                /* Scatter gather transfer statistics */
-               len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
-                                  s->xfer_elem / s->xfer_cnt,
-                                  ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
-               ASC_PRT_NEXT();
+               seq_printf(m, " avg_num_elem %u.%01u, ",
+                          s->xfer_elem / s->xfer_cnt,
+                          ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
 
-               len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
-                                  (s->xfer_sect / 2) / s->xfer_elem,
-                                  ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
-               ASC_PRT_NEXT();
+               seq_printf(m, "avg_elem_size %u.%01u kb, ",
+                          (s->xfer_sect / 2) / s->xfer_elem,
+                          ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
 
-               len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
-                                  (s->xfer_sect / 2) / s->xfer_cnt,
-                                  ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
-               ASC_PRT_NEXT();
+               seq_printf(m, "avg_xfer_size %u.%01u kb\n",
+                          (s->xfer_sect / 2) / s->xfer_cnt,
+                          ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
        }
-
-       return totlen;
 }
 #endif /* ADVANSYS_STATS */
 
 /*
- * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
+ * advansys_show_info() - /proc/scsi/advansys/{0,1,2,3,...}
  *
- * *buffer: I/O buffer
- * **start: if inout == FALSE pointer into buffer where user read should start
- * offset: current offset into a /proc/scsi/advansys/[0...] file
- * length: length of buffer
- * hostno: Scsi_Host host_no
- * inout: TRUE - user is writing; FALSE - user is reading
+ * m: seq_file to print into
+ * shost: Scsi_Host
  *
  * Return the number of bytes read from or written to a
  * /proc/scsi/advansys/[0...] file.
- *
- * Note: This function uses the per board buffer 'prtbuf' which is
- * allocated when the board is initialized in advansys_detect(). The
- * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
- * used to write to the buffer. The way asc_proc_copy() is written
- * if 'prtbuf' is too small it will not be overwritten. Instead the
- * user just won't get all the available statistics.
  */
 static int
-advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
-                  off_t offset, int length, int inout)
+advansys_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct asc_board *boardp = shost_priv(shost);
-       char *cp;
-       int cplen;
-       int cnt;
-       int totcnt;
-       int leftlen;
-       char *curbuf;
-       off_t advoffset;
 
        ASC_DBG(1, "begin\n");
 
-       /*
-        * User write not supported.
-        */
-       if (inout == TRUE)
-               return -ENOSYS;
-
        /*
         * User read of /proc/scsi/advansys/[0...] file.
         */
 
-       /* Copy read data starting at the beginning of the buffer. */
-       *start = buffer;
-       curbuf = buffer;
-       advoffset = 0;
-       totcnt = 0;
-       leftlen = length;
-
        /*
         * Get board configuration information.
         *
         * advansys_info() returns the board string from its own static buffer.
         */
-       cp = (char *)advansys_info(shost);
-       strcat(cp, "\n");
-       cplen = strlen(cp);
        /* Copy board information. */
-       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
-       totcnt += cnt;
-       leftlen -= cnt;
-       if (leftlen == 0) {
-               ASC_DBG(1, "totcnt %d\n", totcnt);
-               return totcnt;
-       }
-       advoffset += cplen;
-       curbuf += cnt;
-
+       seq_printf(m, "%s\n", (char *)advansys_info(shost));
        /*
         * Display Wide Board BIOS Information.
         */
-       if (!ASC_NARROW_BOARD(boardp)) {
-               cp = boardp->prtbuf;
-               cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
-               BUG_ON(cplen >= ASC_PRTBUF_SIZE);
-               cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
-                                 cplen);
-               totcnt += cnt;
-               leftlen -= cnt;
-               if (leftlen == 0) {
-                       ASC_DBG(1, "totcnt %d\n", totcnt);
-                       return totcnt;
-               }
-               advoffset += cplen;
-               curbuf += cnt;
-       }
+       if (!ASC_NARROW_BOARD(boardp))
+               asc_prt_adv_bios(m, shost);
 
        /*
         * Display driver information for each device attached to the board.
         */
-       cp = boardp->prtbuf;
-       cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
-       BUG_ON(cplen >= ASC_PRTBUF_SIZE);
-       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
-       totcnt += cnt;
-       leftlen -= cnt;
-       if (leftlen == 0) {
-               ASC_DBG(1, "totcnt %d\n", totcnt);
-               return totcnt;
-       }
-       advoffset += cplen;
-       curbuf += cnt;
+       asc_prt_board_devices(m, shost);
 
        /*
         * Display EEPROM configuration for the board.
         */
-       cp = boardp->prtbuf;
-       if (ASC_NARROW_BOARD(boardp)) {
-               cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
-       } else {
-               cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
-       }
-       BUG_ON(cplen >= ASC_PRTBUF_SIZE);
-       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
-       totcnt += cnt;
-       leftlen -= cnt;
-       if (leftlen == 0) {
-               ASC_DBG(1, "totcnt %d\n", totcnt);
-               return totcnt;
-       }
-       advoffset += cplen;
-       curbuf += cnt;
+       if (ASC_NARROW_BOARD(boardp))
+               asc_prt_asc_board_eeprom(m, shost);
+       else
+               asc_prt_adv_board_eeprom(m, shost);
 
        /*
         * Display driver configuration and information for the board.
         */
-       cp = boardp->prtbuf;
-       cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
-       BUG_ON(cplen >= ASC_PRTBUF_SIZE);
-       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
-       totcnt += cnt;
-       leftlen -= cnt;
-       if (leftlen == 0) {
-               ASC_DBG(1, "totcnt %d\n", totcnt);
-               return totcnt;
-       }
-       advoffset += cplen;
-       curbuf += cnt;
+       asc_prt_driver_conf(m, shost);
 
 #ifdef ADVANSYS_STATS
        /*
         * Display driver statistics for the board.
         */
-       cp = boardp->prtbuf;
-       cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
-       BUG_ON(cplen >= ASC_PRTBUF_SIZE);
-       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
-       totcnt += cnt;
-       leftlen -= cnt;
-       if (leftlen == 0) {
-               ASC_DBG(1, "totcnt %d\n", totcnt);
-               return totcnt;
-       }
-       advoffset += cplen;
-       curbuf += cnt;
+       asc_prt_board_stats(m, shost);
 #endif /* ADVANSYS_STATS */
 
        /*
         * Display Asc Library dynamic configuration information
         * for the board.
         */
-       cp = boardp->prtbuf;
-       if (ASC_NARROW_BOARD(boardp)) {
-               cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
-       } else {
-               cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
-       }
-       BUG_ON(cplen >= ASC_PRTBUF_SIZE);
-       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
-       totcnt += cnt;
-       leftlen -= cnt;
-       if (leftlen == 0) {
-               ASC_DBG(1, "totcnt %d\n", totcnt);
-               return totcnt;
-       }
-       advoffset += cplen;
-       curbuf += cnt;
-
-       ASC_DBG(1, "totcnt %d\n", totcnt);
-
-       return totcnt;
+       if (ASC_NARROW_BOARD(boardp))
+               asc_prt_asc_board_info(m, shost);
+       else
+               asc_prt_adv_board_info(m, shost);
+       return 0;
 }
 #endif /* CONFIG_PROC_FS */
 
@@ -11743,7 +11250,7 @@ static int AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
 static struct scsi_host_template advansys_template = {
        .proc_name = DRV_NAME,
 #ifdef CONFIG_PROC_FS
-       .proc_info = advansys_proc_info,
+       .show_info = advansys_show_info,
 #endif
        .name = DRV_NAME,
        .info = advansys_info,
@@ -11939,20 +11446,6 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
 #endif /* CONFIG_PCI */
        }
 
-#ifdef CONFIG_PROC_FS
-       /*
-        * Allocate buffer for printing information from
-        * /proc/scsi/advansys/[0...].
-        */
-       boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
-       if (!boardp->prtbuf) {
-               shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n",
-                               ASC_PRTBUF_SIZE);
-               ret = -ENOMEM;
-               goto err_unmap;
-       }
-#endif /* CONFIG_PROC_FS */
-
        if (ASC_NARROW_BOARD(boardp)) {
                /*
                 * Set the board bus type and PCI IRQ before
@@ -12010,7 +11503,7 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
        }
 
        if (ret)
-               goto err_free_proc;
+               goto err_unmap;
 
        /*
         * Save the EEPROM configuration so that it can be displayed
@@ -12055,7 +11548,7 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
                ASC_DBG(2, "AscInitSetConfig()\n");
                ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
                if (ret)
-                       goto err_free_proc;
+                       goto err_unmap;
        } else {
                ADVEEP_3550_CONFIG *ep_3550;
                ADVEEP_38C0800_CONFIG *ep_38C0800;
@@ -12290,7 +11783,7 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
                                shost_printk(KERN_ERR, shost, "request_dma() "
                                                "%d failed %d\n",
                                                shost->dma_channel, ret);
-                               goto err_free_proc;
+                               goto err_unmap;
                        }
                        AscEnableIsaDma(shost->dma_channel);
                }
@@ -12371,8 +11864,6 @@ static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
        if (shost->dma_channel != NO_ISA_DMA)
                free_dma(shost->dma_channel);
 #endif
- err_free_proc:
-       kfree(boardp->prtbuf);
  err_unmap:
        if (boardp->ioremap_addr)
                iounmap(boardp->ioremap_addr);
@@ -12406,7 +11897,6 @@ static int advansys_release(struct Scsi_Host *shost)
                iounmap(board->ioremap_addr);
                advansys_wide_free_mem(board);
        }
-       kfree(board->prtbuf);
        scsi_host_put(shost);
        ASC_DBG(1, "end\n");
        return 0;
index a284be17699f32ce37e7315adbc56d512d75b19e..3f7b6fee0a74ace322495bad7bbbc6c420b15c0c 100644 (file)
@@ -2977,11 +2977,10 @@ static void show_queues(struct Scsi_Host *shpnt)
 }
 
 #undef SPRINTF
-#define SPRINTF(args...) pos += sprintf(pos, ## args)
+#define SPRINTF(args...) seq_printf(m, ##args)
 
-static int get_command(char *pos, Scsi_Cmnd * ptr)
+static void get_command(struct seq_file *m, Scsi_Cmnd * ptr)
 {
-       char *start = pos;
        int i;
 
        SPRINTF("%p: target=%d; lun=%d; cmnd=( ",
@@ -3011,13 +3010,10 @@ static int get_command(char *pos, Scsi_Cmnd * ptr)
        if (ptr->SCp.phase & syncneg)
                SPRINTF("syncneg|");
        SPRINTF("; next=0x%p\n", SCNEXT(ptr));
-
-       return (pos - start);
 }
 
-static int get_ports(struct Scsi_Host *shpnt, char *pos)
+static void get_ports(struct seq_file *m, struct Scsi_Host *shpnt)
 {
-       char *start = pos;
        int s;
 
        SPRINTF("\n%s: %s(%s) ", CURRENT_SC ? "on bus" : "waiting", states[STATE].name, states[PREVSTATE].name);
@@ -3273,11 +3269,9 @@ static int get_ports(struct Scsi_Host *shpnt, char *pos)
        if (s & ENREQINIT)
                SPRINTF("ENREQINIT ");
        SPRINTF(")\n");
-
-       return (pos - start);
 }
 
-static int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
+static int aha152x_set_info(struct Scsi_Host *shpnt, char *buffer, int length)
 {
        if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0)
                return -EINVAL;
@@ -3320,26 +3314,11 @@ static int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
        return length;
 }
 
-#undef SPRINTF
-#define SPRINTF(args...) \
-       do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
-
-static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
-                     off_t offset, int length, int inout)
+static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt)
 {
        int i;
-       char *pos = buffer;
        Scsi_Cmnd *ptr;
        unsigned long flags;
-       int thislength;
-
-       DPRINTK(debug_procinfo, 
-              KERN_DEBUG "aha152x_proc_info: buffer=%p offset=%ld length=%d hostno=%d inout=%d\n",
-              buffer, offset, length, shpnt->host_no, inout);
-
-
-       if (inout)
-               return aha152x_set_info(buffer, length, shpnt);
 
        SPRINTF(AHA152X_REVID "\n");
 
@@ -3392,25 +3371,25 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start
        if (ISSUE_SC) {
                SPRINTF("not yet issued commands:\n");
                for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))
-                       pos += get_command(pos, ptr);
+                       get_command(m, ptr);
        } else
                SPRINTF("no not yet issued commands\n");
        DO_UNLOCK(flags);
 
        if (CURRENT_SC) {
                SPRINTF("current command:\n");
-               pos += get_command(pos, CURRENT_SC);
+               get_command(m, CURRENT_SC);
        } else
                SPRINTF("no current command\n");
 
        if (DISCONNECTED_SC) {
                SPRINTF("disconnected commands:\n");
                for (ptr = DISCONNECTED_SC; ptr; ptr = SCNEXT(ptr))
-                       pos += get_command(pos, ptr);
+                       get_command(m, ptr);
        } else
                SPRINTF("no disconnected commands\n");
 
-       pos += get_ports(shpnt, pos);
+       get_ports(m, shpnt);
 
 #if defined(AHA152X_STAT)
        SPRINTF("statistics:\n"
@@ -3440,24 +3419,7 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start
                        HOSTDATA(shpnt)->time[i]);
        }
 #endif
-
-       DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: pos=%p\n", pos);
-
-       thislength = pos - (buffer + offset);
-       DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: length=%d thislength=%d\n", length, thislength);
-
-       if(thislength<0) {
-               DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: output too short\n");
-               *start = NULL;
-               return 0;
-       }
-
-       thislength = thislength<length ? thislength : length;
-
-       DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: return %d\n", thislength);
-
-       *start = buffer + offset;
-       return thislength < length ? thislength : length;
+       return 0;
 }
 
 static int aha152x_adjust_queue(struct scsi_device *device)
@@ -3470,7 +3432,8 @@ static struct scsi_host_template aha152x_driver_template = {
        .module                         = THIS_MODULE,
        .name                           = AHA152X_REVID,
        .proc_name                      = "aha152x",
-       .proc_info                      = aha152x_proc_info,
+       .show_info                      = aha152x_show_info,
+       .write_info                     = aha152x_set_info,
        .queuecommand                   = aha152x_queue,
        .eh_abort_handler               = aha152x_abort,
        .eh_device_reset_handler        = aha152x_device_reset,
index df775e6ba5796c6cc8be7ed53a50fd4f269e73ac..5f3101797c93977c98cf047797868df0d00da5c0 100644 (file)
@@ -106,33 +106,14 @@ static inline dma_addr_t ecb_cpu_to_dma (struct Scsi_Host *host, void *cpu)
        return hdata->ecb_dma_addr + offset;
 }
 
-static int aha1740_proc_info(struct Scsi_Host *shpnt, char *buffer,
-                            char **start, off_t offset,
-                            int length, int inout)
+static int aha1740_show_info(struct seq_file *m, struct Scsi_Host *shpnt)
 {
-       int len;
-       struct aha1740_hostdata *host;
-
-       if (inout)
-               return-ENOSYS;
-
-       host = HOSTDATA(shpnt);
-
-       len = sprintf(buffer, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
+       struct aha1740_hostdata *host = HOSTDATA(shpnt);
+       seq_printf(m, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
                      "Extended translation %sabled.\n",
                      shpnt->io_port, shpnt->irq, host->edev->slot,
                      host->translation ? "en" : "dis");
-
-       if (offset > len) {
-               *start = buffer;
-               return 0;
-       }
-
-       *start = buffer + offset;
-       len -= offset;
-       if (len > length)
-               len = length;
-       return len;
+       return 0;
 }
 
 static int aha1740_makecode(unchar *sense, unchar *status)
@@ -556,7 +537,7 @@ static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy)
 static struct scsi_host_template aha1740_template = {
        .module           = THIS_MODULE,
        .proc_name        = "aha1740",
-       .proc_info        = aha1740_proc_info,
+       .show_info        = aha1740_show_info,
        .name             = "Adaptec 174x (EISA)",
        .queuecommand     = aha1740_queuecommand,
        .bios_param       = aha1740_biosparam,
index 9328121804bbdf34b660cb6ecbb78db00fa41e77..69d5c43a65e590e8b91651e29447bd2282837ad5 100644 (file)
@@ -906,7 +906,8 @@ struct scsi_host_template aic79xx_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "aic79xx",
        .proc_name              = "aic79xx",
-       .proc_info              = ahd_linux_proc_info,
+       .show_info              = ahd_linux_show_info,
+       .write_info             = ahd_proc_write_seeprom,
        .info                   = ahd_linux_info,
        .queuecommand           = ahd_linux_queue,
        .eh_abort_handler       = ahd_linux_abort,
@@ -1702,19 +1703,13 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
        switch (code) {
        case AC_TRANSFER_NEG:
        {
-               char    buf[80];
                struct  scsi_target *starget;
-               struct  info_str info;
                struct  ahd_initiator_tinfo *tinfo;
                struct  ahd_tmode_tstate *tstate;
                unsigned int target_ppr_options;
 
                BUG_ON(target == CAM_TARGET_WILDCARD);
 
-               info.buffer = buf;
-               info.length = sizeof(buf);
-               info.offset = 0;
-               info.pos = 0;
                tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
                                            target, &tstate);
 
index 28e43498cdffe00ba8c1e9d11d6e639d01eb5e03..c58fa33c659284b7925246d6cf765af8b5104552 100644 (file)
@@ -379,14 +379,6 @@ void ahd_insb(struct ahd_softc * ahd, long port,
 int            ahd_linux_register_host(struct ahd_softc *,
                                        struct scsi_host_template *);
 
-/*************************** Pretty Printing **********************************/
-struct info_str {
-       char *buffer;
-       int length;
-       off_t offset;
-       int pos;
-};
-
 /******************************** Locking *************************************/
 static inline void
 ahd_lockinit(struct ahd_softc *ahd)
@@ -513,8 +505,8 @@ ahd_flush_device_writes(struct ahd_softc *ahd)
 }
 
 /**************************** Proc FS Support *********************************/
-int    ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
-                           off_t, int, int);
+int    ahd_proc_write_seeprom(struct Scsi_Host *, char *, int);
+int    ahd_linux_show_info(struct seq_file *,struct Scsi_Host *);
 
 /*********************** Transaction Access Wrappers **************************/
 static inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
index 59c85d5a153acf86633658ce248aec18fbc2ae47..e9778b4f7e323fa0331d564aac80707e24081c43 100644 (file)
 #include "aic79xx_osm.h"
 #include "aic79xx_inline.h"
 
-static void    copy_mem_info(struct info_str *info, char *data, int len);
-static int     copy_info(struct info_str *info, char *fmt, ...);
 static void    ahd_dump_target_state(struct ahd_softc *ahd,
-                                     struct info_str *info,
+                                     struct seq_file *m,
                                      u_int our_id, char channel,
                                      u_int target_id);
-static void    ahd_dump_device_state(struct info_str *info,
+static void    ahd_dump_device_state(struct seq_file *m,
                                      struct scsi_device *sdev);
-static int     ahd_proc_write_seeprom(struct ahd_softc *ahd,
-                                      char *buffer, int length);
 
 /*
  * Table of syncrates that don't follow the "divisible by 4"
@@ -93,58 +89,15 @@ ahd_calc_syncsrate(u_int period_factor)
        return (10000000 / (period_factor * 4 * 10));
 }
 
-
-static void
-copy_mem_info(struct info_str *info, char *data, int len)
-{
-       if (info->pos + len > info->offset + info->length)
-               len = info->offset + info->length - info->pos;
-
-       if (info->pos + len < info->offset) {
-               info->pos += len;
-               return;
-       }
-
-       if (info->pos < info->offset) {
-               off_t partial;
-
-               partial = info->offset - info->pos;
-               data += partial;
-               info->pos += partial;
-               len  -= partial;
-       }
-
-       if (len > 0) {
-               memcpy(info->buffer, data, len);
-               info->pos += len;
-               info->buffer += len;
-       }
-}
-
-static int
-copy_info(struct info_str *info, char *fmt, ...)
-{
-       va_list args;
-       char buf[256];
-       int len;
-
-       va_start(args, fmt);
-       len = vsprintf(buf, fmt, args);
-       va_end(args);
-
-       copy_mem_info(info, buf, len);
-       return (len);
-}
-
 static void
-ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
+ahd_format_transinfo(struct seq_file *m, struct ahd_transinfo *tinfo)
 {
        u_int speed;
        u_int freq;
        u_int mb;
 
        if (tinfo->period == AHD_PERIOD_UNKNOWN) {
-               copy_info(info, "Renegotiation Pending\n");
+               seq_printf(m, "Renegotiation Pending\n");
                return;
        }
         speed = 3300;
@@ -156,34 +109,34 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
        speed *= (0x01 << tinfo->width);
         mb = speed / 1000;
         if (mb > 0)
-               copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000);
+               seq_printf(m, "%d.%03dMB/s transfers", mb, speed % 1000);
         else
-               copy_info(info, "%dKB/s transfers", speed);
+               seq_printf(m, "%dKB/s transfers", speed);
 
        if (freq != 0) {
                int     printed_options;
 
                printed_options = 0;
-               copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000);
+               seq_printf(m, " (%d.%03dMHz", freq / 1000, freq % 1000);
                if ((tinfo->ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
-                       copy_info(info, " RDSTRM");
+                       seq_printf(m, " RDSTRM");
                        printed_options++;
                }
                if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
-                       copy_info(info, "%s", printed_options ? "|DT" : " DT");
+                       seq_printf(m, "%s", printed_options ? "|DT" : " DT");
                        printed_options++;
                }
                if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
-                       copy_info(info, "%s", printed_options ? "|IU" : " IU");
+                       seq_printf(m, "%s", printed_options ? "|IU" : " IU");
                        printed_options++;
                }
                if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) {
-                       copy_info(info, "%s",
+                       seq_printf(m, "%s",
                                  printed_options ? "|RTI" : " RTI");
                        printed_options++;
                }
                if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
-                       copy_info(info, "%s",
+                       seq_printf(m, "%s",
                                  printed_options ? "|QAS" : " QAS");
                        printed_options++;
                }
@@ -191,19 +144,19 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
 
        if (tinfo->width > 0) {
                if (freq != 0) {
-                       copy_info(info, ", ");
+                       seq_printf(m, ", ");
                } else {
-                       copy_info(info, " (");
+                       seq_printf(m, " (");
                }
-               copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width));
+               seq_printf(m, "%dbit)", 8 * (0x01 << tinfo->width));
        } else if (freq != 0) {
-               copy_info(info, ")");
+               seq_printf(m, ")");
        }
-       copy_info(info, "\n");
+       seq_printf(m, "\n");
 }
 
 static void
-ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
+ahd_dump_target_state(struct ahd_softc *ahd, struct seq_file *m,
                      u_int our_id, char channel, u_int target_id)
 {
        struct  scsi_target *starget;
@@ -213,17 +166,17 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
 
        tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
                                    target_id, &tstate);
-       copy_info(info, "Target %d Negotiation Settings\n", target_id);
-       copy_info(info, "\tUser: ");
-       ahd_format_transinfo(info, &tinfo->user);
+       seq_printf(m, "Target %d Negotiation Settings\n", target_id);
+       seq_printf(m, "\tUser: ");
+       ahd_format_transinfo(m, &tinfo->user);
        starget = ahd->platform_data->starget[target_id];
        if (starget == NULL)
                return;
 
-       copy_info(info, "\tGoal: ");
-       ahd_format_transinfo(info, &tinfo->goal);
-       copy_info(info, "\tCurr: ");
-       ahd_format_transinfo(info, &tinfo->curr);
+       seq_printf(m, "\tGoal: ");
+       ahd_format_transinfo(m, &tinfo->goal);
+       seq_printf(m, "\tCurr: ");
+       ahd_format_transinfo(m, &tinfo->curr);
 
        for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
                struct scsi_device *dev;
@@ -233,29 +186,30 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
                if (dev == NULL)
                        continue;
 
-               ahd_dump_device_state(info, dev);
+               ahd_dump_device_state(m, dev);
        }
 }
 
 static void
-ahd_dump_device_state(struct info_str *info, struct scsi_device *sdev)
+ahd_dump_device_state(struct seq_file *m, struct scsi_device *sdev)
 {
        struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
 
-       copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
+       seq_printf(m, "\tChannel %c Target %d Lun %d Settings\n",
                  sdev->sdev_target->channel + 'A',
                  sdev->sdev_target->id, sdev->lun);
 
-       copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
-       copy_info(info, "\t\tCommands Active %d\n", dev->active);
-       copy_info(info, "\t\tCommand Openings %d\n", dev->openings);
-       copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags);
-       copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
+       seq_printf(m, "\t\tCommands Queued %ld\n", dev->commands_issued);
+       seq_printf(m, "\t\tCommands Active %d\n", dev->active);
+       seq_printf(m, "\t\tCommand Openings %d\n", dev->openings);
+       seq_printf(m, "\t\tMax Tagged Openings %d\n", dev->maxtags);
+       seq_printf(m, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
 }
 
-static int
-ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
+int
+ahd_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
 {
+       struct  ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
        ahd_mode_state saved_modes;
        int have_seeprom;
        u_long s;
@@ -319,64 +273,45 @@ done:
  * Return information to handle /proc support for the driver.
  */
 int
-ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
-                   off_t offset, int length, int inout)
+ahd_linux_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct  ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
-       struct  info_str info;
        char    ahd_info[256];
        u_int   max_targ;
        u_int   i;
-       int     retval;
 
-        /* Has data been written to the file? */ 
-       if (inout == TRUE) {
-               retval = ahd_proc_write_seeprom(ahd, buffer, length);
-               goto done;
-       }
-
-       if (start)
-               *start = buffer;
-
-       info.buffer     = buffer;
-       info.length     = length;
-       info.offset     = offset;
-       info.pos        = 0;
-
-       copy_info(&info, "Adaptec AIC79xx driver version: %s\n",
+       seq_printf(m, "Adaptec AIC79xx driver version: %s\n",
                  AIC79XX_DRIVER_VERSION);
-       copy_info(&info, "%s\n", ahd->description);
+       seq_printf(m, "%s\n", ahd->description);
        ahd_controller_info(ahd, ahd_info);
-       copy_info(&info, "%s\n", ahd_info);
-       copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
+       seq_printf(m, "%s\n", ahd_info);
+       seq_printf(m, "Allocated SCBs: %d, SG List Length: %d\n\n",
                  ahd->scb_data.numscbs, AHD_NSEG);
 
        max_targ = 16;
 
        if (ahd->seep_config == NULL)
-               copy_info(&info, "No Serial EEPROM\n");
+               seq_printf(m, "No Serial EEPROM\n");
        else {
-               copy_info(&info, "Serial EEPROM:\n");
+               seq_printf(m, "Serial EEPROM:\n");
                for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) {
                        if (((i % 8) == 0) && (i != 0)) {
-                               copy_info(&info, "\n");
+                               seq_printf(m, "\n");
                        }
-                       copy_info(&info, "0x%.4x ",
+                       seq_printf(m, "0x%.4x ",
                                  ((uint16_t*)ahd->seep_config)[i]);
                }
-               copy_info(&info, "\n");
+               seq_printf(m, "\n");
        }
-       copy_info(&info, "\n");
+       seq_printf(m, "\n");
 
        if ((ahd->features & AHD_WIDE) == 0)
                max_targ = 8;
 
        for (i = 0; i < max_targ; i++) {
 
-               ahd_dump_target_state(ahd, &info, ahd->our_id, 'A',
+               ahd_dump_target_state(ahd, m, ahd->our_id, 'A',
                                      /*target_id*/i);
        }
-       retval = info.pos > info.offset ? info.pos - info.offset : 0;
-done:
-       return (retval);
+       return 0;
 }
index 5a477cdc780dcf1c3a8ecc0865ce9199a517daf8..c0c62583b5420610b23ab2732eb8a05d0468ef8c 100644 (file)
@@ -803,7 +803,8 @@ struct scsi_host_template aic7xxx_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "aic7xxx",
        .proc_name              = "aic7xxx",
-       .proc_info              = ahc_linux_proc_info,
+       .show_info              = ahc_linux_show_info,
+       .write_info             = ahc_proc_write_seeprom,
        .info                   = ahc_linux_info,
        .queuecommand           = ahc_linux_queue,
        .eh_abort_handler       = ahc_linux_abort,
@@ -1631,10 +1632,8 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
        switch (code) {
        case AC_TRANSFER_NEG:
        {
-               char    buf[80];
                struct  scsi_target *starget;
                struct  ahc_linux_target *targ;
-               struct  info_str info;
                struct  ahc_initiator_tinfo *tinfo;
                struct  ahc_tmode_tstate *tstate;
                int     target_offset;
@@ -1642,10 +1641,6 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
 
                BUG_ON(target == CAM_TARGET_WILDCARD);
 
-               info.buffer = buf;
-               info.length = sizeof(buf);
-               info.offset = 0;
-               info.pos = 0;
                tinfo = ahc_fetch_transinfo(ahc, channel,
                                                channel == 'A' ? ahc->our_id
                                                               : ahc->our_id_b,
index bca0fb83f553391d40e2509b51be31f13cf0e402..bc4cca92ff04ea5f8f4563ab5b2fc0523fc8be3c 100644 (file)
@@ -383,14 +383,6 @@ void ahc_insb(struct ahc_softc * ahc, long port,
 int            ahc_linux_register_host(struct ahc_softc *,
                                        struct scsi_host_template *);
 
-/*************************** Pretty Printing **********************************/
-struct info_str {
-       char *buffer;
-       int length;
-       off_t offset;
-       int pos;
-};
-
 /******************************** Locking *************************************/
 /* Lock protecting internal data structures */
 
@@ -523,8 +515,8 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
 }
 
 /**************************** Proc FS Support *********************************/
-int    ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
-                           off_t, int, int);
+int    ahc_proc_write_seeprom(struct Scsi_Host *, char *, int);
+int    ahc_linux_show_info(struct seq_file *, struct Scsi_Host *);
 
 /*************************** Domain Validation ********************************/
 /*********************** Transaction Access Wrappers *************************/
index f2525f8ed1c73fee722bb256a322556a90c0b48d..383a3d11652d67f292a09d624b5f08106d2e80d6 100644 (file)
 #include "aic7xxx_inline.h"
 #include "aic7xxx_93cx6.h"
 
-static void    copy_mem_info(struct info_str *info, char *data, int len);
-static int     copy_info(struct info_str *info, char *fmt, ...);
 static void    ahc_dump_target_state(struct ahc_softc *ahc,
-                                     struct info_str *info,
+                                     struct seq_file *m,
                                      u_int our_id, char channel,
                                      u_int target_id, u_int target_offset);
-static void    ahc_dump_device_state(struct info_str *info,
+static void    ahc_dump_device_state(struct seq_file *m,
                                      struct scsi_device *dev);
-static int     ahc_proc_write_seeprom(struct ahc_softc *ahc,
-                                      char *buffer, int length);
 
 /*
  * Table of syncrates that don't follow the "divisible by 4"
@@ -94,51 +90,8 @@ ahc_calc_syncsrate(u_int period_factor)
        return (10000000 / (period_factor * 4 * 10));
 }
 
-
-static void
-copy_mem_info(struct info_str *info, char *data, int len)
-{
-       if (info->pos + len > info->offset + info->length)
-               len = info->offset + info->length - info->pos;
-
-       if (info->pos + len < info->offset) {
-               info->pos += len;
-               return;
-       }
-
-       if (info->pos < info->offset) {
-               off_t partial;
-
-               partial = info->offset - info->pos;
-               data += partial;
-               info->pos += partial;
-               len  -= partial;
-       }
-
-       if (len > 0) {
-               memcpy(info->buffer, data, len);
-               info->pos += len;
-               info->buffer += len;
-       }
-}
-
-static int
-copy_info(struct info_str *info, char *fmt, ...)
-{
-       va_list args;
-       char buf[256];
-       int len;
-
-       va_start(args, fmt);
-       len = vsprintf(buf, fmt, args);
-       va_end(args);
-
-       copy_mem_info(info, buf, len);
-       return (len);
-}
-
 static void
-ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
+ahc_format_transinfo(struct seq_file *m, struct ahc_transinfo *tinfo)
 {
        u_int speed;
        u_int freq;
@@ -153,12 +106,12 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
        speed *= (0x01 << tinfo->width);
         mb = speed / 1000;
         if (mb > 0)
-               copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000);
+               seq_printf(m, "%d.%03dMB/s transfers", mb, speed % 1000);
         else
-               copy_info(info, "%dKB/s transfers", speed);
+               seq_printf(m, "%dKB/s transfers", speed);
 
        if (freq != 0) {
-               copy_info(info, " (%d.%03dMHz%s, offset %d",
+               seq_printf(m, " (%d.%03dMHz%s, offset %d",
                         freq / 1000, freq % 1000,
                         (tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0
                         ? " DT" : "", tinfo->offset);
@@ -166,19 +119,19 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
 
        if (tinfo->width > 0) {
                if (freq != 0) {
-                       copy_info(info, ", ");
+                       seq_printf(m, ", ");
                } else {
-                       copy_info(info, " (");
+                       seq_printf(m, " (");
                }
-               copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width));
+               seq_printf(m, "%dbit)", 8 * (0x01 << tinfo->width));
        } else if (freq != 0) {
-               copy_info(info, ")");
+               seq_printf(m, ")");
        }
-       copy_info(info, "\n");
+       seq_printf(m, "\n");
 }
 
 static void
-ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
+ahc_dump_target_state(struct ahc_softc *ahc, struct seq_file *m,
                      u_int our_id, char channel, u_int target_id,
                      u_int target_offset)
 {
@@ -190,18 +143,18 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
        tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
                                    target_id, &tstate);
        if ((ahc->features & AHC_TWIN) != 0)
-               copy_info(info, "Channel %c ", channel);
-       copy_info(info, "Target %d Negotiation Settings\n", target_id);
-       copy_info(info, "\tUser: ");
-       ahc_format_transinfo(info, &tinfo->user);
+               seq_printf(m, "Channel %c ", channel);
+       seq_printf(m, "Target %d Negotiation Settings\n", target_id);
+       seq_printf(m, "\tUser: ");
+       ahc_format_transinfo(m, &tinfo->user);
        starget = ahc->platform_data->starget[target_offset];
        if (!starget)
                return;
 
-       copy_info(info, "\tGoal: ");
-       ahc_format_transinfo(info, &tinfo->goal);
-       copy_info(info, "\tCurr: ");
-       ahc_format_transinfo(info, &tinfo->curr);
+       seq_printf(m, "\tGoal: ");
+       ahc_format_transinfo(m, &tinfo->goal);
+       seq_printf(m, "\tCurr: ");
+       ahc_format_transinfo(m, &tinfo->curr);
 
        for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
                struct scsi_device *sdev;
@@ -211,29 +164,30 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
                if (sdev == NULL)
                        continue;
 
-               ahc_dump_device_state(info, sdev);
+               ahc_dump_device_state(m, sdev);
        }
 }
 
 static void
-ahc_dump_device_state(struct info_str *info, struct scsi_device *sdev)
+ahc_dump_device_state(struct seq_file *m, struct scsi_device *sdev)
 {
        struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
 
-       copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
+       seq_printf(m, "\tChannel %c Target %d Lun %d Settings\n",
                  sdev->sdev_target->channel + 'A',
                  sdev->sdev_target->id, sdev->lun);
 
-       copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
-       copy_info(info, "\t\tCommands Active %d\n", dev->active);
-       copy_info(info, "\t\tCommand Openings %d\n", dev->openings);
-       copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags);
-       copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
+       seq_printf(m, "\t\tCommands Queued %ld\n", dev->commands_issued);
+       seq_printf(m, "\t\tCommands Active %d\n", dev->active);
+       seq_printf(m, "\t\tCommand Openings %d\n", dev->openings);
+       seq_printf(m, "\t\tMax Tagged Openings %d\n", dev->maxtags);
+       seq_printf(m, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
 }
 
-static int
-ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length)
+int
+ahc_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
 {
+       struct  ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
        struct seeprom_descriptor sd;
        int have_seeprom;
        u_long s;
@@ -332,53 +286,36 @@ done:
  * Return information to handle /proc support for the driver.
  */
 int
-ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
-                   off_t offset, int length, int inout)
+ahc_linux_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
        struct  ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
-       struct  info_str info;
        char    ahc_info[256];
        u_int   max_targ;
        u_int   i;
-       int     retval;
 
-        /* Has data been written to the file? */ 
-       if (inout == TRUE) {
-               retval = ahc_proc_write_seeprom(ahc, buffer, length);
-               goto done;
-       }
-
-       if (start)
-               *start = buffer;
-
-       info.buffer     = buffer;
-       info.length     = length;
-       info.offset     = offset;
-       info.pos        = 0;
-
-       copy_info(&info, "Adaptec AIC7xxx driver version: %s\n",
+       seq_printf(m, "Adaptec AIC7xxx driver version: %s\n",
                  AIC7XXX_DRIVER_VERSION);
-       copy_info(&info, "%s\n", ahc->description);
+       seq_printf(m, "%s\n", ahc->description);
        ahc_controller_info(ahc, ahc_info);
-       copy_info(&info, "%s\n", ahc_info);
-       copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
+       seq_printf(m, "%s\n", ahc_info);
+       seq_printf(m, "Allocated SCBs: %d, SG List Length: %d\n\n",
                  ahc->scb_data->numscbs, AHC_NSEG);
 
 
        if (ahc->seep_config == NULL)
-               copy_info(&info, "No Serial EEPROM\n");
+               seq_printf(m, "No Serial EEPROM\n");
        else {
-               copy_info(&info, "Serial EEPROM:\n");
+               seq_printf(m, "Serial EEPROM:\n");
                for (i = 0; i < sizeof(*ahc->seep_config)/2; i++) {
                        if (((i % 8) == 0) && (i != 0)) {
-                               copy_info(&info, "\n");
+                               seq_printf(m, "\n");
                        }
-                       copy_info(&info, "0x%.4x ",
+                       seq_printf(m, "0x%.4x ",
                                  ((uint16_t*)ahc->seep_config)[i]);
                }
-               copy_info(&info, "\n");
+               seq_printf(m, "\n");
        }
-       copy_info(&info, "\n");
+       seq_printf(m, "\n");
 
        max_targ = 16;
        if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
@@ -398,10 +335,8 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
                        target_id = i % 8;
                }
 
-               ahc_dump_target_state(ahc, &info, our_id,
+               ahc_dump_target_state(ahc, m, our_id,
                                      channel, target_id, i);
        }
-       retval = info.pos > info.offset ? info.pos - info.offset : 0;
-done:
-       return (retval);
+       return 0;
 }
index 5b212f0df898c07640cd67f5116beade78ec0c10..33ec9c64340002b6fb64cc732b2adf43b7657069 100644 (file)
@@ -11108,7 +11108,7 @@ MODULE_VERSION(AIC7XXX_H_VERSION);
 
 
 static struct scsi_host_template driver_template = {
-       .proc_info              = aic7xxx_proc_info,
+       .show_info              = aic7xxx_show_info,
        .detect                 = aic7xxx_detect,
        .release                = aic7xxx_release,
        .info                   = aic7xxx_info, 
index b07e4f04fd00b3b82e3121a9decd8fe87b1a5a5e..976f45ccf2cf46dc949ce99ebefe14668822a768 100644 (file)
  *-M*************************************************************************/
 
 
-#define        BLS     (&aic7xxx_buffer[size])
 #define HDRB \
 "               0 - 4K   4 - 16K   16 - 64K  64 - 256K  256K - 1M        1M+"
 
-#ifdef PROC_DEBUG
-extern int vsprintf(char *, const char *, va_list);
-
-static void
-proc_debug(const char *fmt, ...)
-{
-  va_list ap;
-  char buf[256];
-
-  va_start(ap, fmt);
-  vsprintf(buf, fmt, ap);
-  printk(buf);
-  va_end(ap);
-}
-#else /* PROC_DEBUG */
-#  define proc_debug(fmt, args...)
-#endif /* PROC_DEBUG */
-
-static int aic7xxx_buffer_size = 0;
-static char *aic7xxx_buffer = NULL;
-
 
 /*+F*************************************************************************
  * Function:
- *   aic7xxx_set_info
- *
- * Description:
- *   Set parameters for the driver from the /proc filesystem.
- *-F*************************************************************************/
-static int
-aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
-{
-  proc_debug("aic7xxx_set_info(): %s\n", buffer);
-  return (-ENOSYS);  /* Currently this is a no-op */
-}
-
-
-/*+F*************************************************************************
- * Function:
- *   aic7xxx_proc_info
+ *   aic7xxx_show_info
  *
  * Description:
  *   Return information to handle /proc support for the driver.
  *-F*************************************************************************/
 int
-aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, 
-                    int inout)
+aic7xxx_show_info(struct seq_file *m, struct Scsi_Host *HBAptr)
 {
   struct aic7xxx_host *p;
   struct aic_dev_data *aic_dev;
   struct scsi_device *sdptr;
-  int    size = 0;
   unsigned char i;
   unsigned char tindex;
 
@@ -94,66 +55,21 @@ aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t
 
   if (!p)
   {
-    size += sprintf(buffer, "Can't find adapter for host number %d\n", HBAptr->host_no);
-    if (size > length)
-    {
-      return (size);
-    }
-    else
-    {
-      return (length);
-    }
-  }
-
-  if (inout == TRUE) /* Has data been written to the file? */ 
-  {
-    return (aic7xxx_set_info(buffer, length, HBAptr));
+    seq_printf(m, "Can't find adapter for host number %d\n", HBAptr->host_no);
+    return 0;
   }
 
   p = (struct aic7xxx_host *) HBAptr->hostdata;
 
-  /*
-   * It takes roughly 1K of space to hold all relevant card info, not
-   * counting any proc stats, so we start out with a 1.5k buffer size and
-   * if proc_stats is defined, then we sweep the stats structure to see
-   * how many drives we will be printing out for and add 384 bytes per
-   * device with active stats.
-   *
-   * Hmmmm...that 1.5k seems to keep growing as items get added so they
-   * can be easily viewed for debugging purposes.  So, we bumped that
-   * 1.5k to 4k so we can quit having to bump it all the time.
-   */
-
-  size = 4096;
-  list_for_each_entry(aic_dev, &p->aic_devs, list)
-    size += 512;
-  if (aic7xxx_buffer_size != size)
-  {
-    if (aic7xxx_buffer != NULL) 
-    {
-      kfree(aic7xxx_buffer);
-      aic7xxx_buffer_size = 0;
-    }
-    aic7xxx_buffer = kmalloc(size, GFP_KERNEL);
-  }
-  if (aic7xxx_buffer == NULL)
-  {
-    size = sprintf(buffer, "AIC7xxx - kmalloc error at line %d\n",
-        __LINE__);
-    return size;
-  }
-  aic7xxx_buffer_size = size;
-
-  size = 0;
-  size += sprintf(BLS, "Adaptec AIC7xxx driver version: ");
-  size += sprintf(BLS, "%s/", AIC7XXX_C_VERSION);
-  size += sprintf(BLS, "%s", AIC7XXX_H_VERSION);
-  size += sprintf(BLS, "\n");
-  size += sprintf(BLS, "Adapter Configuration:\n");
-  size += sprintf(BLS, "           SCSI Adapter: %s\n",
+  seq_printf(m, "Adaptec AIC7xxx driver version: ");
+  seq_printf(m, "%s/", AIC7XXX_C_VERSION);
+  seq_printf(m, "%s", AIC7XXX_H_VERSION);
+  seq_printf(m, "\n");
+  seq_printf(m, "Adapter Configuration:\n");
+  seq_printf(m, "           SCSI Adapter: %s\n",
       board_names[p->board_name_index]);
   if (p->flags & AHC_TWIN)
-    size += sprintf(BLS, "                         Twin Channel Controller ");
+    seq_printf(m, "                         Twin Channel Controller ");
   else
   {
     char *channel = "";
@@ -184,86 +100,86 @@ aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t
       ultra = "Ultra-2 LVD/SE ";
     else if (p->features & AHC_ULTRA)
       ultra = "Ultra ";
-    size += sprintf(BLS, "                           %s%sController%s ",
+    seq_printf(m, "                           %s%sController%s ",
       ultra, wide, channel);
   }
   switch(p->chip & ~AHC_CHIPID_MASK)
   {
     case AHC_VL:
-      size += sprintf(BLS, "at VLB slot %d\n", p->pci_device_fn);
+      seq_printf(m, "at VLB slot %d\n", p->pci_device_fn);
       break;
     case AHC_EISA:
-      size += sprintf(BLS, "at EISA slot %d\n", p->pci_device_fn);
+      seq_printf(m, "at EISA slot %d\n", p->pci_device_fn);
       break;
     default:
-      size += sprintf(BLS, "at PCI %d/%d/%d\n", p->pci_bus,
+      seq_printf(m, "at PCI %d/%d/%d\n", p->pci_bus,
         PCI_SLOT(p->pci_device_fn), PCI_FUNC(p->pci_device_fn));
       break;
   }
   if( !(p->maddr) )
   {
-    size += sprintf(BLS, "    Programmed I/O Base: %lx\n", p->base);
+    seq_printf(m, "    Programmed I/O Base: %lx\n", p->base);
   }
   else
   {
-    size += sprintf(BLS, "    PCI MMAPed I/O Base: 0x%lx\n", p->mbase);
+    seq_printf(m, "    PCI MMAPed I/O Base: 0x%lx\n", p->mbase);
   }
   if( (p->chip & (AHC_VL | AHC_EISA)) )
   {
-    size += sprintf(BLS, "    BIOS Memory Address: 0x%08x\n", p->bios_address);
+    seq_printf(m, "    BIOS Memory Address: 0x%08x\n", p->bios_address);
   }
-  size += sprintf(BLS, " Adapter SEEPROM Config: %s\n",
+  seq_printf(m, " Adapter SEEPROM Config: %s\n",
           (p->flags & AHC_SEEPROM_FOUND) ? "SEEPROM found and used." :
          ((p->flags & AHC_USEDEFAULTS) ? "SEEPROM not found, using defaults." :
            "SEEPROM not found, using leftover BIOS values.") );
-  size += sprintf(BLS, "      Adaptec SCSI BIOS: %s\n",
+  seq_printf(m, "      Adaptec SCSI BIOS: %s\n",
           (p->flags & AHC_BIOS_ENABLED) ? "Enabled" : "Disabled");
-  size += sprintf(BLS, "                    IRQ: %d\n", HBAptr->irq);
-  size += sprintf(BLS, "                   SCBs: Active %d, Max Active %d,\n",
+  seq_printf(m, "                    IRQ: %d\n", HBAptr->irq);
+  seq_printf(m, "                   SCBs: Active %d, Max Active %d,\n",
             p->activescbs, p->max_activescbs);
-  size += sprintf(BLS, "                         Allocated %d, HW %d, "
+  seq_printf(m, "                         Allocated %d, HW %d, "
             "Page %d\n", p->scb_data->numscbs, p->scb_data->maxhscbs,
             p->scb_data->maxscbs);
   if (p->flags & AHC_EXTERNAL_SRAM)
-    size += sprintf(BLS, "                         Using External SCB SRAM\n");
-  size += sprintf(BLS, "             Interrupts: %ld", p->isr_count);
+    seq_printf(m, "                         Using External SCB SRAM\n");
+  seq_printf(m, "             Interrupts: %ld", p->isr_count);
   if (p->chip & AHC_EISA)
   {
-    size += sprintf(BLS, " %s\n",
+    seq_printf(m, " %s\n",
         (p->pause & IRQMS) ? "(Level Sensitive)" : "(Edge Triggered)");
   }
   else
   {
-    size += sprintf(BLS, "\n");
+    seq_printf(m, "\n");
   }
-  size += sprintf(BLS, "      BIOS Control Word: 0x%04x\n",
+  seq_printf(m, "      BIOS Control Word: 0x%04x\n",
             p->bios_control);
-  size += sprintf(BLS, "   Adapter Control Word: 0x%04x\n",
+  seq_printf(m, "   Adapter Control Word: 0x%04x\n",
             p->adapter_control);
-  size += sprintf(BLS, "   Extended Translation: %sabled\n",
+  seq_printf(m, "   Extended Translation: %sabled\n",
       (p->flags & AHC_EXTEND_TRANS_A) ? "En" : "Dis");
-  size += sprintf(BLS, "Disconnect Enable Flags: 0x%04x\n", p->discenable);
+  seq_printf(m, "Disconnect Enable Flags: 0x%04x\n", p->discenable);
   if (p->features & (AHC_ULTRA | AHC_ULTRA2))
   {
-    size += sprintf(BLS, "     Ultra Enable Flags: 0x%04x\n", p->ultraenb);
+    seq_printf(m, "     Ultra Enable Flags: 0x%04x\n", p->ultraenb);
   }
-  size += sprintf(BLS, "Default Tag Queue Depth: %d\n", aic7xxx_default_queue_depth);
-  size += sprintf(BLS, "    Tagged Queue By Device array for aic7xxx host "
+  seq_printf(m, "Default Tag Queue Depth: %d\n", aic7xxx_default_queue_depth);
+  seq_printf(m, "    Tagged Queue By Device array for aic7xxx host "
                        "instance %d:\n", p->instance);
-  size += sprintf(BLS, "      {");
+  seq_printf(m, "      {");
   for(i=0; i < (MAX_TARGETS - 1); i++)
-    size += sprintf(BLS, "%d,",aic7xxx_tag_info[p->instance].tag_commands[i]);
-  size += sprintf(BLS, "%d}\n",aic7xxx_tag_info[p->instance].tag_commands[i]);
+    seq_printf(m, "%d,",aic7xxx_tag_info[p->instance].tag_commands[i]);
+  seq_printf(m, "%d}\n",aic7xxx_tag_info[p->instance].tag_commands[i]);
 
-  size += sprintf(BLS, "\n");
-  size += sprintf(BLS, "Statistics:\n\n");
+  seq_printf(m, "\n");
+  seq_printf(m, "Statistics:\n\n");
   list_for_each_entry(aic_dev, &p->aic_devs, list)
   {
     sdptr = aic_dev->SDptr;
     tindex = sdptr->channel << 3 | sdptr->id;
-    size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
+    seq_printf(m, "(scsi%d:%d:%d:%d)\n",
         p->host_no, sdptr->channel, sdptr->id, sdptr->lun);
-    size += sprintf(BLS, "  Device using %s/%s",
+    seq_printf(m, "  Device using %s/%s",
           (aic_dev->cur.width == MSG_EXT_WDTR_BUS_16_BIT) ?
           "Wide" : "Narrow",
           (aic_dev->cur.offset != 0) ?
@@ -279,78 +195,59 @@ aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t
       sync_rate = aic7xxx_find_syncrate(p, &period, 0, &options);
       if (sync_rate != NULL)
       {
-        size += sprintf(BLS, "%s MByte/sec, offset %d\n",
+        seq_printf(m, "%s MByte/sec, offset %d\n",
                         sync_rate->rate[rate],
                         aic_dev->cur.offset );
       }
       else
       {
-        size += sprintf(BLS, "3.3 MByte/sec, offset %d\n",
+        seq_printf(m, "3.3 MByte/sec, offset %d\n",
                         aic_dev->cur.offset );
       }
     }
-    size += sprintf(BLS, "  Transinfo settings: ");
-    size += sprintf(BLS, "current(%d/%d/%d/%d), ",
+    seq_printf(m, "  Transinfo settings: ");
+    seq_printf(m, "current(%d/%d/%d/%d), ",
                     aic_dev->cur.period,
                     aic_dev->cur.offset,
                     aic_dev->cur.width,
                     aic_dev->cur.options);
-    size += sprintf(BLS, "goal(%d/%d/%d/%d), ",
+    seq_printf(m, "goal(%d/%d/%d/%d), ",
                     aic_dev->goal.period,
                     aic_dev->goal.offset,
                     aic_dev->goal.width,
                     aic_dev->goal.options);
-    size += sprintf(BLS, "user(%d/%d/%d/%d)\n",
+    seq_printf(m, "user(%d/%d/%d/%d)\n",
                     p->user[tindex].period,
                     p->user[tindex].offset,
                     p->user[tindex].width,
                     p->user[tindex].options);
     if(sdptr->simple_tags)
     {
-      size += sprintf(BLS, "  Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth);
+      seq_printf(m, "  Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth);
     }
     if(aic_dev->barrier_total)
-      size += sprintf(BLS, "  Total transfers %ld:\n    (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n",
+      seq_printf(m, "  Total transfers %ld:\n    (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n",
         aic_dev->r_total+aic_dev->w_total, aic_dev->r_total, aic_dev->w_total,
         aic_dev->barrier_total, aic_dev->ordered_total);
     else
-      size += sprintf(BLS, "  Total transfers %ld:\n    (%ld/%ld reads/writes)\n",
+      seq_printf(m, "  Total transfers %ld:\n    (%ld/%ld reads/writes)\n",
         aic_dev->r_total+aic_dev->w_total, aic_dev->r_total, aic_dev->w_total);
-    size += sprintf(BLS, "%s\n", HDRB);
-    size += sprintf(BLS, "   Reads:");
+    seq_printf(m, "%s\n", HDRB);
+    seq_printf(m, "   Reads:");
     for (i = 0; i < ARRAY_SIZE(aic_dev->r_bins); i++)
     {
-      size += sprintf(BLS, " %10ld", aic_dev->r_bins[i]);
+      seq_printf(m, " %10ld", aic_dev->r_bins[i]);
     }
-    size += sprintf(BLS, "\n");
-    size += sprintf(BLS, "  Writes:");
+    seq_printf(m, "\n");
+    seq_printf(m, "  Writes:");
     for (i = 0; i < ARRAY_SIZE(aic_dev->w_bins); i++)
     {
-      size += sprintf(BLS, " %10ld", aic_dev->w_bins[i]);
+      seq_printf(m, " %10ld", aic_dev->w_bins[i]);
     }
-    size += sprintf(BLS, "\n");
-    size += sprintf(BLS, "\n\n");
-  }
-  if (size >= aic7xxx_buffer_size)
-  {
-    printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n");
-  }
-
-  if (offset > size - 1)
-  {
-    kfree(aic7xxx_buffer);
-    aic7xxx_buffer = NULL;
-    aic7xxx_buffer_size = length = 0;
-    *start = NULL;
+    seq_printf(m, "\n");
+    seq_printf(m, "\n\n");
   }
-  else
-  {
-    *start = buffer;
-    length = min_t(int, length, size - offset);
-    memcpy(buffer, &aic7xxx_buffer[offset], length);
-  }
-
-  return (length);
+  return 0;
 }
 
 /*
index 3e1172adb37b0a9d012c6afba811bcbb033fb80b..09ba1869d366d1ba8881087d4e3c8f88d2e91f5b 100644 (file)
@@ -2836,20 +2836,15 @@ char *acornscsi_info(struct Scsi_Host *host)
     return string;
 }
 
-int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset,
-                       int length, int inout)
+static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance)
 {
-    int pos, begin = 0, devidx;
+    int devidx;
     struct scsi_device *scd;
     AS_Host *host;
-    char *p = buffer;
-
-    if (inout == 1)
-       return -EINVAL;
 
     host  = (AS_Host *)instance->hostdata;
     
-    p += sprintf(p, "AcornSCSI driver v%d.%d.%d"
+    seq_printf(m, "AcornSCSI driver v%d.%d.%d"
 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
     " SYNC"
 #endif
@@ -2864,14 +2859,14 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
 #endif
                "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
 
-    p += sprintf(p,    "SBIC: WD33C93A  Address: %p    IRQ : %d\n",
+    seq_printf(m,      "SBIC: WD33C93A  Address: %p    IRQ : %d\n",
                        host->base + SBIC_REGIDX, host->scsi.irq);
 #ifdef USE_DMAC
-    p += sprintf(p,    "DMAC: uPC71071  Address: %p  IRQ : %d\n\n",
+    seq_printf(m,      "DMAC: uPC71071  Address: %p  IRQ : %d\n\n",
                        host->base + DMAC_OFFSET, host->scsi.irq);
 #endif
 
-    p += sprintf(p,    "Statistics:\n"
+    seq_printf(m,      "Statistics:\n"
                        "Queued commands: %-10u    Issued commands: %-10u\n"
                        "Done commands  : %-10u    Reads          : %-10u\n"
                        "Writes         : %-10u    Others         : %-10u\n"
@@ -2886,7 +2881,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
     for (devidx = 0; devidx < 9; devidx ++) {
        unsigned int statptr, prev;
 
-       p += sprintf(p, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
+       seq_printf(m, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
        statptr = host->status_ptr[devidx] - 10;
 
        if ((signed int)statptr < 0)
@@ -2896,7 +2891,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
 
        for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
            if (host->status[devidx][statptr].when) {
-               p += sprintf(p, "%c%02X:%02X+%2ld",
+               seq_printf(m, "%c%02X:%02X+%2ld",
                        host->status[devidx][statptr].irq ? '-' : ' ',
                        host->status[devidx][statptr].ph,
                        host->status[devidx][statptr].ssr,
@@ -2907,51 +2902,32 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
        }
     }
 
-    p += sprintf(p, "\nAttached devices:\n");
+    seq_printf(m, "\nAttached devices:\n");
 
     shost_for_each_device(scd, instance) {
-       p += sprintf(p, "Device/Lun TaggedQ      Sync\n");
-       p += sprintf(p, "     %d/%d   ", scd->id, scd->lun);
+       seq_printf(m, "Device/Lun TaggedQ      Sync\n");
+       seq_printf(m, "     %d/%d   ", scd->id, scd->lun);
        if (scd->tagged_supported)
-               p += sprintf(p, "%3sabled(%3d) ",
+               seq_printf(m, "%3sabled(%3d) ",
                             scd->simple_tags ? "en" : "dis",
                             scd->current_tag);
        else
-               p += sprintf(p, "unsupported  ");
+               seq_printf(m, "unsupported  ");
 
        if (host->device[scd->id].sync_xfer & 15)
-               p += sprintf(p, "offset %d, %d ns\n",
+               seq_printf(m, "offset %d, %d ns\n",
                             host->device[scd->id].sync_xfer & 15,
                             acornscsi_getperiod(host->device[scd->id].sync_xfer));
        else
-               p += sprintf(p, "async\n");
+               seq_printf(m, "async\n");
 
-       pos = p - buffer;
-       if (pos + begin < offset) {
-           begin += pos;
-           p = buffer;
-       }
-       pos = p - buffer;
-       if (pos + begin > offset + length) {
-           scsi_device_put(scd);
-           break;
-       }
     }
-
-    pos = p - buffer;
-
-    *start = buffer + (offset - begin);
-    pos -= offset - begin;
-
-    if (pos > length)
-       pos = length;
-
-    return pos;
+    return 0;
 }
 
 static struct scsi_host_template acornscsi_template = {
        .module                 = THIS_MODULE,
-       .proc_info              = acornscsi_proc_info,
+       .show_info              = acornscsi_show_info,
        .name                   = "AcornSCSI",
        .info                   = acornscsi_info,
        .queuecommand           = acornscsi_queuecmd,
index 9274510294acaf74c72e9980d2147863000c7303..32d23212de48be5bbee9d6f5989f05f2fe0cf9be 100644 (file)
@@ -220,47 +220,21 @@ static const char *arxescsi_info(struct Scsi_Host *host)
        return string;
 }
 
-/*
- * Function: int arxescsi_proc_info(char *buffer, char **start, off_t offset,
- *                                      int length, int host_no, int inout)
- * Purpose : Return information about the driver to a user process accessing
- *          the /proc filesystem.
- * Params  : buffer - a buffer to write information to
- *          start  - a pointer into this buffer set by this routine to the start
- *                   of the required information.
- *          offset - offset into information that we have read up to.
- *          length - length of buffer
- *          host_no - host number to return information for
- *          inout  - 0 for reading, 1 for writing.
- * Returns : length of data written to buffer.
- */
 static int
-arxescsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
-                  int inout)
+arxescsi_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct arxescsi_info *info;
-       char *p = buffer;
-       int pos;
-
        info = (struct arxescsi_info *)host->hostdata;
-       if (inout == 1)
-               return -EINVAL;
-
-       p += sprintf(p, "ARXE 16-bit SCSI driver v%s\n", VERSION);
-       p += fas216_print_host(&info->info, p);
-       p += fas216_print_stats(&info->info, p);
-       p += fas216_print_devices(&info->info, p);
-
-       *start = buffer + offset;
-       pos = p - buffer - offset;
-       if (pos > length)
-               pos = length;
 
-       return pos;
+       seq_printf(m, "ARXE 16-bit SCSI driver v%s\n", VERSION);
+       fas216_print_host(&info->info, m);
+       fas216_print_stats(&info->info, m);
+       fas216_print_devices(&info->info, m);
+       return 0;
 }
 
 static struct scsi_host_template arxescsi_template = {
-       .proc_info                      = arxescsi_proc_info,
+       .show_info                      = arxescsi_show_info,
        .name                           = "ARXE SCSI card",
        .info                           = arxescsi_info,
        .queuecommand                   = fas216_noqueue_command,
index c93938b246d59c29ec2414b05c1749b216b5b128..b679778376c5f62c6d3a2a83c01beb468fa1a849 100644 (file)
@@ -30,7 +30,6 @@
 #define NCR5380_write(reg, value)      cumanascsi_write(_instance, reg, value)
 #define NCR5380_intr                   cumanascsi_intr
 #define NCR5380_queue_command          cumanascsi_queue_command
-#define NCR5380_proc_info              cumanascsi_proc_info
 
 #define NCR5380_implementation_fields  \
        unsigned ctrl;                  \
index e3bae93c3c22c3a82efa0d337b3eea9a7a650b60..58915f29055b8050774ce2610f987092ad8d60a1 100644 (file)
@@ -337,50 +337,25 @@ cumanascsi_2_set_proc_info(struct Scsi_Host *host, char *buffer, int length)
        return ret;
 }
 
-/* Prototype: int cumanascsi_2_proc_info(char *buffer, char **start, off_t offset,
- *                                      int length, int host_no, int inout)
- * Purpose  : Return information about the driver to a user process accessing
- *           the /proc filesystem.
- * Params   : buffer - a buffer to write information to
- *           start  - a pointer into this buffer set by this routine to the start
- *                    of the required information.
- *           offset - offset into information that we have read up to.
- *           length - length of buffer
- *           host_no - host number to return information for
- *           inout  - 0 for reading, 1 for writing.
- * Returns  : length of data written to buffer.
- */
-int cumanascsi_2_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                           int length, int inout)
+static int cumanascsi_2_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct cumanascsi2_info *info;
-       char *p = buffer;
-       int pos;
-
-       if (inout == 1)
-               return cumanascsi_2_set_proc_info(host, buffer, length);
-
        info = (struct cumanascsi2_info *)host->hostdata;
 
-       p += sprintf(p, "Cumana SCSI II driver v%s\n", VERSION);
-       p += fas216_print_host(&info->info, p);
-       p += sprintf(p, "Term    : o%s\n",
+       seq_printf(m, "Cumana SCSI II driver v%s\n", VERSION);
+       fas216_print_host(&info->info, m);
+       seq_printf(m, "Term    : o%s\n",
                        info->terms ? "n" : "ff");
 
-       p += fas216_print_stats(&info->info, p);
-       p += fas216_print_devices(&info->info, p);
-
-       *start = buffer + offset;
-       pos = p - buffer - offset;
-       if (pos > length)
-               pos = length;
-
-       return pos;
+       fas216_print_stats(&info->info, m);
+       fas216_print_devices(&info->info, m);
+       return 0;
 }
 
 static struct scsi_host_template cumanascsi2_template = {
        .module                         = THIS_MODULE,
-       .proc_info                      = cumanascsi_2_proc_info,
+       .show_info                      = cumanascsi_2_show_info,
+       .write_info                     = cumanascsi_2_set_proc_info,
        .name                           = "Cumana SCSI II",
        .info                           = cumanascsi_2_info,
        .queuecommand                   = fas216_queue_command,
index 8e36908415ec3eecaf6743890e9656303376357c..5bf3c0d134b47e3ed0b309e33b60192490ba820a 100644 (file)
@@ -422,45 +422,20 @@ eesoxscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length)
        return ret;
 }
 
-/* Prototype: int eesoxscsi_proc_info(char *buffer, char **start, off_t offset,
- *                                   int length, int host_no, int inout)
- * Purpose  : Return information about the driver to a user process accessing
- *           the /proc filesystem.
- * Params   : buffer - a buffer to write information to
- *           start  - a pointer into this buffer set by this routine to the start
- *                    of the required information.
- *           offset - offset into information that we have read up to.
- *           length - length of buffer
- *           host_no - host number to return information for
- *           inout  - 0 for reading, 1 for writing.
- * Returns  : length of data written to buffer.
- */
-int eesoxscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                           int length, int inout)
+static int eesoxscsi_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct eesoxscsi_info *info;
-       char *p = buffer;
-       int pos;
-
-       if (inout == 1)
-               return eesoxscsi_set_proc_info(host, buffer, length);
 
        info = (struct eesoxscsi_info *)host->hostdata;
 
-       p += sprintf(p, "EESOX SCSI driver v%s\n", VERSION);
-       p += fas216_print_host(&info->info, p);
-       p += sprintf(p, "Term    : o%s\n",
+       seq_printf(m, "EESOX SCSI driver v%s\n", VERSION);
+       fas216_print_host(&info->info, m);
+       seq_printf(m, "Term    : o%s\n",
                        info->control & EESOX_TERM_ENABLE ? "n" : "ff");
 
-       p += fas216_print_stats(&info->info, p);
-       p += fas216_print_devices(&info->info, p);
-
-       *start = buffer + offset;
-       pos = p - buffer - offset;
-       if (pos > length)
-               pos = length;
-
-       return pos;
+       fas216_print_stats(&info->info, m);
+       fas216_print_devices(&info->info, m);
+       return 0;
 }
 
 static ssize_t eesoxscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf)
@@ -498,7 +473,8 @@ static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR,
 
 static struct scsi_host_template eesox_template = {
        .module                         = THIS_MODULE,
-       .proc_info                      = eesoxscsi_proc_info,
+       .show_info                      = eesoxscsi_show_info,
+       .write_info                     = eesoxscsi_set_proc_info,
        .name                           = "EESOX SCSI",
        .info                           = eesoxscsi_info,
        .queuecommand                   = fas216_queue_command,
index 737554c37d9ec1ea2f794bf026d4ee96bb5f0c1b..b46a6f6c0eb34913afc31af580b4b194678e994b 100644 (file)
@@ -2958,9 +2958,9 @@ void fas216_release(struct Scsi_Host *host)
        queue_free(&info->queues.issue);
 }
 
-int fas216_print_host(FAS216_Info *info, char *buffer)
+void fas216_print_host(FAS216_Info *info, struct seq_file *m)
 {
-       return sprintf(buffer,
+       seq_printf(m,
                        "\n"
                        "Chip    : %s\n"
                        " Address: 0x%p\n"
@@ -2970,11 +2970,9 @@ int fas216_print_host(FAS216_Info *info, char *buffer)
                        info->scsi.irq, info->scsi.dma);
 }
 
-int fas216_print_stats(FAS216_Info *info, char *buffer)
+void fas216_print_stats(FAS216_Info *info, struct seq_file *m)
 {
-       char *p = buffer;
-
-       p += sprintf(p, "\n"
+       seq_printf(m, "\n"
                        "Command Statistics:\n"
                        " Queued     : %u\n"
                        " Issued     : %u\n"
@@ -2991,38 +2989,33 @@ int fas216_print_stats(FAS216_Info *info, char *buffer)
                        info->stats.writes,      info->stats.miscs,
                        info->stats.disconnects, info->stats.aborts,
                        info->stats.bus_resets,  info->stats.host_resets);
-
-       return p - buffer;
 }
 
-int fas216_print_devices(FAS216_Info *info, char *buffer)
+void fas216_print_devices(FAS216_Info *info, struct seq_file *m)
 {
        struct fas216_device *dev;
        struct scsi_device *scd;
-       char *p = buffer;
 
-       p += sprintf(p, "Device/Lun TaggedQ       Parity   Sync\n");
+       seq_printf(m, "Device/Lun TaggedQ       Parity   Sync\n");
 
        shost_for_each_device(scd, info->host) {
                dev = &info->device[scd->id];
-               p += sprintf(p, "     %d/%d   ", scd->id, scd->lun);
+               seq_printf(m, "     %d/%d   ", scd->id, scd->lun);
                if (scd->tagged_supported)
-                       p += sprintf(p, "%3sabled(%3d) ",
+                       seq_printf(m, "%3sabled(%3d) ",
                                     scd->simple_tags ? "en" : "dis",
                                     scd->current_tag);
                else
-                       p += sprintf(p, "unsupported   ");
+                       seq_printf(m, "unsupported   ");
 
-               p += sprintf(p, "%3sabled ", dev->parity_enabled ? "en" : "dis");
+               seq_printf(m, "%3sabled ", dev->parity_enabled ? "en" : "dis");
 
                if (dev->sof)
-                       p += sprintf(p, "offset %d, %d ns\n",
+                       seq_printf(m, "offset %d, %d ns\n",
                                     dev->sof, dev->period * 4);
                else
-                       p += sprintf(p, "async\n");
+                       seq_printf(m, "async\n");
        }
-
-       return p - buffer;
 }
 
 EXPORT_SYMBOL(fas216_init);
index df2e1b3ddfe230da9aef38355d7a3014cd8c7e0e..c57c16ef81936b9978482ecb46c16571d80c06fb 100644 (file)
@@ -358,9 +358,9 @@ extern void fas216_remove (struct Scsi_Host *instance);
  */
 extern void fas216_release (struct Scsi_Host *instance);
 
-extern int fas216_print_host(FAS216_Info *info, char *buffer);
-extern int fas216_print_stats(FAS216_Info *info, char *buffer);
-extern int fas216_print_devices(FAS216_Info *info, char *buffer);
+extern void fas216_print_host(FAS216_Info *info, struct seq_file *m);
+extern void fas216_print_stats(FAS216_Info *info, struct seq_file *m);
+extern void fas216_print_devices(FAS216_Info *info, struct seq_file *m);
 
 /* Function: int fas216_eh_abort(struct scsi_cmnd *SCpnt)
  * Purpose : abort this command
index 48facdc18002d6e7a2e9eb27e30bfa79807d5eec..4266eef8aca12256b469b0983e39c652ac43f7c0 100644 (file)
@@ -31,7 +31,8 @@
 #define NCR5380_write(reg, value)      writeb(value, _base + ((reg) << 2))
 #define NCR5380_intr                   oakscsi_intr
 #define NCR5380_queue_command          oakscsi_queue_command
-#define NCR5380_proc_info              oakscsi_proc_info
+#define NCR5380_show_info              oakscsi_show_info
+#define NCR5380_write_info             oakscsi_write_info
 
 #define NCR5380_implementation_fields  \
        void __iomem *base
@@ -115,7 +116,8 @@ printk("reading %p len %d\n", addr, len);
 
 static struct scsi_host_template oakscsi_template = {
        .module                 = THIS_MODULE,
-       .proc_info              = oakscsi_proc_info,
+       .show_info              = oakscsi_show_info,
+       .write_info             = oakscsi_write_info,
        .name                   = "Oak 16-bit SCSI",
        .info                   = oakscsi_info,
        .queuecommand           = oakscsi_queue_command,
index 246600b935550a450cf7c6d24ce91962ac61af8e..abc9593615e9a56df352b658aa1a9e0febf46d1f 100644 (file)
@@ -237,32 +237,20 @@ powertecscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length)
  *           inout   - 0 for reading, 1 for writing.
  * Returns  : length of data written to buffer.
  */
-int powertecscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                           int length, int inout)
+static int powertecscsi_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct powertec_info *info;
-       char *p = buffer;
-       int pos;
-
-       if (inout == 1)
-               return powertecscsi_set_proc_info(host, buffer, length);
 
        info = (struct powertec_info *)host->hostdata;
 
-       p += sprintf(p, "PowerTec SCSI driver v%s\n", VERSION);
-       p += fas216_print_host(&info->info, p);
-       p += sprintf(p, "Term    : o%s\n",
+       seq_printf(m, "PowerTec SCSI driver v%s\n", VERSION);
+       fas216_print_host(&info->info, m);
+       seq_printf(m, "Term    : o%s\n",
                        info->term_ctl ? "n" : "ff");
 
-       p += fas216_print_stats(&info->info, p);
-       p += fas216_print_devices(&info->info, p);
-
-       *start = buffer + offset;
-       pos = p - buffer - offset;
-       if (pos > length)
-               pos = length;
-
-       return pos;
+       fas216_print_stats(&info->info, m);
+       fas216_print_devices(&info->info, m);
+       return 0;
 }
 
 static ssize_t powertecscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf)
@@ -291,7 +279,8 @@ static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR,
 
 static struct scsi_host_template powertecscsi_template = {
        .module                         = THIS_MODULE,
-       .proc_info                      = powertecscsi_proc_info,
+       .show_info                      = powertecscsi_show_info,
+       .write_info                     = powertecscsi_set_proc_info,
        .name                           = "PowerTec SCSI",
        .info                           = powertecscsi_info,
        .queuecommand                   = fas216_queue_command,
index 2db79b469d9e598f2a090edeedcb7af17bd87140..0f3cdbc80ba63a47d59c2e7d07a2cbf3ed67c8a9 100644 (file)
@@ -719,119 +719,94 @@ static void __init NCR5380_print_options(struct Scsi_Host *instance)
  * Inputs : instance, pointer to this instance.
  */
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void lprint_Scsi_Cmnd(Scsi_Cmnd *cmd)
 {
-       char *pr_bfr;
-       char *start;
-       int len;
-
-       NCR_PRINT(NDEBUG_ANY);
-       NCR_PRINT_PHASE(NDEBUG_ANY);
-
-       pr_bfr = (char *)__get_free_page(GFP_ATOMIC);
-       if (!pr_bfr) {
-               printk("NCR5380_print_status: no memory for print buffer\n");
-               return;
-       }
-       len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0);
-       pr_bfr[len] = 0;
-       printk("\n%s\n", pr_bfr);
-       free_page((unsigned long)pr_bfr);
+       int i, s;
+       unsigned char *command;
+       printk("scsi%d: destination target %d, lun %d\n",
+               H_NO(cmd), cmd->device->id, cmd->device->lun);
+       printk(KERN_CONT "        command = ");
+       command = cmd->cmnd;
+       printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
+       for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
+               printk(KERN_CONT " %02x", command[i]);
+       printk("\n");
 }
 
-
-/******************************************/
-/*
- * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED]
- *
- * *buffer: I/O buffer
- * **start: if inout == FALSE pointer into buffer where user read should start
- * offset: current offset
- * length: length of buffer
- * hostno: Scsi_Host host_no
- * inout: TRUE - user is writing; FALSE - user is reading
- *
- * Return the number of bytes read from or written
-*/
-
-#undef SPRINTF
-#define SPRINTF(fmt,args...)                                                   \
-       do {                                                                    \
-               if (pos + strlen(fmt) + 20 /* slop */ < buffer + length)        \
-                       pos += sprintf(pos, fmt , ## args);                     \
-       } while(0)
-static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
-
-static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer,
-                            char **start, off_t offset, int length, int inout)
+static void NCR5380_print_status(struct Scsi_Host *instance)
 {
-       char *pos = buffer;
        struct NCR5380_hostdata *hostdata;
        Scsi_Cmnd *ptr;
        unsigned long flags;
-       off_t begin = 0;
-#define check_offset()                                 \
-       do {                                            \
-               if (pos - buffer < offset - begin) {    \
-                       begin += pos - buffer;          \
-                       pos = buffer;                   \
-               }                                       \
-       } while (0)
+
+       NCR_PRINT(NDEBUG_ANY);
+       NCR_PRINT_PHASE(NDEBUG_ANY);
 
        hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-       if (inout)                      /* Has data been written to the file ? */
-               return -ENOSYS;         /* Currently this is a no-op */
-       SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
-       check_offset();
+       printk("\nNCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
        local_irq_save(flags);
-       SPRINTF("NCR5380: coroutine is%s running.\n",
+       printk("NCR5380: coroutine is%s running.\n",
                main_running ? "" : "n't");
-       check_offset();
        if (!hostdata->connected)
-               SPRINTF("scsi%d: no currently connected command\n", HOSTNO);
+               printk("scsi%d: no currently connected command\n", HOSTNO);
        else
-               pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected,
-                                      pos, buffer, length);
-       SPRINTF("scsi%d: issue_queue\n", HOSTNO);
-       check_offset();
-       for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) {
-               pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
-               check_offset();
-       }
+               lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected);
+       printk("scsi%d: issue_queue\n", HOSTNO);
+       for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
+               lprint_Scsi_Cmnd(ptr);
 
-       SPRINTF("scsi%d: disconnected_queue\n", HOSTNO);
-       check_offset();
+       printk("scsi%d: disconnected_queue\n", HOSTNO);
        for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
-            ptr = NEXT(ptr)) {
-               pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
-               check_offset();
-       }
+            ptr = NEXT(ptr))
+               lprint_Scsi_Cmnd(ptr);
 
        local_irq_restore(flags);
-       *start = buffer + (offset - begin);
-       if (pos - buffer < offset - begin)
-               return 0;
-       else if (pos - buffer - (offset - begin) < length)
-               return pos - buffer - (offset - begin);
-       return length;
+       printk("\n");
 }
 
-static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length)
+static void show_Scsi_Cmnd(Scsi_Cmnd *cmd, struct seq_file *m)
 {
        int i, s;
        unsigned char *command;
-       SPRINTF("scsi%d: destination target %d, lun %d\n",
+       seq_printf(m, "scsi%d: destination target %d, lun %d\n",
                H_NO(cmd), cmd->device->id, cmd->device->lun);
-       SPRINTF("        command = ");
+       seq_printf(m, "        command = ");
        command = cmd->cmnd;
-       SPRINTF("%2d (0x%02x)", command[0], command[0]);
+       seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
        for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-               SPRINTF(" %02x", command[i]);
-       SPRINTF("\n");
-       return pos;
+               seq_printf(m, " %02x", command[i]);
+       seq_printf(m, "\n");
 }
 
+static int NCR5380_show_info(struct seq_file *m, struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata;
+       Scsi_Cmnd *ptr;
+       unsigned long flags;
+
+       hostdata = (struct NCR5380_hostdata *)instance->hostdata;
+
+       seq_printf(m, "NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
+       local_irq_save(flags);
+       seq_printf(m, "NCR5380: coroutine is%s running.\n",
+               main_running ? "" : "n't");
+       if (!hostdata->connected)
+               seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
+       else
+               show_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m);
+       seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
+       for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
+               show_Scsi_Cmnd(ptr, m);
+
+       seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
+       for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
+            ptr = NEXT(ptr))
+               show_Scsi_Cmnd(ptr, m);
+
+       local_irq_restore(flags);
+       return 0;
+}
 
 /*
  * Function : void NCR5380_init (struct Scsi_Host *instance)
index df740cbbaef458d9c14ecdd3b9a0ad7de924d945..a3e6c8a3ff0faa852f163185c46e98d80fb49a43 100644 (file)
@@ -1100,7 +1100,7 @@ static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
 #include "atari_NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-       .proc_info              = atari_scsi_proc_info,
+       .show_info              = atari_scsi_show_info,
        .name                   = "Atari native SCSI",
        .detect                 = atari_scsi_detect,
        .release                = atari_scsi_release,
index bd52df78b2098be970aa5eac4467c921d2454eb2..11c624bb122dcd47078ac74ac4fd6eafbef9bbb6 100644 (file)
@@ -47,7 +47,7 @@
 #define NCR5380_intr atari_scsi_intr
 #define NCR5380_queue_command atari_scsi_queue_command
 #define NCR5380_abort atari_scsi_abort
-#define NCR5380_proc_info atari_scsi_proc_info
+#define NCR5380_show_info atari_scsi_show_info
 #define NCR5380_dma_read_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 0)
 #define NCR5380_dma_write_setup(inst,d,c) atari_scsi_dma_setup (inst, d, c, 1)
 #define NCR5380_dma_residual(inst) atari_scsi_dma_residual( inst )
index cfc73041f102968198a2a858bbaf5478caf5b43e..15a629d8ed081efe1e5b9e13160703c3d2f8fe6e 100644 (file)
@@ -3099,38 +3099,14 @@ static const char *atp870u_info(struct Scsi_Host *notused)
        return buffer;
 }
 
-#define BLS buffer + len + size
-static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 
-                            char **start, off_t offset, int length, int inout)
+static int atp870u_show_info(struct seq_file *m, struct Scsi_Host *HBAptr)
 {
-       static u8 buff[512];
-       int size = 0;
-       int len = 0;
-       off_t begin = 0;
-       off_t pos = 0;
-       
-       if (inout)      
-               return -EINVAL;
-       if (offset == 0)
-               memset(buff, 0, sizeof(buff));
-       size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
-       len += size;
-       pos = begin + len;
-       size = 0;
-
-       size += sprintf(BLS, "\n");
-       size += sprintf(BLS, "Adapter Configuration:\n");
-       size += sprintf(BLS, "               Base IO: %#.4lx\n", HBAptr->io_port);
-       size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
-       len += size;
-       pos = begin + len;
-       
-       *start = buffer + (offset - begin);     /* Start of wanted data */
-       len -= (offset - begin);        /* Start slop */
-       if (len > length) {
-               len = length;   /* Ending slop */
-       }
-       return (len);
+       seq_printf(m, "ACARD AEC-671X Driver Version: 2.6+ac\n");
+       seq_printf(m, "\n");
+       seq_printf(m, "Adapter Configuration:\n");
+       seq_printf(m, "               Base IO: %#.4lx\n", HBAptr->io_port);
+       seq_printf(m, "                   IRQ: %d\n", HBAptr->irq);
+       return 0;
 }
 
 
@@ -3177,7 +3153,7 @@ static struct scsi_host_template atp870u_template = {
      .module                   = THIS_MODULE,
      .name                     = "atp870u"             /* name */,
      .proc_name                        = "atp870u",
-     .proc_info                        = atp870u_proc_info,
+     .show_info                        = atp870u_show_info,
      .info                     = atp870u_info          /* info */,
      .queuecommand             = atp870u_queuecommand  /* queuecommand */,
      .eh_abort_handler         = atp870u_abort         /* abort */,
index fed486bfd3f462a9afbd2a0ed4360a069526ee7e..694e13c45dfd8362a814dd5626b18c5f04559081 100644 (file)
@@ -4616,26 +4616,21 @@ static void adapter_uninit(struct AdapterCtlBlk *acb)
 
 
 #undef SPRINTF
-#define SPRINTF(args...) pos += sprintf(pos, args)
+#define SPRINTF(args...) seq_printf(m,##args)
 
 #undef YESNO
 #define YESNO(YN) \
  if (YN) SPRINTF(" Yes ");\
  else SPRINTF(" No  ")
 
-static int dc395x_proc_info(struct Scsi_Host *host, char *buffer,
-               char **start, off_t offset, int length, int inout)
+static int dc395x_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
        int spd, spd1;
-       char *pos = buffer;
        struct DeviceCtlBlk *dcb;
        unsigned long flags;
        int dev;
 
-       if (inout)              /* Has data been written to the file ? */
-               return -EPERM;
-
        SPRINTF(DC395X_BANNER " PCI SCSI Host Adapter\n");
        SPRINTF(" Driver Version " DC395X_VERSION "\n");
 
@@ -4735,22 +4730,15 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer,
                SPRINTF("END\n");
        }
 
-       *start = buffer + offset;
        DC395x_UNLOCK_IO(acb->scsi_host, flags);
-
-       if (pos - buffer < offset)
-               return 0;
-       else if (pos - buffer - offset < length)
-               return pos - buffer - offset;
-       else
-               return length;
+       return 0;
 }
 
 
 static struct scsi_host_template dc395x_driver_template = {
        .module                 = THIS_MODULE,
        .proc_name              = DC395X_NAME,
-       .proc_info              = dc395x_proc_info,
+       .show_info              = dc395x_show_info,
        .name                   = DC395X_BANNER " " DC395X_VERSION,
        .queuecommand           = dc395x_queue_command,
        .bios_param             = dc395x_bios_param,
index b6e2700ec1c60fadda27306fcd39bdd375c00cad..19e1b422260a40ec648d3c2f548dfe198d9c1e07 100644 (file)
@@ -553,36 +553,14 @@ static const char *adpt_info(struct Scsi_Host *host)
        return (char *) (pHba->detail);
 }
 
-static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                 int length, int inout)
+static int adpt_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct adpt_device* d;
        int id;
        int chan;
-       int len = 0;
-       int begin = 0;
-       int pos = 0;
        adpt_hba* pHba;
        int unit;
 
-       *start = buffer;
-       if (inout == TRUE) {
-               /*
-                * The user has done a write and wants us to take the
-                * data in the buffer and do something with it.
-                * proc_scsiwrite calls us with inout = 1
-                *
-                * Read data from buffer (writing to us) - NOT SUPPORTED
-                */
-               return -EINVAL;
-       }
-
-       /*
-        * inout = 0 means the user has done a read and wants information
-        * returned, so we write information about the cards into the buffer
-        * proc_scsiread() calls us with inout = 0
-        */
-
        // Find HBA (host bus adapter) we are looking for
        mutex_lock(&adpt_configuration_lock);
        for (pHba = hba_chain; pHba; pHba = pHba->next) {
@@ -596,86 +574,30 @@ static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, of
        }
        host = pHba->host;
 
-       len  = sprintf(buffer    , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
-       len += sprintf(buffer+len, "%s\n", pHba->detail);
-       len += sprintf(buffer+len, "SCSI Host=scsi%d  Control Node=/dev/%s  irq=%d\n", 
+       seq_printf(m, "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
+       seq_printf(m, "%s\n", pHba->detail);
+       seq_printf(m, "SCSI Host=scsi%d  Control Node=/dev/%s  irq=%d\n", 
                        pHba->host->host_no, pHba->name, host->irq);
-       len += sprintf(buffer+len, "\tpost fifo size  = %d\n\treply fifo size = %d\n\tsg table size   = %d\n\n",
+       seq_printf(m, "\tpost fifo size  = %d\n\treply fifo size = %d\n\tsg table size   = %d\n\n",
                        host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
 
-       pos = begin + len;
-
-       /* CHECKPOINT */
-       if(pos > offset + length) {
-               goto stop_output;
-       }
-       if(pos <= offset) {
-               /*
-                * If we haven't even written to where we last left
-                * off (the last time we were called), reset the 
-                * beginning pointer.
-                */
-               len = 0;
-               begin = pos;
-       }
-       len +=  sprintf(buffer+len, "Devices:\n");
+       seq_printf(m, "Devices:\n");
        for(chan = 0; chan < MAX_CHANNEL; chan++) {
                for(id = 0; id < MAX_ID; id++) {
                        d = pHba->channel[chan].device[id];
-                       while(d){
-                               len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
-                               len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
-                               pos = begin + len;
-
-
-                               /* CHECKPOINT */
-                               if(pos > offset + length) {
-                                       goto stop_output;
-                               }
-                               if(pos <= offset) {
-                                       len = 0;
-                                       begin = pos;
-                               }
+                       while(d) {
+                               seq_printf(m,"\t%-24.24s", d->pScsi_dev->vendor);
+                               seq_printf(m," Rev: %-8.8s\n", d->pScsi_dev->rev);
 
                                unit = d->pI2o_dev->lct_data.tid;
-                               len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d)  (%s)\n\n",
+                               seq_printf(m, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d)  (%s)\n\n",
                                               unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
                                               scsi_device_online(d->pScsi_dev)? "online":"offline"); 
-                               pos = begin + len;
-
-                               /* CHECKPOINT */
-                               if(pos > offset + length) {
-                                       goto stop_output;
-                               }
-                               if(pos <= offset) {
-                                       len = 0;
-                                       begin = pos;
-                               }
-
                                d = d->next_lun;
                        }
                }
        }
-
-       /*
-        * begin is where we last checked our position with regards to offset
-        * begin is always less than offset.  len is relative to begin.  It
-        * is the number of bytes written past begin
-        *
-        */
-stop_output:
-       /* stop the output and calculate the correct length */
-       *(buffer + len) = '\0';
-
-       *start = buffer + (offset - begin);     /* Start of wanted data */
-       len -= (offset - begin);
-       if(len > length) {
-               len = length;
-       } else if(len < 0){
-               len = 0;
-               **start = '\0';
-       }
-       return len;
+       return 0;
 }
 
 /*
@@ -3639,7 +3561,7 @@ static struct scsi_host_template driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "dpt_i2o",
        .proc_name              = "dpt_i2o",
-       .proc_info              = adpt_proc_info,
+       .show_info              = adpt_show_info,
        .info                   = adpt_info,
        .queuecommand           = adpt_queue,
        .eh_abort_handler       = adpt_abort,
index 4b11bb04f5c46c51574bcbae994184f3ce19060c..d01f01604140a9204b8273eb220fe21d2d0ff2cf 100644 (file)
@@ -216,7 +216,8 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
        int sig, count;
 
        tpnt->proc_name = "dtc3x80";
-       tpnt->proc_info = &dtc_proc_info;
+       tpnt->show_info = dtc_show_info;
+       tpnt->write_info = dtc_write_info;
 
        for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
                addr = 0;
index cdc621204b667bb4dd317fd09b137afb6950c79b..92d7cfc3f4fcd0c706c412438f39b3a58cecae24 100644 (file)
@@ -88,7 +88,8 @@ static int dtc_bus_reset(Scsi_Cmnd *);
 #define NCR5380_queue_command          dtc_queue_command
 #define NCR5380_abort                  dtc_abort
 #define NCR5380_bus_reset              dtc_bus_reset
-#define NCR5380_proc_info              dtc_proc_info 
+#define NCR5380_show_info              dtc_show_info 
+#define NCR5380_write_info             dtc_write_info 
 
 /* 15 12 11 10
    1001 1100 0000 0000 */
index d5f8362335d305aef18864234f598057f0ce5fca..356def44ce583a23bc1913c4391afe2837d51ae9 100644 (file)
@@ -92,58 +92,22 @@ static unsigned long queue_counter;
 
 static struct scsi_host_template driver_template;
 
-/*
- * eata_proc_info
- * inout : decides on the direction of the dataflow and the meaning of the 
- *         variables
- * buffer: If inout==FALSE data is being written to it else read from it
- * *start: If inout==FALSE start of the valid data in the buffer
- * offset: If inout==FALSE offset from the beginning of the imaginary file 
- *         from which we start writing into the buffer
- * length: If inout==FALSE max number of bytes to be written into the buffer 
- *         else number of bytes in the buffer
- */
-static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
-                             int length, int rw)
+static int eata_pio_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
-       int len = 0;
-       off_t begin = 0, pos = 0;
-
-       if (rw)
-               return -ENOSYS;
-
-       len += sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: "
+       seq_printf(m, "EATA (Extended Attachment) PIO driver version: "
                   "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB);
-       len += sprintf(buffer + len, "queued commands:     %10ld\n"
+       seq_printf(m, "queued commands:     %10ld\n"
                   "processed interrupts:%10ld\n", queue_counter, int_counter);
-       len += sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n",
+       seq_printf(m, "\nscsi%-2d: HBA %.10s\n",
                   shost->host_no, SD(shost)->name);
-       len += sprintf(buffer + len, "Firmware revision: v%s\n",
+       seq_printf(m, "Firmware revision: v%s\n",
                   SD(shost)->revision);
-       len += sprintf(buffer + len, "IO: PIO\n");
-       len += sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base);
-       len += sprintf(buffer + len, "Host Bus: %s\n",
+       seq_printf(m, "IO: PIO\n");
+       seq_printf(m, "Base IO : %#.4x\n", (u32) shost->base);
+       seq_printf(m, "Host Bus: %s\n",
                   (SD(shost)->bustype == 'P')?"PCI ":
                   (SD(shost)->bustype == 'E')?"EISA":"ISA ");
-    
-       pos = begin + len;
-    
-       if (pos < offset) {
-               len = 0;
-               begin = pos;
-       }
-       if (pos > offset + length)
-               goto stop_output;
-    
-stop_output:
-       DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len));
-       *start = buffer + (offset - begin);   /* Start of wanted data */
-       len -= (offset - begin);            /* Start slop */
-       if (len > length)
-               len = length;               /* Ending slop */
-       DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len));
-    
-       return len;
+       return 0;
 }
 
 static int eata_pio_release(struct Scsi_Host *sh)
@@ -985,7 +949,7 @@ static int eata_pio_detect(struct scsi_host_template *tpnt)
 static struct scsi_host_template driver_template = {
        .proc_name              = "eata_pio",
        .name                   = "EATA (Extended Attachment) PIO driver",
-       .proc_info              = eata_pio_proc_info,
+       .show_info              = eata_pio_show_info,
        .detect                 = eata_pio_detect,
        .release                = eata_pio_release,
        .queuecommand           = eata_pio_queue,
index 5041f925c19140eb901a48cfcb1ff7ed448c9146..5cec6c60ca22dd9df89f3ebb8f19ed78c781b0a9 100644 (file)
@@ -745,42 +745,36 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
  
 #include "NCR5380.c"
 
-#define PRINTP(x) len += sprintf(buffer+len, x)
+#define PRINTP(x) seq_printf(m, x)
 #define ANDP ,
 
-static int sprint_opcode(char *buffer, int len, int opcode)
+static void sprint_opcode(struct seq_file *m, int opcode)
 {
-       int start = len;
        PRINTP("0x%02x " ANDP opcode);
-       return len - start;
 }
 
-static int sprint_command(char *buffer, int len, unsigned char *command)
+static void sprint_command(struct seq_file *m, unsigned char *command)
 {
-       int i, s, start = len;
-       len += sprint_opcode(buffer, len, command[0]);
+       int i, s;
+       sprint_opcode(m, command[0]);
        for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
                PRINTP("%02x " ANDP command[i]);
        PRINTP("\n");
-       return len - start;
 }
 
 /**
  *     sprintf_Scsi_Cmnd       -       print a scsi command
- *     @buffer: buffr to print into
- *     @len: buffer length
+ *     @m: seq_fil to print into
  *     @cmd: SCSI command block
  *     
  *     Print out the target and command data in hex
  */
 
-static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd)
+static void sprint_Scsi_Cmnd(struct seq_file *m, Scsi_Cmnd * cmd)
 {
-       int start = len;
        PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun);
        PRINTP("        command = ");
-       len += sprint_command(buffer, len, cmd->cmnd);
-       return len - start;
+       sprint_command(m, cmd->cmnd);
 }
 
 /**
@@ -800,9 +794,8 @@ static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd)
  *     Locks: global cli/lock for queue walk
  */
  
-static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, char **start, off_t offset, int length, int inout)
+static int generic_NCR5380_show_info(struct seq_file *m, struct Scsi_Host *scsi_ptr)
 {
-       int len = 0;
        NCR5380_local_declare();
        unsigned long flags;
        unsigned char status;
@@ -853,16 +846,16 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c
                PRINTP("  T:%d %s " ANDP dev->id ANDP scsi_device_type(dev->type));
                for (i = 0; i < 8; i++)
                        if (dev->vendor[i] >= 0x20)
-                               *(buffer + (len++)) = dev->vendor[i];
-               *(buffer + (len++)) = ' ';
+                               seq_putc(m, dev->vendor[i]);
+               seq_putc(m, ' ');
                for (i = 0; i < 16; i++)
                        if (dev->model[i] >= 0x20)
-                               *(buffer + (len++)) = dev->model[i];
-               *(buffer + (len++)) = ' ';
+                               seq_putc(m, dev->model[i]);
+               seq_putc(m, ' ');
                for (i = 0; i < 4; i++)
                        if (dev->rev[i] >= 0x20)
-                               *(buffer + (len++)) = dev->rev[i];
-               *(buffer + (len++)) = ' ';
+                               seq_putc(m, dev->rev[i]);
+               seq_putc(m, ' ');
 
                PRINTP("\n%10ld kb read    in %5ld secs" ANDP br / 1024 ANDP tr);
                if (tr)
@@ -886,32 +879,28 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c
        if (!hostdata->connected) {
                PRINTP("No currently connected command\n");
        } else {
-               len += sprint_Scsi_Cmnd(buffer, len, (Scsi_Cmnd *) hostdata->connected);
+               sprint_Scsi_Cmnd(m, (Scsi_Cmnd *) hostdata->connected);
        }
 
        PRINTP("issue_queue\n");
 
        for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
-               len += sprint_Scsi_Cmnd(buffer, len, ptr);
+               sprint_Scsi_Cmnd(m, ptr);
 
        PRINTP("disconnected_queue\n");
 
        for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
-               len += sprint_Scsi_Cmnd(buffer, len, ptr);
+               sprint_Scsi_Cmnd(m, ptr);
 
-       *start = buffer + offset;
-       len -= offset;
-       if (len > length)
-               len = length;
        spin_unlock_irqrestore(scsi_ptr->host_lock, flags);
-       return len;
+       return 0;
 }
 
 #undef PRINTP
 #undef ANDP
 
 static struct scsi_host_template driver_template = {
-       .proc_info              = generic_NCR5380_proc_info,
+       .show_info              = generic_NCR5380_show_info,
        .name                   = "Generic NCR5380/NCR53C400 Scsi Driver",
        .detect                 = generic_NCR5380_detect,
        .release                = generic_NCR5380_release_resources,
index 59bceac51a4ccff560a91eca5f4d7de01d4c08e3..6d55b4e7e7923121d58535ab1a7ff83c50298c8c 100644 (file)
@@ -4676,7 +4676,8 @@ static struct scsi_host_template gdth_template = {
         .eh_bus_reset_handler   = gdth_eh_bus_reset,
         .slave_configure        = gdth_slave_configure,
         .bios_param             = gdth_bios_param,
-        .proc_info              = gdth_proc_info,
+        .show_info              = gdth_show_info,
+        .write_info             = gdth_set_info,
        .eh_timed_out           = gdth_timed_out,
         .proc_name              = "gdth",
         .can_queue              = GDTH_MAXCMDS,
index fbf6f0f4b0dd2ccc2f88442c70828fa3c5ad4c41..3fd8b83ffbf9f0df05d9c202d18bb7520cd6ee89 100644 (file)
@@ -1007,6 +1007,7 @@ typedef struct {
 
 /* function prototyping */
 
-int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int);
+int gdth_show_info(struct seq_file *, struct Scsi_Host *);
+int gdth_set_info(struct Scsi_Host *, char *, int);
 
 #endif
index 652754319a4bde12d17f4de76f1c5ff2ad690899..9fb632684863a6ad0340e622b4d80c72d132686b 100644 (file)
@@ -5,23 +5,9 @@
 #include <linux/completion.h>
 #include <linux/slab.h>
 
-int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,   
-                   int inout)
+int gdth_set_info(struct Scsi_Host *host, char *buffer, int length)
 {
     gdth_ha_str *ha = shost_priv(host);
-
-    TRACE2(("gdth_proc_info() length %d offs %d inout %d\n",
-            length,(int)offset,inout));
-
-    if (inout)
-        return(gdth_set_info(buffer,length,host,ha));
-    else
-        return(gdth_get_info(buffer,start,offset,length,host,ha));
-}
-
-static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
-                         gdth_ha_str *ha)
-{
     int ret_val = -EINVAL;
 
     TRACE2(("gdth_set_info() ha %d\n",ha->hanum,));
@@ -149,12 +135,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
     return(-EINVAL);
 }
 
-static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
-                         struct Scsi_Host *host, gdth_ha_str *ha)
+int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
-    int size = 0,len = 0;
+    gdth_ha_str *ha = shost_priv(host);
     int hlen;
-    off_t begin = 0,pos = 0;
     int id, i, j, k, sec, flag;
     int no_mdrv = 0, drv_no, is_mirr;
     u32 cnt;
@@ -189,8 +173,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
     /* request is i.e. "cat /proc/scsi/gdth/0" */ 
     /* format: %-15s\t%-10s\t%-15s\t%s */
     /* driver parameters */
-    size = sprintf(buffer+len,"Driver Parameters:\n");
-    len += size;  pos = begin + len;
+    seq_printf(m, "Driver Parameters:\n");
     if (reserve_list[0] == 0xff)
         strcpy(hrec, "--");
     else {
@@ -201,69 +184,50 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
             hlen += snprintf(hrec + hlen , 161 - hlen, ",%d", reserve_list[i]);
         }
     }
-    size = sprintf(buffer+len,
+    seq_printf(m,
                    " reserve_mode: \t%d         \treserve_list:  \t%s\n",
                    reserve_mode, hrec);
-    len += size;  pos = begin + len;
-    size = sprintf(buffer+len,
+    seq_printf(m,
                    " max_ids:      \t%-3d       \thdr_channel:   \t%d\n",
                    max_ids, hdr_channel);
-    len += size;  pos = begin + len;
 
     /* controller information */
-    size = sprintf(buffer+len,"\nDisk Array Controller Information:\n");
-    len += size;  pos = begin + len;
-    strcpy(hrec, ha->binfo.type_string);
-    size = sprintf(buffer+len,
+    seq_printf(m,"\nDisk Array Controller Information:\n");
+    seq_printf(m,
                    " Number:       \t%d         \tName:          \t%s\n",
-                   ha->hanum, hrec);
-    len += size;  pos = begin + len;
+                   ha->hanum, ha->binfo.type_string);
 
+    seq_printf(m,
+                   " Driver Ver.:  \t%-10s\tFirmware Ver.: \t",
+                   GDTH_VERSION_STR);
     if (ha->more_proc)
-        sprintf(hrec, "%d.%02d.%02d-%c%03X", 
+        seq_printf(m, "%d.%02d.%02d-%c%03X\n", 
                 (u8)(ha->binfo.upd_fw_ver>>24),
                 (u8)(ha->binfo.upd_fw_ver>>16),
                 (u8)(ha->binfo.upd_fw_ver),
                 ha->bfeat.raid ? 'R':'N',
                 ha->binfo.upd_revision);
     else
-        sprintf(hrec, "%d.%02d", (u8)(ha->cpar.version>>8),
+        seq_printf(m, "%d.%02d\n", (u8)(ha->cpar.version>>8),
                 (u8)(ha->cpar.version));
-
-    size = sprintf(buffer+len,
-                   " Driver Ver.:  \t%-10s\tFirmware Ver.: \t%s\n",
-                   GDTH_VERSION_STR, hrec);
-    len += size;  pos = begin + len;
  
-    if (ha->more_proc) {
+    if (ha->more_proc)
         /* more information: 1. about controller */
-        size = sprintf(buffer+len,
+        seq_printf(m,
                        " Serial No.:   \t0x%8X\tCache RAM size:\t%d KB\n",
                        ha->binfo.ser_no, ha->binfo.memsize / 1024);
-        len += size;  pos = begin + len;
-    }
 
 #ifdef GDTH_DMA_STATISTICS
     /* controller statistics */
-    size = sprintf(buffer+len,"\nController Statistics:\n");
-    len += size;  pos = begin + len;
-    size = sprintf(buffer+len,
+    seq_printf(m,"\nController Statistics:\n");
+    seq_printf(m,
                    " 32-bit DMA buffer:\t%lu\t64-bit DMA buffer:\t%lu\n",
                    ha->dma32_cnt, ha->dma64_cnt);
-    len += size;  pos = begin + len;
 #endif
 
-    if (pos < offset) {
-        len = 0;
-        begin = pos;
-    }
-    if (pos > offset + length)
-        goto stop_output;
-
     if (ha->more_proc) {
         /* more information: 2. about physical devices */
-        size = sprintf(buffer+len,"\nPhysical Devices:");
-        len += size;  pos = begin + len;
+        seq_printf(m, "\nPhysical Devices:");
         flag = FALSE;
             
         buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
@@ -309,21 +273,19 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                     strncpy(hrec+8,pdi->product,16);
                     strncpy(hrec+24,pdi->revision,4);
                     hrec[28] = 0;
-                    size = sprintf(buffer+len,
+                    seq_printf(m,
                                    "\n Chn/ID/LUN:   \t%c/%02d/%d    \tName:          \t%s\n",
                                    'A'+i,pdi->target_id,pdi->lun,hrec);
-                    len += size;  pos = begin + len;
                     flag = TRUE;
                     pdi->no_ldrive &= 0xffff;
                     if (pdi->no_ldrive == 0xffff)
                         strcpy(hrec,"--");
                     else
                         sprintf(hrec,"%d",pdi->no_ldrive);
-                    size = sprintf(buffer+len,
+                    seq_printf(m,
                                    " Capacity [MB]:\t%-6d    \tTo Log. Drive: \t%s\n",
                                    pdi->blkcnt/(1024*1024/pdi->blksize),
                                    hrec);
-                    len += size;  pos = begin + len;
                 } else {
                     pdi->devtype = 0xff;
                 }
@@ -333,11 +295,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                     for (k = 0; k < pds->count; ++k) {
                         if (pds->list[k].tid == pdi->target_id &&
                             pds->list[k].lun == pdi->lun) {
-                            size = sprintf(buffer+len,
+                            seq_printf(m,
                                            " Retries:      \t%-6d    \tReassigns:     \t%d\n",
                                            pds->list[k].retries,
                                            pds->list[k].reassigns);
-                            len += size;  pos = begin + len;
                             break;
                         }
                     }
@@ -355,32 +316,20 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                     pdef->sddc_type = 0x08;
 
                     if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
-                        size = sprintf(buffer+len,
+                        seq_printf(m,
                                        " Grown Defects:\t%d\n",
                                        pdef->sddc_cnt);
-                        len += size;  pos = begin + len;
                     }
                 }
-                if (pos < offset) {
-                    len = 0;
-                    begin = pos;
-                }
-               if (pos > offset + length) {
-                   gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
-                    goto stop_output;
-               }
             }
         }
         gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
 
-        if (!flag) {
-            size = sprintf(buffer+len, "\n --\n");
-            len += size;  pos = begin + len;
-        }
+        if (!flag)
+            seq_printf(m, "\n --\n");
 
         /* 3. about logical drives */
-        size = sprintf(buffer+len,"\nLogical Drives:");
-        len += size;  pos = begin + len;
+        seq_printf(m,"\nLogical Drives:");
         flag = FALSE;
 
         buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
@@ -418,10 +367,9 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                 }
                     
                 if (drv_no == i) {
-                    size = sprintf(buffer+len,
+                    seq_printf(m,
                                    "\n Number:       \t%-2d        \tStatus:        \t%s\n",
                                    drv_no, hrec);
-                    len += size;  pos = begin + len;
                     flag = TRUE;
                     no_mdrv = pcdi->cd_ldcnt;
                     if (no_mdrv > 1 || pcdi->ld_slave != -1) {
@@ -436,61 +384,37 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                     } else {
                         strcpy(hrec, "???");
                     }
-                    size = sprintf(buffer+len,
+                    seq_printf(m,
                                    " Capacity [MB]:\t%-6d    \tType:          \t%s\n",
                                    pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize),
                                    hrec);
-                    len += size;  pos = begin + len;
                 } else {
-                    size = sprintf(buffer+len,
+                    seq_printf(m,
                                    " Slave Number: \t%-2d        \tStatus:        \t%s\n",
                                    drv_no & 0x7fff, hrec);
-                    len += size;  pos = begin + len;
                 }
                 drv_no = pcdi->ld_slave;
-                if (pos < offset) {
-                    len = 0;
-                    begin = pos;
-                }
-               if (pos > offset + length) {
-                   gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
-                    goto stop_output;
-               }
             } while (drv_no != -1);
              
-            if (is_mirr) {
-                size = sprintf(buffer+len,
+            if (is_mirr)
+                seq_printf(m,
                                " Missing Drv.: \t%-2d        \tInvalid Drv.:  \t%d\n",
                                no_mdrv - j - k, k);
-                len += size;  pos = begin + len;
-            }
-              
+
             if (!ha->hdr[i].is_arraydrv)
                 strcpy(hrec, "--");
             else
                 sprintf(hrec, "%d", ha->hdr[i].master_no);
-            size = sprintf(buffer+len,
+            seq_printf(m,
                            " To Array Drv.:\t%s\n", hrec);
-            len += size;  pos = begin + len;
-            if (pos < offset) {
-                len = 0;
-                begin = pos;
-            }
-           if (pos > offset + length) {
-               gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
-                goto stop_output;
-           }
         }       
         gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
         
-        if (!flag) {
-            size = sprintf(buffer+len, "\n --\n");
-            len += size;  pos = begin + len;
-        }   
+        if (!flag)
+            seq_printf(m, "\n --\n");
 
         /* 4. about array drives */
-        size = sprintf(buffer+len,"\nArray Drives:");
-        len += size;  pos = begin + len;
+        seq_printf(m,"\nArray Drives:");
         flag = FALSE;
 
         buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
@@ -525,10 +449,9 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                     strcat(hrec, "/expand");
                 else if (pai->ai_ext_state & 0x1)
                     strcat(hrec, "/patch");
-                size = sprintf(buffer+len,
+                seq_printf(m,
                                "\n Number:       \t%-2d        \tStatus:        \t%s\n",
                                i,hrec);
-                len += size;  pos = begin + len;
                 flag = TRUE;
 
                 if (pai->ai_type == 0)
@@ -539,31 +462,19 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
                     strcpy(hrec, "RAID-5");
                 else 
                     strcpy(hrec, "RAID-10");
-                size = sprintf(buffer+len,
+                seq_printf(m,
                                " Capacity [MB]:\t%-6d    \tType:          \t%s\n",
                                pai->ai_size/(1024*1024/pai->ai_secsize),
                                hrec);
-                len += size;  pos = begin + len;
-                if (pos < offset) {
-                    len = 0;
-                    begin = pos;
-                }
-               if (pos > offset + length) {
-                   gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
-                    goto stop_output;
-               }
             }
         }
         gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
         
-        if (!flag) {
-            size = sprintf(buffer+len, "\n --\n");
-            len += size;  pos = begin + len;
-        }
+        if (!flag)
+            seq_printf(m, "\n --\n");
 
         /* 5. about host drives */
-        size = sprintf(buffer+len,"\nHost Drives:");
-        len += size;  pos = begin + len;
+        seq_printf(m,"\nHost Drives:");
         flag = FALSE;
 
         buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr);
@@ -605,33 +516,22 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
             if (!(ha->hdr[i].present))
                 continue;
               
-            size = sprintf(buffer+len,
+            seq_printf(m,
                            "\n Number:       \t%-2d        \tArr/Log. Drive:\t%d\n",
                            i, ha->hdr[i].ldr_no);
-            len += size;  pos = begin + len;
             flag = TRUE;
 
-            size = sprintf(buffer+len,
+            seq_printf(m,
                            " Capacity [MB]:\t%-6d    \tStart Sector:  \t%d\n",
                            (u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec);
-            len += size;  pos = begin + len;
-            if (pos < offset) {
-                len = 0;
-                begin = pos;
-            }
-            if (pos > offset + length)
-                goto stop_output;
         }
         
-        if (!flag) {
-            size = sprintf(buffer+len, "\n --\n");
-            len += size;  pos = begin + len;
-        }
+        if (!flag)
+            seq_printf(m, "\n --\n");
     }
 
     /* controller events */
-    size = sprintf(buffer+len,"\nController Events:\n");
-    len += size;  pos = begin + len;
+    seq_printf(m,"\nController Events:\n");
 
     for (id = -1;;) {
         id = gdth_read_event(ha, id, estr);
@@ -643,29 +543,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
             do_gettimeofday(&tv);
             sec = (int)(tv.tv_sec - estr->first_stamp);
             if (sec < 0) sec = 0;
-            size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n",
+            seq_printf(m," date- %02d:%02d:%02d\t%s\n",
                            sec/3600, sec%3600/60, sec%60, hrec);
-            len += size;  pos = begin + len;
-            if (pos < offset) {
-                len = 0;
-                begin = pos;
-            }
-            if (pos > offset + length)
-                goto stop_output;
         }
         if (id == -1)
             break;
     }
-
 stop_output:
-    *start = buffer +(offset-begin);
-    len -= (offset-begin);
-    if (len > length)
-        len = length;
-    TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n",
-            len,(int)pos,(int)begin,(int)offset,length,size));
-    rc = len;
-
+    rc = 0;
 free_fail:
     kfree(gdtcmd);
     kfree(estr);
index dab15f59f2ccb38797ab7b1e294d7e47f5abed59..aaa6181989727f14906468ff70e6dbd301c3c619 100644 (file)
@@ -8,11 +8,6 @@
 int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
                  int timeout, u32 *info);
 
-static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
-                         gdth_ha_str *ha);
-static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
-                         struct Scsi_Host *host, gdth_ha_str *ha);
-
 static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
                              int length, gdth_ha_str *ha);
 
index dbe4cc6b9f8b75be0823653fb05dd8e15e279cc9..2203ac281103b964917f47c1095d6c6a233ec7bf 100644 (file)
@@ -191,7 +191,8 @@ static int gvp11_bus_reset(struct scsi_cmnd *cmd)
 static struct scsi_host_template gvp11_scsi_template = {
        .module                 = THIS_MODULE,
        .name                   = "GVP Series II SCSI",
-       .proc_info              = wd33c93_proc_info,
+       .show_info              = wd33c93_show_info,
+       .write_info             = wd33c93_write_info,
        .proc_name              = "GVP11",
        .queuecommand           = wd33c93_queuecommand,
        .eh_abort_handler       = wd33c93_abort,
index 26cd9d1d7571b1674b5c6967c321b4abcc1dc531..89a8266560d0ebc2ecf44bb33f136b8cebb64ae9 100644 (file)
@@ -121,45 +121,26 @@ static inline void imm_pb_release(imm_struct *dev)
  * testing...
  * Also gives a method to use a script to obtain optimum timings (TODO)
  */
-static inline int imm_proc_write(imm_struct *dev, char *buffer, int length)
+static int imm_write_info(struct Scsi_Host *host, char *buffer, int length)
 {
-       unsigned long x;
+       imm_struct *dev = imm_dev(host);
 
        if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
-               x = simple_strtoul(buffer + 5, NULL, 0);
-               dev->mode = x;
+               dev->mode = simple_strtoul(buffer + 5, NULL, 0);
                return length;
        }
        printk("imm /proc: invalid variable\n");
-       return (-EINVAL);
+       return -EINVAL;
 }
 
-static int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start,
-                       off_t offset, int length, int inout)
+static int imm_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        imm_struct *dev = imm_dev(host);
-       int len = 0;
-
-       if (inout)
-               return imm_proc_write(dev, buffer, length);
-
-       len += sprintf(buffer + len, "Version : %s\n", IMM_VERSION);
-       len +=
-           sprintf(buffer + len, "Parport : %s\n",
-                   dev->dev->port->name);
-       len +=
-           sprintf(buffer + len, "Mode    : %s\n",
-                   IMM_MODE_STRING[dev->mode]);
 
-       /* Request for beyond end of buffer */
-       if (offset > len)
-               return 0;
-
-       *start = buffer + offset;
-       len -= offset;
-       if (len > length)
-               len = length;
-       return len;
+       seq_printf(m, "Version : %s\n", IMM_VERSION);
+       seq_printf(m, "Parport : %s\n", dev->dev->port->name);
+       seq_printf(m, "Mode    : %s\n", IMM_MODE_STRING[dev->mode]);
+       return 0;
 }
 
 #if IMM_DEBUG > 0
@@ -1118,7 +1099,8 @@ static int imm_adjust_queue(struct scsi_device *device)
 static struct scsi_host_template imm_template = {
        .module                 = THIS_MODULE,
        .proc_name              = "imm",
-       .proc_info              = imm_proc_info,
+       .show_info              = imm_show_info,
+       .write_info             = imm_write_info,
        .name                   = "Iomega VPI2 (imm) interface",
        .queuecommand           = imm_queuecommand,
        .eh_abort_handler       = imm_abort,
index deb5b6d8398ec2a1a2dfc90f7df31e8046d7ff33..bf028218ac36ec6e658b4359bd44cd1ab101a5ec 100644 (file)
@@ -2166,152 +2166,117 @@ static int in2000_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 }
 
 
-static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off, int len, int in)
+static int in2000_write_info(struct Scsi_Host *instance, char *buf, int len)
 {
 
 #ifdef PROC_INTERFACE
 
        char *bp;
-       char tbuf[128];
-       unsigned long flags;
        struct IN2000_hostdata *hd;
-       Scsi_Cmnd *cmd;
        int x, i;
-       static int stop = 0;
 
        hd = (struct IN2000_hostdata *) instance->hostdata;
 
-/* If 'in' is TRUE we need to _read_ the proc file. We accept the following
- * keywords (same format as command-line, but only ONE per read):
- *    debug
- *    disconnect
- *    period
- *    resync
- *    proc
- */
-
-       if (in) {
-               buf[len] = '\0';
-               bp = buf;
-               if (!strncmp(bp, "debug:", 6)) {
-                       bp += 6;
-                       hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK;
-               } else if (!strncmp(bp, "disconnect:", 11)) {
-                       bp += 11;
-                       x = simple_strtoul(bp, NULL, 0);
-                       if (x < DIS_NEVER || x > DIS_ALWAYS)
-                               x = DIS_ADAPTIVE;
-                       hd->disconnect = x;
-               } else if (!strncmp(bp, "period:", 7)) {
-                       bp += 7;
-                       x = simple_strtoul(bp, NULL, 0);
-                       hd->default_sx_per = sx_table[round_period((unsigned int) x)].period_ns;
-               } else if (!strncmp(bp, "resync:", 7)) {
-                       bp += 7;
-                       x = simple_strtoul(bp, NULL, 0);
-                       for (i = 0; i < 7; i++)
-                               if (x & (1 << i))
-                                       hd->sync_stat[i] = SS_UNSET;
-               } else if (!strncmp(bp, "proc:", 5)) {
-                       bp += 5;
-                       hd->proc = simple_strtoul(bp, NULL, 0);
-               } else if (!strncmp(bp, "level2:", 7)) {
-                       bp += 7;
-                       hd->level2 = simple_strtoul(bp, NULL, 0);
-               }
-               return len;
+       buf[len] = '\0';
+       bp = buf;
+       if (!strncmp(bp, "debug:", 6)) {
+               bp += 6;
+               hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK;
+       } else if (!strncmp(bp, "disconnect:", 11)) {
+               bp += 11;
+               x = simple_strtoul(bp, NULL, 0);
+               if (x < DIS_NEVER || x > DIS_ALWAYS)
+                       x = DIS_ADAPTIVE;
+               hd->disconnect = x;
+       } else if (!strncmp(bp, "period:", 7)) {
+               bp += 7;
+               x = simple_strtoul(bp, NULL, 0);
+               hd->default_sx_per = sx_table[round_period((unsigned int) x)].period_ns;
+       } else if (!strncmp(bp, "resync:", 7)) {
+               bp += 7;
+               x = simple_strtoul(bp, NULL, 0);
+               for (i = 0; i < 7; i++)
+                       if (x & (1 << i))
+                               hd->sync_stat[i] = SS_UNSET;
+       } else if (!strncmp(bp, "proc:", 5)) {
+               bp += 5;
+               hd->proc = simple_strtoul(bp, NULL, 0);
+       } else if (!strncmp(bp, "level2:", 7)) {
+               bp += 7;
+               hd->level2 = simple_strtoul(bp, NULL, 0);
        }
+#endif
+       return len;
+}
+
+static int in2000_show_info(struct seq_file *m, struct Scsi_Host *instance)
+{
+
+#ifdef PROC_INTERFACE
+       unsigned long flags;
+       struct IN2000_hostdata *hd;
+       Scsi_Cmnd *cmd;
+       int x;
+
+       hd = (struct IN2000_hostdata *) instance->hostdata;
 
        spin_lock_irqsave(instance->host_lock, flags);
-       bp = buf;
-       *bp = '\0';
-       if (hd->proc & PR_VERSION) {
-               sprintf(tbuf, "\nVersion %s - %s.", IN2000_VERSION, IN2000_DATE);
-               strcat(bp, tbuf);
-       }
+       if (hd->proc & PR_VERSION)
+               seq_printf(m, "\nVersion %s - %s.", IN2000_VERSION, IN2000_DATE);
+
        if (hd->proc & PR_INFO) {
-               sprintf(tbuf, "\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s", (hd->dip_switch & 0x7f), instance->irq, hd->io_base, (hd->dip_switch & 0x40) ? "Yes" : "No", (hd->dip_switch & 0x20) ? "Yes" : "No");
-               strcat(bp, tbuf);
-               strcat(bp, "\nsync_xfer[] =       ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%02x", hd->sync_xfer[x]);
-                       strcat(bp, tbuf);
-               }
-               strcat(bp, "\nsync_stat[] =       ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%02x", hd->sync_stat[x]);
-                       strcat(bp, tbuf);
-               }
+               seq_printf(m, "\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s", (hd->dip_switch & 0x7f), instance->irq, hd->io_base, (hd->dip_switch & 0x40) ? "Yes" : "No", (hd->dip_switch & 0x20) ? "Yes" : "No");
+               seq_printf(m, "\nsync_xfer[] =       ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%02x", hd->sync_xfer[x]);
+               seq_printf(m, "\nsync_stat[] =       ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%02x", hd->sync_stat[x]);
        }
 #ifdef PROC_STATISTICS
        if (hd->proc & PR_STATISTICS) {
-               strcat(bp, "\ncommands issued:    ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%ld", hd->cmd_cnt[x]);
-                       strcat(bp, tbuf);
-               }
-               strcat(bp, "\ndisconnects allowed:");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%ld", hd->disc_allowed_cnt[x]);
-                       strcat(bp, tbuf);
-               }
-               strcat(bp, "\ndisconnects done:   ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%ld", hd->disc_done_cnt[x]);
-                       strcat(bp, tbuf);
-               }
-               sprintf(tbuf, "\ninterrupts:      \t%ld", hd->int_cnt);
-               strcat(bp, tbuf);
+               seq_printf(m, "\ncommands issued:    ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%ld", hd->cmd_cnt[x]);
+               seq_printf(m, "\ndisconnects allowed:");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%ld", hd->disc_allowed_cnt[x]);
+               seq_printf(m, "\ndisconnects done:   ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%ld", hd->disc_done_cnt[x]);
+               seq_printf(m, "\ninterrupts:      \t%ld", hd->int_cnt);
        }
 #endif
        if (hd->proc & PR_CONNECTED) {
-               strcat(bp, "\nconnected:     ");
+               seq_printf(m, "\nconnected:     ");
                if (hd->connected) {
                        cmd = (Scsi_Cmnd *) hd->connected;
-                       sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
-                       strcat(bp, tbuf);
+                       seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
                }
        }
        if (hd->proc & PR_INPUTQ) {
-               strcat(bp, "\ninput_Q:       ");
+               seq_printf(m, "\ninput_Q:       ");
                cmd = (Scsi_Cmnd *) hd->input_Q;
                while (cmd) {
-                       sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
-                       strcat(bp, tbuf);
+                       seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
                        cmd = (Scsi_Cmnd *) cmd->host_scribble;
                }
        }
        if (hd->proc & PR_DISCQ) {
-               strcat(bp, "\ndisconnected_Q:");
+               seq_printf(m, "\ndisconnected_Q:");
                cmd = (Scsi_Cmnd *) hd->disconnected_Q;
                while (cmd) {
-                       sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
-                       strcat(bp, tbuf);
+                       seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
                        cmd = (Scsi_Cmnd *) cmd->host_scribble;
                }
        }
        if (hd->proc & PR_TEST) {
                ;               /* insert your own custom function here */
        }
-       strcat(bp, "\n");
+       seq_printf(m, "\n");
        spin_unlock_irqrestore(instance->host_lock, flags);
-       *start = buf;
-       if (stop) {
-               stop = 0;
-               return 0;       /* return 0 to signal end-of-file */
-       }
-       if (off > 0x40000)      /* ALWAYS stop after 256k bytes have been read */
-               stop = 1;
-       if (hd->proc & PR_STOP) /* stop every other time */
-               stop = 1;
-       return strlen(bp);
-
-#else                          /* PROC_INTERFACE */
-
-       return 0;
-
 #endif                         /* PROC_INTERFACE */
-
+       return 0;
 }
 
 MODULE_LICENSE("GPL");
@@ -2319,7 +2284,8 @@ MODULE_LICENSE("GPL");
 
 static struct scsi_host_template driver_template = {
        .proc_name                      = "in2000",
-       .proc_info                      = in2000_proc_info,
+       .write_info                     = in2000_write_info,
+       .show_info                      = in2000_show_info,
        .name                           = "Always IN2000",
        .detect                         = in2000_detect, 
        .release                        = in2000_release,
index 9aa86a315a088c9a450e8ff061196349e5c13f34..8d5ea8a1e5a6f33ab8235b300417d7ba352f84f7 100644 (file)
@@ -326,10 +326,9 @@ static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
 static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
                              unsigned int count);
 
-static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
-static int ips_host_info(ips_ha_t *, char *, off_t, int);
-static void copy_mem_info(IPS_INFOSTR *, char *, int);
-static int copy_info(IPS_INFOSTR *, char *, ...);
+static int ips_write_info(struct Scsi_Host *, char *, int);
+static int ips_show_info(struct seq_file *, struct Scsi_Host *);
+static int ips_host_info(ips_ha_t *, struct seq_file *);
 static int ips_abort_init(ips_ha_t * ha, int index);
 static int ips_init_phase2(int index);
 
@@ -367,7 +366,8 @@ static struct scsi_host_template ips_driver_template = {
        .eh_abort_handler       = ips_eh_abort,
        .eh_host_reset_handler  = ips_eh_reset,
        .proc_name              = "ips",
-       .proc_info              = ips_proc_info,
+       .show_info              = ips_show_info,
+       .write_info             = ips_write_info,
        .slave_configure        = ips_slave_configure,
        .bios_param             = ips_biosparam,
        .this_id                = -1,
@@ -1433,25 +1433,12 @@ ips_info(struct Scsi_Host *SH)
        return (bp);
 }
 
-/****************************************************************************/
-/*                                                                          */
-/* Routine Name: ips_proc_info                                              */
-/*                                                                          */
-/* Routine Description:                                                     */
-/*                                                                          */
-/*   The passthru interface for the driver                                  */
-/*                                                                          */
-/****************************************************************************/
 static int
-ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-             int length, int func)
+ips_write_info(struct Scsi_Host *host, char *buffer, int length)
 {
        int i;
-       int ret;
        ips_ha_t *ha = NULL;
 
-       METHOD_TRACE("ips_proc_info", 1);
-
        /* Find our host structure */
        for (i = 0; i < ips_next_controller; i++) {
                if (ips_sh[i]) {
@@ -1465,18 +1452,29 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
        if (!ha)
                return (-EINVAL);
 
-       if (func) {
-               /* write */
-               return (0);
-       } else {
-               /* read */
-               if (start)
-                       *start = buffer;
+       return 0;
+}
 
-               ret = ips_host_info(ha, buffer, offset, length);
+static int
+ips_show_info(struct seq_file *m, struct Scsi_Host *host)
+{
+       int i;
+       ips_ha_t *ha = NULL;
 
-               return (ret);
+       /* Find our host structure */
+       for (i = 0; i < ips_next_controller; i++) {
+               if (ips_sh[i]) {
+                       if (ips_sh[i] == host) {
+                               ha = (ips_ha_t *) ips_sh[i]->hostdata;
+                               break;
+                       }
+               }
        }
+
+       if (!ha)
+               return (-EINVAL);
+
+       return ips_host_info(ha, m);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -2035,183 +2033,113 @@ ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
+ips_host_info(ips_ha_t *ha, struct seq_file *m)
 {
-       IPS_INFOSTR info;
-
        METHOD_TRACE("ips_host_info", 1);
 
-       info.buffer = ptr;
-       info.length = len;
-       info.offset = offset;
-       info.pos = 0;
-       info.localpos = 0;
-
-       copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
+       seq_printf(m, "\nIBM ServeRAID General Information:\n\n");
 
        if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
            (le16_to_cpu(ha->nvram->adapter_type) != 0))
-               copy_info(&info, "\tController Type                   : %s\n",
+               seq_printf(m, "\tController Type                   : %s\n",
                          ips_adapter_name[ha->ad_type - 1]);
        else
-               copy_info(&info,
+               seq_printf(m,
                          "\tController Type                   : Unknown\n");
 
        if (ha->io_addr)
-               copy_info(&info,
-                         "\tIO region                         : 0x%lx (%d bytes)\n",
+               seq_printf(m,
+                         "\tIO region                         : 0x%x (%d bytes)\n",
                          ha->io_addr, ha->io_len);
 
        if (ha->mem_addr) {
-               copy_info(&info,
-                         "\tMemory region                     : 0x%lx (%d bytes)\n",
+               seq_printf(m,
+                         "\tMemory region                     : 0x%x (%d bytes)\n",
                          ha->mem_addr, ha->mem_len);
-               copy_info(&info,
+               seq_printf(m,
                          "\tShared memory address             : 0x%lx\n",
-                         ha->mem_ptr);
+                         (unsigned long)ha->mem_ptr);
        }
 
-       copy_info(&info, "\tIRQ number                        : %d\n", ha->pcidev->irq);
+       seq_printf(m, "\tIRQ number                        : %d\n", ha->pcidev->irq);
 
     /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */
     /* That keeps everything happy for "text" operations on the proc file.                    */
 
        if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
        if (ha->nvram->bios_low[3] == 0) {
-            copy_info(&info,
-                                 "\tBIOS Version                      : %c%c%c%c%c%c%c\n",
-                                 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
-                                 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
-                                 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
-                                 ha->nvram->bios_low[2]);
+               seq_printf(m,
+                         "\tBIOS Version                      : %c%c%c%c%c%c%c\n",
+                         ha->nvram->bios_high[0], ha->nvram->bios_high[1],
+                         ha->nvram->bios_high[2], ha->nvram->bios_high[3],
+                         ha->nvram->bios_low[0], ha->nvram->bios_low[1],
+                         ha->nvram->bios_low[2]);
 
         } else {
-                   copy_info(&info,
-                                 "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
-                                 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
-                                 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
-                                 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
-                                 ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
+               seq_printf(m,
+                         "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
+                         ha->nvram->bios_high[0], ha->nvram->bios_high[1],
+                         ha->nvram->bios_high[2], ha->nvram->bios_high[3],
+                         ha->nvram->bios_low[0], ha->nvram->bios_low[1],
+                         ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
         }
 
     }
 
     if (ha->enq->CodeBlkVersion[7] == 0) {
-        copy_info(&info,
-                         "\tFirmware Version                  : %c%c%c%c%c%c%c\n",
-                         ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
-                         ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
-                         ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
-                         ha->enq->CodeBlkVersion[6]);
+        seq_printf(m,
+                 "\tFirmware Version                  : %c%c%c%c%c%c%c\n",
+                 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
+                 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
+                 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
+                 ha->enq->CodeBlkVersion[6]);
     } else {
-        copy_info(&info,
-                         "\tFirmware Version                  : %c%c%c%c%c%c%c%c\n",
-                         ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
-                         ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
-                         ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
-                         ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
+       seq_printf(m,
+                 "\tFirmware Version                  : %c%c%c%c%c%c%c%c\n",
+                 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
+                 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
+                 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
+                 ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
     }
 
     if (ha->enq->BootBlkVersion[7] == 0) {
-        copy_info(&info,
-                         "\tBoot Block Version                : %c%c%c%c%c%c%c\n",
-                         ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
-                         ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
-                         ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
-                         ha->enq->BootBlkVersion[6]);
+        seq_printf(m,
+                 "\tBoot Block Version                : %c%c%c%c%c%c%c\n",
+                 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
+                 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
+                 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
+                 ha->enq->BootBlkVersion[6]);
     } else {
-        copy_info(&info,
-                         "\tBoot Block Version                : %c%c%c%c%c%c%c%c\n",
-                         ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
-                         ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
-                         ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
-                         ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
+        seq_printf(m,
+                 "\tBoot Block Version                : %c%c%c%c%c%c%c%c\n",
+                 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
+                 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
+                 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
+                 ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
     }
 
-       copy_info(&info, "\tDriver Version                    : %s%s\n",
+       seq_printf(m, "\tDriver Version                    : %s%s\n",
                  IPS_VERSION_HIGH, IPS_VERSION_LOW);
 
-       copy_info(&info, "\tDriver Build                      : %d\n",
+       seq_printf(m, "\tDriver Build                      : %d\n",
                  IPS_BUILD_IDENT);
 
-       copy_info(&info, "\tMax Physical Devices              : %d\n",
+       seq_printf(m, "\tMax Physical Devices              : %d\n",
                  ha->enq->ucMaxPhysicalDevices);
-       copy_info(&info, "\tMax Active Commands               : %d\n",
+       seq_printf(m, "\tMax Active Commands               : %d\n",
                  ha->max_cmds);
-       copy_info(&info, "\tCurrent Queued Commands           : %d\n",
+       seq_printf(m, "\tCurrent Queued Commands           : %d\n",
                  ha->scb_waitlist.count);
-       copy_info(&info, "\tCurrent Active Commands           : %d\n",
+       seq_printf(m, "\tCurrent Active Commands           : %d\n",
                  ha->scb_activelist.count - ha->num_ioctl);
-       copy_info(&info, "\tCurrent Queued PT Commands        : %d\n",
+       seq_printf(m, "\tCurrent Queued PT Commands        : %d\n",
                  ha->copp_waitlist.count);
-       copy_info(&info, "\tCurrent Active PT Commands        : %d\n",
+       seq_printf(m, "\tCurrent Active PT Commands        : %d\n",
                  ha->num_ioctl);
 
-       copy_info(&info, "\n");
-
-       return (info.localpos);
-}
-
-/****************************************************************************/
-/*                                                                          */
-/* Routine Name: copy_mem_info                                              */
-/*                                                                          */
-/* Routine Description:                                                     */
-/*                                                                          */
-/*   Copy data into an IPS_INFOSTR structure                                */
-/*                                                                          */
-/****************************************************************************/
-static void
-copy_mem_info(IPS_INFOSTR * info, char *data, int len)
-{
-       METHOD_TRACE("copy_mem_info", 1);
-
-       if (info->pos + len < info->offset) {
-               info->pos += len;
-               return;
-       }
-
-       if (info->pos < info->offset) {
-               data += (info->offset - info->pos);
-               len -= (info->offset - info->pos);
-               info->pos += (info->offset - info->pos);
-       }
-
-       if (info->localpos + len > info->length)
-               len = info->length - info->localpos;
+       seq_printf(m, "\n");
 
-       if (len > 0) {
-               memcpy(info->buffer + info->localpos, data, len);
-               info->pos += len;
-               info->localpos += len;
-       }
-}
-
-/****************************************************************************/
-/*                                                                          */
-/* Routine Name: copy_info                                                  */
-/*                                                                          */
-/* Routine Description:                                                     */
-/*                                                                          */
-/*   printf style wrapper for an info structure                             */
-/*                                                                          */
-/****************************************************************************/
-static int
-copy_info(IPS_INFOSTR * info, char *fmt, ...)
-{
-       va_list args;
-       char buf[128];
-       int len;
-
-       METHOD_TRACE("copy_info", 1);
-
-       va_start(args, fmt);
-       len = vsprintf(buf, fmt, args);
-       va_end(args);
-
-       copy_mem_info(info, buf, len);
-
-       return (len);
+       return 0;
 }
 
 /****************************************************************************/
index f2df0593332ba9ec0ed02de16a699e799bc21ed7..45b9566b928e1895553d85c98056f9aa65793dc5 100644 (file)
    /*
     * Scsi_Host Template
     */
-   static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
    static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
                sector_t capacity, int geom[]);
    static int ips_slave_configure(struct scsi_device *SDptr);
@@ -959,14 +958,6 @@ typedef union {
    IPS_ENH_SG_LIST  *enh_list;
 } IPS_SG_LIST;
 
-typedef struct _IPS_INFOSTR {
-   char *buffer;
-   int   length;
-   int   offset;
-   int   pos;
-   int   localpos;
-} IPS_INFOSTR;
-
 typedef struct {
    char *option_name;
    int  *option_flag;
index 314b4f61b9e3fc73035fbdf48995e34bb31ed4dc..8b9c191a70198bda139e4f58afe9cec8e0303385 100644 (file)
@@ -10368,36 +10368,6 @@ lpfc_io_resume(struct pci_dev *pdev)
        return;
 }
 
-/**
- * lpfc_mgmt_open - method called when 'lpfcmgmt' is opened from userspace
- * @inode: pointer to the inode representing the lpfcmgmt device
- * @filep: pointer to the file representing the open lpfcmgmt device
- *
- * This routine puts a reference count on the lpfc module whenever the
- * character device is opened
- **/
-static int
-lpfc_mgmt_open(struct inode *inode, struct file *filep)
-{
-       try_module_get(THIS_MODULE);
-       return 0;
-}
-
-/**
- * lpfc_mgmt_release - method called when 'lpfcmgmt' is closed in userspace
- * @inode: pointer to the inode representing the lpfcmgmt device
- * @filep: pointer to the file representing the open lpfcmgmt device
- *
- * This routine removes a reference count from the lpfc module when the
- * character device is closed
- **/
-static int
-lpfc_mgmt_release(struct inode *inode, struct file *filep)
-{
-       module_put(THIS_MODULE);
-       return 0;
-}
-
 static struct pci_device_id lpfc_id_table[] = {
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_VIPER,
                PCI_ANY_ID, PCI_ANY_ID, },
@@ -10515,8 +10485,7 @@ static struct pci_driver lpfc_driver = {
 };
 
 static const struct file_operations lpfc_mgmt_fop = {
-       .open = lpfc_mgmt_open,
-       .release = lpfc_mgmt_release,
+       .owner = THIS_MODULE,
 };
 
 static struct miscdevice lpfc_mgmt_dev = {
index 24828b54773a627a2c866d008cabfbc06aa3b534..858075723c87fc2e010f582385126529ac168fff 100644 (file)
@@ -561,7 +561,8 @@ static int macscsi_pwrite (struct Scsi_Host *instance,
 
 static struct scsi_host_template driver_template = {
        .proc_name                      = "Mac5380",
-       .proc_info                      = macscsi_proc_info,
+       .show_info                      = macscsi_show_info,
+       .write_info                     = macscsi_write_info,
        .name                           = "Macintosh NCR5380 SCSI",
        .detect                         = macscsi_detect,
        .release                        = macscsi_release,
index d26e331c6c12e3d6e37790e92ed124a74b34309d..7dc62fce1c4c6739ec1f21faa59be2aebf55f8ee 100644 (file)
@@ -72,7 +72,8 @@
 #define NCR5380_queue_command macscsi_queue_command
 #define NCR5380_abort macscsi_abort
 #define NCR5380_bus_reset macscsi_bus_reset
-#define NCR5380_proc_info macscsi_proc_info
+#define NCR5380_show_info macscsi_show_info
+#define NCR5380_write_info macscsi_write_info
 
 #define BOARD_NORMAL   0
 #define BOARD_NCR53C400        1
index 9504ec0ec68291273a2ad3ef6845e3c4e0c94bc5..7373255aa1e817c86480fb28410dbf8f9f774b32 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/reboot.h>
 #include <linux/module.h>
 #include <linux/list.h>
@@ -2069,385 +2070,201 @@ mega_free_inquiry(void *inquiry, dma_addr_t dma_handle, struct pci_dev *pdev)
 #ifdef CONFIG_PROC_FS
 /* Following code handles /proc fs  */
 
-#define CREATE_READ_PROC(string, func) create_proc_read_entry(string,  \
-                                       S_IRUSR | S_IFREG,              \
-                                       controller_proc_dir_entry,      \
-                                       func, adapter)
-
-/**
- * mega_create_proc_entry()
- * @index - index in soft state array
- * @parent - parent node for this /proc entry
- *
- * Creates /proc entries for our controllers.
- */
-static void
-mega_create_proc_entry(int index, struct proc_dir_entry *parent)
-{
-       struct proc_dir_entry   *controller_proc_dir_entry = NULL;
-       u8              string[64] = { 0 };
-       adapter_t       *adapter = hba_soft_state[index];
-
-       sprintf(string, "hba%d", adapter->host->host_no);
-
-       controller_proc_dir_entry =
-               adapter->controller_proc_dir_entry = proc_mkdir(string, parent);
-
-       if(!controller_proc_dir_entry) {
-               printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n");
-               return;
-       }
-       adapter->proc_read = CREATE_READ_PROC("config", proc_read_config);
-       adapter->proc_stat = CREATE_READ_PROC("stat", proc_read_stat);
-       adapter->proc_mbox = CREATE_READ_PROC("mailbox", proc_read_mbox);
-#if MEGA_HAVE_ENH_PROC
-       adapter->proc_rr = CREATE_READ_PROC("rebuild-rate", proc_rebuild_rate);
-       adapter->proc_battery = CREATE_READ_PROC("battery-status",
-                       proc_battery);
-
-       /*
-        * Display each physical drive on its channel
-        */
-       adapter->proc_pdrvstat[0] = CREATE_READ_PROC("diskdrives-ch0",
-                                       proc_pdrv_ch0);
-       adapter->proc_pdrvstat[1] = CREATE_READ_PROC("diskdrives-ch1",
-                                       proc_pdrv_ch1);
-       adapter->proc_pdrvstat[2] = CREATE_READ_PROC("diskdrives-ch2",
-                                       proc_pdrv_ch2);
-       adapter->proc_pdrvstat[3] = CREATE_READ_PROC("diskdrives-ch3",
-                                       proc_pdrv_ch3);
-
-       /*
-        * Display a set of up to 10 logical drive through each of following
-        * /proc entries
-        */
-       adapter->proc_rdrvstat[0] = CREATE_READ_PROC("raiddrives-0-9",
-                                       proc_rdrv_10);
-       adapter->proc_rdrvstat[1] = CREATE_READ_PROC("raiddrives-10-19",
-                                       proc_rdrv_20);
-       adapter->proc_rdrvstat[2] = CREATE_READ_PROC("raiddrives-20-29",
-                                       proc_rdrv_30);
-       adapter->proc_rdrvstat[3] = CREATE_READ_PROC("raiddrives-30-39",
-                                       proc_rdrv_40);
-#endif
-}
-
-
 /**
- * proc_read_config()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_config()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
  * Display configuration information about the controller.
  */
 static int
-proc_read_config(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_config(struct seq_file *m, void *v)
 {
 
-       adapter_t *adapter = (adapter_t *)data;
-       int len = 0;
-
-       len += sprintf(page+len, "%s", MEGARAID_VERSION);
+       adapter_t *adapter = m->private;
 
+       seq_puts(m, MEGARAID_VERSION);
        if(adapter->product_info.product_name[0])
-               len += sprintf(page+len, "%s\n",
-                               adapter->product_info.product_name);
-
-       len += sprintf(page+len, "Controller Type: ");
+               seq_printf(m, "%s\n", adapter->product_info.product_name);
 
-       if( adapter->flag & BOARD_MEMMAP ) {
-               len += sprintf(page+len,
-                       "438/466/467/471/493/518/520/531/532\n");
-       }
-       else {
-               len += sprintf(page+len,
-                       "418/428/434\n");
-       }
+       seq_puts(m, "Controller Type: ");
 
-       if(adapter->flag & BOARD_40LD) {
-               len += sprintf(page+len,
-                               "Controller Supports 40 Logical Drives\n");
-       }
+       if( adapter->flag & BOARD_MEMMAP )
+               seq_puts(m, "438/466/467/471/493/518/520/531/532\n");
+       else
+               seq_puts(m, "418/428/434\n");
 
-       if(adapter->flag & BOARD_64BIT) {
-               len += sprintf(page+len,
-               "Controller capable of 64-bit memory addressing\n");
-       }
-       if( adapter->has_64bit_addr ) {
-               len += sprintf(page+len,
-                       "Controller using 64-bit memory addressing\n");
-       }
-       else {
-               len += sprintf(page+len,
-                       "Controller is not using 64-bit memory addressing\n");
-       }
+       if(adapter->flag & BOARD_40LD)
+               seq_puts(m, "Controller Supports 40 Logical Drives\n");
 
-       len += sprintf(page+len, "Base = %08lx, Irq = %d, ", adapter->base,
-                       adapter->host->irq);
-
-       len += sprintf(page+len, "Logical Drives = %d, Channels = %d\n",
-                       adapter->numldrv, adapter->product_info.nchannels);
-
-       len += sprintf(page+len, "Version =%s:%s, DRAM = %dMb\n",
-                       adapter->fw_version, adapter->bios_version,
-                       adapter->product_info.dram_size);
-
-       len += sprintf(page+len,
-               "Controller Queue Depth = %d, Driver Queue Depth = %d\n",
-               adapter->product_info.max_commands, adapter->max_cmds);
-
-       len += sprintf(page+len, "support_ext_cdb    = %d\n",
-                       adapter->support_ext_cdb);
-       len += sprintf(page+len, "support_random_del = %d\n",
-                       adapter->support_random_del);
-       len += sprintf(page+len, "boot_ldrv_enabled  = %d\n",
-                       adapter->boot_ldrv_enabled);
-       len += sprintf(page+len, "boot_ldrv          = %d\n",
-                       adapter->boot_ldrv);
-       len += sprintf(page+len, "boot_pdrv_enabled  = %d\n",
-                       adapter->boot_pdrv_enabled);
-       len += sprintf(page+len, "boot_pdrv_ch       = %d\n",
-                       adapter->boot_pdrv_ch);
-       len += sprintf(page+len, "boot_pdrv_tgt      = %d\n",
-                       adapter->boot_pdrv_tgt);
-       len += sprintf(page+len, "quiescent          = %d\n",
-                       atomic_read(&adapter->quiescent));
-       len += sprintf(page+len, "has_cluster        = %d\n",
-                       adapter->has_cluster);
-
-       len += sprintf(page+len, "\nModule Parameters:\n");
-       len += sprintf(page+len, "max_cmd_per_lun    = %d\n",
-                       max_cmd_per_lun);
-       len += sprintf(page+len, "max_sectors_per_io = %d\n",
-                       max_sectors_per_io);
-
-       *eof = 1;
-
-       return len;
+       if(adapter->flag & BOARD_64BIT)
+               seq_puts(m, "Controller capable of 64-bit memory addressing\n");
+       if( adapter->has_64bit_addr )
+               seq_puts(m, "Controller using 64-bit memory addressing\n");
+       else
+               seq_puts(m, "Controller is not using 64-bit memory addressing\n");
+
+       seq_printf(m, "Base = %08lx, Irq = %d, ",
+                  adapter->base, adapter->host->irq);
+
+       seq_printf(m, "Logical Drives = %d, Channels = %d\n",
+                  adapter->numldrv, adapter->product_info.nchannels);
+
+       seq_printf(m, "Version =%s:%s, DRAM = %dMb\n",
+                  adapter->fw_version, adapter->bios_version,
+                  adapter->product_info.dram_size);
+
+       seq_printf(m, "Controller Queue Depth = %d, Driver Queue Depth = %d\n",
+                  adapter->product_info.max_commands, adapter->max_cmds);
+
+       seq_printf(m, "support_ext_cdb    = %d\n", adapter->support_ext_cdb);
+       seq_printf(m, "support_random_del = %d\n", adapter->support_random_del);
+       seq_printf(m, "boot_ldrv_enabled  = %d\n", adapter->boot_ldrv_enabled);
+       seq_printf(m, "boot_ldrv          = %d\n", adapter->boot_ldrv);
+       seq_printf(m, "boot_pdrv_enabled  = %d\n", adapter->boot_pdrv_enabled);
+       seq_printf(m, "boot_pdrv_ch       = %d\n", adapter->boot_pdrv_ch);
+       seq_printf(m, "boot_pdrv_tgt      = %d\n", adapter->boot_pdrv_tgt);
+       seq_printf(m, "quiescent          = %d\n",
+                  atomic_read(&adapter->quiescent));
+       seq_printf(m, "has_cluster        = %d\n", adapter->has_cluster);
+
+       seq_puts(m, "\nModule Parameters:\n");
+       seq_printf(m, "max_cmd_per_lun    = %d\n", max_cmd_per_lun);
+       seq_printf(m, "max_sectors_per_io = %d\n", max_sectors_per_io);
+       return 0;
 }
 
-
-
 /**
- * proc_read_stat()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_stat()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
- * Diaplay statistical information about the I/O activity.
+ * Display statistical information about the I/O activity.
  */
 static int
-proc_read_stat(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_stat(struct seq_file *m, void *v)
 {
-       adapter_t       *adapter;
-       int     len;
+       adapter_t *adapter = m->private;
+#if MEGA_HAVE_STATS
        int     i;
+#endif
 
-       i = 0;  /* avoid compilation warnings */
-       len = 0;
-       adapter = (adapter_t *)data;
-
-       len = sprintf(page, "Statistical Information for this controller\n");
-       len += sprintf(page+len, "pend_cmds = %d\n",
-                       atomic_read(&adapter->pend_cmds));
+       seq_puts(m, "Statistical Information for this controller\n");
+       seq_printf(m, "pend_cmds = %d\n", atomic_read(&adapter->pend_cmds));
 #if MEGA_HAVE_STATS
        for(i = 0; i < adapter->numldrv; i++) {
-               len += sprintf(page+len, "Logical Drive %d:\n", i);
-
-               len += sprintf(page+len,
-                       "\tReads Issued = %lu, Writes Issued = %lu\n",
-                       adapter->nreads[i], adapter->nwrites[i]);
-
-               len += sprintf(page+len,
-                       "\tSectors Read = %lu, Sectors Written = %lu\n",
-                       adapter->nreadblocks[i], adapter->nwriteblocks[i]);
-
-               len += sprintf(page+len,
-                       "\tRead errors = %lu, Write errors = %lu\n\n",
-                       adapter->rd_errors[i], adapter->wr_errors[i]);
+               seq_printf(m, "Logical Drive %d:\n", i);
+               seq_printf(m, "\tReads Issued = %lu, Writes Issued = %lu\n",
+                          adapter->nreads[i], adapter->nwrites[i]);
+               seq_printf(m, "\tSectors Read = %lu, Sectors Written = %lu\n",
+                          adapter->nreadblocks[i], adapter->nwriteblocks[i]);
+               seq_printf(m, "\tRead errors = %lu, Write errors = %lu\n\n",
+                          adapter->rd_errors[i], adapter->wr_errors[i]);
        }
 #else
-       len += sprintf(page+len,
-                       "IO and error counters not compiled in driver.\n");
+       seq_puts(m, "IO and error counters not compiled in driver.\n");
 #endif
-
-       *eof = 1;
-
-       return len;
+       return 0;
 }
 
 
 /**
- * proc_read_mbox()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_mbox()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
  * Display mailbox information for the last command issued. This information
  * is good for debugging.
  */
 static int
-proc_read_mbox(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_mbox(struct seq_file *m, void *v)
 {
-
-       adapter_t       *adapter = (adapter_t *)data;
+       adapter_t       *adapter = m->private;
        volatile mbox_t *mbox = adapter->mbox;
-       int     len = 0;
-
-       len = sprintf(page, "Contents of Mail Box Structure\n");
-       len += sprintf(page+len, "  Fw Command   = 0x%02x\n", 
-                       mbox->m_out.cmd);
-       len += sprintf(page+len, "  Cmd Sequence = 0x%02x\n", 
-                       mbox->m_out.cmdid);
-       len += sprintf(page+len, "  No of Sectors= %04d\n", 
-                       mbox->m_out.numsectors);
-       len += sprintf(page+len, "  LBA          = 0x%02x\n", 
-                       mbox->m_out.lba);
-       len += sprintf(page+len, "  DTA          = 0x%08x\n", 
-                       mbox->m_out.xferaddr);
-       len += sprintf(page+len, "  Logical Drive= 0x%02x\n", 
-                       mbox->m_out.logdrv);
-       len += sprintf(page+len, "  No of SG Elmt= 0x%02x\n",
-                       mbox->m_out.numsgelements);
-       len += sprintf(page+len, "  Busy         = %01x\n", 
-                       mbox->m_in.busy);
-       len += sprintf(page+len, "  Status       = 0x%02x\n", 
-                       mbox->m_in.status);
-
-       *eof = 1;
-
-       return len;
+
+       seq_puts(m, "Contents of Mail Box Structure\n");
+       seq_printf(m, "  Fw Command   = 0x%02x\n", mbox->m_out.cmd);
+       seq_printf(m, "  Cmd Sequence = 0x%02x\n", mbox->m_out.cmdid);
+       seq_printf(m, "  No of Sectors= %04d\n", mbox->m_out.numsectors);
+       seq_printf(m, "  LBA          = 0x%02x\n", mbox->m_out.lba);
+       seq_printf(m, "  DTA          = 0x%08x\n", mbox->m_out.xferaddr);
+       seq_printf(m, "  Logical Drive= 0x%02x\n", mbox->m_out.logdrv);
+       seq_printf(m, "  No of SG Elmt= 0x%02x\n", mbox->m_out.numsgelements);
+       seq_printf(m, "  Busy         = %01x\n", mbox->m_in.busy);
+       seq_printf(m, "  Status       = 0x%02x\n", mbox->m_in.status);
+       return 0;
 }
 
 
 /**
- * proc_rebuild_rate()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_rebuild_rate()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
  * Display current rebuild rate
  */
 static int
-proc_rebuild_rate(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_rebuild_rate(struct seq_file *m, void *v)
 {
-       adapter_t       *adapter = (adapter_t *)data;
+       adapter_t       *adapter = m->private;
        dma_addr_t      dma_handle;
        caddr_t         inquiry;
        struct pci_dev  *pdev;
-       int     len = 0;
 
-       if( make_local_pdev(adapter, &pdev) != 0 ) {
-               *eof = 1;
-               return len;
-       }
+       if( make_local_pdev(adapter, &pdev) != 0 )
+               return 0;
 
-       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
-               free_local_pdev(pdev);
-               *eof = 1;
-               return len;
-       }
+       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
+               goto free_pdev;
 
        if( mega_adapinq(adapter, dma_handle) != 0 ) {
-
-               len = sprintf(page, "Adapter inquiry failed.\n");
-
+               seq_puts(m, "Adapter inquiry failed.\n");
                printk(KERN_WARNING "megaraid: inquiry failed.\n");
-
-               mega_free_inquiry(inquiry, dma_handle, pdev);
-
-               free_local_pdev(pdev);
-
-               *eof = 1;
-
-               return len;
+               goto free_inquiry;
        }
 
-       if( adapter->flag & BOARD_40LD ) {
-               len = sprintf(page, "Rebuild Rate: [%d%%]\n",
-                       ((mega_inquiry3 *)inquiry)->rebuild_rate);
-       }
-       else {
-               len = sprintf(page, "Rebuild Rate: [%d%%]\n",
+       if( adapter->flag & BOARD_40LD )
+               seq_printf(m, "Rebuild Rate: [%d%%]\n",
+                          ((mega_inquiry3 *)inquiry)->rebuild_rate);
+       else
+               seq_printf(m, "Rebuild Rate: [%d%%]\n",
                        ((mraid_ext_inquiry *)
-                       inquiry)->raid_inq.adapter_info.rebuild_rate);
-       }
-
+                        inquiry)->raid_inq.adapter_info.rebuild_rate);
 
+free_inquiry:
        mega_free_inquiry(inquiry, dma_handle, pdev);
-
+free_pdev:
        free_local_pdev(pdev);
-
-       *eof = 1;
-
-       return len;
+       return 0;
 }
 
 
 /**
- * proc_battery()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_battery()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
  * Display information about the battery module on the controller.
  */
 static int
-proc_battery(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_battery(struct seq_file *m, void *v)
 {
-       adapter_t       *adapter = (adapter_t *)data;
+       adapter_t       *adapter = m->private;
        dma_addr_t      dma_handle;
        caddr_t         inquiry;
        struct pci_dev  *pdev;
-       u8      battery_status = 0;
-       char    str[256];
-       int     len = 0;
+       u8      battery_status;
 
-       if( make_local_pdev(adapter, &pdev) != 0 ) {
-               *eof = 1;
-               return len;
-       }
+       if( make_local_pdev(adapter, &pdev) != 0 )
+               return 0;
 
-       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
-               free_local_pdev(pdev);
-               *eof = 1;
-               return len;
-       }
+       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
+               goto free_pdev;
 
        if( mega_adapinq(adapter, dma_handle) != 0 ) {
-
-               len = sprintf(page, "Adapter inquiry failed.\n");
-
+               seq_printf(m, "Adapter inquiry failed.\n");
                printk(KERN_WARNING "megaraid: inquiry failed.\n");
-
-               mega_free_inquiry(inquiry, dma_handle, pdev);
-
-               free_local_pdev(pdev);
-
-               *eof = 1;
-
-               return len;
+               goto free_inquiry;
        }
 
        if( adapter->flag & BOARD_40LD ) {
@@ -2461,146 +2278,80 @@ proc_battery(char *page, char **start, off_t offset, int count, int *eof,
        /*
         * Decode the battery status
         */
-       sprintf(str, "Battery Status:[%d]", battery_status);
+       seq_printf(m, "Battery Status:[%d]", battery_status);
 
        if(battery_status == MEGA_BATT_CHARGE_DONE)
-               strcat(str, " Charge Done");
+               seq_puts(m, " Charge Done");
 
        if(battery_status & MEGA_BATT_MODULE_MISSING)
-               strcat(str, " Module Missing");
+               seq_puts(m, " Module Missing");
        
        if(battery_status & MEGA_BATT_LOW_VOLTAGE)
-               strcat(str, " Low Voltage");
+               seq_puts(m, " Low Voltage");
        
        if(battery_status & MEGA_BATT_TEMP_HIGH)
-               strcat(str, " Temperature High");
+               seq_puts(m, " Temperature High");
        
        if(battery_status & MEGA_BATT_PACK_MISSING)
-               strcat(str, " Pack Missing");
+               seq_puts(m, " Pack Missing");
        
        if(battery_status & MEGA_BATT_CHARGE_INPROG)
-               strcat(str, " Charge In-progress");
+               seq_puts(m, " Charge In-progress");
        
        if(battery_status & MEGA_BATT_CHARGE_FAIL)
-               strcat(str, " Charge Fail");
+               seq_puts(m, " Charge Fail");
        
        if(battery_status & MEGA_BATT_CYCLES_EXCEEDED)
-               strcat(str, " Cycles Exceeded");
-
-       len = sprintf(page, "%s\n", str);
+               seq_puts(m, " Cycles Exceeded");
 
+       seq_putc(m, '\n');
 
+free_inquiry:
        mega_free_inquiry(inquiry, dma_handle, pdev);
-
+free_pdev:
        free_local_pdev(pdev);
-
-       *eof = 1;
-
-       return len;
-}
-
-
-/**
- * proc_pdrv_ch0()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
- *
- * Display information about the physical drives on physical channel 0.
- */
-static int
-proc_pdrv_ch0(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
-{
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_pdrv(adapter, page, 0));
-}
-
-
-/**
- * proc_pdrv_ch1()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
- *
- * Display information about the physical drives on physical channel 1.
- */
-static int
-proc_pdrv_ch1(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
-{
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_pdrv(adapter, page, 1));
+       return 0;
 }
 
 
-/**
- * proc_pdrv_ch2()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
- *
- * Display information about the physical drives on physical channel 2.
+/*
+ * Display scsi inquiry
  */
-static int
-proc_pdrv_ch2(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+static void
+mega_print_inquiry(struct seq_file *m, char *scsi_inq)
 {
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_pdrv(adapter, page, 2));
-}
+       int     i;
 
+       seq_puts(m, "  Vendor: ");
+       seq_write(m, scsi_inq + 8, 8);
+       seq_puts(m, "  Model: ");
+       seq_write(m, scsi_inq + 16, 16);
+       seq_puts(m, "  Rev: ");
+       seq_write(m, scsi_inq + 32, 4);
+       seq_putc(m, '\n');
 
-/**
- * proc_pdrv_ch3()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
- *
- * Display information about the physical drives on physical channel 3.
- */
-static int
-proc_pdrv_ch3(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
-{
-       adapter_t *adapter = (adapter_t *)data;
+       i = scsi_inq[0] & 0x1f;
+       seq_printf(m, "  Type:   %s ", scsi_device_type(i));
 
-       *eof = 1;
+       seq_printf(m, "                 ANSI SCSI revision: %02x",
+                  scsi_inq[2] & 0x07);
 
-       return (proc_pdrv(adapter, page, 3));
+       if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 )
+               seq_puts(m, " CCS\n");
+       else
+               seq_putc(m, '\n');
 }
 
-
 /**
- * proc_pdrv()
+ * proc_show_pdrv()
+ * @m - Synthetic file construction data
  * @page - buffer to write the data in
  * @adapter - pointer to our soft state
  *
  * Display information about the physical drives.
  */
 static int
-proc_pdrv(adapter_t *adapter, char *page, int channel)
+proc_show_pdrv(struct seq_file *m, adapter_t *adapter, int channel)
 {
        dma_addr_t      dma_handle;
        char            *scsi_inq;
@@ -2611,32 +2362,24 @@ proc_pdrv(adapter_t *adapter, char *page, int channel)
        u8      state;
        int     tgt;
        int     max_channels;
-       int     len = 0;
-       char    str[80];
        int     i;
 
-       if( make_local_pdev(adapter, &pdev) != 0 ) {
-               return len;
-       }
+       if( make_local_pdev(adapter, &pdev) != 0 )
+               return 0;
 
-       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
+       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
                goto free_pdev;
-       }
 
        if( mega_adapinq(adapter, dma_handle) != 0 ) {
-               len = sprintf(page, "Adapter inquiry failed.\n");
-
+               seq_puts(m, "Adapter inquiry failed.\n");
                printk(KERN_WARNING "megaraid: inquiry failed.\n");
-
                goto free_inquiry;
        }
 
 
        scsi_inq = pci_alloc_consistent(pdev, 256, &scsi_inq_dma_handle);
-
        if( scsi_inq == NULL ) {
-               len = sprintf(page, "memory not available for scsi inq.\n");
-
+               seq_puts(m, "memory not available for scsi inq.\n");
                goto free_inquiry;
        }
 
@@ -2659,39 +2402,31 @@ proc_pdrv(adapter_t *adapter, char *page, int channel)
                i = channel*16 + tgt;
 
                state = *(pdrv_state + i);
-
                switch( state & 0x0F ) {
-
                case PDRV_ONLINE:
-                       sprintf(str,
-                       "Channel:%2d Id:%2d State: Online",
-                               channel, tgt);
+                       seq_printf(m, "Channel:%2d Id:%2d State: Online",
+                                  channel, tgt);
                        break;
 
                case PDRV_FAILED:
-                       sprintf(str,
-                       "Channel:%2d Id:%2d State: Failed",
-                               channel, tgt);
+                       seq_printf(m, "Channel:%2d Id:%2d State: Failed",
+                                  channel, tgt);
                        break;
 
                case PDRV_RBLD:
-                       sprintf(str,
-                       "Channel:%2d Id:%2d State: Rebuild",
-                               channel, tgt);
+                       seq_printf(m, "Channel:%2d Id:%2d State: Rebuild",
+                                  channel, tgt);
                        break;
 
                case PDRV_HOTSPARE:
-                       sprintf(str,
-                       "Channel:%2d Id:%2d State: Hot spare",
-                               channel, tgt);
+                       seq_printf(m, "Channel:%2d Id:%2d State: Hot spare",
+                                  channel, tgt);
                        break;
 
                default:
-                       sprintf(str,
-                       "Channel:%2d Id:%2d State: Un-configured",
-                               channel, tgt);
+                       seq_printf(m, "Channel:%2d Id:%2d State: Un-configured",
+                                  channel, tgt);
                        break;
-
                }
 
                /*
@@ -2710,11 +2445,8 @@ proc_pdrv(adapter_t *adapter, char *page, int channel)
                 * Check for overflow. We print less than 240
                 * characters for inquiry
                 */
-               if( (len + 240) >= PAGE_SIZE ) break;
-
-               len += sprintf(page+len, "%s.\n", str);
-
-               len += mega_print_inquiry(page+len, scsi_inq);
+               seq_puts(m, ".\n");
+               mega_print_inquiry(m, scsi_inq);
        }
 
 free_pci:
@@ -2723,150 +2455,68 @@ free_inquiry:
        mega_free_inquiry(inquiry, dma_handle, pdev);
 free_pdev:
        free_local_pdev(pdev);
-
-       return len;
-}
-
-
-/*
- * Display scsi inquiry
- */
-static int
-mega_print_inquiry(char *page, char *scsi_inq)
-{
-       int     len = 0;
-       int     i;
-
-       len = sprintf(page, "  Vendor: ");
-       for( i = 8; i < 16; i++ ) {
-               len += sprintf(page+len, "%c", scsi_inq[i]);
-       }
-
-       len += sprintf(page+len, "  Model: ");
-
-       for( i = 16; i < 32; i++ ) {
-               len += sprintf(page+len, "%c", scsi_inq[i]);
-       }
-
-       len += sprintf(page+len, "  Rev: ");
-
-       for( i = 32; i < 36; i++ ) {
-               len += sprintf(page+len, "%c", scsi_inq[i]);
-       }
-
-       len += sprintf(page+len, "\n");
-
-       i = scsi_inq[0] & 0x1f;
-
-       len += sprintf(page+len, "  Type:   %s ", scsi_device_type(i));
-
-       len += sprintf(page+len,
-       "                 ANSI SCSI revision: %02x", scsi_inq[2] & 0x07);
-
-       if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 )
-               len += sprintf(page+len, " CCS\n");
-       else
-               len += sprintf(page+len, "\n");
-
-       return len;
+       return 0;
 }
 
-
 /**
- * proc_rdrv_10()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_pdrv_ch0()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
- * Display real time information about the logical drives 0 through 9.
+ * Display information about the physical drives on physical channel 0.
  */
 static int
-proc_rdrv_10(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_pdrv_ch0(struct seq_file *m, void *v)
 {
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_rdrv(adapter, page, 0, 9));
+       return proc_show_pdrv(m, m->private, 0);
 }
 
 
 /**
- * proc_rdrv_20()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_pdrv_ch1()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
- * Display real time information about the logical drives 0 through 9.
+ * Display information about the physical drives on physical channel 1.
  */
 static int
-proc_rdrv_20(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_pdrv_ch1(struct seq_file *m, void *v)
 {
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_rdrv(adapter, page, 10, 19));
+       return proc_show_pdrv(m, m->private, 1);
 }
 
 
 /**
- * proc_rdrv_30()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_pdrv_ch2()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
- * Display real time information about the logical drives 0 through 9.
+ * Display information about the physical drives on physical channel 2.
  */
 static int
-proc_rdrv_30(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_pdrv_ch2(struct seq_file *m, void *v)
 {
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_rdrv(adapter, page, 20, 29));
+       return proc_show_pdrv(m, m->private, 2);
 }
 
 
 /**
- * proc_rdrv_40()
- * @page - buffer to write the data in
- * @start - where the actual data has been written in page
- * @offset - same meaning as the read system call
- * @count - same meaning as the read system call
- * @eof - set if no more data needs to be returned
- * @data - pointer to our soft state
+ * proc_show_pdrv_ch3()
+ * @m - Synthetic file construction data
+ * @v - File iterator
  *
- * Display real time information about the logical drives 0 through 9.
+ * Display information about the physical drives on physical channel 3.
  */
 static int
-proc_rdrv_40(char *page, char **start, off_t offset, int count, int *eof,
-               void *data)
+proc_show_pdrv_ch3(struct seq_file *m, void *v)
 {
-       adapter_t *adapter = (adapter_t *)data;
-
-       *eof = 1;
-
-       return (proc_rdrv(adapter, page, 30, 39));
+       return proc_show_pdrv(m, m->private, 3);
 }
 
 
 /**
- * proc_rdrv()
- * @page - buffer to write the data in
+ * proc_show_rdrv()
+ * @m - Synthetic file construction data
  * @adapter - pointer to our soft state
  * @start - starting logical drive to display
  * @end - ending logical drive to display
@@ -2875,7 +2525,7 @@ proc_rdrv_40(char *page, char **start, off_t offset, int count, int *eof,
  * /proc/scsi/scsi interface
  */
 static int
-proc_rdrv(adapter_t *adapter, char *page, int start, int end )
+proc_show_rdrv(struct seq_file *m, adapter_t *adapter, int start, int end )
 {
        dma_addr_t      dma_handle;
        logdrv_param    *lparam;
@@ -2887,29 +2537,18 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
        u8      *rdrv_state;
        int     num_ldrv;
        u32     array_sz;
-       int     len = 0;
        int     i;
 
-       if( make_local_pdev(adapter, &pdev) != 0 ) {
-               return len;
-       }
+       if( make_local_pdev(adapter, &pdev) != 0 )
+               return 0;
 
-       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
-               free_local_pdev(pdev);
-               return len;
-       }
+       if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
+               goto free_pdev;
 
        if( mega_adapinq(adapter, dma_handle) != 0 ) {
-
-               len = sprintf(page, "Adapter inquiry failed.\n");
-
+               seq_puts(m, "Adapter inquiry failed.\n");
                printk(KERN_WARNING "megaraid: inquiry failed.\n");
-
-               mega_free_inquiry(inquiry, dma_handle, pdev);
-
-               free_local_pdev(pdev);
-
-               return len;
+               goto free_inquiry;
        }
 
        memset(&mc, 0, sizeof(megacmd_t));
@@ -2935,13 +2574,8 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
                        &disk_array_dma_handle);
 
        if( disk_array == NULL ) {
-               len = sprintf(page, "memory not available.\n");
-
-               mega_free_inquiry(inquiry, dma_handle, pdev);
-
-               free_local_pdev(pdev);
-
-               return len;
+               seq_puts(m, "memory not available.\n");
+               goto free_inquiry;
        }
 
        mc.xferaddr = (u32)disk_array_dma_handle;
@@ -2951,17 +2585,8 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
                mc.opcode = OP_DCMD_READ_CONFIG;
 
                if( mega_internal_command(adapter, &mc, NULL) ) {
-
-                       len = sprintf(page, "40LD read config failed.\n");
-
-                       mega_free_inquiry(inquiry, dma_handle, pdev);
-
-                       pci_free_consistent(pdev, array_sz, disk_array,
-                                       disk_array_dma_handle);
-
-                       free_local_pdev(pdev);
-
-                       return len;
+                       seq_puts(m, "40LD read config failed.\n");
+                       goto free_pci;
                }
 
        }
@@ -2969,24 +2594,10 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
                mc.cmd = NEW_READ_CONFIG_8LD;
 
                if( mega_internal_command(adapter, &mc, NULL) ) {
-
                        mc.cmd = READ_CONFIG_8LD;
-
-                       if( mega_internal_command(adapter, &mc,
-                                               NULL) ){
-
-                               len = sprintf(page,
-                                       "8LD read config failed.\n");
-
-                               mega_free_inquiry(inquiry, dma_handle, pdev);
-
-                               pci_free_consistent(pdev, array_sz,
-                                               disk_array,
-                                               disk_array_dma_handle);
-
-                               free_local_pdev(pdev);
-
-                               return len;
+                       if( mega_internal_command(adapter, &mc, NULL) ) {
+                               seq_puts(m, "8LD read config failed.\n");
+                               goto free_pci;
                        }
                }
        }
@@ -3006,29 +2617,23 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
                 * Check for overflow. We print less than 240 characters for
                 * information about each logical drive.
                 */
-               if( (len + 240) >= PAGE_SIZE ) break;
-
-               len += sprintf(page+len, "Logical drive:%2d:, ", i);
+               seq_printf(m, "Logical drive:%2d:, ", i);
 
                switch( rdrv_state[i] & 0x0F ) {
                case RDRV_OFFLINE:
-                       len += sprintf(page+len, "state: offline");
+                       seq_puts(m, "state: offline");
                        break;
-
                case RDRV_DEGRADED:
-                       len += sprintf(page+len, "state: degraded");
+                       seq_puts(m, "state: degraded");
                        break;
-
                case RDRV_OPTIMAL:
-                       len += sprintf(page+len, "state: optimal");
+                       seq_puts(m, "state: optimal");
                        break;
-
                case RDRV_DELETED:
-                       len += sprintf(page+len, "state: deleted");
+                       seq_puts(m, "state: deleted");
                        break;
-
                default:
-                       len += sprintf(page+len, "state: unknown");
+                       seq_puts(m, "state: unknown");
                        break;
                }
 
@@ -3036,84 +2641,203 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end )
                 * Check if check consistency or initialization is going on
                 * for this logical drive.
                 */
-               if( (rdrv_state[i] & 0xF0) == 0x20 ) {
-                       len += sprintf(page+len,
-                                       ", check-consistency in progress");
-               }
-               else if( (rdrv_state[i] & 0xF0) == 0x10 ) {
-                       len += sprintf(page+len,
-                                       ", initialization in progress");
-               }
+               if( (rdrv_state[i] & 0xF0) == 0x20 )
+                       seq_puts(m, ", check-consistency in progress");
+               else if( (rdrv_state[i] & 0xF0) == 0x10 )
+                       seq_puts(m, ", initialization in progress");
                
-               len += sprintf(page+len, "\n");
-
-               len += sprintf(page+len, "Span depth:%3d, ",
-                               lparam->span_depth);
-
-               len += sprintf(page+len, "RAID level:%3d, ",
-                               lparam->level);
-
-               len += sprintf(page+len, "Stripe size:%3d, ",
-                               lparam->stripe_sz ? lparam->stripe_sz/2: 128);
-
-               len += sprintf(page+len, "Row size:%3d\n",
-                               lparam->row_size);
+               seq_putc(m, '\n');
 
+               seq_printf(m, "Span depth:%3d, ", lparam->span_depth);
+               seq_printf(m, "RAID level:%3d, ", lparam->level);
+               seq_printf(m, "Stripe size:%3d, ",
+                          lparam->stripe_sz ? lparam->stripe_sz/2: 128);
+               seq_printf(m, "Row size:%3d\n", lparam->row_size);
 
-               len += sprintf(page+len, "Read Policy: ");
-
+               seq_puts(m, "Read Policy: ");
                switch(lparam->read_ahead) {
-
                case NO_READ_AHEAD:
-                       len += sprintf(page+len, "No read ahead, ");
+                       seq_puts(m, "No read ahead, ");
                        break;
-
                case READ_AHEAD:
-                       len += sprintf(page+len, "Read ahead, ");
+                       seq_puts(m, "Read ahead, ");
                        break;
-
                case ADAP_READ_AHEAD:
-                       len += sprintf(page+len, "Adaptive, ");
+                       seq_puts(m, "Adaptive, ");
                        break;
 
                }
 
-               len += sprintf(page+len, "Write Policy: ");
-
+               seq_puts(m, "Write Policy: ");
                switch(lparam->write_mode) {
-
                case WRMODE_WRITE_THRU:
-                       len += sprintf(page+len, "Write thru, ");
+                       seq_puts(m, "Write thru, ");
                        break;
-
                case WRMODE_WRITE_BACK:
-                       len += sprintf(page+len, "Write back, ");
+                       seq_puts(m, "Write back, ");
                        break;
                }
 
-               len += sprintf(page+len, "Cache Policy: ");
-
+               seq_puts(m, "Cache Policy: ");
                switch(lparam->direct_io) {
-
                case CACHED_IO:
-                       len += sprintf(page+len, "Cached IO\n\n");
+                       seq_puts(m, "Cached IO\n\n");
                        break;
-
                case DIRECT_IO:
-                       len += sprintf(page+len, "Direct IO\n\n");
+                       seq_puts(m, "Direct IO\n\n");
                        break;
                }
        }
 
-       mega_free_inquiry(inquiry, dma_handle, pdev);
-
+free_pci:
        pci_free_consistent(pdev, array_sz, disk_array,
                        disk_array_dma_handle);
-
+free_inquiry:
+       mega_free_inquiry(inquiry, dma_handle, pdev);
+free_pdev:
        free_local_pdev(pdev);
+       return 0;
+}
+
+/**
+ * proc_show_rdrv_10()
+ * @m - Synthetic file construction data
+ * @v - File iterator
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_show_rdrv_10(struct seq_file *m, void *v)
+{
+       return proc_show_rdrv(m, m->private, 0, 9);
+}
+
+
+/**
+ * proc_show_rdrv_20()
+ * @m - Synthetic file construction data
+ * @v - File iterator
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_show_rdrv_20(struct seq_file *m, void *v)
+{
+       return proc_show_rdrv(m, m->private, 10, 19);
+}
+
+
+/**
+ * proc_show_rdrv_30()
+ * @m - Synthetic file construction data
+ * @v - File iterator
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_show_rdrv_30(struct seq_file *m, void *v)
+{
+       return proc_show_rdrv(m, m->private, 20, 29);
+}
+
+
+/**
+ * proc_show_rdrv_40()
+ * @m - Synthetic file construction data
+ * @v - File iterator
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_show_rdrv_40(struct seq_file *m, void *v)
+{
+       return proc_show_rdrv(m, m->private, 30, 39);
+}
+
+
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int mega_proc_open(struct inode *inode, struct file *file)
+{
+       adapter_t *adapter = proc_get_parent_data(inode);
+       int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
+
+       return single_open(file, show, adapter);
+}
+
+static const struct file_operations mega_proc_fops = {
+       .open           = mega_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+/*
+ * Table of proc files we need to create.
+ */
+struct mega_proc_file {
+       const char *name;
+       unsigned short ptr_offset;
+       int (*show) (struct seq_file *m, void *v);
+};
+
+static const struct mega_proc_file mega_proc_files[] = {
+       { "config",           offsetof(adapter_t, proc_read), proc_show_config },
+       { "stat",             offsetof(adapter_t, proc_stat), proc_show_stat },
+       { "mailbox",          offsetof(adapter_t, proc_mbox), proc_show_mbox },
+#if MEGA_HAVE_ENH_PROC
+       { "rebuild-rate",     offsetof(adapter_t, proc_rr), proc_show_rebuild_rate },
+       { "battery-status",   offsetof(adapter_t, proc_battery), proc_show_battery },
+       { "diskdrives-ch0",   offsetof(adapter_t, proc_pdrvstat[0]), proc_show_pdrv_ch0 },
+       { "diskdrives-ch1",   offsetof(adapter_t, proc_pdrvstat[1]), proc_show_pdrv_ch1 },
+       { "diskdrives-ch2",   offsetof(adapter_t, proc_pdrvstat[2]), proc_show_pdrv_ch2 },
+       { "diskdrives-ch3",   offsetof(adapter_t, proc_pdrvstat[3]), proc_show_pdrv_ch3 },
+       { "raiddrives-0-9",   offsetof(adapter_t, proc_rdrvstat[0]), proc_show_rdrv_10 },
+       { "raiddrives-10-19", offsetof(adapter_t, proc_rdrvstat[1]), proc_show_rdrv_20 },
+       { "raiddrives-20-29", offsetof(adapter_t, proc_rdrvstat[2]), proc_show_rdrv_30 },
+       { "raiddrives-30-39", offsetof(adapter_t, proc_rdrvstat[3]), proc_show_rdrv_40 },
+#endif
+       { NULL }
+};
 
-       return len;
+/**
+ * mega_create_proc_entry()
+ * @index - index in soft state array
+ * @parent - parent node for this /proc entry
+ *
+ * Creates /proc entries for our controllers.
+ */
+static void
+mega_create_proc_entry(int index, struct proc_dir_entry *parent)
+{
+       const struct mega_proc_file *f;
+       adapter_t       *adapter = hba_soft_state[index];
+       struct proc_dir_entry   *dir, *de, **ppde;
+       u8              string[16];
+
+       sprintf(string, "hba%d", adapter->host->host_no);
+
+       dir = adapter->controller_proc_dir_entry =
+               proc_mkdir_data(string, 0, parent, adapter);
+       if(!dir) {
+               printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n");
+               return;
+       }
+
+       for (f = mega_proc_files; f->name; f++) {
+               de = proc_create_data(f->name, S_IRUSR, dir, &mega_proc_fops,
+                                     f->show);
+               if (!de) {
+                       printk(KERN_WARNING "\nmegaraid: proc_create failed\n");
+                       return;
+               }
+
+               ppde = (void *)adapter + f->ptr_offset;
+               *ppde = de;
+       }
 }
+
 #else
 static inline void mega_create_proc_entry(int index, struct proc_dir_entry *parent)
 {
index 4fb2adf6b80ddf4028c0ce70107d20e3cdb6a328..4d0ce4e78dfd582a2f4e5e0fabeefae8b8285f21 100644 (file)
@@ -987,24 +987,7 @@ static int mega_init_scb (adapter_t *);
 static int mega_is_bios_enabled (adapter_t *);
 
 #ifdef CONFIG_PROC_FS
-static int mega_print_inquiry(char *, char *);
 static void mega_create_proc_entry(int, struct proc_dir_entry *);
-static int proc_read_config(char *, char **, off_t, int, int *, void *);
-static int proc_read_stat(char *, char **, off_t, int, int *, void *);
-static int proc_read_mbox(char *, char **, off_t, int, int *, void *);
-static int proc_rebuild_rate(char *, char **, off_t, int, int *, void *);
-static int proc_battery(char *, char **, off_t, int, int *, void *);
-static int proc_pdrv_ch0(char *, char **, off_t, int, int *, void *);
-static int proc_pdrv_ch1(char *, char **, off_t, int, int *, void *);
-static int proc_pdrv_ch2(char *, char **, off_t, int, int *, void *);
-static int proc_pdrv_ch3(char *, char **, off_t, int, int *, void *);
-static int proc_pdrv(adapter_t *, char *, int);
-static int proc_rdrv_10(char *, char **, off_t, int, int *, void *);
-static int proc_rdrv_20(char *, char **, off_t, int, int *, void *);
-static int proc_rdrv_30(char *, char **, off_t, int, int *, void *);
-static int proc_rdrv_40(char *, char **, off_t, int, int *, void *);
-static int proc_rdrv(adapter_t *, char *, int, int);
-
 static int mega_adapinq(adapter_t *, dma_addr_t);
 static int mega_internal_dev_inquiry(adapter_t *, u8, u8, dma_addr_t);
 #endif
index 08685c4cf231b99c89c9eb3b91f1dcbc4641b508..eec052c2670afc63540578bb77ca9a6be2f90fc0 100644 (file)
@@ -504,19 +504,6 @@ _ctl_fasync(int fd, struct file *filep, int mode)
        return fasync_helper(fd, filep, mode, &async_queue);
 }
 
-/**
- * _ctl_release -
- * @inode -
- * @filep -
- *
- * Called when application releases the fasyn callback handler.
- */
-static int
-_ctl_release(struct inode *inode, struct file *filep)
-{
-       return fasync_helper(-1, filep, 0, &async_queue);
-}
-
 /**
  * _ctl_poll -
  * @file -
@@ -3027,7 +3014,6 @@ struct device_attribute *mpt2sas_dev_attrs[] = {
 static const struct file_operations ctl_fops = {
        .owner = THIS_MODULE,
        .unlocked_ioctl = _ctl_ioctl,
-       .release = _ctl_release,
        .poll = _ctl_poll,
        .fasync = _ctl_fasync,
 #ifdef CONFIG_COMPAT
index 054d5231c974771e5af6a47fe4f8e62e074d2578..0b402b6f2d26b34b486996e0fed738260b11ced2 100644 (file)
@@ -502,19 +502,6 @@ _ctl_fasync(int fd, struct file *filep, int mode)
        return fasync_helper(fd, filep, mode, &async_queue);
 }
 
-/**
- * _ctl_release -
- * @inode -
- * @filep -
- *
- * Called when application releases the fasyn callback handler.
- */
-static int
-_ctl_release(struct inode *inode, struct file *filep)
-{
-       return fasync_helper(-1, filep, 0, &async_queue);
-}
-
 /**
  * _ctl_poll -
  * @file -
@@ -3233,7 +3220,6 @@ struct device_attribute *mpt3sas_dev_attrs[] = {
 static const struct file_operations ctl_fops = {
        .owner = THIS_MODULE,
        .unlocked_ioctl = _ctl_ioctl,
-       .release = _ctl_release,
        .poll = _ctl_poll,
        .fasync = _ctl_fasync,
 #ifdef CONFIG_COMPAT
index c29d0dbb9660b97e34515317927208a475215f95..e7f6661a8862112a7a126e2ee4ec07c369c7dd5a 100644 (file)
@@ -76,7 +76,8 @@ int mvme147_detect(struct scsi_host_template *tpnt)
        called++;
 
        tpnt->proc_name = "MVME147";
-       tpnt->proc_info = &wd33c93_proc_info;
+       tpnt->show_info = wd33c93_show_info,
+       tpnt->write_info = wd33c93_write_info,
 
        instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
        if (!instance)
index 1cc0c1c69c880b1f37d0c89063beff4b5566b697..1e3879dcbdcc70d2d3b8e02d6aa341458a044843 100644 (file)
@@ -192,7 +192,7 @@ static int  __init init_nsp32  (void);
 static void __exit exit_nsp32  (void);
 
 /* struct struct scsi_host_template */
-static int         nsp32_proc_info   (struct Scsi_Host *, char *, char **, off_t, int, int);
+static int         nsp32_show_info   (struct seq_file *, struct Scsi_Host *);
 
 static int         nsp32_detect      (struct pci_dev *pdev);
 static int         nsp32_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
@@ -268,7 +268,7 @@ static void nsp32_dmessage(const char *, int, int,    char *, ...);
 static struct scsi_host_template nsp32_template = {
        .proc_name                      = "nsp32",
        .name                           = "Workbit NinjaSCSI-32Bi/UDE",
-       .proc_info                      = nsp32_proc_info,
+       .show_info                      = nsp32_show_info,
        .info                           = nsp32_info,
        .queuecommand                   = nsp32_queuecommand,
        .can_queue                      = 1,
@@ -1442,19 +1442,10 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
 }
 
 #undef SPRINTF
-#define SPRINTF(args...) \
-       do { \
-               if(length > (pos - buffer)) { \
-                       pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
-                       nsp32_dbg(NSP32_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\
-               } \
-       } while(0)
-
-static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start,
-                          off_t offset, int length, int inout)
+#define SPRINTF(args...) seq_printf(m, ##args)
+
+static int nsp32_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
-       char             *pos = buffer;
-       int               thislength;
        unsigned long     flags;
        nsp32_hw_data    *data;
        int               hostno;
@@ -1463,11 +1454,6 @@ static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start,
        int               id, speed;
        long              model;
 
-       /* Write is not supported, just return. */
-       if (inout == TRUE) {
-               return -EINVAL;
-       }
-
        hostno = host->host_no;
        data = (nsp32_hw_data *)host->hostdata;
        base = host->io_port;
@@ -1527,20 +1513,7 @@ static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, char **start,
                }
                SPRINTF("\n");
        }
-
-
-       thislength = pos - (buffer + offset);
-
-       if(thislength < 0) {
-               *start = NULL;
-                return 0;
-        }
-
-
-       thislength = min(thislength, length);
-       *start = buffer + offset;
-
-       return thislength;
+       return 0;
 }
 #undef SPRINTF
 
index 2f72c9807b12181684d1e84fa40998281c4e3523..62f1a6031765d33755cbf5f9f0987bddc5760a5d 100644 (file)
@@ -388,7 +388,8 @@ int __init pas16_detect(struct scsi_host_template * tpnt)
     int  count;
 
     tpnt->proc_name = "pas16";
-    tpnt->proc_info = &pas16_proc_info;
+    tpnt->show_info = pas16_show_info;
+    tpnt->write_info = pas16_write_info;
 
     if (pas16_addr != 0) {
        overrides[0].io_port = pas16_addr;
index a04281cace2e318e8c1896f7d30b818e41e24000..3721342835e9a1b6ebce6e5906747039c129bc48 100644 (file)
@@ -163,7 +163,8 @@ static int pas16_bus_reset(Scsi_Cmnd *);
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
 #define NCR5380_bus_reset pas16_bus_reset
-#define NCR5380_proc_info pas16_proc_info
+#define NCR5380_show_info pas16_show_info
+#define NCR5380_write_info pas16_write_info
 
 /* 15 14 12 10 7 5 3 
    1101 0100 1010 1000 */
index b61a753eb8960c19659a53fc18cf35d35c2e70f1..987fbb1b244e9661be7401d6de906f444840a1ea 100644 (file)
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0
 
 static struct scsi_host_template nsp_driver_template = {
        .proc_name               = "nsp_cs",
-       .proc_info               = nsp_proc_info,
+       .show_info               = nsp_show_info,
        .name                    = "WorkBit NinjaSCSI-3/32Bi(16bit)",
        .info                    = nsp_info,
        .queuecommand            = nsp_queuecommand,
@@ -1365,33 +1365,19 @@ static const char *nsp_info(struct Scsi_Host *shpnt)
 }
 
 #undef SPRINTF
-#define SPRINTF(args...) \
-        do { \
-               if(length > (pos - buffer)) { \
-                       pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
-                       nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\
-               } \
-       } while(0)
-
-static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start,
-                        off_t offset, int length, int inout)
+#define SPRINTF(args...) seq_printf(m, ##args)
+
+static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        int id;
-       char *pos = buffer;
-       int thislength;
        int speed;
        unsigned long flags;
        nsp_hw_data *data;
        int hostno;
 
-       if (inout) {
-               return -EINVAL;
-       }
-
        hostno = host->host_no;
        data = (nsp_hw_data *)host->hostdata;
 
-
        SPRINTF("NinjaSCSI status\n\n");
        SPRINTF("Driver version:        $Revision: 1.23 $\n");
        SPRINTF("SCSI host No.:         %d\n",          hostno);
@@ -1458,19 +1444,7 @@ static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start,
                }
                SPRINTF("\n");
        }
-
-       thislength = pos - (buffer + offset);
-
-       if(thislength < 0) {
-               *start = NULL;
-                return 0;
-        }
-
-
-       thislength = min(thislength, length);
-       *start = buffer + offset;
-
-       return thislength;
+       return 0;
 }
 #undef SPRINTF
 
index 7fc9a9d0a448b6a01c42461758ef118f5190ed93..afd64f0adc4baf62a8686fe1f9d554f58e60846b 100644 (file)
@@ -292,13 +292,8 @@ static int        nsp_cs_config (struct pcmcia_device *link);
 /* Linux SCSI subsystem specific functions */
 static struct Scsi_Host *nsp_detect     (struct scsi_host_template *sht);
 static const  char      *nsp_info       (struct Scsi_Host *shpnt);
-static        int        nsp_proc_info  (
-                                        struct Scsi_Host *host,
-                                        char   *buffer,
-                                        char  **start,
-                                        off_t   offset,
-                                        int     length,
-                                        int     inout);
+static        int        nsp_show_info  (struct seq_file *m,
+                                        struct Scsi_Host *host);
 static int nsp_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
 
 /* Error handler */
index b46f5e90683793043853ca6a6f2ad500b9746806..8e1b737750652700e091d7ccd20d45d8341697f0 100644 (file)
@@ -3598,19 +3598,6 @@ static int pmcraid_chr_open(struct inode *inode, struct file *filep)
        return 0;
 }
 
-/**
- * pmcraid_release - char node "release" entry point
- */
-static int pmcraid_chr_release(struct inode *inode, struct file *filep)
-{
-       struct pmcraid_instance *pinstance = filep->private_data;
-
-       filep->private_data = NULL;
-       fasync_helper(-1, filep, 0, &pinstance->aen_queue);
-
-       return 0;
-}
-
 /**
  * pmcraid_fasync - Async notifier registration from applications
  *
@@ -4167,7 +4154,6 @@ static long pmcraid_chr_ioctl(
 static const struct file_operations pmcraid_fops = {
        .owner = THIS_MODULE,
        .open = pmcraid_chr_open,
-       .release = pmcraid_chr_release,
        .fasync = pmcraid_chr_fasync,
        .unlocked_ioctl = pmcraid_chr_ioctl,
 #ifdef CONFIG_COMPAT
index d164c9639361c773fb41717509608587cb2ab9a6..1db8b26063b4b93eb2372f960ae04e72d91f7524 100644 (file)
@@ -118,8 +118,9 @@ static inline void ppa_pb_release(ppa_struct *dev)
  * Also gives a method to use a script to obtain optimum timings (TODO)
  */
 
-static inline int ppa_proc_write(ppa_struct *dev, char *buffer, int length)
+static inline int ppa_write_info(struct Scsi_Host *host, char *buffer, int length)
 {
+       ppa_struct *dev = ppa_dev(host);
        unsigned long x;
 
        if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
@@ -137,35 +138,17 @@ static inline int ppa_proc_write(ppa_struct *dev, char *buffer, int length)
        return -EINVAL;
 }
 
-static int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout)
+static int ppa_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
-       int len = 0;
        ppa_struct *dev = ppa_dev(host);
 
-       if (inout)
-               return ppa_proc_write(dev, buffer, length);
-
-       len += sprintf(buffer + len, "Version : %s\n", PPA_VERSION);
-       len +=
-           sprintf(buffer + len, "Parport : %s\n",
-                   dev->dev->port->name);
-       len +=
-           sprintf(buffer + len, "Mode    : %s\n",
-                   PPA_MODE_STRING[dev->mode]);
+       seq_printf(m, "Version : %s\n", PPA_VERSION);
+       seq_printf(m, "Parport : %s\n", dev->dev->port->name);
+       seq_printf(m, "Mode    : %s\n", PPA_MODE_STRING[dev->mode]);
 #if PPA_DEBUG > 0
-       len +=
-           sprintf(buffer + len, "recon_tmo : %lu\n", dev->recon_tmo);
+       seq_printf(m, "recon_tmo : %lu\n", dev->recon_tmo);
 #endif
-
-       /* Request for beyond end of buffer */
-       if (offset > length)
-               return 0;
-
-       *start = buffer + offset;
-       len -= offset;
-       if (len > length)
-               len = length;
-       return len;
+       return 0;
 }
 
 static int device_check(ppa_struct *dev);
@@ -981,7 +964,8 @@ static int ppa_adjust_queue(struct scsi_device *device)
 static struct scsi_host_template ppa_template = {
        .module                 = THIS_MODULE,
        .proc_name              = "ppa",
-       .proc_info              = ppa_proc_info,
+       .show_info              = ppa_show_info,
+       .write_info             = ppa_write_info,
        .name                   = "Iomega VPI0 (ppa) interface",
        .queuecommand           = ppa_queuecommand,
        .eh_abort_handler       = ppa_abort,
index 2c6dd3dfe0f4de6d4ff867f873d1697c8dd2afd7..ccb5e6404d09a85a026ac2c03c1470433b2937ba 100644 (file)
@@ -5351,7 +5351,7 @@ static struct pci_driver qla2xxx_pci_driver = {
        .err_handler    = &qla2xxx_err_handler,
 };
 
-static struct file_operations apidev_fops = {
+static const struct file_operations apidev_fops = {
        .owner = THIS_MODULE,
        .llseek = noop_llseek,
 };
index 5cda11c07c689a55b7df5080ac580389963d5d78..5add6f4e79281a252928519f9613cf9c92f275dc 100644 (file)
@@ -2823,31 +2823,27 @@ static const char * scsi_debug_info(struct Scsi_Host * shp)
 /* scsi_debug_proc_info
  * Used if the driver currently has no own support for /proc/scsi
  */
-static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                               int length, int inout)
+static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int length)
 {
-       int len, pos, begin;
-       int orig_length;
+       char arr[16];
+       int opts;
+       int minLen = length > 15 ? 15 : length;
 
-       orig_length = length;
-
-       if (inout == 1) {
-               char arr[16];
-               int minLen = length > 15 ? 15 : length;
+       if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+               return -EACCES;
+       memcpy(arr, buffer, minLen);
+       arr[minLen] = '\0';
+       if (1 != sscanf(arr, "%d", &opts))
+               return -EINVAL;
+       scsi_debug_opts = opts;
+       if (scsi_debug_every_nth != 0)
+               scsi_debug_cmnd_count = 0;
+       return length;
+}
 
-               if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-                       return -EACCES;
-               memcpy(arr, buffer, minLen);
-               arr[minLen] = '\0';
-               if (1 != sscanf(arr, "%d", &pos))
-                       return -EINVAL;
-               scsi_debug_opts = pos;
-               if (scsi_debug_every_nth != 0)
-                        scsi_debug_cmnd_count = 0;
-               return length;
-       }
-       begin = 0;
-       pos = len = sprintf(buffer, "scsi_debug adapter driver, version "
+static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host)
+{
+       seq_printf(m, "scsi_debug adapter driver, version "
            "%s [%s]\n"
            "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, "
            "every_nth=%d(curr:%d)\n"
@@ -2862,15 +2858,7 @@ static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **sta
            scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads,
            sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets,
            num_host_resets, dix_reads, dix_writes, dif_errors);
-       if (pos < offset) {
-               len = 0;
-               begin = pos;
-       }
-       *start = buffer + (offset - begin);     /* Start of wanted data */
-       len -= (offset - begin);
-       if (len > length)
-               len = length;
-       return len;
+       return 0;
 }
 
 static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf)
@@ -3957,7 +3945,8 @@ write:
 static DEF_SCSI_QCMD(scsi_debug_queuecommand)
 
 static struct scsi_host_template sdebug_driver_template = {
-       .proc_info =            scsi_debug_proc_info,
+       .show_info =            scsi_debug_show_info,
+       .write_info =           scsi_debug_write_info,
        .proc_name =            sdebug_proc_name,
        .name =                 "SCSI DEBUG",
        .info =                 scsi_debug_info,
index 765398c063c7f751f383a279ac7ddaa9f841a05c..c31187d79343a17af26404a2d6c547dc392ae151 100644 (file)
@@ -71,9 +71,14 @@ struct kmem_cache *scsi_sdb_cache;
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 
+static bool acpi_scsi_bus_match(struct device *dev)
+{
+       return dev->bus == &scsi_bus_type;
+}
+
 int scsi_register_acpi_bus_type(struct acpi_bus_type *bus)
 {
-        bus->bus = &scsi_bus_type;
+        bus->match = acpi_scsi_bus_match;
         return register_acpi_bus_type(bus);
 }
 EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type);
index ad747dc337da355315c9bb3f0f506e5d84b8f2ee..db66357211ed167d4df1019f151b7e99214788c8 100644 (file)
@@ -45,58 +45,50 @@ static struct proc_dir_entry *proc_scsi;
 /* Protect sht->present and sht->proc_dir */
 static DEFINE_MUTEX(global_host_template_mutex);
 
-/**
- * proc_scsi_read - handle read from /proc by calling host's proc_info() command
- * @buffer: passed to proc_info
- * @start: passed to proc_info
- * @offset: passed to proc_info
- * @length: passed to proc_info
- * @eof: returns whether length read was less than requested
- * @data: pointer to a &struct Scsi_Host
- */
-
-static int proc_scsi_read(char *buffer, char **start, off_t offset,
-                         int length, int *eof, void *data)
-{
-       struct Scsi_Host *shost = data;
-       int n;
-
-       n = shost->hostt->proc_info(shost, buffer, start, offset, length, 0);
-       *eof = (n < length);
-
-       return n;
-}
-
-/**
- * proc_scsi_write_proc - Handle write to /proc by calling host's proc_info()
- * @file: not used
- * @buf: source of data to write.
- * @count: number of bytes (at most PROC_BLOCK_SIZE) to write.
- * @data: pointer to &struct Scsi_Host
- */
-static int proc_scsi_write_proc(struct file *file, const char __user *buf,
-                           unsigned long count, void *data)
+static ssize_t proc_scsi_host_write(struct file *file, const char __user *buf,
+                           size_t count, loff_t *ppos)
 {
-       struct Scsi_Host *shost = data;
+       struct Scsi_Host *shost = PDE_DATA(file_inode(file));
        ssize_t ret = -ENOMEM;
        char *page;
-       char *start;
     
        if (count > PROC_BLOCK_SIZE)
                return -EOVERFLOW;
 
+       if (!shost->hostt->write_info)
+               return -EINVAL;
+
        page = (char *)__get_free_page(GFP_KERNEL);
        if (page) {
                ret = -EFAULT;
                if (copy_from_user(page, buf, count))
                        goto out;
-               ret = shost->hostt->proc_info(shost, page, &start, 0, count, 1);
+               ret = shost->hostt->write_info(shost, page, count);
        }
 out:
        free_page((unsigned long)page);
        return ret;
 }
 
+static int proc_scsi_show(struct seq_file *m, void *v)
+{
+       struct Scsi_Host *shost = m->private;
+       return shost->hostt->show_info(m, shost);
+}
+
+static int proc_scsi_host_open(struct inode *inode, struct file *file)
+{
+       return single_open_size(file, proc_scsi_show, PDE_DATA(inode),
+                               4 * PAGE_SIZE);
+}
+
+static const struct file_operations proc_scsi_fops = {
+       .open = proc_scsi_host_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .write = proc_scsi_host_write
+};
+
 /**
  * scsi_proc_hostdir_add - Create directory in /proc for a scsi host
  * @sht: owner of this directory
@@ -106,7 +98,7 @@ out:
 
 void scsi_proc_hostdir_add(struct scsi_host_template *sht)
 {
-       if (!sht->proc_info)
+       if (!sht->show_info)
                return;
 
        mutex_lock(&global_host_template_mutex);
@@ -125,7 +117,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
  */
 void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
 {
-       if (!sht->proc_info)
+       if (!sht->show_info)
                return;
 
        mutex_lock(&global_host_template_mutex);
@@ -151,16 +143,12 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
                return;
 
        sprintf(name,"%d", shost->host_no);
-       p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
-                       sht->proc_dir, proc_scsi_read, shost);
-       if (!p) {
+       p = proc_create_data(name, S_IRUGO | S_IWUSR,
+               sht->proc_dir, &proc_scsi_fops, shost);
+       if (!p)
                printk(KERN_ERR "%s: Failed to register host %d in"
                       "%s\n", __func__, shost->host_no,
                       sht->proc_name);
-               return;
-       } 
-
-       p->write_proc = proc_scsi_write_proc;
 }
 
 /**
index 599568299fbea49bce5847b060645d59f059b76e..bac55f7f69f9e09e7da940e9a34ffbda75ef47a1 100644 (file)
@@ -1171,112 +1171,36 @@ printk("sym_user_command: data=%ld\n", uc->data);
 #endif /* SYM_LINUX_USER_COMMAND_SUPPORT */
 
 
-#ifdef SYM_LINUX_USER_INFO_SUPPORT
-/*
- *  Informations through the proc file system.
- */
-struct info_str {
-       char *buffer;
-       int length;
-       int offset;
-       int pos;
-};
-
-static void copy_mem_info(struct info_str *info, char *data, int len)
-{
-       if (info->pos + len > info->length)
-               len = info->length - info->pos;
-
-       if (info->pos + len < info->offset) {
-               info->pos += len;
-               return;
-       }
-       if (info->pos < info->offset) {
-               data += (info->offset - info->pos);
-               len  -= (info->offset - info->pos);
-       }
-
-       if (len > 0) {
-               memcpy(info->buffer + info->pos, data, len);
-               info->pos += len;
-       }
-}
-
-static int copy_info(struct info_str *info, char *fmt, ...)
-{
-       va_list args;
-       char buf[81];
-       int len;
-
-       va_start(args, fmt);
-       len = vsprintf(buf, fmt, args);
-       va_end(args);
-
-       copy_mem_info(info, buf, len);
-       return len;
-}
-
 /*
  *  Copy formatted information into the input buffer.
  */
-static int sym_host_info(struct Scsi_Host *shost, char *ptr, off_t offset, int len)
+static int sym_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
+#ifdef SYM_LINUX_USER_INFO_SUPPORT
        struct sym_data *sym_data = shost_priv(shost);
        struct pci_dev *pdev = sym_data->pdev;
        struct sym_hcb *np = sym_data->ncb;
-       struct info_str info;
-
-       info.buffer     = ptr;
-       info.length     = len;
-       info.offset     = offset;
-       info.pos        = 0;
 
-       copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, "
-                        "revision id 0x%x\n", np->s.chip_name,
-                        pdev->device, pdev->revision);
-       copy_info(&info, "At PCI address %s, IRQ %u\n",
+       seq_printf(m, "Chip " NAME53C "%s, device id 0x%x, "
+                "revision id 0x%x\n", np->s.chip_name,
+                pdev->device, pdev->revision);
+       seq_printf(m, "At PCI address %s, IRQ %u\n",
                         pci_name(pdev), pdev->irq);
-       copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n",
-                        (int) (np->minsync_dt ? np->minsync_dt : np->minsync),
-                        np->maxwide ? "Wide" : "Narrow",
-                        np->minsync_dt ? ", DT capable" : "");
+       seq_printf(m, "Min. period factor %d, %s SCSI BUS%s\n",
+                (int) (np->minsync_dt ? np->minsync_dt : np->minsync),
+                np->maxwide ? "Wide" : "Narrow",
+                np->minsync_dt ? ", DT capable" : "");
 
-       copy_info(&info, "Max. started commands %d, "
-                        "max. commands per LUN %d\n",
-                        SYM_CONF_MAX_START, SYM_CONF_MAX_TAG);
+       seq_printf(m, "Max. started commands %d, "
+                "max. commands per LUN %d\n",
+                SYM_CONF_MAX_START, SYM_CONF_MAX_TAG);
 
-       return info.pos > info.offset? info.pos - info.offset : 0;
-}
-#endif /* SYM_LINUX_USER_INFO_SUPPORT */
-
-/*
- *  Entry point of the scsi proc fs of the driver.
- *  - func = 0 means read  (returns adapter infos)
- *  - func = 1 means write (not yet merget from sym53c8xx)
- */
-static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer,
-                       char **start, off_t offset, int length, int func)
-{
-       int retv;
-
-       if (func) {
-#ifdef SYM_LINUX_USER_COMMAND_SUPPORT
-               retv = sym_user_command(shost, buffer, length);
-#else
-               retv = -EINVAL;
-#endif
-       } else {
-               if (start)
-                       *start = buffer;
-#ifdef SYM_LINUX_USER_INFO_SUPPORT
-               retv = sym_host_info(shost, buffer, offset, length);
+       return 0;
 #else
-               retv = -EINVAL;
-#endif
-       }
-
-       return retv;
+       return -EINVAL;
+#endif /* SYM_LINUX_USER_INFO_SUPPORT */
 }
+
 #endif /* SYM_LINUX_PROC_INFO_SUPPORT */
 
 /*
@@ -1742,7 +1666,10 @@ static struct scsi_host_template sym2_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .max_sectors            = 0xFFFF,
 #ifdef SYM_LINUX_PROC_INFO_SUPPORT
-       .proc_info              = sym53c8xx_proc_info,
+       .show_info              = sym_show_info,
+#ifdef SYM_LINUX_USER_COMMAND_SUPPORT
+       .write_info             = sym_user_command,
+#endif
        .proc_name              = NAME53C8XX,
 #endif
 };
index d672d97fb84adcee58886164c72579615ac65c10..f1e4b4148c75ced73820cba96a325ba2ffdb5d8d 100644 (file)
@@ -201,7 +201,8 @@ int __init t128_detect(struct scsi_host_template * tpnt){
     int sig, count;
 
     tpnt->proc_name = "t128";
-    tpnt->proc_info = &t128_proc_info;
+    tpnt->show_info = t128_show_info;
+    tpnt->write_info = t128_write_info;
 
     for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
        base = 0;
index ada1115079c9e6890b00108e83f70f15061058a0..1df82c28e56d6af8b1a4558bee1144e03299f43f 100644 (file)
@@ -140,7 +140,8 @@ static int t128_bus_reset(struct scsi_cmnd *);
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort
 #define NCR5380_bus_reset t128_bus_reset
-#define NCR5380_proc_info t128_proc_info
+#define NCR5380_show_info t128_show_info
+#define NCR5380_write_info t128_write_info
 
 /* 15 14 12 10 7 5 3
    1101 0100 1010 1000 */
index c0ee4ea28a19707896c3a74021c4e231bd5d4880..41883a87931d1d68d4336478b4cc5c5c6ab8f967 100644 (file)
@@ -2054,22 +2054,16 @@ wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs,
        printk("           Version %s - %s\n", WD33C93_VERSION, WD33C93_DATE);
 }
 
-int
-wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off, int len, int in)
+int wd33c93_write_info(struct Scsi_Host *instance, char *buf, int len)
 {
-
 #ifdef PROC_INTERFACE
-
        char *bp;
-       char tbuf[128];
        struct WD33C93_hostdata *hd;
-       struct scsi_cmnd *cmd;
        int x;
-       static int stop = 0;
 
        hd = (struct WD33C93_hostdata *) instance->hostdata;
 
-/* If 'in' is TRUE we need to _read_ the proc file. We accept the following
+/* We accept the following
  * keywords (same format as command-line, but arguments are not optional):
  *    debug
  *    disconnect
@@ -2083,145 +2077,124 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off
  *    nosync
  */
 
-       if (in) {
-               buf[len] = '\0';
-               for (bp = buf; *bp; ) {
-                       while (',' == *bp || ' ' == *bp)
-                               ++bp;
-               if (!strncmp(bp, "debug:", 6)) {
-                               hd->args = simple_strtoul(bp+6, &bp, 0) & DB_MASK;
-               } else if (!strncmp(bp, "disconnect:", 11)) {
-                               x = simple_strtoul(bp+11, &bp, 0);
-                       if (x < DIS_NEVER || x > DIS_ALWAYS)
-                               x = DIS_ADAPTIVE;
-                       hd->disconnect = x;
-               } else if (!strncmp(bp, "period:", 7)) {
+       buf[len] = '\0';
+       for (bp = buf; *bp; ) {
+               while (',' == *bp || ' ' == *bp)
+                       ++bp;
+       if (!strncmp(bp, "debug:", 6)) {
+                       hd->args = simple_strtoul(bp+6, &bp, 0) & DB_MASK;
+       } else if (!strncmp(bp, "disconnect:", 11)) {
+                       x = simple_strtoul(bp+11, &bp, 0);
+               if (x < DIS_NEVER || x > DIS_ALWAYS)
+                       x = DIS_ADAPTIVE;
+               hd->disconnect = x;
+       } else if (!strncmp(bp, "period:", 7)) {
+               x = simple_strtoul(bp+7, &bp, 0);
+               hd->default_sx_per =
+                       hd->sx_table[round_period((unsigned int) x,
+                                                 hd->sx_table)].period_ns;
+       } else if (!strncmp(bp, "resync:", 7)) {
+                       set_resync(hd, (int)simple_strtoul(bp+7, &bp, 0));
+       } else if (!strncmp(bp, "proc:", 5)) {
+                       hd->proc = simple_strtoul(bp+5, &bp, 0);
+       } else if (!strncmp(bp, "nodma:", 6)) {
+                       hd->no_dma = simple_strtoul(bp+6, &bp, 0);
+       } else if (!strncmp(bp, "level2:", 7)) {
+                       hd->level2 = simple_strtoul(bp+7, &bp, 0);
+               } else if (!strncmp(bp, "burst:", 6)) {
+                       hd->dma_mode =
+                               simple_strtol(bp+6, &bp, 0) ? CTRL_BURST:CTRL_DMA;
+               } else if (!strncmp(bp, "fast:", 5)) {
+                       x = !!simple_strtol(bp+5, &bp, 0);
+                       if (x != hd->fast)
+                               set_resync(hd, 0xff);
+                       hd->fast = x;
+               } else if (!strncmp(bp, "nosync:", 7)) {
                        x = simple_strtoul(bp+7, &bp, 0);
-                       hd->default_sx_per =
-                               hd->sx_table[round_period((unsigned int) x,
-                                                         hd->sx_table)].period_ns;
-               } else if (!strncmp(bp, "resync:", 7)) {
-                               set_resync(hd, (int)simple_strtoul(bp+7, &bp, 0));
-               } else if (!strncmp(bp, "proc:", 5)) {
-                               hd->proc = simple_strtoul(bp+5, &bp, 0);
-               } else if (!strncmp(bp, "nodma:", 6)) {
-                               hd->no_dma = simple_strtoul(bp+6, &bp, 0);
-               } else if (!strncmp(bp, "level2:", 7)) {
-                               hd->level2 = simple_strtoul(bp+7, &bp, 0);
-                       } else if (!strncmp(bp, "burst:", 6)) {
-                               hd->dma_mode =
-                                       simple_strtol(bp+6, &bp, 0) ? CTRL_BURST:CTRL_DMA;
-                       } else if (!strncmp(bp, "fast:", 5)) {
-                               x = !!simple_strtol(bp+5, &bp, 0);
-                               if (x != hd->fast)
-                                       set_resync(hd, 0xff);
-                               hd->fast = x;
-                       } else if (!strncmp(bp, "nosync:", 7)) {
-                               x = simple_strtoul(bp+7, &bp, 0);
-                               set_resync(hd, x ^ hd->no_sync);
-                               hd->no_sync = x;
-                       } else {
-                               break; /* unknown keyword,syntax-error,... */
-                       }
+                       set_resync(hd, x ^ hd->no_sync);
+                       hd->no_sync = x;
+               } else {
+                       break; /* unknown keyword,syntax-error,... */
                }
-               return len;
        }
+       return len;
+#else
+       return 0;
+#endif
+}
+
+int
+wd33c93_show_info(struct seq_file *m, struct Scsi_Host *instance)
+{
+#ifdef PROC_INTERFACE
+       struct WD33C93_hostdata *hd;
+       struct scsi_cmnd *cmd;
+       int x;
+
+       hd = (struct WD33C93_hostdata *) instance->hostdata;
 
        spin_lock_irq(&hd->lock);
-       bp = buf;
-       *bp = '\0';
-       if (hd->proc & PR_VERSION) {
-               sprintf(tbuf, "\nVersion %s - %s.",
+       if (hd->proc & PR_VERSION)
+               seq_printf(m, "\nVersion %s - %s.",
                        WD33C93_VERSION, WD33C93_DATE);
-               strcat(bp, tbuf);
-       }
+
        if (hd->proc & PR_INFO) {
-               sprintf(tbuf, "\nclock_freq=%02x no_sync=%02x no_dma=%d"
+               seq_printf(m, "\nclock_freq=%02x no_sync=%02x no_dma=%d"
                        " dma_mode=%02x fast=%d",
                        hd->clock_freq, hd->no_sync, hd->no_dma, hd->dma_mode, hd->fast);
-               strcat(bp, tbuf);
-               strcat(bp, "\nsync_xfer[] =       ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%02x", hd->sync_xfer[x]);
-                       strcat(bp, tbuf);
-               }
-               strcat(bp, "\nsync_stat[] =       ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%02x", hd->sync_stat[x]);
-                       strcat(bp, tbuf);
-               }
+               seq_printf(m, "\nsync_xfer[] =       ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%02x", hd->sync_xfer[x]);
+               seq_printf(m, "\nsync_stat[] =       ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%02x", hd->sync_stat[x]);
        }
 #ifdef PROC_STATISTICS
        if (hd->proc & PR_STATISTICS) {
-               strcat(bp, "\ncommands issued:    ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%ld", hd->cmd_cnt[x]);
-                       strcat(bp, tbuf);
-               }
-               strcat(bp, "\ndisconnects allowed:");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%ld", hd->disc_allowed_cnt[x]);
-                       strcat(bp, tbuf);
-               }
-               strcat(bp, "\ndisconnects done:   ");
-               for (x = 0; x < 7; x++) {
-                       sprintf(tbuf, "\t%ld", hd->disc_done_cnt[x]);
-                       strcat(bp, tbuf);
-               }
-               sprintf(tbuf,
+               seq_printf(m, "\ncommands issued:    ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%ld", hd->cmd_cnt[x]);
+               seq_printf(m, "\ndisconnects allowed:");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%ld", hd->disc_allowed_cnt[x]);
+               seq_printf(m, "\ndisconnects done:   ");
+               for (x = 0; x < 7; x++)
+                       seq_printf(m, "\t%ld", hd->disc_done_cnt[x]);
+               seq_printf(m,
                        "\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO",
                        hd->int_cnt, hd->dma_cnt, hd->pio_cnt);
-               strcat(bp, tbuf);
        }
 #endif
        if (hd->proc & PR_CONNECTED) {
-               strcat(bp, "\nconnected:     ");
+               seq_printf(m, "\nconnected:     ");
                if (hd->connected) {
                        cmd = (struct scsi_cmnd *) hd->connected;
-                       sprintf(tbuf, " %d:%d(%02x)",
+                       seq_printf(m, " %d:%d(%02x)",
                                cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
-                       strcat(bp, tbuf);
                }
        }
        if (hd->proc & PR_INPUTQ) {
-               strcat(bp, "\ninput_Q:       ");
+               seq_printf(m, "\ninput_Q:       ");
                cmd = (struct scsi_cmnd *) hd->input_Q;
                while (cmd) {
-                       sprintf(tbuf, " %d:%d(%02x)",
+                       seq_printf(m, " %d:%d(%02x)",
                                cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
-                       strcat(bp, tbuf);
                        cmd = (struct scsi_cmnd *) cmd->host_scribble;
                }
        }
        if (hd->proc & PR_DISCQ) {
-               strcat(bp, "\ndisconnected_Q:");
+               seq_printf(m, "\ndisconnected_Q:");
                cmd = (struct scsi_cmnd *) hd->disconnected_Q;
                while (cmd) {
-                       sprintf(tbuf, " %d:%d(%02x)",
+                       seq_printf(m, " %d:%d(%02x)",
                                cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
-                       strcat(bp, tbuf);
                        cmd = (struct scsi_cmnd *) cmd->host_scribble;
                }
        }
-       strcat(bp, "\n");
+       seq_printf(m, "\n");
        spin_unlock_irq(&hd->lock);
-       *start = buf;
-       if (stop) {
-               stop = 0;
-               return 0;
-       }
-       if (off > 0x40000)      /* ALWAYS stop after 256k bytes have been read */
-               stop = 1;
-       if (hd->proc & PR_STOP) /* stop every other time */
-               stop = 1;
-       return strlen(bp);
-
-#else                          /* PROC_INTERFACE */
-
-       return 0;
-
 #endif                         /* PROC_INTERFACE */
-
+       return 0;
 }
 
 EXPORT_SYMBOL(wd33c93_host_reset);
@@ -2229,4 +2202,5 @@ EXPORT_SYMBOL(wd33c93_init);
 EXPORT_SYMBOL(wd33c93_abort);
 EXPORT_SYMBOL(wd33c93_queuecommand);
 EXPORT_SYMBOL(wd33c93_intr);
-EXPORT_SYMBOL(wd33c93_proc_info);
+EXPORT_SYMBOL(wd33c93_show_info);
+EXPORT_SYMBOL(wd33c93_write_info);
index 3b463d7304dca635cf3f4360c7aa6d9430127f63..08abe508e9ada325aef82e6f29b4f4547da7c889 100644 (file)
@@ -345,7 +345,8 @@ void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs,
 int wd33c93_abort (struct scsi_cmnd *cmd);
 int wd33c93_queuecommand (struct Scsi_Host *h, struct scsi_cmnd *cmd);
 void wd33c93_intr (struct Scsi_Host *instance);
-int wd33c93_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
+int wd33c93_show_info(struct seq_file *, struct Scsi_Host *);
+int wd33c93_write_info(struct Scsi_Host *, char *, int);
 int wd33c93_host_reset (struct scsi_cmnd *);
 
 #endif /* WD33C93_H */
index d89a5dfd3adec9463061651a23cf0d486489f02b..f9a6e4b0affe895ed8e388f4afaf3d70df941fca 100644 (file)
@@ -1296,9 +1296,9 @@ static void wd7000_revision(Adapter * host)
 
 
 #undef SPRINTF
-#define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); }
+#define SPRINTF(args...) { seq_printf(m, ## args); }
 
-static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host)
+static int wd7000_set_info(struct Scsi_Host *host, char *buffer, int length)
 {
        dprintk("Buffer = <%.*s>, length = %d\n", length, buffer, length);
 
@@ -1310,22 +1310,15 @@ static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host)
 }
 
 
-static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,  int inout)
+static int wd7000_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        Adapter *adapter = (Adapter *)host->hostdata;
        unsigned long flags;
-       char *pos = buffer;
 #ifdef WD7000_DEBUG
        Mailbox *ogmbs, *icmbs;
        short count;
 #endif
 
-       /*
-        * Has data been written to the file ?
-        */
-       if (inout)
-               return (wd7000_set_info(buffer, length, host));
-
        spin_lock_irqsave(host->host_lock, flags);
        SPRINTF("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", host->host_no, adapter->rev1, adapter->rev2);
        SPRINTF("  IO base:      0x%x\n", adapter->iobase);
@@ -1368,17 +1361,7 @@ static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start,
 
        spin_unlock_irqrestore(host->host_lock, flags);
 
-       /*
-        * Calculate start of next buffer, and return value.
-        */
-       *start = buffer + offset;
-
-       if ((pos - buffer) < offset)
-               return (0);
-       else if ((pos - buffer - offset) < length)
-               return (pos - buffer - offset);
-       else
-               return (length);
+       return 0;
 }
 
 
@@ -1413,7 +1396,8 @@ static __init int wd7000_detect(struct scsi_host_template *tpnt)
        for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1);
 
        tpnt->proc_name = "wd7000";
-       tpnt->proc_info = &wd7000_proc_info;
+       tpnt->show_info = &wd7000_show_info;
+       tpnt->write_info = wd7000_set_info;
 
        /*
         * Set up SCB free list, which is shared by all adapters
@@ -1658,7 +1642,8 @@ MODULE_LICENSE("GPL");
 
 static struct scsi_host_template driver_template = {
        .proc_name              = "wd7000",
-       .proc_info              = wd7000_proc_info,
+       .show_info              = wd7000_show_info,
+       .write_info             = wd7000_set_info,
        .name                   = "Western Digital WD-7000",
        .detect                 = wd7000_detect,
        .release                = wd7000_release,
index 8adc79d1b40277ac15092a53bac28749627c60cf..e82b1cdfd18947016bc702cb24fd22b23f8faf6c 100644 (file)
@@ -723,7 +723,6 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
 }
 
 static const struct file_operations ffs_ep0_operations = {
-       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
 
        .open =         ffs_ep0_open,
@@ -943,7 +942,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
 }
 
 static const struct file_operations ffs_epfile_operations = {
-       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
 
        .open =         ffs_epfile_open,
@@ -1223,6 +1221,7 @@ static struct file_system_type ffs_fs_type = {
        .mount          = ffs_fs_mount,
        .kill_sb        = ffs_fs_kill_sb,
 };
+MODULE_ALIAS_FS("functionfs");
 
 
 /* Driver's main init/cleanup functions *************************************/
index d9297eebbf732f4cd889e5b377dae389532ecf92..1e4cfb05f70b9a0bba6a2fa421ef696d7649e8e8 100644 (file)
@@ -1065,7 +1065,7 @@ static int rndis_proc_show(struct seq_file *m, void *v)
 static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
                                size_t count, loff_t *ppos)
 {
-       rndis_params *p = PDE(file_inode(file))->data;
+       rndis_params *p = PDE_DATA(file_inode(file));
        u32 speed = 0;
        int i, fl_speed = 0;
 
@@ -1109,7 +1109,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
 
 static int rndis_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, rndis_proc_show, PDE(inode)->data);
+       return single_open(file, rndis_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations rndis_proc_fops = {
index 192cf088f834a07c2388b50f0cc357e9f9298d36..57b4519047911dc36000580b87296e1716ebf5ed 100644 (file)
@@ -947,12 +947,13 @@ static int dt9812_di_rinsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
        u8 bits = 0;
 
        dt9812_digital_in(devpriv->slot, &bits);
        for (n = 0; n < insn->n; n++)
-               data[n] = ((1 << insn->chanspec) & bits) != 0;
+               data[n] = ((1 << channel) & bits) != 0;
        return n;
 }
 
@@ -961,12 +962,13 @@ static int dt9812_do_winsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
        u8 bits = 0;
 
        dt9812_digital_out_shadow(devpriv->slot, &bits);
        for (n = 0; n < insn->n; n++) {
-               u8 mask = 1 << insn->chanspec;
+               u8 mask = 1 << channel;
 
                bits &= ~mask;
                if (data[n])
@@ -981,13 +983,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
 
        for (n = 0; n < insn->n; n++) {
                u16 value = 0;
 
-               dt9812_analog_in(devpriv->slot, insn->chanspec, &value,
-                                DT9812_GAIN_1);
+               dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1);
                data[n] = value;
        }
        return n;
@@ -998,12 +1000,13 @@ static int dt9812_ao_rinsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
        u16 value;
 
        for (n = 0; n < insn->n; n++) {
                value = 0;
-               dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value);
+               dt9812_analog_out_shadow(devpriv->slot, channel, &value);
                data[n] = value;
        }
        return n;
@@ -1014,10 +1017,11 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
 
        for (n = 0; n < insn->n; n++)
-               dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]);
+               dt9812_analog_out(devpriv->slot, channel, data[n]);
        return n;
 }
 
index 1a0062a04456c54c517acc7d73454014555a7611..6aac1f60bc42c1cc927cd2a9930aa1bc356f28cb 100644 (file)
@@ -730,10 +730,14 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
 static int usbduxsub_start(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
-       uint8_t local_transfer_buffer[16];
+       uint8_t *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to zero */
-       local_transfer_buffer[0] = 0;
+       *local_transfer_buffer = 0;
        errcode = usb_control_msg(usbduxsub->usbdev,
                                  /* create a pipe for a control transfer */
                                  usb_sndctrlpipe(usbduxsub->usbdev, 0),
@@ -751,22 +755,25 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (start)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
+       uint8_t *local_transfer_buffer;
 
-       uint8_t local_transfer_buffer[16];
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to one */
-       local_transfer_buffer[0] = 1;
+       *local_transfer_buffer = 1;
        errcode = usb_control_msg(usbduxsub->usbdev,
                                  usb_sndctrlpipe(usbduxsub->usbdev, 0),
                                  /* bRequest, "Firmware" */
@@ -781,12 +788,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (stop)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
index 4bf5dd094dc9da043b2aea8302c6638e229cf926..1ba0e3df492d1e9ceeedcebe4af3e85b82a08491 100644 (file)
@@ -436,10 +436,14 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
 static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
 {
        int ret;
-       unsigned char local_transfer_buffer[16];
+       unsigned char *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to zero */
-       local_transfer_buffer[0] = 0;
+       *local_transfer_buffer = 0;
        /* bRequest, "Firmware" */
        ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
                              USBDUXFASTSUB_FIRMWARE,
@@ -450,22 +454,25 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
                              local_transfer_buffer,
                              1,      /* Length */
                              EZTIMEOUT);    /* Timeout */
-       if (ret < 0) {
+       if (ret < 0)
                dev_err(&udfs->interface->dev,
                        "control msg failed (start)\n");
-               return ret;
-       }
 
-       return 0;
+       kfree(local_transfer_buffer);
+       return ret;
 }
 
 static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
 {
        int ret;
-       unsigned char local_transfer_buffer[16];
+       unsigned char *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to one */
-       local_transfer_buffer[0] = 1;
+       *local_transfer_buffer = 1;
        /* bRequest, "Firmware" */
        ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
                              USBDUXFASTSUB_FIRMWARE,
@@ -474,13 +481,12 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
                              0x0000,   /* Index */
                              local_transfer_buffer, 1, /* Length */
                              EZTIMEOUT);       /* Timeout */
-       if (ret < 0) {
+       if (ret < 0)
                dev_err(&udfs->interface->dev,
                        "control msg failed (stop)\n");
-               return ret;
-       }
 
-       return 0;
+       kfree(local_transfer_buffer);
+       return ret;
 }
 
 static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
index d066351a71b2793d4f1ad60dd27e8db7dd0ea0e7..a728c8fc32a270e4a8963dc0eca3e14799fd6602 100644 (file)
@@ -681,7 +681,11 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
 static int usbduxsub_start(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
-       uint8_t local_transfer_buffer[16];
+       uint8_t *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to zero */
        local_transfer_buffer[0] = 0;
@@ -702,19 +706,22 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (start)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
+       uint8_t *local_transfer_buffer;
 
-       uint8_t local_transfer_buffer[16];
+       local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to one */
        local_transfer_buffer[0] = 1;
@@ -732,12 +739,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (stop)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
index 362c214bcc0bb05d4b7113104a37d13f02d62616..db790f9fc9db9289c1530c9f5227037bbca0c9d5 100644 (file)
 #include "comedidev.h"
 #include "comedi_internal.h"
 #include <linux/proc_fs.h>
-#include <linux/string.h>
+#include <linux/seq_file.h>
 
-static int comedi_read(char *buf, char **start, off_t offset, int len,
-                      int *eof, void *data)
+static int comedi_read(struct seq_file *m, void *v)
 {
        int i;
        int devices_q = 0;
-       int l = 0;
        struct comedi_driver *driv;
 
-       l += sprintf(buf + l,
+       seq_printf(m,
                     "comedi version " COMEDI_RELEASE "\n"
                     "format string: %s\n",
                     "\"%2d: %-20s %-20s %4d\", i, "
@@ -49,42 +47,51 @@ static int comedi_read(char *buf, char **start, off_t offset, int len,
 
        for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
                struct comedi_device *dev = comedi_dev_from_minor(i);
-
                if (!dev)
                        continue;
 
                if (dev->attached) {
                        devices_q = 1;
-                       l += sprintf(buf + l, "%2d: %-20s %-20s %4d\n",
-                                    i,
-                                    dev->driver->driver_name,
-                                    dev->board_name, dev->n_subdevices);
+                       seq_printf(m, "%2d: %-20s %-20s %4d\n",
+                                  i, dev->driver->driver_name,
+                                  dev->board_name, dev->n_subdevices);
                }
        }
        if (!devices_q)
-               l += sprintf(buf + l, "no devices\n");
+               seq_puts(m, "no devices\n");
 
        for (driv = comedi_drivers; driv; driv = driv->next) {
-               l += sprintf(buf + l, "%s:\n", driv->driver_name);
-               for (i = 0; i < driv->num_names; i++) {
-                       l += sprintf(buf + l, " %s\n",
-                                    *(char **)((char *)driv->board_name +
-                                               i * driv->offset));
-               }
+               seq_printf(m, "%s:\n", driv->driver_name);
+               for (i = 0; i < driv->num_names; i++)
+                       seq_printf(m, " %s\n",
+                                  *(char **)((char *)driv->board_name +
+                                             i * driv->offset));
+
                if (!driv->num_names)
-                       l += sprintf(buf + l, " %s\n", driv->driver_name);
+                       seq_printf(m, " %s\n", driv->driver_name);
        }
 
-       return l;
+       return 0;
 }
 
-void comedi_proc_init(void)
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int comedi_proc_open(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *comedi_proc;
+       return single_open(file, comedi_read, NULL);
+}
+
+static const struct file_operations comedi_proc_fops = {
+       .open           = comedi_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-       comedi_proc = create_proc_entry("comedi", S_IFREG | S_IRUGO, NULL);
-       if (comedi_proc)
-               comedi_proc->read_proc = comedi_read;
+void comedi_proc_init(void)
+{
+       proc_create("comedi", 0644, NULL, &comedi_proc_fops);
 }
 
 void comedi_proc_cleanup(void)
index a65b822db698759cb63d4231c546c306f4a1c1d5..a6b006b0e983ebca081fcc588bb0f0ecf7b40210 100644 (file)
  *
  * ---------------------------------------------------------------------------
  */
+#include <linux/seq_file.h>
 #include "csr_wifi_hip_unifi.h"
 #include "csr_wifi_hip_card.h"
 
 
+static void unifi_print_unsafe_sdio_status(card_t *card, struct seq_file *m)
+{
+#ifdef CSR_UNSAFE_SDIO_ACCESS
+       s32 iostate;
+       CsrResult r;
+       static const char *const states[] = {
+               "AWAKE", "DROWSY", "TORPID"
+       };
+#define SHARED_READ_RETRY_LIMIT 10
+       u8 b;
+
+       seq_printf(m, "Host State: %s\n", states[card->host_state]);
+
+       r = unifi_check_io_status(card, &iostate);
+       if (iostate == 1) {
+               seq_puts(m, remaining, "I/O Check: F1 disabled\n");
+        } else {
+               if (iostate == 1) {
+                       seq_puts(m, "I/O Check: pending interrupt\n");
+
+               seq_printf(m, "BH reason interrupt = %d\n", card->bh_reason_unifi);
+               seq_printf(m, "BH reason host      = %d\n", card->bh_reason_host);
+
+               for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) {
+                       r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b);
+                       if (r == CSR_RESULT_SUCCESS && !(b & 0x80)) {
+                               seq_printf(m, "fhsr: %u (driver thinks is %u)\n",
+                                          b, card->from_host_signals_r);
+                               break;
+                       }
+               }
+
+               iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
+               seq_printf(m, "thsw: %u (driver thinks is %u)\n",
+                          iostate, card->to_host_signals_w);
+        }
+#endif
+}
+
 /*
  * ---------------------------------------------------------------------------
  *  unifi_print_status
  *      None.
  * ---------------------------------------------------------------------------
  */
-s32 unifi_print_status(card_t *card, char *str, s32 *remain)
+s32 unifi_print_status(card_t *card, struct seq_file *m)
 {
-    char *p = str;
-    sdio_config_data_t *cfg;
-    u16 i, n;
-    s32 remaining = *remain;
-    s32 written;
-#ifdef CSR_UNSAFE_SDIO_ACCESS
-    s32 iostate;
-    CsrResult r;
-    static const char *const states[] = {
-        "AWAKE", "DROWSY", "TORPID"
-    };
-    #define SHARED_READ_RETRY_LIMIT 10
-    u8 b;
-#endif
-
-    if (remaining <= 0)
-    {
-        return 0;
-    }
-
-    i = n = 0;
-    written = scnprintf(p, remaining, "Chip ID %u\n",
-                          (u16)card->chip_id);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "Chip Version %04X\n",
-                          card->chip_version);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "HIP v%u.%u\n",
-                          (card->config_data.version >> 8) & 0xFF,
-                          card->config_data.version & 0xFF);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "Build %u: %s\n",
-                          card->build_id, card->build_id_string);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    cfg = &card->config_data;
-
-    written = scnprintf(p, remaining, "sdio ctrl offset          %u\n",
-                          cfg->sdio_ctrl_offset);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "fromhost sigbuf handle    %u\n",
-                          cfg->fromhost_sigbuf_handle);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "tohost_sigbuf_handle      %u\n",
-                          cfg->tohost_sigbuf_handle);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "num_fromhost_sig_frags    %u\n",
-                          cfg->num_fromhost_sig_frags);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "num_tohost_sig_frags      %u\n",
-                          cfg->num_tohost_sig_frags);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "num_fromhost_data_slots   %u\n",
-                          cfg->num_fromhost_data_slots);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "num_tohost_data_slots     %u\n",
-                          cfg->num_tohost_data_slots);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "data_slot_size            %u\n",
-                          cfg->data_slot_size);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    /* Added by protocol version 0x0001 */
-    written = scnprintf(p, remaining, "overlay_size              %u\n",
-                          (u16)cfg->overlay_size);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    /* Added by protocol version 0x0300 */
-    written = scnprintf(p, remaining, "data_slot_round           %u\n",
-                          cfg->data_slot_round);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "sig_frag_size             %u\n",
-                          cfg->sig_frag_size);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    /* Added by protocol version 0x0300 */
-    written = scnprintf(p, remaining, "tohost_sig_pad            %u\n",
-                          cfg->tohost_signal_padding);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    written = scnprintf(p, remaining, "\nInternal state:\n");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    written = scnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n",
-                          card->last_phy_panic_code, card->last_phy_panic_arg);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n",
-                          card->last_mac_panic_code, card->last_mac_panic_arg);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    written = scnprintf(p, remaining, "fhsr: %u\n",
-                          (u16)card->from_host_signals_r);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "fhsw: %u\n",
-                          (u16)card->from_host_signals_w);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "thsr: %u\n",
-                          (u16)card->to_host_signals_r);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "thsw: %u\n",
-                          (u16)card->to_host_signals_w);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining,
-                          "fh buffer contains: %d signals, %td bytes\n",
-                          card->fh_buffer.count,
-                          card->fh_buffer.ptr - card->fh_buffer.buf);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    written = scnprintf(p, remaining, "paused: ");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++)
-    {
-        written = scnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0");
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-    }
-    written = scnprintf(p, remaining, "\n");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    written = scnprintf(p, remaining,
-                          "fh command q: %u waiting, %u free of %u:\n",
-                          CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue),
-                          CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue),
-                          UNIFI_SOFT_COMMAND_Q_LENGTH);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        written = scnprintf(p, remaining,
-                              "fh traffic q[%u]: %u waiting, %u free of %u:\n",
-                              i,
-                              CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]),
-                              CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]),
-                              UNIFI_SOFT_TRAFFIC_Q_LENGTH);
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-    }
-
-    written = scnprintf(p, remaining, "fh data slots free: %u\n",
-                          card->from_host_data?CardGetFreeFromHostDataSlots(card) : 0);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-
-    written = scnprintf(p, remaining, "From host data slots:");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    n = card->config_data.num_fromhost_data_slots;
-    for (i = 0; i < n && card->from_host_data; i++)
-    {
-        written = scnprintf(p, remaining, " %u",
-                              (u16)card->from_host_data[i].bd.data_length);
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-    }
-    written = scnprintf(p, remaining, "\n");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    written = scnprintf(p, remaining, "To host data slots:");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    n = card->config_data.num_tohost_data_slots;
-    for (i = 0; i < n && card->to_host_data; i++)
-    {
-        written = scnprintf(p, remaining, " %u",
-                              (u16)card->to_host_data[i].data_length);
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-    }
-
-    written = scnprintf(p, remaining, "\n");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-#ifdef CSR_UNSAFE_SDIO_ACCESS
-    written = scnprintf(p, remaining, "Host State: %s\n", states[card->host_state]);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    r = unifi_check_io_status(card, &iostate);
-    if (iostate == 1)
-    {
-        written = scnprintf(p, remaining, "I/O Check: F1 disabled\n");
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-    }
-    else
-    {
-        if (iostate == 1)
-        {
-            written = scnprintf(p, remaining, "I/O Check: pending interrupt\n");
-            UNIFI_SNPRINTF_RET(p, remaining, written);
-        }
-
-        written = scnprintf(p, remaining, "BH reason interrupt = %d\n",
-                              card->bh_reason_unifi);
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-        written = scnprintf(p, remaining, "BH reason host      = %d\n",
-                              card->bh_reason_host);
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-
-        for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++)
-        {
-            r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b);
-            if ((r == CSR_RESULT_SUCCESS) && (!(b & 0x80)))
-            {
-                written = scnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n",
-                                      b, card->from_host_signals_r);
-                UNIFI_SNPRINTF_RET(p, remaining, written);
-                break;
-            }
-        }
-        iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
-        written = scnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n",
-                              iostate, card->to_host_signals_w);
-        UNIFI_SNPRINTF_RET(p, remaining, written);
-    }
-#endif
-
-    written = scnprintf(p, remaining, "\nStats:\n");
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "Total SDIO bytes: R=%u W=%u\n",
-                          card->sdio_bytes_read, card->sdio_bytes_written);
-
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-    written = scnprintf(p, remaining, "Interrupts generated on card: %u\n",
-                          card->unifi_interrupt_seq);
-    UNIFI_SNPRINTF_RET(p, remaining, written);
-
-    *remain = remaining;
-    return (p - str);
-} /* unifi_print_status() */
-
-
+       sdio_config_data_t *cfg;
+       u16 i, n;
+
+       i = n = 0;
+       seq_printf(m, "Chip ID %u\n", card->chip_id);
+       seq_printf(m, "Chip Version %04X\n", card->chip_version);
+       seq_printf(m, "HIP v%u.%u\n",
+                  (card->config_data.version >> 8) & 0xFF,
+                  card->config_data.version & 0xFF);
+       seq_printf(m, "Build %u: %s\n", card->build_id, card->build_id_string);
+
+       cfg = &card->config_data;
+
+       seq_printf(m, "sdio ctrl offset          %u\n", cfg->sdio_ctrl_offset);
+       seq_printf(m, "fromhost sigbuf handle    %u\n", cfg->fromhost_sigbuf_handle);
+       seq_printf(m, "tohost_sigbuf_handle      %u\n", cfg->tohost_sigbuf_handle);
+       seq_printf(m, "num_fromhost_sig_frags    %u\n", cfg->num_fromhost_sig_frags);
+       seq_printf(m, "num_tohost_sig_frags      %u\n", cfg->num_tohost_sig_frags);
+       seq_printf(m, "num_fromhost_data_slots   %u\n", cfg->num_fromhost_data_slots);
+       seq_printf(m, "num_tohost_data_slots     %u\n", cfg->num_tohost_data_slots);
+       seq_printf(m, "data_slot_size            %u\n", cfg->data_slot_size);
+
+       /* Added by protocol version 0x0001 */
+       seq_printf(m, "overlay_size              %u\n", cfg->overlay_size);
+
+       /* Added by protocol version 0x0300 */
+       seq_printf(m, "data_slot_round           %u\n", cfg->data_slot_round);
+       seq_printf(m, "sig_frag_size             %u\n", cfg->sig_frag_size);
+
+       /* Added by protocol version 0x0300 */
+       seq_printf(m, "tohost_sig_pad            %u\n", cfg->tohost_signal_padding);
+
+       seq_puts(m, "\nInternal state:\n");
+
+       seq_printf(m, "Last PHY PANIC: %04x:%04x\n",
+                  card->last_phy_panic_code, card->last_phy_panic_arg);
+       seq_printf(m, "Last MAC PANIC: %04x:%04x\n",
+                  card->last_mac_panic_code, card->last_mac_panic_arg);
+
+       seq_printf(m, "fhsr: %hu\n", (u16)card->from_host_signals_r);
+       seq_printf(m, "fhsw: %hu\n", (u16)card->from_host_signals_w);
+       seq_printf(m, "thsr: %hu\n", (u16)card->to_host_signals_r);
+       seq_printf(m, "thsw: %hu\n", (u16)card->to_host_signals_w);
+       seq_printf(m, "fh buffer contains: %d signals, %td bytes\n",
+                  card->fh_buffer.count,
+                  card->fh_buffer.ptr - card->fh_buffer.buf);
+
+       seq_puts(m, "paused: ");
+       for (i = 0; i < ARRAY_SIZE(card->tx_q_paused_flag); i++)
+               seq_printf(m, card->tx_q_paused_flag[i] ? "1" : "0");
+       seq_putc(m, '\n');
+
+       seq_printf(m, "fh command q: %u waiting, %u free of %u:\n",
+                  CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue),
+                  CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue),
+                  UNIFI_SOFT_COMMAND_Q_LENGTH);
+
+       for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
+               seq_printf(m, "fh traffic q[%u]: %u waiting, %u free of %u:\n",
+                          i,
+                          CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]),
+                          CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]),
+                          UNIFI_SOFT_TRAFFIC_Q_LENGTH);
+
+       seq_printf(m, "fh data slots free: %u\n",
+                  card->from_host_data ? CardGetFreeFromHostDataSlots(card) : 0);
+
+       seq_puts(m, "From host data slots:");
+       n = card->config_data.num_fromhost_data_slots;
+       for (i = 0; i < n && card->from_host_data; i++)
+               seq_printf(m, " %hu", (u16)card->from_host_data[i].bd.data_length);
+       seq_putc(m, '\n');
+
+       seq_puts(m, "To host data slots:");
+       n = card->config_data.num_tohost_data_slots;
+       for (i = 0; i < n && card->to_host_data; i++)
+               seq_printf(m, " %hu", (u16)card->to_host_data[i].data_length);
+       seq_putc(m, '\n');
+
+       unifi_print_unsafe_sdio_status(card, m);
+
+       seq_puts(m, "\nStats:\n");
+       seq_printf(m, "Total SDIO bytes: R=%u W=%u\n",
+                  card->sdio_bytes_read, card->sdio_bytes_written);
+
+       seq_printf(m, "Interrupts generated on card: %u\n", card->unifi_interrupt_seq);
+       return 0;
+}
index 9d85cfd576166e9209b26bdff9614ce725e3e2ce..4126e85bfe9bc424e93f0bc588b7266357a6c7bb 100644 (file)
@@ -47,21 +47,6 @@ CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn);
  * This is used in the linux /proc interface and might be useful
  * in other systems.
  */
-s32 unifi_print_status(card_t *card, char *str, s32 *remain);
-
-#define UNIFI_SNPRINTF_RET(buf_p, remain, written)                  \
-    do {                                                            \
-        if (written >= remain) {                                    \
-            if (remain >= 2) {                                      \
-                buf_p[remain - 2] = '\n';                           \
-                buf_p[remain - 1] = 0;                              \
-            }                                                       \
-            buf_p += remain;                                        \
-            remain = 0;                                             \
-        } else if (written > 0) {                                   \
-            buf_p += written;                                       \
-            remain -= written;                                      \
-        }                                                           \
-    } while (0)
+s32 unifi_print_status(card_t *card, struct seq_file *m);
 
 #endif /* __CSR_WIFI_HIP_UNIFI_UDI_H__ */
index 3bd52fdeac3b162f2b628444a9a4e97782cd4a95..33742ba13779bc0d539f35ced50c92efb67b3585 100644 (file)
@@ -1941,7 +1941,7 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length)
  *
  ****************************************************************************
  */
-static struct file_operations unifi_fops = {
+static const struct file_operations unifi_fops = {
     .owner      = THIS_MODULE,
     .open       = unifi_open,
     .release    = unifi_release,
@@ -2041,7 +2041,7 @@ void uf_destroy_device_nodes(unifi_priv_t *priv)
  * ----------------------------------------------------------------
  */
 static int
-uf_create_debug_device(struct file_operations *fops)
+uf_create_debug_device(const struct file_operations *fops)
 {
     int ret;
 
index af9c28f073b977585d09166fa574f29e687ed1cb..f9b5c22c00b86660a193bea8528339f5f246d5f7 100644 (file)
@@ -31,6 +31,7 @@
  * ---------------------------------------------------------------------------
  */
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include "csr_wifi_hip_unifi.h"
 #include "csr_wifi_hip_unifiversion.h"
@@ -76,9 +77,28 @@ DEFINE_SEMAPHORE(Unifi_instance_mutex);
  */
 DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq);
 
+#ifdef CONFIG_PROC_FS
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int uf_proc_show(struct seq_file *m, void *v);
+
+#define UNIFI_DEBUG_TXT_BUFFER (8 * 1024)
+
+static int uf_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open_size(file, uf_proc_show, PDE_DATA(inode),
+                               UNIFI_DEBUG_TXT_BUFFER);
+}
+
+static const struct file_operations uf_proc_fops = {
+       .open           = uf_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-static int uf_read_proc(char *page, char **start, off_t offset, int count,
-                        int *eof, void *data);
+#endif /* CONFIG_PROC_FS */
 
 #ifdef CSR_WIFI_RX_PATH_SPLIT
 
@@ -327,8 +347,8 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
      * The following complex casting is in place in order to eliminate 64-bit compilation warning
      * "cast to/from pointer from/to integer of different size"
      */
-    if (!create_proc_read_entry(priv->proc_entry_name, 0, 0,
-                uf_read_proc, (void *)(long)priv->instance))
+    if (!proc_create_data(priv->proc_entry_name, 0, NULL,
+                         &uf_proc_fops, (void *)(long)priv->instance))
     {
         unifi_error(priv, "unifi: can't create /proc/driver/unifi\n");
     }
@@ -827,7 +847,7 @@ uf_put_instance(int inst)
 
 /*
  * ---------------------------------------------------------------------------
- *  uf_read_proc
+ *  uf_proc_show
  *
  *      Read method for driver node in /proc/driver/unifi0
  *
@@ -844,107 +864,54 @@ uf_put_instance(int inst)
  * ---------------------------------------------------------------------------
  */
 #ifdef CONFIG_PROC_FS
-static int
-uf_read_proc(char *page, char **start, off_t offset, int count,
-        int *eof, void *data)
+static int uf_proc_show(struct seq_file *m, void *v)
 {
-#define UNIFI_DEBUG_TXT_BUFFER 8*1024
-    unifi_priv_t *priv;
-    int actual_amount_to_copy;
-    char *p, *orig_p;
-    s32 remain = UNIFI_DEBUG_TXT_BUFFER;
-    s32 written;
-    int i;
-
-    /*
-    * The following complex casting is in place in order to eliminate 64-bit compilation warning
-    * "cast to/from pointer from/to integer of different size"
-    */
-    priv = uf_find_instance((int)(long)data);
-    if (!priv) {
-        return 0;
-    }
-
-    p = kmalloc( UNIFI_DEBUG_TXT_BUFFER, GFP_KERNEL );
-
-    orig_p = p;
-
-    written = scnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n",
-            CSR_WIFI_VERSION, __DATE__, __TIME__);
-    UNIFI_SNPRINTF_RET(p, remain, written);
+       unifi_priv_t *priv;
+       int i;
+
+       /*
+        * The following complex casting is in place in order to eliminate
+        * 64-bit compilation warning "cast to/from pointer from/to integer of
+        * different size"
+        */
+       priv = uf_find_instance((long)m->private);
+       if (!priv)
+               return 0;
+
+       seq_printf(m, "UniFi SDIO Driver: %s %s %s\n",
+                  CSR_WIFI_VERSION, __DATE__, __TIME__);
 #ifdef CSR_SME_USERSPACE
-    written = scnprintf(p, remain, "SME: CSR userspace ");
-    UNIFI_SNPRINTF_RET(p, remain, written);
+       seq_puts(m, "SME: CSR userspace ");
 #ifdef CSR_SUPPORT_WEXT
-    written = scnprintf(p, remain, "with WEXT support\n");
+       seq_puts(m, "with WEXT support\n");
 #else
-    written = scnprintf(p, remain, "\n");
+       seq_putc(m, '\n');
 #endif /* CSR_SUPPORT_WEXT */
-    UNIFI_SNPRINTF_RET(p, remain, written);
 #endif /* CSR_SME_USERSPACE */
 #ifdef CSR_NATIVE_LINUX
-    written = scnprintf(p, remain, "SME: native\n");
-    UNIFI_SNPRINTF_RET(p, remain, written);
+       seq_puts(m, "SME: native\n");
 #endif
 
 #ifdef CSR_SUPPORT_SME
-    written = scnprintf(p, remain,
-            "Firmware (ROM) build:%u, Patch:%u\n",
-            priv->card_info.fw_build,
-            priv->sme_versions.firmwarePatch);
-    UNIFI_SNPRINTF_RET(p, remain, written);
+       seq_printf(m, "Firmware (ROM) build:%u, Patch:%u\n",
+                  priv->card_info.fw_build,
+                  priv->sme_versions.firmwarePatch);
 #endif
-    p += unifi_print_status(priv->card, p, &remain);
-
-    written = scnprintf(p, remain, "Last dbg str: %s\n",
-            priv->last_debug_string);
-    UNIFI_SNPRINTF_RET(p, remain, written);
-
-    written = scnprintf(p, remain, "Last dbg16:");
-    UNIFI_SNPRINTF_RET(p, remain, written);
-    for (i = 0; i < 8; i++) {
-        written = scnprintf(p, remain, " %04X",
-                priv->last_debug_word16[i]);
-        UNIFI_SNPRINTF_RET(p, remain, written);
-    }
-    written = scnprintf(p, remain, "\n");
-    UNIFI_SNPRINTF_RET(p, remain, written);
-    written = scnprintf(p, remain, "           ");
-    UNIFI_SNPRINTF_RET(p, remain, written);
-    for (; i < 16; i++) {
-        written = scnprintf(p, remain, " %04X",
-                priv->last_debug_word16[i]);
-        UNIFI_SNPRINTF_RET(p, remain, written);
-    }
-    written = scnprintf(p, remain, "\n");
-    UNIFI_SNPRINTF_RET(p, remain, written);
-    *start = page;
-
-    written = UNIFI_DEBUG_TXT_BUFFER - remain;
-
-    if( offset >= written )
-    {
-        *eof = 1;
-        kfree( orig_p );
-        return(0);
-    }
-
-    if( offset + count > written )
-    {
-        actual_amount_to_copy = written - offset;
-        *eof = 1;
-    }
-    else
-    {
-        actual_amount_to_copy = count;
-    }
 
-    memcpy( page, &(orig_p[offset]), actual_amount_to_copy );
+       unifi_print_status(priv->card, m);
 
-    kfree( orig_p );
+       seq_printf(m, "Last dbg str: %s\n", priv->last_debug_string);
 
-    return( actual_amount_to_copy );
-} /* uf_read_proc() */
+       seq_puts(m, "Last dbg16:");
+       for (i = 0; i < 8; i++)
+               seq_printf(m, " %04X", priv->last_debug_word16[i]);
+       seq_putc(m, '\n');
+       seq_puts(m, "           ");
+       for (; i < 16; i++)
+               seq_printf(m, " %04X", priv->last_debug_word16[i]);
+       seq_putc(m, '\n');
+       return 0;
+}
 #endif
 
 
index e99b82311823c77a572daa8e9d11ac5a529f2825..b9ccb76502511e6b845f322d5f8cde85e794bef4 100644 (file)
@@ -12,8 +12,9 @@ cxt1e1-y :=   \
   linux.o              \
   functions.o          \
   hwprobe.o            \
-  sbeproc.o            \
   pmc93x6_eeprom.o     \
   sbecrc.o             \
   comet_tables.o       \
   sbeid.o
+
+cxt1e1-$(CONFIG_PROC_FS) += sbeproc.o
index f42531c3d8da714c753e5532838aab37674a39bb..49f10f0b7d29090129e40c71133b446163a0b192 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
 #include "pmcc4_sysdep.h"
 #include "pmcc4_private.h"
 #include "sbeproc.h"
 
-/* forwards */
-void        sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *);
+extern void sbecom_get_brdinfo(ci_t *, struct sbe_brd_info *, u_int8_t *);
 extern struct s_hdw_info hdw_info[MAX_BOARDS];
 
-#ifdef CONFIG_PROC_FS
-
-/********************************************************************/
-/* procfs stuff                                                     */
-/********************************************************************/
-
-
-void
-sbecom_proc_brd_cleanup (ci_t * ci)
+void sbecom_proc_brd_cleanup(ci_t *ci)
 {
-    if (ci->dir_dev)
-    {
-       char dir[7 + SBE_IFACETMPL_SIZE + 1];
-       snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
-        remove_proc_entry("info", ci->dir_dev);
-        remove_proc_entry(dir, NULL);
-        ci->dir_dev = NULL;
-    }
+       if (ci->dir_dev) {
+               char dir[7 + SBE_IFACETMPL_SIZE + 1];
+               snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
+               remove_proc_entry("info", ci->dir_dev);
+               remove_proc_entry(dir, NULL);
+               ci->dir_dev = NULL;
+       }
 }
 
-
-static int
-sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset,
-                          int length, int *eof, void *priv)
+static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip)
 {
-    ci_t       *ci = (ci_t *) priv;
-    int         len = 0;
-    char       *spd;
-    struct sbe_brd_info *bip;
-
-    if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info))))
-    {
-        return -ENOMEM;
-    }
-#if 0
-    /** RLD DEBUG **/
-    pr_info(">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n",
-            (int) offset, (int) length);
-#endif
-
-    {
-        hdw_info_t *hi = &hdw_info[ci->brdno];
-
-        u_int8_t *bsn = 0;
-
-        switch (hi->promfmt)
-        {
-        case PROM_FORMAT_TYPE1:
-            bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
-            break;
-        case PROM_FORMAT_TYPE2:
-            bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
-            break;
-        }
-
-        sbecom_get_brdinfo (ci, bip, bsn);
-    }
-
-#if 0
-    /** RLD DEBUG **/
-    pr_info(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
-            (char *) &bip->first_iname, (char *) &bip->first_iname,
-            (char *) &bip->last_iname, (char *) &bip->last_iname);
-#endif
-    len += sprintf (buffer + len, "Board Type:    ");
-    switch (bip->brd_id)
-    {
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
-        len += sprintf (buffer + len, "wanPMC-C1T3");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
-        len += sprintf (buffer + len, "wanPTMC-256T3 <E1>");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
-        len += sprintf (buffer + len, "wanPTMC-256T3 <T1>");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
-        len += sprintf (buffer + len, "wanPTMC-C24TE1");
-        break;
-
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
-        len += sprintf (buffer + len, "wanPMC-C4T1E1");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
-        len += sprintf (buffer + len, "wanPMC-C2T1E1");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
-        len += sprintf (buffer + len, "wanPMC-C1T1E1");
-        break;
-
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
-        len += sprintf (buffer + len, "wanPCI-C4T1E1");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
-        len += sprintf (buffer + len, "wanPCI-C2T1E1");
-        break;
-    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
-        len += sprintf (buffer + len, "wanPCI-C1T1E1");
-        break;
-
-    default:
-        len += sprintf (buffer + len, "unknown");
-        break;
-    }
-    len += sprintf (buffer + len, "  [%08X]\n", bip->brd_id);
+       hdw_info_t *hi = &hdw_info[ci->brdno];
+       u_int8_t *bsn = 0;
+
+       switch (hi->promfmt)
+       {
+       case PROM_FORMAT_TYPE1:
+               bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
+               break;
+       case PROM_FORMAT_TYPE2:
+               bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
+               break;
+       }
+
+       sbecom_get_brdinfo (ci, bip, bsn);
+
+       pr_devel(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
+                bip->first_iname, bip->first_iname,
+                bip->last_iname, bip->last_iname);
+}
 
-    len += sprintf (buffer + len, "Board Number:  %d\n", bip->brdno);
-    len += sprintf (buffer + len, "Hardware ID:   0x%02X\n", ci->hdw_bid);
-    len += sprintf (buffer + len, "Board SN:      %06X\n", bip->brd_sn);
-       len += sprintf(buffer + len, "Board MAC:     %pMF\n",
-               bip->brd_mac_addr);
-    len += sprintf (buffer + len, "Ports:         %d\n", ci->max_port);
-    len += sprintf (buffer + len, "Channels:      %d\n", bip->brd_chan_cnt);
+/*
+ * Describe the driver state through /proc
+ */
+static int sbecom_proc_get_sbe_info(struct seq_file *m, void *v)
+{
+       ci_t       *ci = m->private;
+       char       *spd;
+       struct sbe_brd_info *bip;
+
+       if (!(bip = OS_kmalloc(sizeof(struct sbe_brd_info))))
+               return -ENOMEM;
+
+       pr_devel(">> sbecom_proc_get_sbe_info: entered\n");
+
+       sbecom_proc_get_brdinfo(ci, bip);
+
+       seq_puts(m, "Board Type:    ");
+       switch (bip->brd_id) {
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
+               seq_puts(m, "wanPMC-C1T3");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
+               seq_puts(m, "wanPTMC-256T3 <E1>");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
+               seq_puts(m, "wanPTMC-256T3 <T1>");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
+               seq_puts(m, "wanPTMC-C24TE1");
+               break;
+
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
+               seq_puts(m, "wanPMC-C4T1E1");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
+               seq_puts(m, "wanPMC-C2T1E1");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
+               seq_puts(m, "wanPMC-C1T1E1");
+               break;
+
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
+               seq_puts(m, "wanPCI-C4T1E1");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
+               seq_puts(m, "wanPCI-C2T1E1");
+               break;
+       case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
+               seq_puts(m, "wanPCI-C1T1E1");
+               break;
+
+       default:
+               seq_puts(m, "unknown");
+               break;
+       }
+
+       seq_printf(m, "  [%08X]\n", bip->brd_id);
+
+       seq_printf(m, "Board Number:  %d\n", bip->brdno);
+       seq_printf(m, "Hardware ID:   0x%02X\n", ci->hdw_bid);
+       seq_printf(m, "Board SN:      %06X\n", bip->brd_sn);
+       seq_printf(m, "Board MAC:     %pMF\n", bip->brd_mac_addr);
+       seq_printf(m, "Ports:         %d\n", ci->max_port);
+       seq_printf(m, "Channels:      %d\n", bip->brd_chan_cnt);
 #if 1
-    len += sprintf (buffer + len, "Interface:     %s -> %s\n",
-                    (char *) &bip->first_iname, (char *) &bip->last_iname);
+       seq_printf(m, "Interface:     %s -> %s\n",
+                  bip->first_iname, bip->last_iname);
 #else
-    len += sprintf (buffer + len, "Interface:     <not available> 1st %p lst %p\n",
-                    (char *) &bip->first_iname, (char *) &bip->last_iname);
+       seq_printf(m, "Interface:     <not available> 1st %p lst %p\n",
+                  bip->first_iname, bip->last_iname);
 #endif
 
-    switch (bip->brd_pci_speed)
-    {
-    case BINFO_PCI_SPEED_33:
-        spd = "33Mhz";
-        break;
-    case BINFO_PCI_SPEED_66:
-        spd = "66Mhz";
-        break;
-    default:
-        spd = "<not available>";
-        break;
-    }
-    len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd);
-    len += sprintf (buffer + len, "Release:       %s\n", ci->release);
+       switch (bip->brd_pci_speed) {
+       case BINFO_PCI_SPEED_33:
+               spd = "33Mhz";
+               break;
+       case BINFO_PCI_SPEED_66:
+               spd = "66Mhz";
+               break;
+       default:
+               spd = "<not available>";
+               break;
+       }
+       seq_printf(m, "PCI Bus Speed: %s\n", spd);
+       seq_printf(m, "Release:       %s\n", ci->release);
 
 #ifdef SBE_PMCC4_ENABLE
-    {
-               extern int cxt1e1_max_mru;
-#if 0
-        extern int max_chans_used;
-        extern int cxt1e1_max_mtu;
-#endif
-        extern int max_rxdesc_used, max_txdesc_used;
-
-        len += sprintf (buffer + len, "\ncxt1e1_max_mru:         %d\n", cxt1e1_max_mru);
+       {
+               extern int cxt1e1_max_mru;
 #if 0
-        len += sprintf (buffer + len, "\nmax_chans_used:  %d\n", max_chans_used);
-        len += sprintf (buffer + len, "cxt1e1_max_mtu:         %d\n", cxt1e1_max_mtu);
-#endif
-        len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used);
-        len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used);
-    }
-#endif
-
-    OS_kfree (bip);                 /* cleanup */
-
-    /***
-     * How to be a proc read function
-     * ------------------------------
-     * Prototype:
-     *    int f(char *buffer, char **start, off_t offset,
-     *          int count, int *peof, void *dat)
-     *
-     * Assume that the buffer is "count" bytes in size.
-     *
-     * If you know you have supplied all the data you
-     * have, set *peof.
-     *
-     * You have three ways to return data:
-     * 0) Leave *start = NULL.  (This is the default.)
-     *    Put the data of the requested offset at that
-     *    offset within the buffer.  Return the number (n)
-     *    of bytes there are from the beginning of the
-     *    buffer up to the last byte of data.  If the
-     *    number of supplied bytes (= n - offset) is
-     *    greater than zero and you didn't signal eof
-     *    and the reader is prepared to take more data
-     *    you will be called again with the requested
-     *    offset advanced by the number of bytes
-     *    absorbed.  This interface is useful for files
-     *    no larger than the buffer.
-     * 1) Set *start = an unsigned long value less than
-     *    the buffer address but greater than zero.
-     *    Put the data of the requested offset at the
-     *    beginning of the buffer.  Return the number of
-     *    bytes of data placed there.  If this number is
-     *    greater than zero and you didn't signal eof
-     *    and the reader is prepared to take more data
-     *    you will be called again with the requested
-     *    offset advanced by *start.  This interface is
-     *    useful when you have a large file consisting
-     *    of a series of blocks which you want to count
-     *    and return as wholes.
-     *    (Hack by Paul.Russell@rustcorp.com.au)
-     * 2) Set *start = an address within the buffer.
-     *    Put the data of the requested offset at *start.
-     *    Return the number of bytes of data placed there.
-     *    If this number is greater than zero and you
-     *    didn't signal eof and the reader is prepared to
-     *    take more data you will be called again with the
-     *    requested offset advanced by the number of bytes
-     *    absorbed.
-     */
-
-#if 1
-    /* #4 - interpretation of above = set EOF, return len */
-    *eof = 1;
+               extern int max_chans_used;
+               extern int cxt1e1_max_mtu;
 #endif
+               extern int max_rxdesc_used, max_txdesc_used;
 
+               seq_printf(m, "\ncxt1e1_max_mru:         %d\n", cxt1e1_max_mru);
 #if 0
-    /*
-     * #1 - from net/wireless/atmel.c RLD NOTE -there's something wrong with
-     * this plagarized code which results in this routine being called TWICE.
-     * The second call returns ZERO, resulting in hidden failure, but at
-     * least only a single message set is being displayed.
-     */
-    if (len <= offset + length)
-        *eof = 1;
-    *start = buffer + offset;
-    len -= offset;
-    if (len > length)
-        len = length;
-    if (len < 0)
-        len = 0;
-#endif
-
-#if 0                               /* #2 from net/tokenring/olympic.c +
-                                     * lanstreamer.c */
-    {
-        off_t       begin = 0;
-        int         size = 0;
-        off_t       pos = 0;
-
-        size = len;
-        pos = begin + size;
-        if (pos < offset)
-        {
-            len = 0;
-            begin = pos;
-        }
-        *start = buffer + (offset - begin);     /* Start of wanted data */
-        len -= (offset - begin);    /* Start slop */
-        if (len > length)
-            len = length;           /* Ending slop */
-    }
+               seq_printf(m, "\nmax_chans_used:  %d\n", max_chans_used);
+               seq_printf(m, "cxt1e1_max_mtu:         %d\n", cxt1e1_max_mtu);
 #endif
-
-#if 0                               /* #3 from
-                                     * char/ftape/lowlevel/ftape-proc.c */
-    len = strlen (buffer);
-    *start = NULL;
-    if (offset + length >= len)
-        *eof = 1;
-    else
-        *eof = 0;
-#endif
-
-#if 0
-    pr_info(">> proc_fs: returned len = %d., start %p\n", len, start);  /* RLD DEBUG */
+               seq_printf(m, "max_rxdesc_used: %d\n", max_rxdesc_used);
+               seq_printf(m, "max_txdesc_used: %d\n", max_txdesc_used);
+       }
 #endif
 
-/***
-   using NONE: returns = 314.314.314.
-   using #1  : returns = 314, 0.
-   using #2  : returns = 314, 0, 0.
-   using #3  : returns = 314, 314.
-   using #4  : returns = 314, 314.
-***/
+       kfree(bip);
 
-    return len;
+       pr_devel(">> proc_fs: finished\n");
+       return 0;
 }
 
-/* initialize the /proc subsystem for the specific SBE driver */
-
-int         __init
-sbecom_proc_brd_init (ci_t * ci)
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int sbecom_proc_open(struct inode *inode, struct file *file)
 {
-    struct proc_dir_entry *e;
-    char dir[7 + SBE_IFACETMPL_SIZE + 1];
-
-    /* create a directory in the root procfs */
-    snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
-    ci->dir_dev = proc_mkdir(dir, NULL);
-    if (!ci->dir_dev)
-    {
-        pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
-        goto fail;
-    }
-    e = create_proc_read_entry ("info", S_IFREG | S_IRUGO,
-                                ci->dir_dev, sbecom_proc_get_sbe_info, ci);
-    if (!e)
-    {
-        pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
-        goto fail;
-    }
-    return 0;
-
-fail:
-    sbecom_proc_brd_cleanup (ci);
-    return 1;
+       return single_open(file, sbecom_proc_get_sbe_info, PDE_DATA(inode));
 }
 
-#else                           /*** ! CONFIG_PROC_FS ***/
+static const struct file_operations sbecom_proc_fops = {
+       .open           = sbecom_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-/* stubbed off dummy routines */
-
-void
-sbecom_proc_brd_cleanup (ci_t * ci)
-{
-}
-
-int         __init
-sbecom_proc_brd_init (ci_t * ci)
+/*
+ * Initialize the /proc subsystem for the specific SBE driver
+ */
+int __init sbecom_proc_brd_init(ci_t *ci)
 {
-    return 0;
-}
-
-#endif                          /*** CONFIG_PROC_FS ***/
+       char dir[7 + SBE_IFACETMPL_SIZE + 1];
 
+       snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
+       ci->dir_dev = proc_mkdir(dir, NULL);
+       if (!ci->dir_dev) {
+               pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
+               goto fail;
+       }
+
+       if (!proc_create_data("info", S_IFREG | S_IRUGO, ci->dir_dev,
+                             &sbecom_proc_fops, ci)) {
+               pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
+               goto fail;
+       }
+       return 0;
 
-/*** End-of-File ***/
+fail:
+       sbecom_proc_brd_cleanup(ci);
+       return 1;
+}
index e82be6afd1e84e8ce018291793f8cdc0b0b17664..e5c072cf1952d1f505517c784e21a0043e15a8b7 100644 (file)
 
 
 #ifdef CONFIG_PROC_FS
-#ifdef __KERNEL__
 void        sbecom_proc_brd_cleanup (ci_t *);
 int __init  sbecom_proc_brd_init (ci_t *);
 
-#endif                          /*** __KERNEL__ ***/
+#else
+
+static inline void sbecom_proc_brd_cleanup(ci_t * ci)
+{
+}
+
+static inline int __init sbecom_proc_brd_init(ci_t * ci)
+{
+       return 0;
+}
+
 #endif                          /*** CONFIG_PROC_FS ***/
+
 #endif                          /*** _INC_SBEPROC_H_ ***/
index 3553998b72bc2758344c77dac88f1b50f72dd2a9..9a9b45624ba9ba4f7a621a0031a25ce75348daa8 100644 (file)
@@ -167,34 +167,3 @@ void dgrp_carrier(struct ch_struct *ch)
                ch->ch_flag &= ~CH_PHYS_CD;
 
 }
-
-/**
- * dgrp_chk_perm() -- check permissions for net device
- * @inode: pointer to inode structure for the net communication device
- * @op: operation to be tested
- *
- * The file permissions and ownerships are tested to determine whether
- * the operation "op" is permitted on the file pointed to by the inode.
- * Returns 0 if the operation is permitted, -EACCESS otherwise
- */
-int dgrp_chk_perm(int mode, int op)
-{
-       if (!uid_eq(GLOBAL_ROOT_UID, current_euid()))
-               mode >>= 6;
-       else if (in_egroup_p(GLOBAL_ROOT_GID))
-               mode >>= 3;
-
-       if ((mode & op & 0007) == op)
-               return 0;
-
-       if (capable(CAP_SYS_ADMIN))
-               return 0;
-
-       return -EACCES;
-}
-
-/* dgrp_chk_perm wrapper for permission call in struct inode_operations */
-int dgrp_inode_permission(struct inode *inode, int op)
-{
-       return dgrp_chk_perm(inode->i_mode, op);
-}
index 0583fe9c7b035cd6810635bf6beb7c6e5a47daf1..076dd6bc5ac40157130ac3c9030f8d3775433cb8 100644 (file)
@@ -49,20 +49,20 @@ extern struct dgrp_poll_data dgrp_poll_data;
 extern void dgrp_poll_handler(unsigned long arg);
 
 /* from dgrp_mon_ops.c */
-extern void dgrp_register_mon_hook(struct proc_dir_entry *de);
+extern const struct file_operations dgrp_mon_ops;
 
 /* from dgrp_tty.c */
 extern int dgrp_tty_init(struct nd_struct *nd);
 extern void dgrp_tty_uninit(struct nd_struct *nd);
 
 /* from dgrp_ports_ops.c */
-extern void dgrp_register_ports_hook(struct proc_dir_entry *de);
+extern const struct file_operations dgrp_ports_ops;
 
 /* from dgrp_net_ops.c */
-extern void dgrp_register_net_hook(struct proc_dir_entry *de);
+extern const struct file_operations dgrp_net_ops;
 
 /* from dgrp_dpa_ops.c */
-extern void dgrp_register_dpa_hook(struct proc_dir_entry *de);
+extern const struct file_operations dgrp_dpa_ops;
 extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int);
 
 /* from dgrp_sysfs.c */
@@ -76,61 +76,6 @@ extern void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c);
 extern void dgrp_remove_tty_sysfs(struct device *c);
 
 /* from dgrp_specproc.c */
-/*
- *  The list of DGRP entries with r/w capabilities.  These
- *  magic numbers are used for identification purposes.
- */
-enum {
-       DGRP_CONFIG = 1,        /* Configure portservers */
-       DGRP_NETDIR = 2,        /* Directory for "net" devices */
-       DGRP_MONDIR = 3,        /* Directory for "mon" devices */
-       DGRP_PORTSDIR = 4,      /* Directory for "ports" devices */
-       DGRP_INFO = 5,          /* Get info. about the running module */
-       DGRP_NODEINFO = 6,      /* Get info. about the configured nodes */
-       DGRP_DPADIR = 7,        /* Directory for the "dpa" devices */
-};
-
-/*
- *  Directions for proc handlers
- */
-enum {
-       INBOUND = 1,            /* Data being written to kernel */
-       OUTBOUND = 2,           /* Data being read from the kernel */
-};
-
-/**
- * dgrp_proc_entry: structure for dgrp proc dirs
- * @id: ID number associated with this particular entry.  Should be
- *    unique across all of DGRP.
- * @name: text name associated with the /proc entry
- * @mode: file access permisssions for the /proc entry
- * @child: pointer to table describing a subdirectory for this entry
- * @de: pointer to directory entry for this object once registered.  Used
- *    to grab the handle of the object for unregistration
- * @excl_sem: semaphore to provide exclusive to struct
- * @excl_cnt: counter of current accesses
- *
- *  Each entry in a DGRP proc directory is described with a
- *  dgrp_proc_entry structure.  A collection of these
- *  entries (in an array) represents the members associated
- *  with a particular /proc directory, and is referred to
- *  as a table.  All tables are terminated by an entry with
- *  zeros for every member.
- */
-struct dgrp_proc_entry {
-       int                  id;          /* Integer identifier */
-       const char        *name;          /* ASCII identifier */
-       mode_t             mode;          /* File access permissions */
-       struct dgrp_proc_entry *child;    /* Child pointer */
-
-       /* file ops to use, pass NULL to use default */
-       struct file_operations *proc_file_ops;
-
-       struct proc_dir_entry *de;        /* proc entry pointer */
-       struct semaphore   excl_sem;      /* Protects exclusive access var */
-       int                excl_cnt;      /* Counts number of curr accesses */
-};
-
 extern void dgrp_unregister_proc(void);
 extern void dgrp_register_proc(void);
 
@@ -144,8 +89,6 @@ extern void dgrp_register_proc(void);
  *-----------------------------------------------------------------------*/
 
 void dgrp_carrier(struct ch_struct *ch);
-extern int dgrp_inode_permission(struct inode *inode, int op);
-extern int dgrp_chk_perm(int mode, int op);
 
 
 /*
index 021cca498f2c510ccb6bcd63a23582e39b094f16..1fc13de4bdd699a6a38dec3146d8ee749395da62 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/cred.h>
 #include <linux/sched.h>
 #include <linux/ratelimit.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "dgrp_common.h"
@@ -52,7 +53,7 @@ static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
                           unsigned long arg);
 static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *);
 
-static const struct file_operations dpa_ops = {
+const struct file_operations dgrp_dpa_ops = {
        .owner   =  THIS_MODULE,
        .read    =  dgrp_dpa_read,
        .poll    =  dgrp_dpa_select,
@@ -61,12 +62,6 @@ static const struct file_operations dpa_ops = {
        .release =  dgrp_dpa_release,
 };
 
-static struct inode_operations dpa_inode_ops = {
-       .permission = dgrp_inode_permission
-};
-
-
-
 struct digi_node {
        uint    nd_state;               /* Node state: 1 = up, 0 = down. */
        uint    nd_chan_count;          /* Number of channels found */
@@ -111,17 +106,6 @@ struct digi_debug {
 #define DIGI_SETDEBUG      (('d'<<8) | 247)    /* set debug info */
 
 
-void dgrp_register_dpa_hook(struct proc_dir_entry *de)
-{
-       struct nd_struct *node = de->data;
-
-       de->proc_iops = &dpa_inode_ops;
-       de->proc_fops = &dpa_ops;
-
-       node->nd_dpa_de = de;
-       spin_lock_init(&node->nd_dpa_lock);
-}
-
 /*
  * dgrp_dpa_open -- open the DPA device for a particular PortServer
  */
@@ -130,8 +114,6 @@ static int dgrp_dpa_open(struct inode *inode, struct file *file)
        struct nd_struct *nd;
        int rtn = 0;
 
-       struct proc_dir_entry *de;
-
        rtn = try_module_get(THIS_MODULE);
        if (!rtn)
                return -ENXIO;
@@ -154,12 +136,7 @@ static int dgrp_dpa_open(struct inode *inode, struct file *file)
        /*
         *  Get the node pointer, and fail if it doesn't exist.
         */
-       de = PDE(inode);
-       if (!de) {
-               rtn = -ENXIO;
-               goto done;
-       }
-       nd = (struct nd_struct *)de->data;
+       nd = PDE_DATA(inode);
        if (!nd) {
                rtn = -ENXIO;
                goto done;
index 4792d056a36532b179968dda51f73b37ce56cb95..d18be4180e3bad40cad4c83557db85c78fb9e1ef 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/tty.h>
 #include <linux/sched.h>
 #include <asm/unaligned.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/uaccess.h>
 
@@ -49,7 +50,7 @@ static ssize_t dgrp_mon_read(struct file *, char __user *, size_t, loff_t *);
 static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
                           unsigned long arg);
 
-static const struct file_operations mon_ops = {
+const struct file_operations dgrp_mon_ops = {
        .owner   = THIS_MODULE,
        .read    = dgrp_mon_read,
        .unlocked_ioctl = dgrp_mon_ioctl,
@@ -57,20 +58,6 @@ static const struct file_operations mon_ops = {
        .release = dgrp_mon_release,
 };
 
-static struct inode_operations mon_inode_ops = {
-       .permission = dgrp_inode_permission
-};
-
-void dgrp_register_mon_hook(struct proc_dir_entry *de)
-{
-       struct nd_struct *node = de->data;
-
-       de->proc_iops = &mon_inode_ops;
-       de->proc_fops = &mon_ops;
-       node->nd_mon_de = de;
-       sema_init(&node->nd_mon_semaphore, 1);
-}
-
 /**
  * dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer
  * @inode: struct inode *
@@ -81,7 +68,6 @@ void dgrp_register_mon_hook(struct proc_dir_entry *de)
 static int dgrp_mon_open(struct inode *inode, struct file *file)
 {
        struct nd_struct *nd;
-       struct proc_dir_entry *de;
        struct timeval tv;
        uint32_t time;
        u8 *buf;
@@ -109,13 +95,7 @@ static int dgrp_mon_open(struct inode *inode, struct file *file)
        /*
         *  Get the node pointer, and fail if it doesn't exist.
         */
-       de = PDE(inode);
-       if (!de) {
-               rtn = -ENXIO;
-               goto done;
-       }
-
-       nd = (struct nd_struct *)de->data;
+       nd = PDE_DATA(inode);
        if (!nd) {
                rtn = -ENXIO;
                goto done;
index e6018823b9deca9079ff3ee72251a5669ad99b2f..9914f1c5bcd36011e1874e52a16812858988544a 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <linux/module.h>
 #include <linux/proc_fs.h>
-#include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/tty.h>
@@ -72,7 +72,7 @@ static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
 static unsigned int dgrp_net_select(struct file *file,
                                    struct poll_table_struct *table);
 
-static const struct file_operations net_ops = {
+const struct file_operations dgrp_net_ops = {
        .owner   =  THIS_MODULE,
        .read    =  dgrp_net_read,
        .write   =  dgrp_net_write,
@@ -82,23 +82,6 @@ static const struct file_operations net_ops = {
        .release =  dgrp_net_release,
 };
 
-static struct inode_operations net_inode_ops = {
-       .permission = dgrp_inode_permission
-};
-
-void dgrp_register_net_hook(struct proc_dir_entry *de)
-{
-       struct nd_struct *node = de->data;
-
-       de->proc_iops = &net_inode_ops;
-       de->proc_fops = &net_ops;
-       node->nd_net_de = de;
-       sema_init(&node->nd_net_semaphore, 1);
-       node->nd_state = NS_CLOSED;
-       dgrp_create_node_class_sysfs_files(node);
-}
-
-
 /**
  * dgrp_dump() -- prints memory for debugging purposes.
  * @mem: Memory location which should be printed to the console
@@ -801,7 +784,6 @@ out_err:
 static int dgrp_net_open(struct inode *inode, struct file *file)
 {
        struct nd_struct *nd;
-       struct proc_dir_entry *de;
        ulong  lock_flags;
        int rtn;
 
@@ -825,13 +807,7 @@ static int dgrp_net_open(struct inode *inode, struct file *file)
        /*
         *  Get the node pointer, and fail if it doesn't exist.
         */
-       de = PDE(inode);
-       if (!de) {
-               rtn = -ENXIO;
-               goto done;
-       }
-
-       nd = (struct nd_struct *) de->data;
+       nd = PDE_DATA(inode);
        if (!nd) {
                rtn = -ENXIO;
                goto done;
index cd1fc20886242f27a38b0b17f4c5880a47ba8835..4ce030815f27176cfa65504a95494a92da75e3f4 100644 (file)
@@ -47,7 +47,7 @@
 /* File operation declarations */
 static int dgrp_ports_open(struct inode *, struct file *);
 
-static const struct file_operations ports_ops = {
+const struct file_operations dgrp_ports_ops = {
        .owner   = THIS_MODULE,
        .open    = dgrp_ports_open,
        .read    = seq_read,
@@ -55,20 +55,6 @@ static const struct file_operations ports_ops = {
        .release = seq_release
 };
 
-static struct inode_operations ports_inode_ops = {
-       .permission = dgrp_inode_permission
-};
-
-
-void dgrp_register_ports_hook(struct proc_dir_entry *de)
-{
-       struct nd_struct *node = de->data;
-
-       de->proc_iops = &ports_inode_ops;
-       de->proc_fops = &ports_ops;
-       node->nd_ports_de = de;
-}
-
 static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos)
 {
        if (*pos == 0)
@@ -163,7 +149,7 @@ static int dgrp_ports_open(struct inode *inode, struct file *file)
        rtn = seq_open(file, &ports_seq_ops);
        if (!rtn) {
                seq = file->private_data;
-               seq->private = PDE(inode)->data;
+               seq->private = PDE_DATA(inode);
        }
 
        return rtn;
index 73f287f966046b7f89ff5e4a6c3038f9c98d6d52..205d80ef44558a0c26468e3b4a4d4c34ce50e786 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/sched.h>
 #include <linux/cred.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 
 #include "dgrp_common.h"
 
-static struct dgrp_proc_entry dgrp_table[];
 static struct proc_dir_entry *dgrp_proc_dir_entry;
 
 static int dgrp_add_id(long id);
 static int dgrp_remove_nd(struct nd_struct *nd);
-static void unregister_dgrp_device(struct proc_dir_entry *de);
-static void register_dgrp_device(struct nd_struct *node,
+static struct proc_dir_entry *add_proc_file(struct nd_struct *node,
                                 struct proc_dir_entry *root,
-                                void (*register_hook)(struct proc_dir_entry *de));
+                                const struct file_operations *fops);
 
 /* File operation declarations */
-static int dgrp_gen_proc_open(struct inode *, struct file *);
-static int dgrp_gen_proc_close(struct inode *, struct file *);
 static int parse_write_config(char *);
 
-
-static const struct file_operations dgrp_proc_file_ops = {
-       .owner   = THIS_MODULE,
-       .open    = dgrp_gen_proc_open,
-       .release = dgrp_gen_proc_close,
-};
-
-static struct inode_operations proc_inode_ops = {
-       .permission = dgrp_inode_permission
-};
-
-
-static void register_proc_table(struct dgrp_proc_entry *,
-                               struct proc_dir_entry *);
-static void unregister_proc_table(struct dgrp_proc_entry *,
-                                 struct proc_dir_entry *);
-
-static struct dgrp_proc_entry dgrp_net_table[];
-static struct dgrp_proc_entry dgrp_mon_table[];
-static struct dgrp_proc_entry dgrp_ports_table[];
-static struct dgrp_proc_entry dgrp_dpa_table[];
-
 static ssize_t dgrp_config_proc_write(struct file *file,
                                      const char __user *buffer,
                                      size_t count, loff_t *pos);
@@ -89,7 +64,7 @@ static int dgrp_nodeinfo_proc_open(struct inode *inode, struct file *file);
 static int dgrp_info_proc_open(struct inode *inode, struct file *file);
 static int dgrp_config_proc_open(struct inode *inode, struct file *file);
 
-static struct file_operations config_proc_file_ops = {
+static const struct file_operations config_proc_file_ops = {
        .owner   = THIS_MODULE,
        .open    = dgrp_config_proc_open,
        .read    = seq_read,
@@ -98,7 +73,7 @@ static struct file_operations config_proc_file_ops = {
        .write   = dgrp_config_proc_write,
 };
 
-static struct file_operations info_proc_file_ops = {
+static const struct file_operations info_proc_file_ops = {
        .owner   = THIS_MODULE,
        .open    = dgrp_info_proc_open,
        .read    = seq_read,
@@ -106,7 +81,7 @@ static struct file_operations info_proc_file_ops = {
        .release = single_release,
 };
 
-static struct file_operations nodeinfo_proc_file_ops = {
+static const struct file_operations nodeinfo_proc_file_ops = {
        .owner   = THIS_MODULE,
        .open    = dgrp_nodeinfo_proc_open,
        .read    = seq_read,
@@ -114,71 +89,25 @@ static struct file_operations nodeinfo_proc_file_ops = {
        .release = seq_release,
 };
 
-static struct dgrp_proc_entry dgrp_table[] = {
-       {
-               .id = DGRP_CONFIG,
-               .name = "config",
-               .mode = 0644,
-               .proc_file_ops = &config_proc_file_ops,
-       },
-       {
-               .id = DGRP_INFO,
-               .name = "info",
-               .mode = 0644,
-               .proc_file_ops = &info_proc_file_ops,
-       },
-       {
-               .id = DGRP_NODEINFO,
-               .name = "nodeinfo",
-               .mode = 0644,
-               .proc_file_ops = &nodeinfo_proc_file_ops,
-       },
-       {
-               .id = DGRP_NETDIR,
-               .name = "net",
-               .mode = 0500,
-               .child = dgrp_net_table
-       },
-       {
-               .id = DGRP_MONDIR,
-               .name = "mon",
-               .mode = 0500,
-               .child = dgrp_mon_table
-       },
-       {
-               .id = DGRP_PORTSDIR,
-               .name = "ports",
-               .mode = 0500,
-               .child = dgrp_ports_table
-       },
-       {
-               .id = DGRP_DPADIR,
-               .name = "dpa",
-               .mode = 0500,
-               .child = dgrp_dpa_table
-       }
-};
-
 static struct proc_dir_entry *net_entry_pointer;
 static struct proc_dir_entry *mon_entry_pointer;
 static struct proc_dir_entry *dpa_entry_pointer;
 static struct proc_dir_entry *ports_entry_pointer;
 
-static struct dgrp_proc_entry dgrp_net_table[] = {
-       {0}
-};
-
-static struct dgrp_proc_entry dgrp_mon_table[] = {
-       {0}
-};
-
-static struct dgrp_proc_entry dgrp_ports_table[] = {
-       {0}
-};
-
-static struct dgrp_proc_entry dgrp_dpa_table[] = {
-       {0}
-};
+static void remove_files(struct nd_struct *nd)
+{
+       char buf[3];
+       ID_TO_CHAR(nd->nd_ID, buf);
+       dgrp_remove_node_class_sysfs_files(nd);
+       if (nd->nd_net_de)
+               remove_proc_entry(buf, net_entry_pointer);
+       if (nd->nd_mon_de)
+               remove_proc_entry(buf, mon_entry_pointer);
+       if (nd->nd_dpa_de)
+               remove_proc_entry(buf, dpa_entry_pointer);
+       if (nd->nd_ports_de)
+               remove_proc_entry(buf, ports_entry_pointer);
+}
 
 void dgrp_unregister_proc(void)
 {
@@ -188,12 +117,19 @@ void dgrp_unregister_proc(void)
        ports_entry_pointer = NULL;
 
        if (dgrp_proc_dir_entry) {
-               unregister_proc_table(dgrp_table, dgrp_proc_dir_entry);
-               remove_proc_entry(dgrp_proc_dir_entry->name,
-                                 dgrp_proc_dir_entry->parent);
+               struct nd_struct *nd;
+               list_for_each_entry(nd, &nd_struct_list, list)
+                       remove_files(nd);
+               remove_proc_entry("dgrp/config", NULL);
+               remove_proc_entry("dgrp/info", NULL);
+               remove_proc_entry("dgrp/nodeinfo", NULL);
+               remove_proc_entry("dgrp/net", NULL);
+               remove_proc_entry("dgrp/mon", NULL);
+               remove_proc_entry("dgrp/dpa", NULL);
+               remove_proc_entry("dgrp/ports", NULL);
+               remove_proc_entry("dgrp", NULL);
                dgrp_proc_dir_entry = NULL;
        }
-
 }
 
 void dgrp_register_proc(void)
@@ -201,209 +137,16 @@ void dgrp_register_proc(void)
        /*
         *      Register /proc/dgrp
         */
-       dgrp_proc_dir_entry = proc_create("dgrp", S_IFDIR, NULL,
-                                         &dgrp_proc_file_ops);
-       register_proc_table(dgrp_table, dgrp_proc_dir_entry);
-}
-
-/*
- * /proc/sys support
- */
-static int dgrp_proc_match(int len, const char *name, struct proc_dir_entry *de)
-{
-       if (!de || !de->low_ino)
-               return 0;
-       if (de->namelen != len)
-               return 0;
-       return !memcmp(name, de->name, len);
-}
-
-
-/*
- *  Scan the entries in table and add them all to /proc at the position
- *  referred to by "root"
- */
-static void register_proc_table(struct dgrp_proc_entry *table,
-                               struct proc_dir_entry *root)
-{
-       struct proc_dir_entry *de;
-       int len;
-       mode_t mode;
-
-       if (table == NULL)
+       dgrp_proc_dir_entry = proc_mkdir("dgrp", NULL);
+       if (!dgrp_proc_dir_entry)
                return;
-       if (root == NULL)
-               return;
-
-       for (; table->id; table++) {
-               /* Can't do anything without a proc name. */
-               if (!table->name)
-                       continue;
-
-               /* Maybe we can't do anything with it... */
-               if (!table->proc_file_ops &&
-                   !table->child) {
-                       pr_warn("dgrp: Can't register %s\n",
-                               table->name);
-                       continue;
-               }
-
-               len = strlen(table->name);
-               mode = table->mode;
-
-               de = NULL;
-               if (!table->child)
-                       mode |= S_IFREG;
-               else {
-                       mode |= S_IFDIR;
-                       for (de = root->subdir; de; de = de->next) {
-                               if (dgrp_proc_match(len, table->name, de))
-                                       break;
-                       }
-                       /* If the subdir exists already, de is non-NULL */
-               }
-
-               if (!de) {
-                       de = create_proc_entry(table->name, mode, root);
-                       if (!de)
-                               continue;
-                       de->data = (void *) table;
-                       if (!table->child) {
-                               de->proc_iops = &proc_inode_ops;
-                               if (table->proc_file_ops)
-                                       de->proc_fops = table->proc_file_ops;
-                               else
-                                       de->proc_fops = &dgrp_proc_file_ops;
-                       }
-               }
-               table->de = de;
-               if (de->mode & S_IFDIR)
-                       register_proc_table(table->child, de);
-
-               if (table->id == DGRP_NETDIR)
-                       net_entry_pointer = de;
-
-               if (table->id == DGRP_MONDIR)
-                       mon_entry_pointer = de;
-
-               if (table->id == DGRP_DPADIR)
-                       dpa_entry_pointer = de;
-
-               if (table->id == DGRP_PORTSDIR)
-                       ports_entry_pointer = de;
-       }
-}
-
-/*
- * Unregister a /proc sysctl table and any subdirectories.
- */
-static void unregister_proc_table(struct dgrp_proc_entry *table,
-                                 struct proc_dir_entry *root)
-{
-       struct proc_dir_entry *de;
-       struct nd_struct *tmp;
-
-       if (table == NULL)
-               return;
-
-       list_for_each_entry(tmp, &nd_struct_list, list) {
-               if ((table == dgrp_net_table) && (tmp->nd_net_de)) {
-                       unregister_dgrp_device(tmp->nd_net_de);
-                       dgrp_remove_node_class_sysfs_files(tmp);
-               }
-
-               if ((table == dgrp_mon_table) && (tmp->nd_mon_de))
-                       unregister_dgrp_device(tmp->nd_mon_de);
-
-               if ((table == dgrp_dpa_table) && (tmp->nd_dpa_de))
-                       unregister_dgrp_device(tmp->nd_dpa_de);
-
-               if ((table == dgrp_ports_table) && (tmp->nd_ports_de))
-                       unregister_dgrp_device(tmp->nd_ports_de);
-       }
-
-       for (; table->id; table++) {
-               de = table->de;
-
-               if (!de)
-                       continue;
-               if (de->mode & S_IFDIR) {
-                       if (!table->child) {
-                               pr_alert("dgrp: malformed sysctl tree on free\n");
-                               continue;
-                       }
-                       unregister_proc_table(table->child, de);
-
-       /* Don't unregister directories which still have entries */
-                       if (de->subdir)
-                               continue;
-               }
-
-               /* Don't unregister proc entries that are still being used.. */
-               if ((atomic_read(&de->count)) != 1) {
-                       pr_alert("proc entry %s in use, not removing\n",
-                               de->name);
-                       continue;
-               }
-
-               remove_proc_entry(de->name, de->parent);
-               table->de = NULL;
-       }
-}
-
-static int dgrp_gen_proc_open(struct inode *inode, struct file *file)
-{
-       struct proc_dir_entry *de;
-       struct dgrp_proc_entry *entry;
-       int ret = 0;
-
-       de = (struct proc_dir_entry *) PDE(file_inode(file));
-       if (!de || !de->data) {
-               ret = -ENXIO;
-               goto done;
-       }
-
-       entry = (struct dgrp_proc_entry *) de->data;
-       if (!entry) {
-               ret = -ENXIO;
-               goto done;
-       }
-
-       down(&entry->excl_sem);
-
-       if (entry->excl_cnt)
-               ret = -EBUSY;
-       else
-               entry->excl_cnt++;
-
-       up(&entry->excl_sem);
-
-done:
-       return ret;
-}
-
-static int dgrp_gen_proc_close(struct inode *inode, struct file *file)
-{
-       struct proc_dir_entry *de;
-       struct dgrp_proc_entry *entry;
-
-       de = (struct proc_dir_entry *) PDE(file_inode(file));
-       if (!de || !de->data)
-               goto done;
-
-       entry = (struct dgrp_proc_entry *) de->data;
-       if (!entry)
-               goto done;
-
-       down(&entry->excl_sem);
-
-       if (entry->excl_cnt)
-               entry->excl_cnt = 0;
-
-       up(&entry->excl_sem);
-
-done:
-       return 0;
+       proc_create("dgrp/config", 0644, NULL, &config_proc_file_ops);
+       proc_create("dgrp/info", 0644, NULL, &info_proc_file_ops);
+       proc_create("dgrp/nodeinfo", 0644, NULL, &nodeinfo_proc_file_ops);
+       net_entry_pointer = proc_mkdir_mode("dgrp/net", 0500, NULL);
+       mon_entry_pointer = proc_mkdir_mode("dgrp/mon", 0500, NULL);
+       dpa_entry_pointer = proc_mkdir_mode("dgrp/dpa", 0500, NULL);
+       ports_entry_pointer = proc_mkdir_mode("dgrp/ports", 0500, NULL);
 }
 
 static void *dgrp_config_proc_start(struct seq_file *m, loff_t *pos)
@@ -734,6 +477,10 @@ static int dgrp_add_id(long id)
        init_waitqueue_head(&nd->nd_tx_waitq);
        init_waitqueue_head(&nd->nd_mon_wqueue);
        init_waitqueue_head(&nd->nd_dpa_wqueue);
+       sema_init(&nd->nd_mon_semaphore, 1);
+       sema_init(&nd->nd_net_semaphore, 1);
+       spin_lock_init(&nd->nd_dpa_lock);
+       nd->nd_state = NS_CLOSED;
        for (i = 0; i < SEQ_MAX; i++)
                init_waitqueue_head(&nd->nd_seq_wque[i]);
 
@@ -748,12 +495,12 @@ static int dgrp_add_id(long id)
        if (ret)
                goto error_out;
 
-       register_dgrp_device(nd, net_entry_pointer, dgrp_register_net_hook);
-       register_dgrp_device(nd, mon_entry_pointer, dgrp_register_mon_hook);
-       register_dgrp_device(nd, dpa_entry_pointer, dgrp_register_dpa_hook);
-       register_dgrp_device(nd, ports_entry_pointer,
-                             dgrp_register_ports_hook);
-
+       dgrp_create_node_class_sysfs_files(nd);
+       nd->nd_net_de = add_proc_file(nd, net_entry_pointer, &dgrp_net_ops);
+       nd->nd_mon_de = add_proc_file(nd, mon_entry_pointer, &dgrp_mon_ops);
+       nd->nd_dpa_de = add_proc_file(nd, dpa_entry_pointer, &dgrp_dpa_ops);
+       nd->nd_ports_de = add_proc_file(nd, ports_entry_pointer,
+                                       &dgrp_ports_ops);
        return 0;
 
        /* FIXME this guy should free the tty driver stored in nd and destroy
@@ -772,16 +519,7 @@ static int dgrp_remove_nd(struct nd_struct *nd)
        if (nd->nd_tty_ref_cnt)
                return -EBUSY;
 
-       if (nd->nd_net_de) {
-               unregister_dgrp_device(nd->nd_net_de);
-               dgrp_remove_node_class_sysfs_files(nd);
-       }
-
-       unregister_dgrp_device(nd->nd_mon_de);
-
-       unregister_dgrp_device(nd->nd_ports_de);
-
-       unregister_dgrp_device(nd->nd_dpa_de);
+       remove_files(nd);
 
        dgrp_tty_uninit(nd);
 
@@ -793,38 +531,11 @@ static int dgrp_remove_nd(struct nd_struct *nd)
        return 0;
 }
 
-static void register_dgrp_device(struct nd_struct *node,
+static struct proc_dir_entry *add_proc_file(struct nd_struct *node,
                                 struct proc_dir_entry *root,
-                                void (*register_hook)(struct proc_dir_entry *de))
+                                const struct file_operations *fops)
 {
        char buf[3];
-       struct proc_dir_entry *de;
-
        ID_TO_CHAR(node->nd_ID, buf);
-
-       de = create_proc_entry(buf, 0600 | S_IFREG, root);
-       if (!de)
-               return;
-
-       de->data = (void *) node;
-
-       if (register_hook)
-               register_hook(de);
-
-}
-
-static void unregister_dgrp_device(struct proc_dir_entry *de)
-{
-       if (!de)
-               return;
-
-       /* Don't unregister proc entries that are still being used.. */
-       if ((atomic_read(&de->count)) != 1) {
-               pr_alert("%s - proc entry %s in use. Not removing.\n",
-                        __func__, de->name);
-               return;
-       }
-
-       remove_proc_entry(de->name, de->parent);
-       de = NULL;
+       return proc_create_data(buf, 0600, root, fops, node);
 }
index 5337b415d450cee2540b00b9c09809cd49ad3bb6..21b369e0150f327b639b4d56f9165f83c675b650 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/netdevice.h>
 #define FT1000_PROC "ft1000"
 #define MAX_FILE_LEN 255
 
-#define PUTM_TO_PAGE(len, page, args...) \
-       len += snprintf(page+len, PAGE_SIZE - len, args)
-
-#define PUTX_TO_PAGE(len, page, message, size, var) \
-       len += snprintf(page+len, PAGE_SIZE - len, message); \
+#define seq_putx(m, message, size, var) \
+       seq_printf(m, message); \
        for(i = 0; i < (size - 1); i++) { \
-               len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \
+               seq_printf(m, "%02x:", var[i]); \
        } \
-       len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i])
+       seq_printf(m, "%02x\n", var[i])
 
-#define PUTD_TO_PAGE(len, page, message, size, var) \
-       len += snprintf(page+len, PAGE_SIZE - len, message); \
+#define seq_putd(m, message, size, var) \
+       seq_printf(m, message); \
        for(i = 0; i < (size - 1); i++) { \
-               len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \
+               seq_printf(m, "%d.", var[i]); \
        } \
-       len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i])
+       seq_printf(m, "%d\n", var[i])
 
-static int ft1000ReadProc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+static int ft1000ReadProc(struct seq_file *m, void *v)
 {
-       struct net_device *dev;
-       int len;
-       int i;
-       struct ft1000_info *info;
-       char *status[] = {
+       static const char *status[] = {
                "Idle (Disconnect)", "Searching", "Active (Connected)",
                "Waiting for L2", "Sleep", "No Coverage", "", ""
        };
-       char *signal[] = { "", "*", "**", "***", "****" };
+       static const char *signal[] = { "", "*", "**", "***", "****" };
+
+       struct net_device *dev = m->private;
+       struct ft1000_info *info = netdev_priv(dev);
+       int i;
        int strength;
        int quality;
        struct timeval tv;
        time_t delta;
 
-       dev = (struct net_device *)data;
-       info = netdev_priv(dev);
-
-       if (off > 0) {
-               *eof = 1;
-               return 0;
-       }
-
-       /* Wrap-around */
-
        if (info->AsicID == ELECTRABUZZ_ID) {
                if (info->ProgConStat != 0xFF) {
                        info->LedStat =
                                ft1000_read_dpram(dev, FT1000_DSP_LED);
                        info->ConStat =
-                               ft1000_read_dpram(dev,
-                                                 FT1000_DSP_CON_STATE);
+                               ft1000_read_dpram(dev, FT1000_DSP_CON_STATE);
                } else {
                        info->ConStat = 0xf;
                }
        } else {
                if (info->ProgConStat != 0xFF) {
                        info->LedStat =
-                               ntohs(ft1000_read_dpram_mag_16
-                                 (dev, FT1000_MAG_DSP_LED,
-                                  FT1000_MAG_DSP_LED_INDX));
+                               ntohs(ft1000_read_dpram_mag_16(
+                                             dev, FT1000_MAG_DSP_LED,
+                                             FT1000_MAG_DSP_LED_INDX));
                        info->ConStat =
-                               ntohs(ft1000_read_dpram_mag_16
-                                 (dev, FT1000_MAG_DSP_CON_STATE,
-                                  FT1000_MAG_DSP_CON_STATE_INDX));
+                               ntohs(ft1000_read_dpram_mag_16(
+                                             dev, FT1000_MAG_DSP_CON_STATE,
+                                             FT1000_MAG_DSP_CON_STATE_INDX));
                } else {
                        info->ConStat = 0xf;
                }
@@ -135,36 +121,46 @@ static int ft1000ReadProc(char *page, char **start, off_t off,
        }
 
        do_gettimeofday(&tv);
-       delta = (tv.tv_sec - info->ConTm);
-       len = 0;
-       PUTM_TO_PAGE(len, page, "Connection Time: %02ld:%02ld:%02ld\n",
+       delta = tv.tv_sec - info->ConTm;
+       seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n",
                         ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
-       PUTM_TO_PAGE(len, page, "Connection Time[s]: %ld\n", delta);
-       PUTM_TO_PAGE(len, page, "Asic ID: %s\n",
-                        (info->AsicID) ==
+       seq_printf(m, "Connection Time[s]: %ld\n", delta);
+       seq_printf(m, "Asic ID: %s\n",
+                        info->AsicID ==
                         ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
-       PUTX_TO_PAGE(len, page, "SKU: ", SKUSZ, info->Sku);
-       PUTX_TO_PAGE(len, page, "EUI64: ", EUISZ, info->eui64);
-       PUTD_TO_PAGE(len, page, "DSP version number: ", DSPVERSZ, info->DspVer);
-       PUTX_TO_PAGE(len, page, "Hardware Serial Number: ", HWSERNUMSZ,
-                        info->HwSerNum);
-       PUTX_TO_PAGE(len, page, "Caliberation Version: ", CALVERSZ,
-                        info->RfCalVer);
-       PUTD_TO_PAGE(len, page, "Caliberation Date: ", CALDATESZ,
-                        info->RfCalDate);
-       PUTM_TO_PAGE(len, page, "Media State: %s\n",
+       seq_putx(m, "SKU: ", SKUSZ, info->Sku);
+       seq_putx(m, "EUI64: ", EUISZ, info->eui64);
+       seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer);
+       seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum);
+       seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer);
+       seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate);
+       seq_printf(m, "Media State: %s\n",
                         (info->mediastate) ? "link" : "no link");
-       PUTM_TO_PAGE(len, page, "Connection Status: %s\n",
-                        status[((info->ConStat) & 0x7)]);
-       PUTM_TO_PAGE(len, page, "RX packets: %ld\n", info->stats.rx_packets);
-       PUTM_TO_PAGE(len, page, "TX packets: %ld\n", info->stats.tx_packets);
-       PUTM_TO_PAGE(len, page, "RX bytes: %ld\n", info->stats.rx_bytes);
-       PUTM_TO_PAGE(len, page, "TX bytes: %ld\n", info->stats.tx_bytes);
-       PUTM_TO_PAGE(len, page, "Signal Strength: %s\n", signal[strength]);
-       PUTM_TO_PAGE(len, page, "Signal Quality: %s\n", signal[quality]);
-       return len;
+       seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]);
+       seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets);
+       seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets);
+       seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes);
+       seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes);
+       seq_printf(m, "Signal Strength: %s\n", signal[strength]);
+       seq_printf(m, "Signal Quality: %s\n", signal[quality]);
+       return 0;
+}
+
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int ft1000_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ft1000ReadProc, PDE_DATA(inode));
 }
 
+static const struct file_operations ft1000_proc_fops = {
+       .open           = ft1000_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static int ft1000NotifyProc(struct notifier_block *this, unsigned long event,
                                void *ptr)
 {
@@ -176,8 +172,8 @@ static int ft1000NotifyProc(struct notifier_block *this, unsigned long event,
        switch (event) {
        case NETDEV_CHANGENAME:
                remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
-               create_proc_read_entry(dev->name, 0644, info->ft1000_proc_dir,
-                                          ft1000ReadProc, dev);
+               proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
+                                &ft1000_proc_fops, dev);
                snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
                break;
        }
@@ -195,8 +191,10 @@ void ft1000InitProc(struct net_device *dev)
        info = netdev_priv(dev);
 
        info->ft1000_proc_dir = proc_mkdir(FT1000_PROC, init_net.proc_net);
-       create_proc_read_entry(dev->name, 0644, info->ft1000_proc_dir,
-                                  ft1000ReadProc, dev);
+
+       proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
+                        &ft1000_proc_fops, dev);
+
        snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
        register_netdevice_notifier(&ft1000_netdev_notifier);
 }
index 297389e8c608367f5f5c3db88bdc448d73504b98..3251d2e073b5ebc3f5cbac27469fff23a99fbd59 100644 (file)
@@ -55,7 +55,7 @@ int numofmsgbuf = 0;
 //
 // Table of entry-point routines for char device
 //
-static struct file_operations ft1000fops =
+static const struct file_operations ft1000fops =
 {
        .unlocked_ioctl = ft1000_ioctl,
        .poll           = ft1000_poll_dev,
index b99640637fe0edb49a13f80b986e22ac40295dc2..d8294d6c9560a2127f5c7332015476e9055f1500 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/netdevice.h>
 
 
 #define FT1000_PROC_DIR "ft1000"
 
 
-#define PUTM_TO_PAGE(len,page,args...) \
-       len += snprintf(page+len, PAGE_SIZE - len, args)
+#define seq_putx(m, message, size, var) \
+       seq_printf(m, message); \
+       for(i = 0; i < (size - 1); i++) \
+               seq_printf(m, "%02x:", var[i]); \
+       seq_printf(m, "%02x\n", var[i])
 
-#define PUTX_TO_PAGE(len,page,message,size,var) \
-       len += snprintf(page+len, PAGE_SIZE - len, message); \
-       for (i = 0; i < (size - 1); i++) {\
-               len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \
-       } \
-       len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i])
-
-#define PUTD_TO_PAGE(len,page,message,size,var) \
-       len += snprintf(page+len, PAGE_SIZE - len, message); \
-       for (i = 0; i < (size - 1); i++) {\
-               len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \
-       } \
-       len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i])
+#define seq_putd(m, message, size, var) \
+       seq_printf(m, message); \
+       for(i = 0; i < (size - 1); i++) \
+               seq_printf(m, "%d.", var[i]); \
+       seq_printf(m, "%d\n", var[i])
 
 
 #define FTNET_PROC init_net.proc_net
@@ -55,19 +51,9 @@ int ft1000_read_dpram16 (struct ft1000_usb *ft1000dev, u16 indx,
                         u8 *buffer, u8 highlow);
 
 
-static int
-ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof,
-               void *data)
+static int ft1000ReadProc(struct seq_file *m, void *v)
 {
-       struct net_device *dev;
-       int len;
-       int i;
-       unsigned short ledStat;
-       unsigned short conStat;
-
-       struct ft1000_info *info;
-
-       char *status[] = { 
+       static const char *status[] = { 
                "Idle (Disconnect)", 
                "Searching",
                "Active (Connected)",
@@ -77,22 +63,18 @@ ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof,
                "",
                "",
        };
+       static const char *signal[] = { "", "*", "**", "***", "****" };
 
-       char *signal[] = { "", "*", "**", "***", "****" };
+       struct net_device *dev = m->private;
+       struct ft1000_info *info = netdev_priv(dev);
+       int i;
+       unsigned short ledStat;
+       unsigned short conStat;
        int strength;
        int quality;
        struct timeval tv;
        time_t delta;
 
-       dev = (struct net_device *) data;
-       info = netdev_priv(dev);
-
-       if (off > 0) {
-               *eof = 1;
-               return 0;
-       }
-
-
        if (info->ProgConStat != 0xFF) {
                ft1000_read_dpram16(info->priv, FT1000_MAG_DSP_LED,
                           (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX);
@@ -144,36 +126,43 @@ ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof,
                quality = 0;
        }
 
-       len = 0;
-       PUTM_TO_PAGE(len, page, "Connection Time: %02ld:%02ld:%02ld\n",
+       seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n",
                ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
-       PUTM_TO_PAGE(len, page, "Connection Time[s]: %ld\n", delta);
-       PUTM_TO_PAGE(len, page, "Asic ID: %s\n",
-       (info->AsicID) ==
-       ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
-       PUTX_TO_PAGE(len, page, "SKU: ", SKUSZ, info->Sku);
-       PUTX_TO_PAGE(len, page, "EUI64: ", EUISZ, info->eui64);
-       PUTD_TO_PAGE(len, page, "DSP version number: ", DSPVERSZ, info->DspVer);
-       PUTX_TO_PAGE(len, page, "Hardware Serial Number: ", HWSERNUMSZ,
-               info->HwSerNum);
-       PUTX_TO_PAGE(len, page, "Caliberation Version: ", CALVERSZ,
-               info->RfCalVer);
-       PUTD_TO_PAGE(len, page, "Caliberation Date: ", CALDATESZ,
-               info->RfCalDate);
-       PUTM_TO_PAGE(len, page, "Media State: %s\n",
-               (info->mediastate) ? "link" : "no link");
-       PUTM_TO_PAGE(len, page, "Connection Status: %s\n",
-               status[((info->ConStat) & 0x7)]);
-       PUTM_TO_PAGE(len, page, "RX packets: %ld\n", info->stats.rx_packets);
-       PUTM_TO_PAGE(len, page, "TX packets: %ld\n", info->stats.tx_packets);
-       PUTM_TO_PAGE(len, page, "RX bytes: %ld\n", info->stats.rx_bytes);
-       PUTM_TO_PAGE(len, page, "TX bytes: %ld\n", info->stats.tx_bytes);
-       PUTM_TO_PAGE(len, page, "Signal Strength: %s\n", signal[strength]);
-       PUTM_TO_PAGE(len, page, "Signal Quality: %s\n", signal[quality]);
-
-       return len;
+       seq_printf(m, "Connection Time[s]: %ld\n", delta);
+       seq_printf(m, "Asic ID: %s\n",
+       (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
+       seq_putx(m, "SKU: ", SKUSZ, info->Sku);
+       seq_putx(m, "EUI64: ", EUISZ, info->eui64);
+       seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer);
+       seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum);
+       seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer);
+       seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate);
+       seq_printf(m, "Media State: %s\n", (info->mediastate) ? "link" : "no link");
+       seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]);
+       seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets);
+       seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets);
+       seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes);
+       seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes);
+       seq_printf(m, "Signal Strength: %s\n", signal[strength]);
+       seq_printf(m, "Signal Quality: %s\n", signal[quality]);
+       return 0;
+}
+
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int ft1000_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ft1000ReadProc, PDE_DATA(inode));
 }
 
+static const struct file_operations ft1000_proc_fops = {
+       .open           = ft1000_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static int
 ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr)
 {
@@ -186,9 +175,9 @@ ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr)
        switch (event) {
        case NETDEV_CHANGENAME:
                remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
-               ft1000_proc_file = create_proc_read_entry(dev->name, 0644,
-                                       info->ft1000_proc_dir,
-                                       ft1000ReadProc, dev);
+               ft1000_proc_file =
+                       proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
+                                        &ft1000_proc_fops, dev);
                snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
                break;
        }
@@ -217,10 +206,10 @@ int ft1000_init_proc(struct net_device *dev)
        }
 
        ft1000_proc_file =
-               create_proc_read_entry(dev->name, 0644,
-                       info->ft1000_proc_dir, ft1000ReadProc, dev);
+               proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
+                                &ft1000_proc_fops, dev);
 
-       if (ft1000_proc_file == NULL) {
+       if (!ft1000_proc_file) {
                printk(KERN_WARNING "Unable to create /proc entry.\n");
                goto fail_entry;
        }
index 4b3a019409b5793632efa538cdcf65e0030f217f..b028b0d1317b8c4d89967c64bd5d5e20cdfa9f35 100644 (file)
@@ -483,17 +483,6 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
                goto err_out;
        }
 
-       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
-                       IPU_IRQ_EOF);
-       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
-                       "imx_drm", ipu_crtc);
-       if (ret < 0) {
-               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-               goto err_out;
-       }
-
-       disable_irq(ipu_crtc->irq);
-
        return 0;
 err_out:
        ipu_put_resources(ipu_crtc);
@@ -504,6 +493,7 @@ err_out:
 static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                struct ipu_client_platformdata *pdata)
 {
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
        int ret;
 
        ret = ipu_get_resources(ipu_crtc, pdata);
@@ -522,6 +512,17 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                goto err_put_resources;
        }
 
+       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
+                       IPU_IRQ_EOF);
+       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+                       "imx_drm", ipu_crtc);
+       if (ret < 0) {
+               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+               goto err_put_resources;
+       }
+
+       disable_irq(ipu_crtc->irq);
+
        return 0;
 
 err_put_resources:
index 083b20e6253e3cc446c39f2c464d267553971e46..48e1005349dac8e40a0066f942c5738c6ff8466c 100644 (file)
@@ -229,26 +229,18 @@ void usb_stor_report_bus_reset(struct us_data *us)
 
 /* we use this macro to help us write into the buffer */
 #undef SPRINTF
-#define SPRINTF(args...) \
-       do { \
-               if (pos < buffer+length) \
-                       pos += sprintf(pos, ## args); \
-       } while (0)
+#define SPRINTF(args...) seq_printf(m, ##args)
 
-/*
- * proc_info()
- */
-static int proc_info(struct Scsi_Host *host, char *buffer, char **start,
-                                       off_t offset, int length, int inout)
+static int write_info(struct Scsi_Host *host, char *buffer, int length)
+{
+       return length;
+}
+
+static int show_info(struct seq_file *m, struct Scsi_Host *host)
 {
        struct us_data *us = host_to_us(host);
-       char *pos = buffer;
        const char *string;
 
-       /* pr_info("scsiglue --- proc_info\n"); */
-       if (inout)
-               return length;
-
        /* print the controller name */
        SPRINTF("   Host scsi%d: usb-storage\n", host->host_no);
 
@@ -278,29 +270,17 @@ static int proc_info(struct Scsi_Host *host, char *buffer, char **start,
        SPRINTF("    Transport: %s\n", us->transport_name);
 
        /* show the device flags */
-       if (pos < buffer + length) {
-               pos += sprintf(pos, "       Quirks:");
+       SPRINTF("       Quirks:");
 
 #define US_FLAG(name, value) \
        do { \
                if (us->fflags & value) \
-                       pos += sprintf(pos, " " #name); \
+                       SPRINTF(" " #name); \
        } while (0);
 US_DO_ALL_FLAGS
 #undef US_FLAG
-
-               *(pos++) = '\n';
-       }
-
-       /* Calculate start of next buffer, and return value. */
-       *start = buffer + offset;
-
-       if ((pos - buffer) < offset)
-               return 0;
-       else if ((pos - buffer - offset) < length)
-               return pos - buffer - offset;
-       else
-               return length;
+       seq_putc(m, '\n');
+       return 0;
 }
 
 /***********************************************************************
@@ -351,7 +331,8 @@ struct scsi_host_template usb_stor_host_template = {
        /* basic userland interface stuff */
        .name =                         "eucr-storage",
        .proc_name =                    "eucr-storage",
-       .proc_info =                    proc_info,
+       .write_info =                   write_info,
+       .show_info =                    show_info,
        .info =                         host_info,
 
        /* command interface -- queued only */
index 70ea4145b4c846be5e70188de6a9af66cdf8fad0..edacc8001640b5f3494c4b727eb965debeeba2dd 100644 (file)
@@ -372,7 +372,6 @@ typedef struct r8180_priv
        struct Stats stats;
        struct _link_detect_t link_detect;  //YJ,add,080828
        struct iw_statistics wstats;
-       struct proc_dir_entry *dir_dev;
 
        /*RX stuff*/
        u32 *rxring;
index d10d75e8a33fc6775b8901297a6c9de397b064ce..f7c1d9905ec6d6a0d5b6545e01683095e1735516 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/syscalls.h>
 #include <linux/eeprom_93cx6.h>
 #include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include "r8180_hw.h"
 #include "r8180.h"
@@ -204,51 +206,35 @@ void rtl8180_start_tx_beacon(struct net_device *dev);
 
 static struct proc_dir_entry *rtl8180_proc;
 
-static int proc_get_registers(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_registers(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
-       int len = 0;
-       int i, n;
-       int max = 0xff;
+       struct net_device *dev = m->private;
+       int i, n, max = 0xff;
 
        /* This dump the current register page */
        for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
+               seq_printf(m, "\nD:  %2x > ", n);
 
                for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len, "%2x ",
-                                       read_nic_byte(dev, n));
+                       seq_printf(m, "%2x ", read_nic_byte(dev, n));
        }
-       len += snprintf(page + len, count - len, "\n");
-
-       *eof = 1;
-       return len;
+       seq_putc(m, '\n');
+       return 0;
 }
 
 int get_curr_tx_free_desc(struct net_device *dev, int priority);
 
-static int proc_get_stats_hw(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_stats_hw(struct seq_file *m, void *v)
 {
-       int len = 0;
-
-       *eof = 1;
-       return len;
+       return 0;
 }
 
-static int proc_get_stats_rx(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_stats_rx(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
+       struct net_device *dev = m->private;
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
-       int len = 0;
-
-       len += snprintf(page + len, count - len,
+       seq_printf(m,
                "RX OK: %lu\n"
                "RX Retry: %lu\n"
                "RX CRC Error(0-500): %lu\n"
@@ -263,22 +249,17 @@ static int proc_get_stats_rx(char *page, char **start,
                priv->stats.rxicverr
                );
 
-       *eof = 1;
-       return len;
+       return 0;
 }
 
-static int proc_get_stats_tx(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_stats_tx(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
+       struct net_device *dev = m->private;
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-       int len = 0;
        unsigned long totalOK;
 
        totalOK = priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint;
-       len += snprintf(page + len, count - len,
+       seq_printf(m,
                "TX OK: %lu\n"
                "TX Error: %lu\n"
                "TX Retry: %lu\n"
@@ -291,8 +272,7 @@ static int proc_get_stats_tx(char *page, char **start,
                priv->stats.txbeaconerr
        );
 
-       *eof = 1;
-       return len;
+       return 0;
 }
 
 void rtl8180_proc_module_init(void)
@@ -308,59 +288,61 @@ void rtl8180_proc_module_remove(void)
 
 void rtl8180_proc_remove_one(struct net_device *dev)
 {
-       struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-       if (priv->dir_dev) {
-               remove_proc_entry("stats-hw", priv->dir_dev);
-               remove_proc_entry("stats-tx", priv->dir_dev);
-               remove_proc_entry("stats-rx", priv->dir_dev);
-               remove_proc_entry("registers", priv->dir_dev);
-               priv->dir_dev = NULL;
-       }
+       remove_proc_subtree(dev->name, rtl8180_proc);
 }
 
-void rtl8180_proc_init_one(struct net_device *dev)
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int rtl8180_proc_open(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *e;
-       struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+       struct net_device *dev = proc_get_parent_data(inode);
+       int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
 
-       priv->dir_dev = rtl8180_proc;
-       if (!priv->dir_dev) {
-               DMESGE("Unable to initialize /proc/net/r8180/%s\n",
-                     dev->name);
-               return;
-       }
+       return single_open(file, show, dev);
+}
 
-       e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_hw, dev);
-       if (!e) {
-               DMESGE("Unable to initialize "
-                     "/proc/net/r8180/%s/stats-hw\n",
-                     dev->name);
-       }
+static const struct file_operations rtl8180_proc_fops = {
+       .open           = rtl8180_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-       e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_rx, dev);
-       if (!e) {
-               DMESGE("Unable to initialize "
-                     "/proc/net/r8180/%s/stats-rx\n",
-                     dev->name);
-       }
+/*
+ * Table of proc files we need to create.
+ */
+struct rtl8180_proc_file {
+       char name[12];
+       int (*show)(struct seq_file *, void *);
+};
 
+static const struct rtl8180_proc_file rtl8180_proc_files[] = {
+       { "stats-hw",   &proc_get_stats_hw },
+       { "stats-rx",   &proc_get_stats_rx },
+       { "stats-tx",   &proc_get_stats_tx },
+       { "registers",  &proc_get_registers },
+       { "" }
+};
+
+void rtl8180_proc_init_one(struct net_device *dev)
+{
+       const struct rtl8180_proc_file *f;
+       struct proc_dir_entry *dir;
 
-       e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_tx, dev);
-       if (!e) {
-               DMESGE("Unable to initialize "
-                     "/proc/net/r8180/%s/stats-tx\n",
-                     dev->name);
+       dir = proc_mkdir_data(dev->name, 0, rtl8180_proc, dev);
+       if (!dir) {
+               DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name);
+               return;
        }
 
-       e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers, dev);
-       if (!e) {
-               DMESGE("Unable to initialize "
-                     "/proc/net/r8180/%s/registers\n",
-                     dev->name);
+       for (f = rtl8180_proc_files; f->name[0]; f++) {
+               if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
+                                     &rtl8180_proc_fops, f->show)) {
+                       DMESGE("Unable to initialize /proc/net/r8180/%s/%s\n",
+                              dev->name, f->name);
+                       return;
+               }
        }
 }
 
index 313a92ec683395e4608683e8ef7a57f07f887497..a2c4fb4ba1af9e2dd5c6d030285cc95d9dcb79c2 100644 (file)
@@ -7,7 +7,6 @@ r8192e_pci-objs :=              \
        r8190P_rtl8256.o        \
        rtl_cam.o               \
        rtl_core.o              \
-       rtl_debug.o             \
        rtl_dm.o                \
        rtl_eeprom.o            \
        rtl_ethtool.o           \
index 4ebf99b3097543b07cad50a264e700d70b926e27..2b6c61c5d3d8b2ad1108f0da8836ecff42f0d10c 100644 (file)
@@ -2966,8 +2966,6 @@ static int rtl8192_pci_probe(struct pci_dev *pdev,
                goto err_free_irq;
        RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name);
 
-       rtl8192_proc_init_one(dev);
-
        if (priv->polling_timer_on == 0)
                check_rfctrl_gpio_timer((unsigned long)dev);
 
@@ -3003,7 +3001,6 @@ static void rtl8192_pci_disconnect(struct pci_dev *pdev)
                del_timer_sync(&priv->gpio_polling_timer);
                cancel_delayed_work(&priv->gpio_change_rf_wq);
                priv->polling_timer_on = 0;
-               rtl8192_proc_remove_one(dev);
                rtl8192_down(dev, true);
                deinit_hal_dm(dev);
                if (priv->pFirmware) {
@@ -3093,7 +3090,6 @@ static int __init rtl8192_pci_module_init(void)
        printk(KERN_INFO "\nLinux kernel driver for RTL8192E WLAN cards\n");
        printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan Driver\n");
 
-       rtl8192_proc_module_init();
        if (0 != pci_register_driver(&rtl8192_pci_driver)) {
                DMESG("No device found");
                /*pci_unregister_driver (&rtl8192_pci_driver);*/
@@ -3107,7 +3103,6 @@ static void __exit rtl8192_pci_module_exit(void)
        pci_unregister_driver(&rtl8192_pci_driver);
 
        RT_TRACE(COMP_DOWN, "Exiting");
-       rtl8192_proc_module_remove();
 }
 
 void check_rfctrl_gpio_timer(unsigned long data)
index 320d5fc026b4215579fb94d974aa08c24028fc34..87d4d349c8905b447574c1564ed09679e45b5a66 100644 (file)
@@ -1085,10 +1085,4 @@ void ActUpdateChannelAccessSetting(struct net_device *dev,
                           enum wireless_mode WirelessMode,
                           struct channel_access_setting *ChnlAccessSetting);
 
-/* proc stuff from rtl_debug.c */
-void rtl8192_proc_init_one(struct net_device *dev);
-void rtl8192_proc_remove_one(struct net_device *dev);
-void rtl8192_proc_module_init(void);
-void rtl8192_proc_module_remove(void);
-
 #endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c b/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c
deleted file mode 100644 (file)
index c19b14c..0000000
+++ /dev/null
@@ -1,1029 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "rtl_core.h"
-#include "r8192E_phy.h"
-#include "r8192E_phyreg.h"
-#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
-#include "r8192E_cmdpkt.h"
-
-/****************************************************************************
-   -----------------------------PROCFS STUFF-------------------------
-*****************************************************************************/
-/*This part is related to PROC, which will record some statistics. */
-static struct proc_dir_entry *rtl8192_proc;
-
-static int proc_get_stats_ap(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-       struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-       struct rtllib_device *ieee = priv->rtllib;
-       struct rtllib_network *target;
-       int len = 0;
-
-       list_for_each_entry(target, &ieee->network_list, list) {
-
-               len += snprintf(page + len, count - len,
-                               "%s ", target->ssid);
-
-               if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
-                       len += snprintf(page + len, count - len,
-                                       "WPA\n");
-               else
-                       len += snprintf(page + len, count - len,
-                                       "non_WPA\n");
-
-       }
-
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_registers_0(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x000;
-
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0>>8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B "
-                       "0C 0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; n++, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_1(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x100;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0>>8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B "
-                       "0C 0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_2(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x200;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0 >> 8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C "
-                       "0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_3(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x300;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0>>8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B "
-                       "0C 0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_4(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x400;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0>>8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B "
-                       "0C 0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_5(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x500;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0 >> 8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B "
-                       "0C 0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_6(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x600;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0>>8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B "
-                       "0C 0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_7(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x700;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n ",
-                       (page0 >> 8));
-       len += snprintf(page + len, count - len,
-                       "\nD:  OF > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C "
-                       "0D 0E 0F");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ", n);
-               for (i = 0; i < 16 && n <= max; i++, n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2.2x ", read_nic_byte(dev,
-                                       (page0 | n)));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_8(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x800;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0 >> 8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-
-}
-static int proc_get_registers_9(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0x900;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0>>8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-static int proc_get_registers_a(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0xa00;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0>>8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-static int proc_get_registers_b(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0xb00;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0 >> 8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-static int proc_get_registers_c(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0xc00;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0>>8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-static int proc_get_registers_d(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0xd00;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0>>8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-static int proc_get_registers_e(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n, page0;
-
-       int max = 0xff;
-       page0 = 0xe00;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page %x##################\n",
-                       (page0>>8));
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_QueryBBReg(dev,
-                                       (page0 | n), bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_reg_rf_a(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n;
-
-       int max = 0xff;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### RF-A ##################\n ");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_phy_QueryRFReg(dev,
-                                       (enum rf90_radio_path)RF90_PATH_A, n,
-                                       bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_reg_rf_b(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n;
-
-       int max = 0xff;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### RF-B ##################\n ");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_phy_QueryRFReg(dev,
-                                       (enum rf90_radio_path)RF90_PATH_B, n,
-                                       bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_reg_rf_c(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n;
-
-       int max = 0xff;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### RF-C ##################\n");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_phy_QueryRFReg(dev,
-                                       (enum rf90_radio_path)RF90_PATH_C, n,
-                                       bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_reg_rf_d(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-
-       int len = 0;
-       int i, n;
-
-       int max = 0xff;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### RF-D ##################\n ");
-       for (n = 0; n <= max;) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
-               for (i = 0; i < 4 && n <= max; n += 4, i++)
-                       len += snprintf(page + len, count - len,
-                                       "%8.8x ", rtl8192_phy_QueryRFReg(dev,
-                                       (enum rf90_radio_path)RF90_PATH_D, n,
-                                       bMaskDWord));
-       }
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_cam_register_1(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-       u32 target_command = 0;
-       u32 target_content = 0;
-       u8 entry_i = 0;
-       u32 ulStatus;
-       int len = 0;
-       int i = 100, j = 0;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### SECURITY CAM (0-10) ######"
-                       "############\n ");
-       for (j = 0; j < 11; j++) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", j);
-               for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
-                       target_command = entry_i+CAM_CONTENT_COUNT*j;
-                       target_command = target_command | BIT31;
-
-                       while ((i--) >= 0) {
-                               ulStatus = read_nic_dword(dev, RWCAM);
-                               if (ulStatus & BIT31)
-                                       continue;
-                               else
-                                       break;
-                       }
-                       write_nic_dword(dev, RWCAM, target_command);
-                       target_content = read_nic_dword(dev, RCAMO);
-                       len += snprintf(page + len, count - len, "%8.8x ",
-                                       target_content);
-               }
-       }
-
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_cam_register_2(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-       u32 target_command = 0;
-       u32 target_content = 0;
-       u8 entry_i = 0;
-       u32 ulStatus;
-       int len = 0;
-       int i = 100, j = 0;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### SECURITY CAM (11-21) "
-                       "##################\n ");
-       for (j = 11; j < 22; j++) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", j);
-               for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
-                       target_command = entry_i + CAM_CONTENT_COUNT * j;
-                       target_command = target_command | BIT31;
-
-                       while ((i--) >= 0) {
-                               ulStatus = read_nic_dword(dev, RWCAM);
-                               if (ulStatus & BIT31)
-                                       continue;
-                               else
-                                       break;
-                       }
-                       write_nic_dword(dev, RWCAM, target_command);
-                       target_content = read_nic_dword(dev, RCAMO);
-                       len += snprintf(page + len, count - len, "%8.8x ",
-                                       target_content);
-               }
-       }
-
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-
-static int proc_get_cam_register_3(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-       u32 target_command = 0;
-       u32 target_content = 0;
-       u8 entry_i = 0;
-       u32 ulStatus;
-       int len = 0;
-       int i = 100, j = 0;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n#################### SECURITY CAM (22-31) ######"
-                       "############\n ");
-       for (j = 22; j < TOTAL_CAM_ENTRY; j++) {
-               len += snprintf(page + len, count - len, "\nD:  %2x > ", j);
-               for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
-                       target_command = entry_i + CAM_CONTENT_COUNT * j;
-                       target_command = target_command | BIT31;
-
-                       while ((i--) >= 0) {
-                               ulStatus = read_nic_dword(dev, RWCAM);
-                               if (ulStatus & BIT31)
-                                       continue;
-                               else
-                                       break;
-                       }
-                       write_nic_dword(dev, RWCAM, target_command);
-                       target_content = read_nic_dword(dev, RCAMO);
-                       len += snprintf(page + len, count - len, "%8.8x ",
-                                       target_content);
-               }
-       }
-
-       len += snprintf(page + len, count - len, "\n");
-       *eof = 1;
-       return len;
-}
-static int proc_get_stats_tx(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-       struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
-       int len = 0;
-
-       len += snprintf(page + len, count - len,
-               "TX VI priority ok int: %lu\n"
-               "TX VO priority ok int: %lu\n"
-               "TX BE priority ok int: %lu\n"
-               "TX BK priority ok int: %lu\n"
-               "TX MANAGE priority ok int: %lu\n"
-               "TX BEACON priority ok int: %lu\n"
-               "TX BEACON priority error int: %lu\n"
-               "TX CMDPKT priority ok int: %lu\n"
-               "TX queue stopped?: %d\n"
-               "TX fifo overflow: %lu\n"
-               "TX total data packets %lu\n"
-               "TX total data bytes :%lu\n",
-               priv->stats.txviokint,
-               priv->stats.txvookint,
-               priv->stats.txbeokint,
-               priv->stats.txbkokint,
-               priv->stats.txmanageokint,
-               priv->stats.txbeaconokint,
-               priv->stats.txbeaconerr,
-               priv->stats.txcmdpktokint,
-               netif_queue_stopped(dev),
-               priv->stats.txoverflow,
-               priv->rtllib->stats.tx_packets,
-               priv->rtllib->stats.tx_bytes
-
-
-               );
-
-       *eof = 1;
-       return len;
-}
-
-
-
-static int proc_get_stats_rx(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
-{
-       struct net_device *dev = data;
-       struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
-       int len = 0;
-
-       len += snprintf(page + len, count - len,
-               "RX packets: %lu\n"
-               "RX data crc err: %lu\n"
-               "RX mgmt crc err: %lu\n"
-               "RX desc err: %lu\n"
-               "RX rx overflow error: %lu\n",
-               priv->stats.rxint,
-               priv->stats.rxdatacrcerr,
-               priv->stats.rxmgmtcrcerr,
-               priv->stats.rxrdu,
-               priv->stats.rxoverflow);
-
-       *eof = 1;
-       return len;
-}
-
-void rtl8192_proc_module_init(void)
-{
-       RT_TRACE(COMP_INIT, "Initializing proc filesystem");
-       rtl8192_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
-}
-
-
-void rtl8192_proc_module_remove(void)
-{
-       remove_proc_entry(DRV_NAME, init_net.proc_net);
-}
-
-
-void rtl8192_proc_remove_one(struct net_device *dev)
-{
-       struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
-       printk(KERN_INFO "dev name %s\n", dev->name);
-
-       if (priv->dir_dev) {
-               remove_proc_entry("stats-tx", priv->dir_dev);
-               remove_proc_entry("stats-rx", priv->dir_dev);
-               remove_proc_entry("stats-ap", priv->dir_dev);
-               remove_proc_entry("registers-0", priv->dir_dev);
-               remove_proc_entry("registers-1", priv->dir_dev);
-               remove_proc_entry("registers-2", priv->dir_dev);
-               remove_proc_entry("registers-3", priv->dir_dev);
-               remove_proc_entry("registers-4", priv->dir_dev);
-               remove_proc_entry("registers-5", priv->dir_dev);
-               remove_proc_entry("registers-6", priv->dir_dev);
-               remove_proc_entry("registers-7", priv->dir_dev);
-               remove_proc_entry("registers-8", priv->dir_dev);
-               remove_proc_entry("registers-9", priv->dir_dev);
-               remove_proc_entry("registers-a", priv->dir_dev);
-               remove_proc_entry("registers-b", priv->dir_dev);
-               remove_proc_entry("registers-c", priv->dir_dev);
-               remove_proc_entry("registers-d", priv->dir_dev);
-               remove_proc_entry("registers-e", priv->dir_dev);
-               remove_proc_entry("RF-A", priv->dir_dev);
-               remove_proc_entry("RF-B", priv->dir_dev);
-               remove_proc_entry("RF-C", priv->dir_dev);
-               remove_proc_entry("RF-D", priv->dir_dev);
-               remove_proc_entry("SEC-CAM-1", priv->dir_dev);
-               remove_proc_entry("SEC-CAM-2", priv->dir_dev);
-               remove_proc_entry("SEC-CAM-3", priv->dir_dev);
-               remove_proc_entry("wlan0", rtl8192_proc);
-               priv->dir_dev = NULL;
-       }
-}
-
-
-void rtl8192_proc_init_one(struct net_device *dev)
-{
-       struct proc_dir_entry *e;
-       struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
-
-       priv->dir_dev = create_proc_entry(dev->name,
-                                         S_IFDIR | S_IRUGO | S_IXUGO,
-                                         rtl8192_proc);
-       if (!priv->dir_dev) {
-               RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192"
-                        "/%s\n", dev->name);
-               return;
-       }
-       e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_rx, dev);
-
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/stats-rx\n",
-                     dev->name);
-
-       e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_tx, dev);
-
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/stats-tx\n",
-                     dev->name);
-
-       e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_ap, dev);
-
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/stats-ap\n",
-                     dev->name);
-
-       e = create_proc_read_entry("registers-0", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_0, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-0\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_1, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-1\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_2, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-2\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-3", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_3, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-3\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-4", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_4, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-4\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-5", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_5, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-5\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-6", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_6, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-6\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-7", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_7, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-7\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_8, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-8\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_9, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-9\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_a, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-a\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_b, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-b\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_c, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-c\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_d, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-d\n",
-                     dev->name);
-       e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers_e, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers-e\n",
-                     dev->name);
-       e = create_proc_read_entry("RF-A", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_reg_rf_a, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/RF-A\n",
-                     dev->name);
-       e = create_proc_read_entry("RF-B", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_reg_rf_b, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/RF-B\n",
-                     dev->name);
-       e = create_proc_read_entry("RF-C", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_reg_rf_c, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/RF-C\n",
-                     dev->name);
-       e = create_proc_read_entry("RF-D", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_reg_rf_d, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/RF-D\n",
-                     dev->name);
-       e = create_proc_read_entry("SEC-CAM-1", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_cam_register_1, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/SEC-CAM-1\n",
-                     dev->name);
-       e = create_proc_read_entry("SEC-CAM-2", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_cam_register_2, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/SEC-CAM-2\n",
-                     dev->name);
-       e = create_proc_read_entry("SEC-CAM-3", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_cam_register_3, dev);
-       if (!e)
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/SEC-CAM-3\n",
-                     dev->name);
-}
index 4217b88e6fc3e211d82000eefa9a98baa95f2dca..e51cb49ce10edef2f0f8b35e87bf1b9a0ee3e969 100644 (file)
@@ -412,19 +412,18 @@ static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
 }
 
 
-static char *rtllib_ccmp_print_stats(char *p, void *priv)
+static void rtllib_ccmp_print_stats(struct seq_file *m, void *priv)
 {
        struct rtllib_ccmp_data *ccmp = priv;
-       p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-                    "tx_pn=%pM rx_pn=%pM "
-                    "format_errors=%d replays=%d decrypt_errors=%d\n",
-                    ccmp->key_idx, ccmp->key_set,
-                    ccmp->tx_pn, ccmp->rx_pn,
-                    ccmp->dot11RSNAStatsCCMPFormatErrors,
-                    ccmp->dot11RSNAStatsCCMPReplays,
-                    ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
-       return p;
+       seq_printf(m,
+                  "key[%d] alg=CCMP key_set=%d "
+                  "tx_pn=%pM rx_pn=%pM "
+                  "format_errors=%d replays=%d decrypt_errors=%d\n",
+                  ccmp->key_idx, ccmp->key_set,
+                  ccmp->tx_pn, ccmp->rx_pn,
+                  ccmp->dot11RSNAStatsCCMPFormatErrors,
+                  ccmp->dot11RSNAStatsCCMPReplays,
+                  ccmp->dot11RSNAStatsCCMPDecryptErrors);
 }
 
 static struct lib80211_crypto_ops rtllib_crypt_ccmp = {
index 800925053fb0df48e50a17e97cc32b593e9c6e8d..5cfd73baf1cc489325054afdaaa92b6f2c0192a7 100644 (file)
@@ -708,30 +708,30 @@ static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv)
 }
 
 
-static char *rtllib_tkip_print_stats(char *p, void *priv)
+static void rtllib_tkip_print_stats(struct seq_file *m, void *priv)
 {
        struct rtllib_tkip_data *tkip = priv;
-       p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
-                    "tx_pn=%02x%02x%02x%02x%02x%02x "
-                    "rx_pn=%02x%02x%02x%02x%02x%02x "
-                    "replays=%d icv_errors=%d local_mic_failures=%d\n",
-                    tkip->key_idx, tkip->key_set,
-                    (tkip->tx_iv32 >> 24) & 0xff,
-                    (tkip->tx_iv32 >> 16) & 0xff,
-                    (tkip->tx_iv32 >> 8) & 0xff,
-                    tkip->tx_iv32 & 0xff,
-                    (tkip->tx_iv16 >> 8) & 0xff,
-                    tkip->tx_iv16 & 0xff,
-                    (tkip->rx_iv32 >> 24) & 0xff,
-                    (tkip->rx_iv32 >> 16) & 0xff,
-                    (tkip->rx_iv32 >> 8) & 0xff,
-                    tkip->rx_iv32 & 0xff,
-                    (tkip->rx_iv16 >> 8) & 0xff,
-                    tkip->rx_iv16 & 0xff,
-                    tkip->dot11RSNAStatsTKIPReplays,
-                    tkip->dot11RSNAStatsTKIPICVErrors,
-                    tkip->dot11RSNAStatsTKIPLocalMICFailures);
-       return p;
+       seq_printf(m,
+                  "key[%d] alg=TKIP key_set=%d "
+                  "tx_pn=%02x%02x%02x%02x%02x%02x "
+                  "rx_pn=%02x%02x%02x%02x%02x%02x "
+                  "replays=%d icv_errors=%d local_mic_failures=%d\n",
+                  tkip->key_idx, tkip->key_set,
+                  (tkip->tx_iv32 >> 24) & 0xff,
+                  (tkip->tx_iv32 >> 16) & 0xff,
+                  (tkip->tx_iv32 >> 8) & 0xff,
+                  tkip->tx_iv32 & 0xff,
+                  (tkip->tx_iv16 >> 8) & 0xff,
+                  tkip->tx_iv16 & 0xff,
+                  (tkip->rx_iv32 >> 24) & 0xff,
+                  (tkip->rx_iv32 >> 16) & 0xff,
+                  (tkip->rx_iv32 >> 8) & 0xff,
+                  tkip->rx_iv32 & 0xff,
+                  (tkip->rx_iv16 >> 8) & 0xff,
+                  tkip->rx_iv16 & 0xff,
+                  tkip->dot11RSNAStatsTKIPReplays,
+                  tkip->dot11RSNAStatsTKIPICVErrors,
+                  tkip->dot11RSNAStatsTKIPLocalMICFailures);
 }
 
 static struct lib80211_crypto_ops rtllib_crypt_tkip = {
index 8cdf38913a330717444248fee3841b018a8fb491..c4df6e01ef7401692db11509ea6abf162269efa7 100644 (file)
@@ -247,12 +247,10 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
 }
 
 
-static char *prism2_wep_print_stats(char *p, void *priv)
+static void prism2_wep_print_stats(struct seq_file *m, void *priv)
 {
        struct prism2_wep_data *wep = priv;
-       p += sprintf(p, "key[%d] alg=WEP len=%d\n",
-                    wep->key_idx, wep->key_len);
-       return p;
+       seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
 }
 
 static struct lib80211_crypto_ops rtllib_crypt_wep = {
index f9dae958a5d437f6a51e6d826be5552826646b5d..84ea721d5d8e09d5e86fca6555fe6497aaabbb83 100644 (file)
@@ -208,61 +208,51 @@ static int debug = \
                            ;
 static struct proc_dir_entry *rtllib_proc;
 
-static int show_debug_level(char *page, char **start, off_t offset,
-                           int count, int *eof, void *data)
+static int show_debug_level(struct seq_file *m, void *v)
 {
-       return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
+       return seq_printf(m, "0x%08X\n", rtllib_debug_level);
 }
 
-static int store_debug_level(struct file *file, const char __user *buffer,
-                            unsigned long count, void *data)
+static ssize_t write_debug_level(struct file *file, const char __user *buffer,
+                            size_t count, loff_t *ppos)
 {
-       char buf[] = "0x00000000";
-       unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
-       char *p = (char *)buf;
        unsigned long val;
+       int err = kstrtoul_from_user(buffer, count, 0, &val);
+       if (err)
+               return err;
+       rtllib_debug_level = val;
+       return count;
+}
 
-       if (copy_from_user(buf, buffer, len))
-               return count;
-       buf[len] = 0;
-       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
-               p++;
-               if (p[0] == 'x' || p[0] == 'X')
-                       p++;
-               val = simple_strtoul(p, &p, 16);
-       } else
-               val = simple_strtoul(p, &p, 10);
-       if (p == buf)
-               printk(KERN_INFO DRV_NAME
-                      ": %s is not in hex or decimal form.\n", buf);
-       else
-               rtllib_debug_level = val;
-
-       return strnlen(buf, count);
+static int open_debug_level(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_debug_level, NULL);
 }
 
+static const struct file_operations fops = {
+       .open = open_debug_level,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .write = write_debug_level
+};
+
 int __init rtllib_init(void)
 {
        struct proc_dir_entry *e;
 
        rtllib_debug_level = debug;
-       rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
+       rtllib_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
        if (rtllib_proc == NULL) {
                RTLLIB_ERROR("Unable to create " DRV_NAME
                                " proc directory\n");
                return -EIO;
        }
-       e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
-                             rtllib_proc);
+       e = proc_create("debug_level", S_IRUGO | S_IWUSR, rtllib_proc, &fops);
        if (!e) {
                remove_proc_entry(DRV_NAME, init_net.proc_net);
                rtllib_proc = NULL;
                return -EIO;
        }
-       e->read_proc = show_debug_level;
-       e->write_proc = store_debug_level;
-       e->data = NULL;
-
        return 0;
 }
 
index 76c56e5aed79cda4e648831b71ea81590da41482..e0870c05a5e016400c003614f5cab7813780a6d5 100644 (file)
@@ -243,39 +243,34 @@ static int debug = \
                            ;
 struct proc_dir_entry *ieee80211_proc;
 
-static int show_debug_level(char *page, char **start, off_t offset,
-                           int count, int *eof, void *data)
+static int show_debug_level(struct seq_file *m, void *v)
 {
-       return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
+       return seq_printf(m, "0x%08X\n", ieee80211_debug_level);
 }
 
-static int store_debug_level(struct file *file, const char *buffer,
-                            unsigned long count, void *data)
+static ssize_t write_debug_level(struct file *file, const char __user *buffer,
+                            size_t count, loff_t *ppos)
 {
-       char buf[] = "0x00000000";
-       unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
-       char *p = (char *)buf;
        unsigned long val;
+       int err = kstrtoul_from_user(buffer, count, 0, &val);
+       if (err)
+               return err;
+       ieee80211_debug_level = val;
+       return count;
+}
 
-       if (copy_from_user(buf, buffer, len))
-               return count;
-       buf[len] = 0;
-       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
-               p++;
-               if (p[0] == 'x' || p[0] == 'X')
-                       p++;
-               val = simple_strtoul(p, &p, 16);
-       } else
-               val = simple_strtoul(p, &p, 10);
-       if (p == buf)
-               printk(KERN_INFO DRV_NAME
-                      ": %s is not in hex or decimal form.\n", buf);
-       else
-               ieee80211_debug_level = val;
-
-       return strnlen(buf, count);
+static int open_debug_level(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_debug_level, NULL);
 }
 
+static const struct file_operations fops = {
+       .open = open_debug_level,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .write = write_debug_level
+};
+
 int __init ieee80211_debug_init(void)
 {
        struct proc_dir_entry *e;
@@ -288,17 +283,13 @@ int __init ieee80211_debug_init(void)
                                " proc directory\n");
                return -EIO;
        }
-       e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
-                             ieee80211_proc);
+       e = proc_create("debug_level", S_IRUGO | S_IWUSR, 
+                             ieee80211_proc, &fops);
        if (!e) {
                remove_proc_entry(DRV_NAME, init_net.proc_net);
                ieee80211_proc = NULL;
                return -EIO;
        }
-       e->read_proc = show_debug_level;
-       e->write_proc = store_debug_level;
-       e->data = NULL;
-
        return 0;
 }
 
index 6eda928e4090559c74d82fb3e2bbd52cb2f970ab..c426dfdd9fddf54587876519046e51a8acca3d2e 100644 (file)
@@ -99,7 +99,7 @@ static int crypto_info_open(struct inode *inode, struct file *file)
        return seq_open(file, &crypto_seq_ops);
 }
 
-static struct file_operations proc_crypto_ops = {
+static const struct file_operations proc_crypto_ops = {
        .open           = crypto_info_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -108,9 +108,5 @@ static struct file_operations proc_crypto_ops = {
 
 void __init crypto_init_proc(void)
 {
-       struct proc_dir_entry *proc;
-
-       proc = create_proc_entry("crypto", 0, NULL);
-       if (proc)
-               proc->proc_fops = &proc_crypto_ops;
+       proc_create("crypto", 0, NULL, &proc_crypto_ops);
 }
index e538e026b512e0e526ee8fb9ac1c25bd8c566a8b..bedeb330ad4f82c7eaa743b35db960a465c008f1 100644 (file)
@@ -946,7 +946,6 @@ typedef struct r8192_priv {
        /*stats*/
        struct Stats stats;
        struct iw_statistics wstats;
-       struct proc_dir_entry *dir_dev;
 
        /*RX stuff*/
 //     u32 *rxring;
index f7de2f6d49a5e7c86ac98bbdfc1961fd8d467164..14592339755618195b04cef0bb45f9c810a29e1f 100644 (file)
@@ -71,6 +71,8 @@ double __extendsfdf2(float a) {return a;}
 //#include "r8192xU_phyreg.h"
 #include <linux/usb.h>
 #include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 // FIXME: check if 2.6.7 is ok
 
 #ifdef CONFIG_RTL8192_PM
@@ -472,103 +474,73 @@ void watch_dog_timer_callback(unsigned long data);
 
 static struct proc_dir_entry *rtl8192_proc;
 
-static int proc_get_stats_ap(char *page, char **start, off_t offset, int count,
-                                                       int *eof, void *data)
+static int proc_get_stats_ap(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
+       struct net_device *dev = m->private;
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee80211;
        struct ieee80211_network *target;
 
-       int len = 0;
-
        list_for_each_entry(target, &ieee->network_list, list) {
-
-               len += snprintf(page + len, count - len, "%s ", target->ssid);
-
+               const char *wpa = "non_WPA";
                if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
-                       len += snprintf(page + len, count - len, "WPA\n");
-               else
-                       len += snprintf(page + len, count - len, "non_WPA\n");
+                       wpa = "WPA";
+
+               seq_printf(m, "%s %s\n", target->ssid, wpa);
        }
 
-       *eof = 1;
-       return len;
+       return 0;
 }
 
-static int proc_get_registers(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_registers(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
-//     struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+       struct net_device *dev = m->private;
+       int i,n, max = 0xff;
 
-       int len = 0;
-       int i,n;
-
-       int max=0xff;
-
-       /* This dump the current register page */
-       len += snprintf(page + len, count - len,
-                       "\n####################page 0##################\n ");
+       seq_puts(m, "\n####################page 0##################\n ");
 
        for (n=0;n<=max;) {
                //printk( "\nD: %2x> ", n);
-               len += snprintf(page + len, count - len,
-                       "\nD:  %2x > ",n);
+               seq_printf(m, "\nD:  %2x > ",n);
 
                for (i=0;i<16 && n<=max;i++,n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2x ",read_nic_byte(dev,0x000|n));
+                       seq_printf(m, "%2x ",read_nic_byte(dev,0x000|n));
 
                //      printk("%2x ",read_nic_byte(dev,n));
        }
-       len += snprintf(page + len, count - len,
-                       "\n####################page 1##################\n ");
+
+       seq_puts(m, "\n####################page 1##################\n ");
        for (n=0;n<=max;) {
                //printk( "\nD: %2x> ", n);
-               len += snprintf(page + len, count - len,
-                               "\nD:  %2x > ",n);
+               seq_printf(m, "\nD:  %2x > ",n);
 
                for (i=0;i<16 && n<=max;i++,n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2x ",read_nic_byte(dev,0x100|n));
+                       seq_printf(m, "%2x ",read_nic_byte(dev,0x100|n));
 
                //      printk("%2x ",read_nic_byte(dev,n));
        }
-       len += snprintf(page + len, count - len,
-                       "\n####################page 3##################\n ");
+
+       seq_puts(m, "\n####################page 3##################\n ");
        for (n=0;n<=max;) {
                //printk( "\nD: %2x> ", n);
-               len += snprintf(page + len, count - len,
-                       "\nD:  %2x > ",n);
+               seq_printf(m, "\nD:  %2x > ",n);
 
                for(i=0;i<16 && n<=max;i++,n++)
-                       len += snprintf(page + len, count - len,
-                                       "%2x ",read_nic_byte(dev,0x300|n));
+                       seq_printf(m, "%2x ",read_nic_byte(dev,0x300|n));
 
                //      printk("%2x ",read_nic_byte(dev,n));
        }
 
-       len += snprintf(page + len, count - len,"\n");
-       *eof = 1;
-       return len;
+       seq_putc(m, '\n');
+       return 0;
 }
 
-
-
-
-
-static int proc_get_stats_tx(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_stats_tx(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
+       struct net_device *dev = m->private;
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 
-       int len = 0;
-
-       len += snprintf(page + len, count - len,
+       seq_printf(m,
                "TX VI priority ok int: %lu\n"
                "TX VI priority error int: %lu\n"
                "TX VO priority ok int: %lu\n"
@@ -629,22 +601,15 @@ static int proc_get_stats_tx(char *page, char **start,
 //             priv->stats.txbeaconerr
                );
 
-       *eof = 1;
-       return len;
+       return 0;
 }
 
-
-
-static int proc_get_stats_rx(char *page, char **start,
-                         off_t offset, int count,
-                         int *eof, void *data)
+static int proc_get_stats_rx(struct seq_file *m, void *v)
 {
-       struct net_device *dev = data;
+       struct net_device *dev = m->private;
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 
-       int len = 0;
-
-       len += snprintf(page + len, count - len,
+       seq_printf(m,
                "RX packets: %lu\n"
                "RX urb status error: %lu\n"
                "RX invalid urb error: %lu\n",
@@ -652,9 +617,9 @@ static int proc_get_stats_rx(char *page, char **start,
                priv->stats.rxstaterr,
                priv->stats.rxurberr);
 
-       *eof = 1;
-       return len;
+       return 0;
 }
+
 void rtl8192_proc_module_init(void)
 {
        RT_TRACE(COMP_INIT, "Initializing proc filesystem");
@@ -667,74 +632,70 @@ void rtl8192_proc_module_remove(void)
        remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
 }
 
-
-void rtl8192_proc_remove_one(struct net_device *dev)
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int rtl8192_proc_open(struct inode *inode, struct file *file)
 {
-       struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+       struct net_device *dev = proc_get_parent_data(inode);
+       int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
 
-
-       if (priv->dir_dev) {
-       //      remove_proc_entry("stats-hw", priv->dir_dev);
-               remove_proc_entry("stats-tx", priv->dir_dev);
-               remove_proc_entry("stats-rx", priv->dir_dev);
-       //      remove_proc_entry("stats-ieee", priv->dir_dev);
-               remove_proc_entry("stats-ap", priv->dir_dev);
-               remove_proc_entry("registers", priv->dir_dev);
-       //      remove_proc_entry("cck-registers",priv->dir_dev);
-       //      remove_proc_entry("ofdm-registers",priv->dir_dev);
-               //remove_proc_entry(dev->name, rtl8192_proc);
-               remove_proc_entry("wlan0", rtl8192_proc);
-               priv->dir_dev = NULL;
-       }
+       return single_open(file, show, dev);
 }
 
+static const struct file_operations rtl8192_proc_fops = {
+       .open           = rtl8192_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
-void rtl8192_proc_init_one(struct net_device *dev)
-{
-       struct proc_dir_entry *e;
-       struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-       priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc);
-       if (!priv->dir_dev) {
-               RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
-                     dev->name);
-               return;
-       }
-       e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_rx, dev);
-
-       if (!e) {
-               RT_TRACE(COMP_ERR,"Unable to initialize "
-                     "/proc/net/rtl8192/%s/stats-rx\n",
-                     dev->name);
-       }
-
+/*
+ * Table of proc files we need to create.
+ */
+struct rtl8192_proc_file {
+       char name[12];
+       int (*show)(struct seq_file *, void *);
+};
 
-       e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_tx, dev);
+static const struct rtl8192_proc_file rtl8192_proc_files[] = {
+       { "stats-rx",   &proc_get_stats_rx },
+       { "stats-tx",   &proc_get_stats_tx },
+       { "stats-ap",   &proc_get_stats_ap },
+       { "registers",  &proc_get_registers },
+       { "" }
+};
 
-       if (!e) {
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/stats-tx\n",
-                     dev->name);
-       }
+void rtl8192_proc_init_one(struct net_device *dev)
+{
+       const struct rtl8192_proc_file *f;
+       struct proc_dir_entry *dir;
 
-       e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_stats_ap, dev);
+       if (rtl8192_proc) {
+               dir = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev);
+               if (!dir) {
+                       RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
+                                dev->name);
+                       return;
+               }
 
-       if (!e) {
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/stats-ap\n",
-                     dev->name);
+               for (f = rtl8192_proc_files; f->name[0]; f++) {
+                       if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
+                                             &rtl8192_proc_fops, f->show)) {
+                               RT_TRACE(COMP_ERR, "Unable to initialize "
+                                        "/proc/net/rtl8192/%s/%s\n",
+                                        dev->name, f->name);
+                               return;
+                       }
+               }
        }
+}
 
-       e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
-                                  priv->dir_dev, proc_get_registers, dev);
-       if (!e) {
-               RT_TRACE(COMP_ERR, "Unable to initialize "
-                     "/proc/net/rtl8192/%s/registers\n",
-                     dev->name);
-       }
+void rtl8192_proc_remove_one(struct net_device *dev)
+{
+       remove_proc_subtree(dev->name, rtl8192_proc);
 }
+
 /****************************************************************************
    -----------------------------MISC STUFF-------------------------
 *****************************************************************************/
index 052911c931037a855c634685f4467b395494568f..2ac3fe647ee60ca87da4e8381485876bbb66e266 100644 (file)
@@ -1968,18 +1968,16 @@ int slave_configure(struct scsi_device *sdev)
 
 /* we use this macro to help us write into the buffer */
 #undef SPRINTF
-#define SPRINTF(args...) \
-       do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
+#define SPRINTF(args...) seq_printf(m, ##args)
 
-int proc_info(struct Scsi_Host *host, char *buffer,
-             char **start, off_t offset, int length, int inout)
+static int write_info(struct Scsi_Host *host, char *buffer, int length)
 {
-       char *pos = buffer;
-
        /* if someone is sending us data, just throw it away */
-       if (inout)
-               return length;
+       return length;
+}
 
+static int show_info(struct seq_file *m, struct Scsi_Host *host)
+{
        /* print the controller name */
        SPRINTF("   Host scsi%d: %s\n", host->host_no, RTS51X_NAME);
 
@@ -1988,18 +1986,7 @@ int proc_info(struct Scsi_Host *host, char *buffer,
        SPRINTF("      Product: RTS51xx USB Card Reader\n");
        SPRINTF("      Version: %s\n", DRIVER_VERSION);
        SPRINTF("        Build: %s\n", __TIME__);
-
-       /*
-        * Calculate start of next buffer, and return value.
-        */
-       *start = buffer + offset;
-
-       if ((pos - buffer) < offset)
-               return 0;
-       else if ((pos - buffer - offset) < length)
-               return pos - buffer - offset;
-       else
-               return length;
+       return 0;
 }
 
 /* queue a command */
@@ -2100,7 +2087,8 @@ struct scsi_host_template rts51x_host_template = {
        /* basic userland interface stuff */
        .name = RTS51X_NAME,
        .proc_name = RTS51X_NAME,
-       .proc_info = proc_info,
+       .show_info = show_info,
+       .write_info = write_info,
        .info = rts5139_info,
 
        /* command interface -- queued only */
index cdfe550371cec9cb58c7e91ed1c6ddd494b07bc3..c2446d02d328a6846b5b35395c609f972d027ae4 100644 (file)
@@ -147,8 +147,6 @@ struct scsi_cmnd;
 
 int slave_alloc(struct scsi_device *sdev);
 int slave_configure(struct scsi_device *sdev);
-int proc_info(struct Scsi_Host *host, char *buffer,
-             char **start, off_t offset, int length, int inout);
 int queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int command_abort(struct scsi_cmnd *srb);
 int device_reset(struct scsi_cmnd *srb);
index 80e6d12d156bc46196ba8f631526d6b657faf28c..ca8359481c48953ca5fc3ba40af9f991fc23cda7 100644 (file)
@@ -4,6 +4,3 @@
 
 obj-$(CONFIG_BPCTL) += bpctl_mod.o
 obj-$(CONFIG_SBYPASS) += bypasslib/
-
-
-bpctl_mod-objs := bp_mod.o  bp_proc.o
diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c
deleted file mode 100644 (file)
index a01ca97..0000000
+++ /dev/null
@@ -1,1327 +0,0 @@
-/******************************************************************************/
-/*                                                                            */
-/* Copyright (c) 2004-2006 Silicom, Ltd                                       */
-/* All rights reserved.                                                       */
-/*                                                                            */
-/* This program is free software; you can redistribute it and/or modify       */
-/* it under the terms of the GNU General Public License as published by       */
-/* the Free Software Foundation, located in the file LICENSE.                 */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-
-#if defined(CONFIG_SMP) && !defined(__SMP__)
-#define __SMP__
-#endif
-
-#include <linux/proc_fs.h>
-#include <linux/netdevice.h>
-#include <asm/uaccess.h>
-/* #include <linux/smp_lock.h> */
-#include "bp_mod.h"
-
-#define BP_PROC_DIR "bypass"
-/* #define BYPASS_SUPPORT "bypass" */
-
-#ifdef BYPASS_SUPPORT
-
-#define GPIO6_SET_ENTRY_SD           "gpio6_set"
-#define GPIO6_CLEAR_ENTRY_SD         "gpio6_clear"
-
-#define GPIO7_SET_ENTRY_SD           "gpio7_set"
-#define GPIO7_CLEAR_ENTRY_SD         "gpio7_clear"
-
-#define PULSE_SET_ENTRY_SD            "pulse_set"
-#define ZERO_SET_ENTRY_SD            "zero_set"
-#define PULSE_GET1_ENTRY_SD            "pulse_get1"
-#define PULSE_GET2_ENTRY_SD            "pulse_get2"
-
-#define CMND_ON_ENTRY_SD              "cmnd_on"
-#define CMND_OFF_ENTRY_SD             "cmnd_off"
-#define RESET_CONT_ENTRY_SD           "reset_cont"
-
- /*COMMANDS*/
-#define BYPASS_INFO_ENTRY_SD     "bypass_info"
-#define BYPASS_SLAVE_ENTRY_SD    "bypass_slave"
-#define BYPASS_CAPS_ENTRY_SD     "bypass_caps"
-#define WD_SET_CAPS_ENTRY_SD     "wd_set_caps"
-#define BYPASS_ENTRY_SD          "bypass"
-#define BYPASS_CHANGE_ENTRY_SD   "bypass_change"
-#define BYPASS_WD_ENTRY_SD       "bypass_wd"
-#define WD_EXPIRE_TIME_ENTRY_SD  "wd_expire_time"
-#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd"
-#define DIS_BYPASS_ENTRY_SD      "dis_bypass"
-#define BYPASS_PWUP_ENTRY_SD     "bypass_pwup"
-#define BYPASS_PWOFF_ENTRY_SD     "bypass_pwoff"
-#define STD_NIC_ENTRY_SD         "std_nic"
-#define STD_NIC_ENTRY_SD         "std_nic"
-#define TAP_ENTRY_SD             "tap"
-#define TAP_CHANGE_ENTRY_SD      "tap_change"
-#define DIS_TAP_ENTRY_SD         "dis_tap"
-#define TAP_PWUP_ENTRY_SD        "tap_pwup"
-#define TWO_PORT_LINK_ENTRY_SD   "two_port_link"
-#define WD_EXP_MODE_ENTRY_SD     "wd_exp_mode"
-#define WD_AUTORESET_ENTRY_SD    "wd_autoreset"
-#define TPL_ENTRY_SD             "tpl"
-#define WAIT_AT_PWUP_ENTRY_SD    "wait_at_pwup"
-#define HW_RESET_ENTRY_SD        "hw_reset"
-#define DISC_ENTRY_SD             "disc"
-#define DISC_CHANGE_ENTRY_SD      "disc_change"
-#define DIS_DISC_ENTRY_SD         "dis_disc"
-#define DISC_PWUP_ENTRY_SD        "disc_pwup"
-
-static struct proc_dir_entry *bp_procfs_dir;
-
-static struct proc_dir_entry *proc_getdir(char *name,
-                                         struct proc_dir_entry *proc_dir)
-{
-       struct proc_dir_entry *pde = proc_dir;
-       for (pde = pde->subdir; pde; pde = pde->next) {
-               if (pde->namelen && (strcmp(name, pde->name) == 0)) {
-                       /* directory exists */
-                       break;
-               }
-       }
-       if (pde == (struct proc_dir_entry *)0) {
-               /* create the directory */
-               pde = create_proc_entry(name, S_IFDIR, proc_dir);
-               if (pde == (struct proc_dir_entry *)0)
-                       return pde;
-       }
-       return pde;
-}
-
-int
-bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr,
-                           char *proc_name,
-                           write_proc_t *write_proc,
-                           read_proc_t *read_proc,
-                           struct proc_dir_entry *parent_pfs, void *data)
-{
-       strcpy(pfs_unit_curr->proc_name, proc_name);
-       pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name,
-                                                     S_IFREG | S_IRUSR |
-                                                     S_IWUSR | S_IRGRP |
-                                                     S_IROTH, parent_pfs);
-       if (pfs_unit_curr->proc_entry == 0)
-               return -1;
-
-       pfs_unit_curr->proc_entry->read_proc = read_proc;
-       pfs_unit_curr->proc_entry->write_proc = write_proc;
-       pfs_unit_curr->proc_entry->data = data;
-
-       return 0;
-
-}
-
-int
-get_bypass_info_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-       int len = 0;
-
-       len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->bp_name);
-       len +=
-           sprintf(page + len, "Firmware version\t0x%x\n",
-                   pbp_device_block->bp_fw_ver);
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_bypass_slave_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       struct pci_dev *pci_slave_dev = pbp_device_block->bp_slave;
-       struct net_device *net_slave_dev;
-       int len = 0;
-
-       if (is_bypass_fn(pbp_device_block)) {
-               net_slave_dev = pci_get_drvdata(pci_slave_dev);
-               if (net_slave_dev)
-                       len = sprintf(page, "%s\n", net_slave_dev->name);
-               else
-                       len = sprintf(page, "fail\n");
-       } else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_bypass_caps_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_caps_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "-1\n");
-       else
-               len = sprintf(page, "0x%x\n", ret);
-       *eof = 1;
-       return len;
-
-}
-
-int
-get_wd_set_caps_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_wd_set_caps_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "-1\n");
-       else
-               len = sprintf(page, "0x%x\n", ret);
-       *eof = 1;
-       return len;
-}
-
-int
-set_bypass_pfs(struct file *file, const char *buffer,
-              unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_bypass_fn(pbp_device_block, bypass_param);
-
-       return count;
-}
-
-int
-set_tap_pfs(struct file *file, const char *buffer,
-           unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_tap_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-set_disc_pfs(struct file *file, const char *buffer,
-            unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_disc_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-get_bypass_pfs(char *page, char **start, off_t off, int count,
-              int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_tap_pfs(char *page, char **start, off_t off, int count,
-           int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tap_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_disc_pfs(char *page, char **start, off_t off, int count,
-            int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_disc_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_bypass_change_pfs(char *page, char **start, off_t off, int count,
-                     int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_change_fn(pbp_device_block);
-       if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_tap_change_pfs(char *page, char **start, off_t off, int count,
-                  int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tap_change_fn(pbp_device_block);
-       if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_disc_change_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_disc_change_fn(pbp_device_block);
-       if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-set_bypass_wd_pfs(struct file *file, const char *buffer,
-                 unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       unsigned int timeout = 0;
-       char *timeout_ptr = kbuf;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       timeout_ptr = kbuf;
-       timeout = atoi(&timeout_ptr);
-
-       set_bypass_wd_fn(pbp_device_block, timeout);
-
-       return count;
-}
-
-int
-get_bypass_wd_pfs(char *page, char **start, off_t off, int count,
-                 int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0, timeout = 0;
-
-       ret = get_bypass_wd_fn(pbp_device_block, &timeout);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (timeout == -1)
-               len = sprintf(page, "unknown\n");
-       else if (timeout == 0)
-               len = sprintf(page, "disable\n");
-       else
-               len = sprintf(page, "%d\n", timeout);
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_wd_expire_time_pfs(char *page, char **start, off_t off, int count,
-                      int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0, timeout = 0;
-
-       ret = get_wd_expire_time_fn(pbp_device_block, &timeout);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (timeout == -1)
-               len = sprintf(page, "expire\n");
-       else if (timeout == 0)
-               len = sprintf(page, "disable\n");
-
-       else
-               len = sprintf(page, "%d\n", timeout);
-       *eof = 1;
-       return len;
-}
-
-int
-get_tpl_pfs(char *page, char **start, off_t off, int count,
-           int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tpl_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
-}
-
-#ifdef PMC_FIX_FLAG
-int
-get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bp_wait_at_pwup_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_hw_reset_pfs(char *page, char **start, off_t off, int count,
-                int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bp_hw_reset_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
-}
-
-#endif                         /*PMC_WAIT_FLAG */
-
-int
-reset_bypass_wd_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = reset_bypass_wd_timer_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "disable\n");
-       else if (ret == 1)
-               len = sprintf(page, "success\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-set_dis_bypass_pfs(struct file *file, const char *buffer,
-                  unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_dis_bypass_fn(pbp_device_block, bypass_param);
-
-       return count;
-}
-
-int
-set_dis_tap_pfs(struct file *file, const char *buffer,
-               unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_dis_tap_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-set_dis_disc_pfs(struct file *file, const char *buffer,
-                unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_dis_disc_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-get_dis_bypass_pfs(char *page, char **start, off_t off, int count,
-                  int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_dis_bypass_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_dis_tap_pfs(char *page, char **start, off_t off, int count,
-               int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_dis_tap_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_dis_disc_pfs(char *page, char **start, off_t off, int count,
-                int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_dis_disc_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-set_bypass_pwup_pfs(struct file *file, const char *buffer,
-                   unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_bypass_pwup_fn(pbp_device_block, bypass_param);
-
-       return count;
-}
-
-int
-set_bypass_pwoff_pfs(struct file *file, const char *buffer,
-                    unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_bypass_pwoff_fn(pbp_device_block, bypass_param);
-
-       return count;
-}
-
-int
-set_tap_pwup_pfs(struct file *file, const char *buffer,
-                unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_tap_pwup_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-set_disc_pwup_pfs(struct file *file, const char *buffer,
-                 unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_disc_pwup_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-get_bypass_pwup_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_pwup_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_pwoff_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_tap_pwup_pfs(char *page, char **start, off_t off, int count,
-                int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tap_pwup_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_disc_pwup_pfs(char *page, char **start, off_t off, int count,
-                 int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_disc_pwup_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-set_std_nic_pfs(struct file *file, const char *buffer,
-               unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_std_nic_fn(pbp_device_block, bypass_param);
-
-       return count;
-}
-
-int
-get_std_nic_pfs(char *page, char **start, off_t off, int count,
-               int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_std_nic_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_wd_exp_mode_fn(pbp_device_block);
-       if (ret == 1)
-               len = sprintf(page, "tap\n");
-       else if (ret == 0)
-               len = sprintf(page, "bypass\n");
-       else if (ret == 2)
-               len = sprintf(page, "disc\n");
-
-       else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-set_wd_exp_mode_pfs(struct file *file, const char *buffer,
-                   unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "tap") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "bypass") == 0)
-               bypass_param = 0;
-       else if (strcmp(kbuf, "disc") == 0)
-               bypass_param = 2;
-
-       set_wd_exp_mode_fn(pbp_device_block, bypass_param);
-
-       return count;
-}
-
-int
-get_wd_autoreset_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_wd_autoreset_fn(pbp_device_block);
-       if (ret >= 0)
-               len = sprintf(page, "%d\n", ret);
-       else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-set_wd_autoreset_pfs(struct file *file, const char *buffer,
-                    unsigned long count, void *data)
-{
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-       u32 timeout = 0;
-       char *timeout_ptr = kbuf;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       timeout_ptr = kbuf;
-       timeout = atoi(&timeout_ptr);
-
-       set_wd_autoreset_fn(pbp_device_block, timeout);
-
-       return count;
-}
-
-int
-set_tpl_pfs(struct file *file, const char *buffer,
-           unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tpl_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tpl_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tpl_param = 0;
-
-       set_tpl_fn(pbp_device_block, tpl_param);
-
-       return count;
-}
-
-#ifdef PMC_FIX_FLAG
-int
-set_wait_at_pwup_pfs(struct file *file, const char *buffer,
-                    unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tpl_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tpl_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tpl_param = 0;
-
-       set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param);
-
-       return count;
-}
-
-int
-set_hw_reset_pfs(struct file *file, const char *buffer,
-                unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tpl_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count))
-               return -1;
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tpl_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tpl_param = 0;
-
-       set_bp_hw_reset_fn(pbp_device_block, tpl_param);
-
-       return count;
-}
-
-#endif                         /*PMC_FIX_FLAG */
-
-int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block)
-{
-       struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
-       static struct proc_dir_entry *procfs_dir;
-       int ret = 0;
-
-       sprintf(current_pfs->dir_name, "bypass_%s", dev->name);
-
-       if (!bp_procfs_dir)
-               return -1;
-
-       /* create device proc dir */
-       procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir);
-       if (procfs_dir == 0) {
-               printk(KERN_DEBUG "Could not create procfs directory %s\n",
-                      current_pfs->dir_name);
-               return -1;
-       }
-       current_pfs->bypass_entry = procfs_dir;
-
-       if (bypass_proc_create_entry(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL,   /* write */
-                                    get_bypass_info_pfs,       /* read  */
-                                    procfs_dir, pbp_device_block))
-               ret = -1;
-
-       if (pbp_device_block->bp_caps & SW_CTL_CAP) {
-
-               /* Create set param proc's */
-               if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL,      /* write */
-                                               get_bypass_slave_pfs,   /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL,        /* write */
-                                               get_bypass_caps_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL,        /* write */
-                                               get_wd_set_caps_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-               if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs,       /* write */
-                                               get_bypass_wd_pfs,      /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL,  /* write */
-                                               get_wd_expire_time_pfs, /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL,        /* write */
-                                               reset_bypass_wd_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs,     /* write */
-                                               get_std_nic_pfs,        /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (pbp_device_block->bp_caps & BP_CAP) {
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs,        /* write */
-                                                       get_bypass_pfs, /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs,    /* write */
-                                                       get_dis_bypass_pfs,     /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs, /* write */
-                                                       get_bypass_pwup_pfs,    /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs,      /* write */
-                                                       get_bypass_pwoff_pfs,   /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL,    /* write */
-                                                       get_bypass_change_pfs,  /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-               }
-
-               if (pbp_device_block->bp_caps & TAP_CAP) {
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs, /* write */
-                                                       get_tap_pfs,    /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs,     /* write */
-                                                       get_dis_tap_pfs,        /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs,  /* write */
-                                                       get_tap_pwup_pfs,       /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL,  /* write */
-                                                       get_tap_change_pfs,     /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-               }
-               if (pbp_device_block->bp_caps & DISC_CAP) {
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs,       /* write */
-                                                       get_disc_pfs,   /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-#if 1
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs,   /* write */
-                                                       get_dis_disc_pfs,       /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-#endif
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs,        /* write */
-                                                       get_disc_pwup_pfs,      /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL, /* write */
-                                                       get_disc_change_pfs,    /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-               }
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs, /* write */
-                                               get_wd_exp_mode_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs,      /* write */
-                                               get_wd_autoreset_pfs,   /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-               if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs, /* write */
-                                               get_tpl_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-#ifdef PMC_FIX_FLAG
-               if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs,       /* write */
-                                               get_wait_at_pwup_pfs,   /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-               if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs,       /* write */
-                                               get_hw_reset_pfs,       /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-#endif
-
-       }
-       if (ret < 0)
-               printk(KERN_DEBUG "Create proc entry failed\n");
-
-       return ret;
-}
-
-int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block)
-{
-
-       struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
-       struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr =
-           NULL;
-       char name[256];
-
-       for (pde = pde->subdir; pde;) {
-               strcpy(name, pde->name);
-               pde_curr = pde;
-               pde = pde->next;
-               remove_proc_entry(name, current_pfs->bypass_entry);
-       }
-       if (!pde)
-               remove_proc_entry(current_pfs->dir_name, bp_procfs_dir);
-
-       return 0;
-}
-
-#endif                         /* BYPASS_SUPPORT */
similarity index 84%
rename from drivers/staging/silicom/bp_mod.c
rename to drivers/staging/silicom/bpctl_mod.c
index 58c5f5cf4cec00ccdaa74c32aef388e8a5250ec7..3117559c041b25111380276d66653a2732371e88 100644 (file)
@@ -35,7 +35,6 @@
 #define BP_MOD_DESCR "Silicom Bypass-SD Control driver"
 #define BP_SYNC_FLAG 1
 
-static int Device_Open = 0;
 static int major_num = 0;
 
 MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il");
@@ -60,35 +59,9 @@ typedef enum {
        bp_none,
 } bp_media_type;
 
-struct pfs_unit_sd {
-       struct proc_dir_entry *proc_entry;
-       char proc_name[32];
-};
-
 struct bypass_pfs_sd {
        char dir_name[32];
        struct proc_dir_entry *bypass_entry;
-       struct pfs_unit_sd bypass_info;
-       struct pfs_unit_sd bypass_slave;
-       struct pfs_unit_sd bypass_caps;
-       struct pfs_unit_sd wd_set_caps;
-       struct pfs_unit_sd bypass;
-       struct pfs_unit_sd bypass_change;
-       struct pfs_unit_sd bypass_wd;
-       struct pfs_unit_sd wd_expire_time;
-       struct pfs_unit_sd reset_bypass_wd;
-       struct pfs_unit_sd dis_bypass;
-       struct pfs_unit_sd bypass_pwup;
-       struct pfs_unit_sd bypass_pwoff;
-       struct pfs_unit_sd std_nic;
-       struct pfs_unit_sd tap;
-       struct pfs_unit_sd dis_tap;
-       struct pfs_unit_sd tap_pwup;
-       struct pfs_unit_sd tap_change;
-       struct pfs_unit_sd wd_exp_mode;
-       struct pfs_unit_sd wd_autoreset;
-       struct pfs_unit_sd tpl;
-
 };
 
 typedef struct _bpctl_dev {
@@ -315,27 +288,6 @@ static struct notifier_block bp_notifier_block = {
        .notifier_call = bp_device_event,
 };
 
-static int device_open(struct inode *inode, struct file *file)
-{
-#ifdef DEBUG
-       printk("device_open(%p)\n", file);
-#endif
-       Device_Open++;
-/*
-* Initialize the message
-*/
-       return SUCCESS;
-}
-
-static int device_release(struct inode *inode, struct file *file)
-{
-#ifdef DEBUG
-       printk("device_release(%p,%p)\n", inode, file);
-#endif
-       Device_Open--;
-       return SUCCESS;
-}
-
 int is_bypass_fn(bpctl_dev_t *pbpctl_dev);
 int wdt_time_left(bpctl_dev_t *pbpctl_dev);
 
@@ -1728,62 +1680,33 @@ int gpio6_clear_fn(bpctl_dev_t *pbpctl_dev)
 }
 #endif                         /*BYPASS_DEBUG */
 
-static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev)
+static bpctl_dev_t *lookup_port(bpctl_dev_t *dev)
 {
-       int idx_dev = 0;
-
-       if (pbpctl_dev == NULL)
-               return NULL;
-
-       if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) {
-               for (idx_dev = 0;
-                    ((bpctl_dev_arr[idx_dev].pdev != NULL)
-                     && (idx_dev < device_num)); idx_dev++) {
-                       if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)
-                           && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)
-                           && ((bpctl_dev_arr[idx_dev].func == 1)
-                               && (pbpctl_dev->func == 0))) {
-
-                               return &(bpctl_dev_arr[idx_dev]);
-                       }
-                       if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) &&
-                           (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) &&
-                           ((bpctl_dev_arr[idx_dev].func == 3)
-                            && (pbpctl_dev->func == 2))) {
+       bpctl_dev_t *p;
+       int n;
+       for (n = 0, p = bpctl_dev_arr; n < device_num && p->pdev; n++) {
+               if (p->bus == dev->bus
+                   && p->slot == dev->slot
+                   && p->func == (dev->func ^ 1))
+                       return p;
+       }
+       return NULL;
+}
 
-                               return &(bpctl_dev_arr[idx_dev]);
-                       }
-               }
+static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev)
+{
+       if (pbpctl_dev) {
+               if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2)
+                       return lookup_port(pbpctl_dev);
        }
        return NULL;
 }
 
 static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev)
 {
-       int idx_dev = 0;
-
-       if (pbpctl_dev == NULL)
-               return NULL;
-
-       if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) {
-               for (idx_dev = 0;
-                    ((bpctl_dev_arr[idx_dev].pdev != NULL)
-                     && (idx_dev < device_num)); idx_dev++) {
-                       if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)
-                           && (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)
-                           && ((bpctl_dev_arr[idx_dev].func == 0)
-                               && (pbpctl_dev->func == 1))) {
-
-                               return &(bpctl_dev_arr[idx_dev]);
-                       }
-                       if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) &&
-                           (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) &&
-                           ((bpctl_dev_arr[idx_dev].func == 2)
-                            && (pbpctl_dev->func == 3))) {
-
-                               return &(bpctl_dev_arr[idx_dev]);
-                       }
-               }
+       if (pbpctl_dev) {
+               if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3)
+                       return lookup_port(pbpctl_dev);
        }
        return NULL;
 }
@@ -5858,11 +5781,9 @@ static long device_ioctl(struct file *file,      /* see include/linux/fs.h */
        return ret;
 }
 
-struct file_operations Fops = {
+static const struct file_operations Fops = {
        .owner = THIS_MODULE,
        .unlocked_ioctl = device_ioctl,
-       .open = device_open,
-       .release = device_release,      /* a.k.a. close */
 };
 
 #ifndef PCI_DEVICE
@@ -6686,6 +6607,118 @@ static bpmod_info_t tx_ctl_pci_tbl[] = {
        {0,}
 };
 
+static void find_fw(bpctl_dev_t *dev)
+{
+       unsigned long mmio_start, mmio_len;
+       struct pci_dev *pdev1 = dev->pdev;
+
+       if ((OLD_IF_SERIES(dev->subdevice)) ||
+           (INTEL_IF_SERIES(dev->subdevice)))
+               dev->bp_fw_ver = 0xff;
+       else
+               dev->bp_fw_ver = bypass_fw_ver(dev);
+
+       if (dev->bp_10gb == 1 && dev->bp_fw_ver == 0xff) {
+               int cnt = 100;
+               while (cnt--) {
+                       iounmap((void *)dev->mem_map);
+                       mmio_start = pci_resource_start(pdev1, 0);
+                       mmio_len = pci_resource_len(pdev1, 0);
+
+                       dev->mem_map = (unsigned long)
+                           ioremap(mmio_start, mmio_len);
+
+                       dev->bp_fw_ver = bypass_fw_ver(dev);
+                       if (dev-> bp_fw_ver == 0xa8)
+                               break;
+               }
+       }
+       /* dev->bp_fw_ver=0xa8; */
+       printk("firmware version: 0x%x\n", dev->bp_fw_ver);
+}
+
+static int init_one(bpctl_dev_t *dev, bpmod_info_t *info, struct pci_dev *pdev1)
+{
+       unsigned long mmio_start, mmio_len;
+
+       dev->pdev = pdev1;
+       mmio_start = pci_resource_start(pdev1, 0);
+       mmio_len = pci_resource_len(pdev1, 0);
+
+       dev->desc = dev_desc[info->index].name;
+       dev->name = info->bp_name;
+       dev->device = info->device;
+       dev->vendor = info->vendor;
+       dev->subdevice = info->subdevice;
+       dev->subvendor = info->subvendor;
+       dev->func = PCI_FUNC(pdev1->devfn);
+       dev->slot = PCI_SLOT(pdev1->devfn);
+       dev->bus = pdev1->bus->number;
+       dev->mem_map = (unsigned long)ioremap(mmio_start, mmio_len);
+#ifdef BP_SYNC_FLAG
+       spin_lock_init(&dev->bypass_wr_lock);
+#endif
+       if (BP10G9_IF_SERIES(dev->subdevice))
+               dev->bp_10g9 = 1;
+       if (BP10G_IF_SERIES(dev->subdevice))
+               dev->bp_10g = 1;
+       if (PEG540_IF_SERIES(dev->subdevice))
+               dev->bp_540 = 1;
+       if (PEGF5_IF_SERIES(dev->subdevice))
+               dev->bp_fiber5 = 1;
+       if (PEG80_IF_SERIES(dev->subdevice))
+               dev->bp_i80 = 1;
+       if (PEGF80_IF_SERIES(dev->subdevice))
+               dev->bp_i80 = 1;
+       if ((dev->subdevice & 0xa00) == 0xa00)
+               dev->bp_i80 = 1;
+       if (BP10GB_IF_SERIES(dev->subdevice)) {
+               if (dev->ifindex == 0) {
+                       unregister_chrdev(major_num, DEVICE_NAME);
+                       printk("Please load network driver for %s adapter!\n",
+                            dev->name);
+                       return -1;
+               }
+
+               if (dev->ndev && !(dev->ndev->flags & IFF_UP)) {
+                       unregister_chrdev(major_num, DEVICE_NAME);
+                       printk("Please bring up network interfaces for %s adapter!\n",
+                            dev->name);
+                       return -1;
+               }
+               dev->bp_10gb = 1;
+       }
+
+       if (!dev->bp_10g9) {
+               if (is_bypass_fn(dev)) {
+                       printk(KERN_INFO "%s found, ",
+                              dev->name);
+                       find_fw(dev);
+               }
+               dev->wdt_status = WDT_STATUS_UNKNOWN;
+               dev->reset_time = 0;
+               atomic_set(&dev->wdt_busy, 0);
+               dev->bp_status_un = 1;
+
+               bypass_caps_init(dev);
+
+               init_bypass_wd_auto(dev);
+               init_bypass_tpl_auto(dev);
+               if (NOKIA_SERIES(dev->subdevice))
+                       reset_cont(dev);
+       }
+#ifdef BP_SELF_TEST
+       if ((dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL))) {
+               memset(dev->bp_tx_data, 0xff, 6);
+               memset(dev->bp_tx_data + 6, 0x0, 1);
+               memset(dev->bp_tx_data + 7, 0xaa, 5);
+               *(__be16 *)(dev->bp_tx_data + 12) = htons(ETH_P_BPTEST);
+       } else
+               printk("bp_ctl: Memory allocation error!\n");
+#endif
+       return 0;
+}
+
 /*
 * Initialize the module - Register the character device
 */
@@ -6694,7 +6727,7 @@ static int __init bypass_init_module(void)
 {
        int ret_val, idx, idx_dev = 0;
        struct pci_dev *pdev1 = NULL;
-       unsigned long mmio_start, mmio_len;
+       bpctl_dev_t *dev;
 
        printk(BP_MOD_DESCR " v" BP_MOD_VER "\n");
        ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops);
@@ -6729,181 +6762,16 @@ static int __init bypass_init_module(void)
        memset(bpctl_dev_arr, 0, ((device_num) * sizeof(bpctl_dev_t)));
 
        pdev1 = NULL;
+       dev = bpctl_dev_arr;
        for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
                while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
                                               tx_ctl_pci_tbl[idx].device,
                                               tx_ctl_pci_tbl[idx].subvendor,
                                               tx_ctl_pci_tbl[idx].subdevice,
                                               pdev1))) {
-                       bpctl_dev_arr[idx_dev].pdev = pdev1;
-
-                       mmio_start = pci_resource_start(pdev1, 0);
-                       mmio_len = pci_resource_len(pdev1, 0);
-
-                       bpctl_dev_arr[idx_dev].desc =
-                           dev_desc[tx_ctl_pci_tbl[idx].index].name;
-                       bpctl_dev_arr[idx_dev].name =
-                           tx_ctl_pci_tbl[idx].bp_name;
-                       bpctl_dev_arr[idx_dev].device =
-                           tx_ctl_pci_tbl[idx].device;
-                       bpctl_dev_arr[idx_dev].vendor =
-                           tx_ctl_pci_tbl[idx].vendor;
-                       bpctl_dev_arr[idx_dev].subdevice =
-                           tx_ctl_pci_tbl[idx].subdevice;
-                       bpctl_dev_arr[idx_dev].subvendor =
-                           tx_ctl_pci_tbl[idx].subvendor;
-                       /* bpctl_dev_arr[idx_dev].pdev=pdev1; */
-                       bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn);
-                       bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn);
-                       bpctl_dev_arr[idx_dev].bus = pdev1->bus->number;
-                       bpctl_dev_arr[idx_dev].mem_map =
-                           (unsigned long)ioremap(mmio_start, mmio_len);
-#ifdef BP_SYNC_FLAG
-                       spin_lock_init(&bpctl_dev_arr[idx_dev].bypass_wr_lock);
-#endif
-                       if (BP10G9_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
-                               bpctl_dev_arr[idx_dev].bp_10g9 = 1;
-                       if (BP10G_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
-                               bpctl_dev_arr[idx_dev].bp_10g = 1;
-                       if (PEG540_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) {
-
-                               bpctl_dev_arr[idx_dev].bp_540 = 1;
-                       }
-                       if (PEGF5_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
-                               bpctl_dev_arr[idx_dev].bp_fiber5 = 1;
-                       if (PEG80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
-                               bpctl_dev_arr[idx_dev].bp_i80 = 1;
-                       if (PEGF80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
-                               bpctl_dev_arr[idx_dev].bp_i80 = 1;
-                       if ((bpctl_dev_arr[idx_dev].subdevice & 0xa00) == 0xa00)
-                               bpctl_dev_arr[idx_dev].bp_i80 = 1;
-                       if (BP10GB_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) {
-                               if (bpctl_dev_arr[idx_dev].ifindex == 0) {
-                                       unregister_chrdev(major_num,
-                                                         DEVICE_NAME);
-                                       printk
-                                           ("Please load network driver for %s adapter!\n",
-                                            bpctl_dev_arr[idx_dev].name);
-                                       return -1;
-                               }
-
-                               if (bpctl_dev_arr[idx_dev].ndev) {
-                                       if (!
-                                           (bpctl_dev_arr[idx_dev].ndev->
-                                            flags & IFF_UP)) {
-                                               if (!
-                                                   (bpctl_dev_arr[idx_dev].
-                                                    ndev->flags & IFF_UP)) {
-                                                       unregister_chrdev
-                                                           (major_num,
-                                                            DEVICE_NAME);
-                                                       printk
-                                                           ("Please bring up network interfaces for %s adapter!\n",
-                                                            bpctl_dev_arr
-                                                            [idx_dev].name);
-                                                       return -1;
-                                               }
-
-                                       }
-                               }
-                               bpctl_dev_arr[idx_dev].bp_10gb = 1;
-                       }
-
-                       if (!bpctl_dev_arr[idx_dev].bp_10g9) {
-
-                               if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) {
-                                       printk(KERN_INFO "%s found, ",
-                                              bpctl_dev_arr[idx_dev].name);
-                                       if ((OLD_IF_SERIES
-                                            (bpctl_dev_arr[idx_dev].subdevice))
-                                           ||
-                                           (INTEL_IF_SERIES
-                                            (bpctl_dev_arr[idx_dev].
-                                             subdevice)))
-                                               bpctl_dev_arr[idx_dev].
-                                                   bp_fw_ver = 0xff;
-                                       else
-                                               bpctl_dev_arr[idx_dev].
-                                                   bp_fw_ver =
-                                                   bypass_fw_ver(&bpctl_dev_arr
-                                                                 [idx_dev]);
-                                       if ((bpctl_dev_arr[idx_dev].bp_10gb ==
-                                            1)
-                                           && (bpctl_dev_arr[idx_dev].
-                                               bp_fw_ver == 0xff)) {
-                                               int cnt = 100;
-                                               while (cnt--) {
-                                                       iounmap((void
-                                                                *)
-                                                               (bpctl_dev_arr
-                                                                [idx_dev].
-                                                                mem_map));
-                                                       mmio_start =
-                                                           pci_resource_start
-                                                           (pdev1, 0);
-                                                       mmio_len =
-                                                           pci_resource_len
-                                                           (pdev1, 0);
-
-                                                       bpctl_dev_arr[idx_dev].
-                                                           mem_map =
-                                                           (unsigned long)
-                                                           ioremap(mmio_start,
-                                                                   mmio_len);
-
-                                                       bpctl_dev_arr[idx_dev].
-                                                           bp_fw_ver =
-                                                           bypass_fw_ver
-                                                           (&bpctl_dev_arr
-                                                            [idx_dev]);
-                                                       if (bpctl_dev_arr
-                                                           [idx_dev].
-                                                           bp_fw_ver == 0xa8)
-                                                               break;
-
-                                               }
-                                       }
-                                       /* bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; */
-                                       printk("firmware version: 0x%x\n",
-                                              bpctl_dev_arr[idx_dev].
-                                              bp_fw_ver);
-                               }
-                               bpctl_dev_arr[idx_dev].wdt_status =
-                                   WDT_STATUS_UNKNOWN;
-                               bpctl_dev_arr[idx_dev].reset_time = 0;
-                               atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy, 0);
-                               bpctl_dev_arr[idx_dev].bp_status_un = 1;
-
-                               bypass_caps_init(&bpctl_dev_arr[idx_dev]);
-
-                               init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]);
-                               init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]);
-                               if (NOKIA_SERIES
-                                   (bpctl_dev_arr[idx_dev].subdevice))
-                                       reset_cont(&bpctl_dev_arr[idx_dev]);
-                       }
-#ifdef BP_SELF_TEST
-                       if ((bpctl_dev_arr[idx_dev].bp_tx_data =
-                            kmalloc(BPTEST_DATA_LEN, GFP_KERNEL))) {
-
-                               memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0x0,
-                                      BPTEST_DATA_LEN);
-
-                               memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0xff,
-                                      6);
-                               memset(bpctl_dev_arr[idx_dev].bp_tx_data + 6,
-                                      0x0, 1);
-                               memset(bpctl_dev_arr[idx_dev].bp_tx_data + 7,
-                                      0xaa, 5);
-
-                               *(__be16 *) (bpctl_dev_arr[idx_dev].bp_tx_data +
-                                            12) = htons(ETH_P_BPTEST);
-
-                       } else
-                               printk("bp_ctl: Memory allocation error!\n");
-#endif
-                       idx_dev++;
-
+                       if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0)
+                               return -1;
+                       dev++;
                }
        }
        if_scan_init();
@@ -6913,33 +6781,27 @@ static int __init bypass_init_module(void)
        {
 
                bpctl_dev_t *pbpctl_dev_c = NULL;
-               for (idx_dev = 0;
-                    ((bpctl_dev_arr[idx_dev].pdev != NULL)
-                     && (idx_dev < device_num)); idx_dev++) {
-                       if (bpctl_dev_arr[idx_dev].bp_10g9) {
-                               pbpctl_dev_c =
-                                   get_status_port_fn(&bpctl_dev_arr[idx_dev]);
-                               if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) {
+               for (idx_dev = 0, dev = bpctl_dev_arr;
+                    idx_dev < device_num && dev->pdev;
+                    idx_dev++, dev++) {
+                       if (dev->bp_10g9) {
+                               pbpctl_dev_c = get_status_port_fn(dev);
+                               if (is_bypass_fn(dev)) {
                                        printk(KERN_INFO "%s found, ",
-                                              bpctl_dev_arr[idx_dev].name);
-                                       bpctl_dev_arr[idx_dev].bp_fw_ver =
-                                           bypass_fw_ver(&bpctl_dev_arr
-                                                         [idx_dev]);
+                                              dev->name);
+                                       dev->bp_fw_ver = bypass_fw_ver(dev);
                                        printk("firmware version: 0x%x\n",
-                                              bpctl_dev_arr[idx_dev].
-                                              bp_fw_ver);
-
+                                              dev->bp_fw_ver);
                                }
-                               bpctl_dev_arr[idx_dev].wdt_status =
-                                   WDT_STATUS_UNKNOWN;
-                               bpctl_dev_arr[idx_dev].reset_time = 0;
-                               atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy, 0);
-                               bpctl_dev_arr[idx_dev].bp_status_un = 1;
+                               dev->wdt_status = WDT_STATUS_UNKNOWN;
+                               dev->reset_time = 0;
+                               atomic_set(&dev->wdt_busy, 0);
+                               dev->bp_status_un = 1;
 
-                               bypass_caps_init(&bpctl_dev_arr[idx_dev]);
+                               bypass_caps_init(dev);
 
-                               init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]);
-                               init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]);
+                               init_bypass_wd_auto(dev);
+                               init_bypass_tpl_auto(dev);
 
                        }
 
@@ -7338,78 +7200,11 @@ EXPORT_SYMBOL_NOVERS(bp_if_scan_sd);
 
 #define BP_PROC_DIR "bypass"
 
-#define GPIO6_SET_ENTRY_SD           "gpio6_set"
-#define GPIO6_CLEAR_ENTRY_SD         "gpio6_clear"
-
-#define GPIO7_SET_ENTRY_SD           "gpio7_set"
-#define GPIO7_CLEAR_ENTRY_SD         "gpio7_clear"
-
-#define PULSE_SET_ENTRY_SD            "pulse_set"
-#define ZERO_SET_ENTRY_SD            "zero_set"
-#define PULSE_GET1_ENTRY_SD            "pulse_get1"
-#define PULSE_GET2_ENTRY_SD            "pulse_get2"
-
-#define CMND_ON_ENTRY_SD              "cmnd_on"
-#define CMND_OFF_ENTRY_SD             "cmnd_off"
-#define RESET_CONT_ENTRY_SD           "reset_cont"
-
- /*COMMANDS*/
-#define BYPASS_INFO_ENTRY_SD     "bypass_info"
-#define BYPASS_SLAVE_ENTRY_SD    "bypass_slave"
-#define BYPASS_CAPS_ENTRY_SD     "bypass_caps"
-#define WD_SET_CAPS_ENTRY_SD     "wd_set_caps"
-#define BYPASS_ENTRY_SD          "bypass"
-#define BYPASS_CHANGE_ENTRY_SD   "bypass_change"
-#define BYPASS_WD_ENTRY_SD       "bypass_wd"
-#define WD_EXPIRE_TIME_ENTRY_SD  "wd_expire_time"
-#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd"
-#define DIS_BYPASS_ENTRY_SD      "dis_bypass"
-#define BYPASS_PWUP_ENTRY_SD     "bypass_pwup"
-#define BYPASS_PWOFF_ENTRY_SD     "bypass_pwoff"
-#define STD_NIC_ENTRY_SD         "std_nic"
-#define STD_NIC_ENTRY_SD         "std_nic"
-#define TAP_ENTRY_SD             "tap"
-#define TAP_CHANGE_ENTRY_SD      "tap_change"
-#define DIS_TAP_ENTRY_SD         "dis_tap"
-#define TAP_PWUP_ENTRY_SD        "tap_pwup"
-#define TWO_PORT_LINK_ENTRY_SD   "two_port_link"
-#define WD_EXP_MODE_ENTRY_SD     "wd_exp_mode"
-#define WD_AUTORESET_ENTRY_SD    "wd_autoreset"
-#define TPL_ENTRY_SD             "tpl"
-#define WAIT_AT_PWUP_ENTRY_SD    "wait_at_pwup"
-#define HW_RESET_ENTRY_SD        "hw_reset"
-#define DISC_ENTRY_SD             "disc"
-#define DISC_CHANGE_ENTRY_SD      "disc_change"
-#define DIS_DISC_ENTRY_SD         "dis_disc"
-#define DISC_PWUP_ENTRY_SD        "disc_pwup"
 static struct proc_dir_entry *bp_procfs_dir;
 
-static struct proc_dir_entry *proc_getdir(char *name,
-                                         struct proc_dir_entry *proc_dir)
-{
-       struct proc_dir_entry *pde = proc_dir;
-
-       for (pde = pde->subdir; pde; pde = pde->next) {
-               if (pde->namelen && (strcmp(name, pde->name) == 0)) {
-                       /* directory exists */
-                       break;
-               }
-       }
-       if (pde == (struct proc_dir_entry *)0) {
-               /* create the directory */
-               pde = proc_mkdir(name, proc_dir);
-               if (pde == (struct proc_dir_entry *)0) {
-
-                       return pde;
-               }
-       }
-
-       return pde;
-}
-
 int bp_proc_create(void)
 {
-       bp_procfs_dir = proc_getdir(BP_PROC_DIR, init_net.proc_net);
+       bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net);
        if (bp_procfs_dir == (struct proc_dir_entry *)0) {
                printk(KERN_DEBUG
                       "Could not create procfs nicinfo directory %s\n",
@@ -7419,144 +7214,99 @@ int bp_proc_create(void)
        return 0;
 }
 
-int
-bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr,
-                           char *proc_name,
-                           write_proc_t *write_proc,
-                           read_proc_t *read_proc,
-                           struct proc_dir_entry *parent_pfs, void *data)
+static int procfs_add(char *proc_name, const struct file_operations *fops,
+                     bpctl_dev_t *dev)
 {
-       strcpy(pfs_unit_curr->proc_name, proc_name);
-       pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name,
-                                                     S_IFREG | S_IRUSR |
-                                                     S_IWUSR | S_IRGRP |
-                                                     S_IROTH, parent_pfs);
-       if (pfs_unit_curr->proc_entry == NULL)
+       struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set;
+       if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev))
                return -1;
-
-       pfs_unit_curr->proc_entry->read_proc = read_proc;
-       pfs_unit_curr->proc_entry->write_proc = write_proc;
-       pfs_unit_curr->proc_entry->data = data;
-
        return 0;
-
 }
 
-int
-get_bypass_info_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-       int len = 0;
-
-       len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->name);
-       len +=
-           sprintf(page + len, "Firmware version\t0x%x\n",
-                   pbp_device_block->bp_fw_ver);
+#define RO_FOPS(name)  \
+static int name##_open(struct inode *inode, struct file *file) \
+{                                                              \
+       return single_open(file, show_##name, PDE_DATA(inode));\
+}                                                              \
+static const struct file_operations name##_ops = {             \
+       .open = name##_open,                                    \
+       .read = seq_read,                                       \
+       .llseek = seq_lseek,                                    \
+       .release = single_release,                              \
+};
 
-       *eof = 1;
-       return len;
-}
+#define RW_FOPS(name)  \
+static int name##_open(struct inode *inode, struct file *file) \
+{                                                              \
+       return single_open(file, show_##name, PDE_DATA(inode));\
+}                                                              \
+static const struct file_operations name##_ops = {             \
+       .open = name##_open,                                    \
+       .read = seq_read,                                       \
+       .write = name##_write,                                  \
+       .llseek = seq_lseek,                                    \
+       .release = single_release,                              \
+};
 
-int
-get_bypass_slave_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
+static int show_bypass_info(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0;
-       bpctl_dev_t *pbp_device_block_slave = NULL;
-       int idx_dev = 0;
-       struct net_device *net_slave_dev = NULL;
-
-       if ((pbp_device_block->func == 0) || (pbp_device_block->func == 2)) {
-               for (idx_dev = 0;
-                    ((bpctl_dev_arr[idx_dev].pdev != NULL)
-                     && (idx_dev < device_num)); idx_dev++) {
-                       if ((bpctl_dev_arr[idx_dev].bus ==
-                            pbp_device_block->bus)
-                           && (bpctl_dev_arr[idx_dev].slot ==
-                               pbp_device_block->slot)) {
-                               if ((pbp_device_block->func == 0)
-                                   && (bpctl_dev_arr[idx_dev].func == 1)) {
-                                       pbp_device_block_slave =
-                                           &bpctl_dev_arr[idx_dev];
-                                       break;
-                               }
-                               if ((pbp_device_block->func == 2) &&
-                                   (bpctl_dev_arr[idx_dev].func == 3)) {
-                                       pbp_device_block_slave =
-                                           &bpctl_dev_arr[idx_dev];
-                                       break;
-                               }
-                       }
-               }
-       } else
-               pbp_device_block_slave = pbp_device_block;
-       if (!pbp_device_block_slave) {
-               len = sprintf(page, "fail\n");
-               *eof = 1;
-               return len;
-       }
-       net_slave_dev = pbp_device_block_slave->ndev;
-       if (net_slave_dev)
-               len = sprintf(page, "%s\n", net_slave_dev->name);
+       bpctl_dev_t *dev = m->private;
 
-       *eof = 1;
-       return len;
+       seq_printf(m, "Name\t\t\t%s\n", dev->name);
+       seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver);
+       return 0;
 }
+RO_FOPS(bypass_info)
 
-int
-get_bypass_caps_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
+static int show_bypass_slave(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
+       bpctl_dev_t *dev = m->private;
+       bpctl_dev_t *slave = get_status_port_fn(dev);
+       if (!slave)
+               slave = dev;
+       if (!slave)
+               seq_printf(m, "fail\n");
+       else if (slave->ndev)
+               seq_printf(m, "%s\n", slave->ndev->name);
+       return 0;
+}
+RO_FOPS(bypass_slave)
 
-       ret = get_bypass_caps_fn(pbp_device_block);
+static int show_bypass_caps(struct seq_file *m, void *v)
+{
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bypass_caps_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "-1\n");
+               seq_printf(m, "-1\n");
        else
-               len = sprintf(page, "0x%x\n", ret);
-       *eof = 1;
-       return len;
-
+               seq_printf(m, "0x%x\n", ret);
+       return 0;
 }
+RO_FOPS(bypass_caps)
 
-int
-get_wd_set_caps_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
+static int show_wd_set_caps(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_wd_set_caps_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_wd_set_caps_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "-1\n");
+               seq_printf(m, "-1\n");
        else
-               len = sprintf(page, "0x%x\n", ret);
-       *eof = 1;
-       return len;
+               seq_printf(m, "0x%x\n", ret);
+       return 0;
 }
+RO_FOPS(wd_set_caps)
 
-int
-set_bypass_pfs(struct file *file, const char *buffer,
-              unsigned long count, void *data)
+static int user_on_off(const void __user *buffer, size_t count)
 {
 
        char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
+       int length = 0;
 
        if (count > (sizeof(kbuf) - 1))
                return -1;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
+       if (copy_from_user(&kbuf, buffer, count))
                return -1;
-       }
 
        kbuf[count] = '\0';
        length = strlen(kbuf);
@@ -7564,806 +7314,467 @@ set_bypass_pfs(struct file *file, const char *buffer,
                kbuf[--length] = '\0';
 
        if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_bypass_fn(pbp_device_block, bypass_param);
-
-       return count;
+               return 1;
+       if (strcmp(kbuf, "off") == 0)
+               return 0;
+       return 0;
 }
 
-int
-set_tap_pfs(struct file *file, const char *buffer,
-           unsigned long count, void *data)
+static ssize_t bypass_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
+       int bypass_param = user_on_off(buffer, count);
+       if (bypass_param < 0)
                return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_tap_fn(pbp_device_block, tap_param);
 
+       set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
        return count;
 }
-
-int
-set_disc_pfs(struct file *file, const char *buffer,
-            unsigned long count, void *data)
+static int show_bypass(struct seq_file *m, void *v)
 {
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bypass_fn(dev);
+       if (ret == BP_NOT_CAP)
+               seq_printf(m, "fail\n");
+       else if (ret == 1)
+               seq_printf(m, "on\n");
+       else if (ret == 0)
+               seq_printf(m, "off\n");
+       return 0;
+}
+RW_FOPS(bypass)
 
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
+static ssize_t tap_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
+{
+       int tap_param = user_on_off(buffer, count);
+       if (tap_param < 0)
                return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_disc_fn(pbp_device_block, tap_param);
 
+       set_tap_fn(PDE_DATA(file_inode(file)), tap_param);
        return count;
 }
-
-int
-get_bypass_pfs(char *page, char **start, off_t off, int count,
-              int *eof, void *data)
+static int show_tap(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_tap_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "off\n");
+       return 0;
 }
+RW_FOPS(tap)
 
-int
-get_tap_pfs(char *page, char **start, off_t off, int count,
-           int *eof, void *data)
+static ssize_t disc_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tap_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 1)
-               len = sprintf(page, "on\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
+       int tap_param = user_on_off(buffer, count);
+       if (tap_param < 0)
+               return -1;
 
-       *eof = 1;
-       return len;
+       set_disc_fn(PDE_DATA(file_inode(file)), tap_param);
+       return count;
 }
-
-int
-get_disc_pfs(char *page, char **start, off_t off, int count,
-            int *eof, void *data)
+static int show_disc(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_disc_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_disc_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "off\n");
+       return 0;
 }
+RW_FOPS(disc)
 
-int
-get_bypass_change_pfs(char *page, char **start, off_t off, int count,
-                     int *eof, void *data)
+static int show_bypass_change(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_change_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bypass_change_fn(dev);
        if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "fail\n");
+       return 0;
 }
+RO_FOPS(bypass_change)
 
-int
-get_tap_change_pfs(char *page, char **start, off_t off, int count,
-                  int *eof, void *data)
+static int show_tap_change(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tap_change_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_tap_change_fn(dev);
        if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "fail\n");
+       return 0;
 }
+RO_FOPS(tap_change)
 
-int
-get_disc_change_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
+static int show_disc_change(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_disc_change_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_disc_change_fn(dev);
        if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
-}
-
-#define isdigit(c) (c >= '0' && c <= '9')
-__inline static int atoi(char **s)
-{
-       int i = 0;
-       while (isdigit(**s))
-               i = i * 10 + *((*s)++) - '0';
-       return i;
+               seq_printf(m, "fail\n");
+       return 0;
 }
+RO_FOPS(disc_change)
 
-int
-set_bypass_wd_pfs(struct file *file, const char *buffer,
-                 unsigned long count, void *data)
+static ssize_t bypass_wd_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+       bpctl_dev_t *dev = PDE_DATA(file_inode(file));
        int timeout;
-       int ret;
-
-       ret = kstrtoint_from_user(buffer, count, 10, &timeout);
+       int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
        if (ret)
                return ret;
-       set_bypass_wd_fn(pbp_device_block, timeout);
-
+       set_bypass_wd_fn(dev, timeout);
        return count;
 }
-
-int
-get_bypass_wd_pfs(char *page, char **start, off_t off, int count,
-                 int *eof, void *data)
+static int show_bypass_wd(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+       bpctl_dev_t *dev = m->private;
+       int ret = 0, timeout = 0;
 
-       int len = 0, ret = 0, timeout = 0;
-
-       ret = get_bypass_wd_fn(pbp_device_block, &timeout);
+       ret = get_bypass_wd_fn(dev, &timeout);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m,  "fail\n");
        else if (timeout == -1)
-               len = sprintf(page, "unknown\n");
+               seq_printf(m,  "unknown\n");
        else if (timeout == 0)
-               len = sprintf(page, "disable\n");
+               seq_printf(m,  "disable\n");
        else
-               len = sprintf(page, "%d\n", timeout);
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "%d\n", timeout);
+       return 0;
 }
+RW_FOPS(bypass_wd)
 
-int
-get_wd_expire_time_pfs(char *page, char **start, off_t off, int count,
-                      int *eof, void *data)
+static int show_wd_expire_time(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0, timeout = 0;
-
-       ret = get_wd_expire_time_fn(pbp_device_block, &timeout);
+       bpctl_dev_t *dev = m->private;
+       int ret = 0, timeout = 0;
+       ret = get_wd_expire_time_fn(dev, &timeout);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (timeout == -1)
-               len = sprintf(page, "expire\n");
+               seq_printf(m, "expire\n");
        else if (timeout == 0)
-               len = sprintf(page, "disable\n");
-
+               seq_printf(m, "disable\n");
        else
-               len = sprintf(page, "%d\n", timeout);
-       *eof = 1;
-       return len;
+               seq_printf(m, "%d\n", timeout);
+       return 0;
 }
+RO_FOPS(wd_expire_time)
 
-int
-get_tpl_pfs(char *page, char **start, off_t off, int count,
-           int *eof, void *data)
+static ssize_t tpl_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
+       bpctl_dev_t *dev = PDE_DATA(file_inode(file));
+       int tpl_param = user_on_off(buffer, count);
+       if (tpl_param < 0)
+               return -1;
 
-       ret = get_tpl_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+       set_tpl_fn(dev, tpl_param);
+       return count;
+}
+static int show_tpl(struct seq_file *m, void *v)
+{
+       bpctl_dev_t *dev = m->private;
+       int ret = get_tpl_fn(dev);
+       if (ret == BP_NOT_CAP)
+               seq_printf(m, "fail\n");
        else if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "off\n");
+       return 0;
 }
+RW_FOPS(tpl)
 
 #ifdef PMC_FIX_FLAG
-int
-get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
+static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
+       bpctl_dev_t *dev = PDE_DATA(file_inode(file));
+       int tpl_param = user_on_off(buffer, count);
+       if (tpl_param < 0)
+               return -1;
 
-       ret = get_bp_wait_at_pwup_fn(pbp_device_block);
+       set_bp_wait_at_pwup_fn(dev, tpl_param);
+       return count;
+}
+static int show_wait_at_pwup(struct seq_file *m, void *v)
+{
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bp_wait_at_pwup_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "off\n");
+       return 0;
 }
+RW_FOPS(wait_at_pwup)
 
-int
-get_hw_reset_pfs(char *page, char **start, off_t off, int count,
-                int *eof, void *data)
+static ssize_t hw_reset_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
+       bpctl_dev_t *dev = PDE_DATA(file_inode(file));
+       int tpl_param = user_on_off(buffer, count);
+       if (tpl_param < 0)
+               return -1;
 
-       ret = get_bp_hw_reset_fn(pbp_device_block);
+       set_bp_hw_reset_fn(dev, tpl_param);
+       return count;
+}
+static int show_hw_reset(struct seq_file *m, void *v)
+{
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bp_hw_reset_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 1)
-               len = sprintf(page, "on\n");
+               seq_printf(m, "on\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "off\n");
+       return 0;
 }
+RW_FOPS(hw_reset)
 
 #endif                         /*PMC_WAIT_FLAG */
 
-int
-reset_bypass_wd_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
+static int show_reset_bypass_wd(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = reset_bypass_wd_timer_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = reset_bypass_wd_timer_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "disable\n");
+               seq_printf(m, "disable\n");
        else if (ret == 1)
-               len = sprintf(page, "success\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "success\n");
+       return 0;
 }
+RO_FOPS(reset_bypass_wd)
 
-int
-set_dis_bypass_pfs(struct file *file, const char *buffer,
-                  unsigned long count, void *data)
+static ssize_t dis_bypass_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
+       int bypass_param = user_on_off(buffer, count);
+       if (bypass_param < 0)
                return -EINVAL;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_dis_bypass_fn(pbp_device_block, bypass_param);
-
+       set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
        return count;
 }
-
-int
-set_dis_tap_pfs(struct file *file, const char *buffer,
-               unsigned long count, void *data)
+static int show_dis_bypass(struct seq_file *m, void *v)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
-               return -EINVAL;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_dis_tap_fn(pbp_device_block, tap_param);
-
-       return count;
+       bpctl_dev_t *dev = m->private;
+       int ret = get_dis_bypass_fn(dev);
+       if (ret == BP_NOT_CAP)
+               seq_printf(m, "fail\n");
+       else if (ret == 0)
+               seq_printf(m, "off\n");
+       else
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(dis_bypass)
 
-int
-set_dis_disc_pfs(struct file *file, const char *buffer,
-                unsigned long count, void *data)
+static ssize_t dis_tap_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
+       int tap_param = user_on_off(buffer, count);
+       if (tap_param < 0)
                return -EINVAL;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_dis_disc_fn(pbp_device_block, tap_param);
-
+       set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param);
        return count;
 }
-
-int
-get_dis_bypass_pfs(char *page, char **start, off_t off, int count,
-                  int *eof, void *data)
+static int show_dis_tap(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_dis_bypass_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_dis_tap_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(dis_tap)
 
-int
-get_dis_tap_pfs(char *page, char **start, off_t off, int count,
-               int *eof, void *data)
+static ssize_t dis_disc_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_dis_tap_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
+       int tap_param = user_on_off(buffer, count);
+       if (tap_param < 0)
+               return -EINVAL;
 
-       *eof = 1;
-       return len;
+       set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param);
+       return count;
 }
-
-int
-get_dis_disc_pfs(char *page, char **start, off_t off, int count,
-                int *eof, void *data)
+static int show_dis_disc(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_dis_disc_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_dis_disc_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(dis_disc)
 
-int
-set_bypass_pwup_pfs(struct file *file, const char *buffer,
-                   unsigned long count, void *data)
+static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
+       int bypass_param = user_on_off(buffer, count);
+       if (bypass_param < 0)
                return -EINVAL;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_bypass_pwup_fn(pbp_device_block, bypass_param);
-
+       set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param);
        return count;
 }
-
-int
-set_bypass_pwoff_pfs(struct file *file, const char *buffer,
-                    unsigned long count, void *data)
+static int show_bypass_pwup(struct seq_file *m, void *v)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
-               return -EINVAL;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_bypass_pwoff_fn(pbp_device_block, bypass_param);
-
-       return count;
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bypass_pwup_fn(dev);
+       if (ret == BP_NOT_CAP)
+               seq_printf(m, "fail\n");
+       else if (ret == 0)
+               seq_printf(m, "off\n");
+       else
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(bypass_pwup)
 
-int
-set_tap_pwup_pfs(struct file *file, const char *buffer,
-                unsigned long count, void *data)
+static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
+       int bypass_param = user_on_off(buffer, count);
+       if (bypass_param < 0)
                return -EINVAL;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_tap_pwup_fn(pbp_device_block, tap_param);
-
+       set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param);
        return count;
 }
-
-int
-set_disc_pwup_pfs(struct file *file, const char *buffer,
-                 unsigned long count, void *data)
+static int show_bypass_pwoff(struct seq_file *m, void *v)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tap_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
-               return -EINVAL;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tap_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tap_param = 0;
-
-       set_disc_pwup_fn(pbp_device_block, tap_param);
-
-       return count;
-}
-
-int
-get_bypass_pwup_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_pwup_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_bypass_pwoff_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(bypass_pwoff)
 
-int
-get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
+static ssize_t tap_pwup_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_bypass_pwoff_fn(pbp_device_block);
-       if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
-       else if (ret == 0)
-               len = sprintf(page, "off\n");
-       else
-               len = sprintf(page, "on\n");
+       int tap_param = user_on_off(buffer, count);
+       if (tap_param < 0)
+               return -EINVAL;
 
-       *eof = 1;
-       return len;
+       set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
+       return count;
 }
-
-int
-get_tap_pwup_pfs(char *page, char **start, off_t off, int count,
-                int *eof, void *data)
+static int show_tap_pwup(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_tap_pwup_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_tap_pwup_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(tap_pwup)
 
-int
-get_disc_pwup_pfs(char *page, char **start, off_t off, int count,
-                 int *eof, void *data)
+static ssize_t disc_pwup_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
+       int tap_param = user_on_off(buffer, count);
+       if (tap_param < 0)
+               return -EINVAL;
 
-       ret = get_disc_pwup_fn(pbp_device_block);
+       set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
+       return count;
+}
+static int show_disc_pwup(struct seq_file *m, void *v)
+{
+       bpctl_dev_t *dev = m->private;
+       int ret = get_disc_pwup_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(disc_pwup)
 
-int
-set_std_nic_pfs(struct file *file, const char *buffer,
-               unsigned long count, void *data)
+static ssize_t std_nic_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int bypass_param = 0, length = 0;
-
-       if (count >= sizeof(kbuf))
+       int bypass_param = user_on_off(buffer, count);
+       if (bypass_param < 0)
                return -EINVAL;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               bypass_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               bypass_param = 0;
-
-       set_std_nic_fn(pbp_device_block, bypass_param);
-
+       set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param);
        return count;
 }
-
-int
-get_std_nic_pfs(char *page, char **start, off_t off, int count,
-               int *eof, void *data)
+static int show_std_nic(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_std_nic_fn(pbp_device_block);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_std_nic_fn(dev);
        if (ret == BP_NOT_CAP)
-               len = sprintf(page, "fail\n");
+               seq_printf(m, "fail\n");
        else if (ret == 0)
-               len = sprintf(page, "off\n");
+               seq_printf(m, "off\n");
        else
-               len = sprintf(page, "on\n");
-
-       *eof = 1;
-       return len;
-}
-
-int
-get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count,
-                   int *eof, void *data)
-{
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_wd_exp_mode_fn(pbp_device_block);
-       if (ret == 1)
-               len = sprintf(page, "tap\n");
-       else if (ret == 0)
-               len = sprintf(page, "bypass\n");
-       else if (ret == 2)
-               len = sprintf(page, "disc\n");
-
-       else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "on\n");
+       return 0;
 }
+RW_FOPS(std_nic)
 
-int
-set_wd_exp_mode_pfs(struct file *file, const char *buffer,
-                   unsigned long count, void *data)
+static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-
        char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
        int bypass_param = 0, length = 0;
 
        if (count > (sizeof(kbuf) - 1))
                return -1;
 
-       if (copy_from_user(&kbuf, buffer, count)) {
+       if (copy_from_user(&kbuf, buffer, count))
                return -1;
-       }
 
        kbuf[count] = '\0';
        length = strlen(kbuf);
@@ -8377,143 +7788,47 @@ set_wd_exp_mode_pfs(struct file *file, const char *buffer,
        else if (strcmp(kbuf, "disc") == 0)
                bypass_param = 2;
 
-       set_wd_exp_mode_fn(pbp_device_block, bypass_param);
+       set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param);
 
        return count;
 }
-
-int
-get_wd_autoreset_pfs(char *page, char **start, off_t off, int count,
-                    int *eof, void *data)
+static int show_wd_exp_mode(struct seq_file *m, void *v)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int len = 0, ret = 0;
-
-       ret = get_wd_autoreset_fn(pbp_device_block);
-       if (ret >= 0)
-               len = sprintf(page, "%d\n", ret);
+       bpctl_dev_t *dev = m->private;
+       int ret = get_wd_exp_mode_fn(dev);
+       if (ret == 1)
+               seq_printf(m, "tap\n");
+       else if (ret == 0)
+               seq_printf(m, "bypass\n");
+       else if (ret == 2)
+               seq_printf(m, "disc\n");
        else
-               len = sprintf(page, "fail\n");
-
-       *eof = 1;
-       return len;
+               seq_printf(m, "fail\n");
+       return 0;
 }
+RW_FOPS(wd_exp_mode)
 
-int
-set_wd_autoreset_pfs(struct file *file, const char *buffer,
-                    unsigned long count, void *data)
+static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
        int timeout;
-       int ret;
-
-       ret = kstrtoint_from_user(buffer, count, 10, &timeout);
+       int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
        if (ret)
                return ret;
-       set_wd_autoreset_fn(pbp_device_block, timeout);
-
+       set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout);
        return count;
 }
-
-int
-set_tpl_pfs(struct file *file, const char *buffer,
-           unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tpl_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tpl_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tpl_param = 0;
-
-       set_tpl_fn(pbp_device_block, tpl_param);
-
-       return count;
-}
-
-#ifdef PMC_FIX_FLAG
-int
-set_wait_at_pwup_pfs(struct file *file, const char *buffer,
-                    unsigned long count, void *data)
-{
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tpl_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tpl_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tpl_param = 0;
-
-       set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param);
-
-       return count;
-}
-
-int
-set_hw_reset_pfs(struct file *file, const char *buffer,
-                unsigned long count, void *data)
+static int show_wd_autoreset(struct seq_file *m, void *v)
 {
-
-       char kbuf[256];
-       bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
-
-       int tpl_param = 0, length = 0;
-
-       if (count > (sizeof(kbuf) - 1))
-               return -1;
-
-       if (copy_from_user(&kbuf, buffer, count)) {
-               return -1;
-       }
-
-       kbuf[count] = '\0';
-       length = strlen(kbuf);
-       if (kbuf[length - 1] == '\n')
-               kbuf[--length] = '\0';
-
-       if (strcmp(kbuf, "on") == 0)
-               tpl_param = 1;
-       else if (strcmp(kbuf, "off") == 0)
-               tpl_param = 0;
-
-       set_bp_hw_reset_fn(pbp_device_block, tpl_param);
-
-       return count;
+       bpctl_dev_t *dev = m->private;
+       int ret = get_wd_autoreset_fn(dev);
+       if (ret >= 0)
+               seq_printf(m, "%d\n", ret);
+       else
+               seq_printf(m, "fail\n");
+       return 0;
 }
-
-#endif                         /*PMC_FIX_FLAG */
+RW_FOPS(wd_autoreset)
 
 int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block)
 {
@@ -8530,168 +7845,54 @@ int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block)
                return -1;
 
        /* create device proc dir */
-       procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir);
-       if (procfs_dir == 0) {
+       procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir);
+       if (!procfs_dir) {
                printk(KERN_DEBUG "Could not create procfs directory %s\n",
                       current_pfs->dir_name);
                return -1;
        }
        current_pfs->bypass_entry = procfs_dir;
 
-       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL,        /* write */
-                                       get_bypass_info_pfs,    /* read  */
-                                       procfs_dir, pbp_device_block))
-               ret = -1;
-
+#define ENTRY(x) ret |= procfs_add(#x, &x##_ops, pbp_device_block)
+       ENTRY(bypass_info);
        if (pbp_device_block->bp_caps & SW_CTL_CAP) {
-
                /* Create set param proc's */
-               if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL,      /* write */
-                                               get_bypass_slave_pfs,   /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL,        /* write */
-                                               get_bypass_caps_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL,        /* write */
-                                               get_wd_set_caps_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-               if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs,       /* write */
-                                               get_bypass_wd_pfs,      /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL,  /* write */
-                                               get_wd_expire_time_pfs, /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL,        /* write */
-                                               reset_bypass_wd_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs,     /* write */
-                                               get_std_nic_pfs,        /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
+               ENTRY(bypass_slave);
+               ENTRY(bypass_caps);
+               ENTRY(wd_set_caps);
+               ENTRY(bypass_wd);
+               ENTRY(wd_expire_time);
+               ENTRY(reset_bypass_wd);
+               ENTRY(std_nic);
                if (pbp_device_block->bp_caps & BP_CAP) {
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs,        /* write */
-                                                       get_bypass_pfs, /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs,    /* write */
-                                                       get_dis_bypass_pfs,     /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs, /* write */
-                                                       get_bypass_pwup_pfs,    /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs,      /* write */
-                                                       get_bypass_pwoff_pfs,   /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL,    /* write */
-                                                       get_bypass_change_pfs,  /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
+                       ENTRY(bypass);
+                       ENTRY(dis_bypass);
+                       ENTRY(bypass_pwup);
+                       ENTRY(bypass_pwoff);
+                       ENTRY(bypass_change);
                }
-
                if (pbp_device_block->bp_caps & TAP_CAP) {
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs, /* write */
-                                                       get_tap_pfs,    /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs,     /* write */
-                                                       get_dis_tap_pfs,        /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs,  /* write */
-                                                       get_tap_pwup_pfs,       /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL,  /* write */
-                                                       get_tap_change_pfs,     /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
+                       ENTRY(tap);
+                       ENTRY(dis_tap);
+                       ENTRY(tap_pwup);
+                       ENTRY(tap_change);
                }
                if (pbp_device_block->bp_caps & DISC_CAP) {
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs,       /* write */
-                                                       get_disc_pfs,   /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-#if 1
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs,   /* write */
-                                                       get_dis_disc_pfs,       /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-#endif
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs,        /* write */
-                                                       get_disc_pwup_pfs,      /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
-
-                       if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL, /* write */
-                                                       get_disc_change_pfs,    /* read  */
-                                                       procfs_dir,
-                                                       pbp_device_block))
-                               ret = -1;
+                       ENTRY(disc);
+                       ENTRY(dis_disc);
+                       ENTRY(disc_pwup);
+                       ENTRY(disc_change);
                }
 
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs, /* write */
-                                               get_wd_exp_mode_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
-               if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs,      /* write */
-                                               get_wd_autoreset_pfs,   /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-               if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs, /* write */
-                                               get_tpl_pfs,    /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
+               ENTRY(wd_exp_mode);
+               ENTRY(wd_autoreset);
+               ENTRY(tpl);
 #ifdef PMC_FIX_FLAG
-               if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs,       /* write */
-                                               get_wait_at_pwup_pfs,   /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-               if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs,       /* write */
-                                               get_hw_reset_pfs,       /* read  */
-                                               procfs_dir, pbp_device_block))
-                       ret = -1;
-
+               ENTRY(wait_at_pwup);
+               ENTRY(hw_reset);
 #endif
-
        }
+#undef ENTRY
        if (ret < 0)
                printk(KERN_DEBUG "Create proc entry failed\n");
 
@@ -8702,21 +7903,7 @@ int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block)
 {
 
        struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
-       struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr =
-           NULL;
-       char name[256];
-
-       if (!pde)
-               return 0;
-       for (pde = pde->subdir; pde;) {
-               strcpy(name, pde->name);
-               pde_curr = pde;
-               pde = pde->next;
-               remove_proc_entry(name, current_pfs->bypass_entry);
-       }
-       if (!pde)
-               remove_proc_entry(current_pfs->dir_name, bp_procfs_dir);
+       remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir);
        current_pfs->bypass_entry = NULL;
-
        return 0;
 }
index db1da28cecba84d4800363df964647e85b8177c9..be26917a68968897758d0ce70fbd56ebb976f484 100644 (file)
@@ -76,37 +76,28 @@ int drv_insert_node_res_element(void *hnode, void *node_resource,
        struct node_res_object **node_res_obj =
            (struct node_res_object **)node_resource;
        struct process_context *ctxt = (struct process_context *)process_ctxt;
-       int status = 0;
        int retval;
 
        *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
-       if (!*node_res_obj) {
-               status = -ENOMEM;
-               goto func_end;
-       }
+       if (!*node_res_obj)
+               return -ENOMEM;
 
        (*node_res_obj)->node = hnode;
-       retval = idr_get_new(ctxt->node_id, *node_res_obj,
-                                               &(*node_res_obj)->id);
-       if (retval == -EAGAIN) {
-               if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) {
-                       pr_err("%s: OUT OF MEMORY\n", __func__);
-                       status = -ENOMEM;
-                       goto func_end;
-               }
-
-               retval = idr_get_new(ctxt->node_id, *node_res_obj,
-                                               &(*node_res_obj)->id);
+       retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL);
+       if (retval >= 0) {
+               (*node_res_obj)->id = retval;
+               return 0;
        }
-       if (retval) {
+
+       kfree(*node_res_obj);
+
+       if (retval == -ENOSPC) {
                pr_err("%s: FAILED, IDR is FULL\n", __func__);
-               status = -EFAULT;
+               return -EFAULT;
+       } else {
+               pr_err("%s: OUT OF MEMORY\n", __func__);
+               return -ENOMEM;
        }
-func_end:
-       if (status)
-               kfree(*node_res_obj);
-
-       return status;
 }
 
 /* Release all Node resources and its context
@@ -201,35 +192,26 @@ int drv_proc_insert_strm_res_element(void *stream_obj,
        struct strm_res_object **pstrm_res =
            (struct strm_res_object **)strm_res;
        struct process_context *ctxt = (struct process_context *)process_ctxt;
-       int status = 0;
        int retval;
 
        *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
-       if (*pstrm_res == NULL) {
-               status = -EFAULT;
-               goto func_end;
-       }
+       if (*pstrm_res == NULL)
+               return -EFAULT;
 
        (*pstrm_res)->stream = stream_obj;
-       retval = idr_get_new(ctxt->stream_id, *pstrm_res,
-                                               &(*pstrm_res)->id);
-       if (retval == -EAGAIN) {
-               if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) {
-                       pr_err("%s: OUT OF MEMORY\n", __func__);
-                       status = -ENOMEM;
-                       goto func_end;
-               }
-
-               retval = idr_get_new(ctxt->stream_id, *pstrm_res,
-                                               &(*pstrm_res)->id);
+       retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL);
+       if (retval >= 0) {
+               (*pstrm_res)->id = retval;
+               return 0;
        }
-       if (retval) {
+
+       if (retval == -ENOSPC) {
                pr_err("%s: FAILED, IDR is FULL\n", __func__);
-               status = -EPERM;
+               return -EPERM;
+       } else {
+               pr_err("%s: OUT OF MEMORY\n", __func__);
+               return -ENOMEM;
        }
-
-func_end:
-       return status;
 }
 
 static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
index 453c83d7fe8ccbb82dbaa79d55ac96f6336772a0..a89ab9bf38e45946c0dfbb2fd5fe807d7abfa807 100644 (file)
@@ -60,6 +60,7 @@
  */
 #undef __NO_VERSION__
 
+#include <linux/file.h>
 #include "device.h"
 #include "card.h"
 #include "channel.h"
@@ -2946,87 +2947,51 @@ static int Config_FileGetParameter(unsigned char *string,
  return true;
 }
 
-int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter) {
-    unsigned char *config_path = CONFIG_PATH;
-    unsigned char *buffer = NULL;
-    unsigned char tmpbuffer[20];
-    struct file   *filp=NULL;
-    mm_segment_t old_fs = get_fs();
-    //int oldfsuid=0,oldfsgid=0;
-    int result=0;
-
-    set_fs (KERNEL_DS);
-
-    /* Can't do this anymore, so we rely on correct filesystem permissions:
-    //Make sure a caller can read or write power as root
-    oldfsuid=current->cred->fsuid;
-    oldfsgid=current->cred->fsgid;
-    current->cred->fsuid = 0;
-    current->cred->fsgid = 0;
-    */
-
-    //open file
-      filp = filp_open(config_path, O_RDWR, 0);
-        if (IS_ERR(filp)) {
-            printk("Config_FileOperation:open file fail?\n");
-            result=-1;
-             goto error2;
-         }
+int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter)
+{
+       unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
+       unsigned char tmpbuffer[20];
+       struct file *file;
+       int result=0;
 
-     if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
-           printk("file %s cann't readable or writable?\n",config_path);
-         result = -1;
-         goto error1;
-       }
-
-buffer = kmalloc(1024, GFP_KERNEL);
-if(buffer==NULL) {
-  printk("allocate mem for file fail?\n");
-  result = -1;
-  goto error1;
-}
+       if (!buffer) {
+               printk("allocate mem for file fail?\n");
+               return -1;
+       }
+       file = filp_open(CONFIG_PATH, O_RDONLY, 0);
+       if (IS_ERR(file)) {
+               kfree(buffer);
+               printk("Config_FileOperation:open file fail?\n");
+               return -1;
+       }
 
-if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
- printk("read file error?\n");
- result = -1;
- goto error1;
-}
+       if (kernel_read(file, 0, buffer, 1024) < 0) {
              printk("read file error?\n");
              result = -1;
              goto error1;
+       }
 
-if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
-  printk("get parameter error?\n");
-  result = -1;
-  goto error1;
-}
+       if (Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
+               printk("get parameter error?\n");
+               result = -1;
+               goto error1;
+       }
 
-if(memcmp(tmpbuffer,"USA",3)==0) {
-  result=ZoneType_USA;
-}
-else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
-  result=ZoneType_Japan;
-}
-else if(memcmp(tmpbuffer,"EUROPE",5)==0) {
- result=ZoneType_Europe;
-}
-else {
-  result = -1;
-  printk("Unknown Zonetype[%s]?\n",tmpbuffer);
-}
+       if (memcmp(tmpbuffer,"USA",3)==0) {
+               result = ZoneType_USA;
+       } else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
+               result = ZoneType_Japan;
+       } else if(memcmp(tmpbuffer,"EUROPE",5)==0) {
+               result = ZoneType_Europe;
+       } else {
+               result = -1;
+               printk("Unknown Zonetype[%s]?\n",tmpbuffer);
+       }
 
 error1:
-  kfree(buffer);
-
-  if(filp_close(filp,NULL))
-       printk("Config_FileOperation:close file fail\n");
-
-error2:
-  set_fs (old_fs);
-
-  /*
-  current->cred->fsuid=oldfsuid;
-  current->cred->fsgid=oldfsgid;
-  */
-
-  return result;
+       kfree(buffer);
+       fput(file);
+       return result;
 }
 
 
index 22918a106d7365df4e1f1dbd06bd975c7f9c41d1..d2479b766450e69e81d198ad768b5564ad3f6336 100644 (file)
@@ -790,7 +790,7 @@ u64 CARDqGetNextTBTT(u64 qwTSF, WORD wBeaconInterval)
        if ((~uLowNextTBTT) < uLowRemain)
                qwTSF = ((qwTSF >> 32) + 1) << 32;
 
-       qwTSF = (qwTSF & 0xffffffff00000000UL) |
+       qwTSF = (qwTSF & 0xffffffff00000000ULL) |
                (u64)(uLowNextTBTT + uLowRemain);
 
     return (qwTSF);
index d5f53e1a74a2e8509e5e3f28eb77b17fa8943204..457d91c1325d5ec1f4e43c76496bf4cb94962302 100644 (file)
@@ -46,6 +46,7 @@
  */
 #undef __NO_VERSION__
 
+#include <linux/file.h>
 #include "device.h"
 #include "card.h"
 #include "baseband.h"
@@ -669,8 +670,6 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
        if (device->flags & DEVICE_FLAGS_OPENED)
                device_close(device->dev);
 
-       usb_put_dev(interface_to_usbdev(intf));
-
        return 0;
 }
 
@@ -681,8 +680,6 @@ static int vt6656_resume(struct usb_interface *intf)
        if (!device || !device->dev)
                return -ENODEV;
 
-       usb_get_dev(interface_to_usbdev(intf));
-
        if (!(device->flags & DEVICE_FLAGS_OPENED))
                device_open(device->dev);
 
@@ -1320,53 +1317,29 @@ static int Config_FileGetParameter(unsigned char *string,
 /* if read fails, return NULL, or return data pointer */
 static unsigned char *Config_FileOperation(struct vnt_private *pDevice)
 {
-    unsigned char *config_path = CONFIG_PATH;
-    unsigned char *buffer = NULL;
-    struct file   *filp=NULL;
-    mm_segment_t old_fs = get_fs();
-
-    int result = 0;
-
-    set_fs (KERNEL_DS);
-
-    /* open file */
-      filp = filp_open(config_path, O_RDWR, 0);
-        if (IS_ERR(filp)) {
-            printk("Config_FileOperation file Not exist\n");
-            result=-1;
-             goto error2;
-         }
+       unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
+       struct file   *file;
 
-     if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
-           printk("file %s is not read or writeable?\n",config_path);
-         result = -1;
-         goto error1;
-       }
-
-    buffer = kmalloc(1024, GFP_KERNEL);
-    if(buffer==NULL) {
-      printk("allocate mem for file fail?\n");
-      result = -1;
-      goto error1;
-    }
-
-    if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
-     printk("read file error?\n");
-     result = -1;
-    }
+       if (!buffer) {
+               printk("allocate mem for file fail?\n");
+               return NULL;
+       }
 
-error1:
-  if(filp_close(filp,NULL))
-       printk("Config_FileOperation:close file fail\n");
+       file = filp_open(CONFIG_PATH, O_RDONLY, 0);
+       if (IS_ERR(file)) {
+               kfree(buffer);
+               printk("Config_FileOperation file Not exist\n");
+               return NULL;
+       }
 
-error2:
-  set_fs (old_fs);
+       if (kernel_read(file, 0, buffer, 1024) < 0) {
+               printk("read file error?\n");
+               kfree(buffer);
+               buffer = NULL;
+       }
 
-if(result!=0) {
-    kfree(buffer);
-    buffer=NULL;
-}
-  return buffer;
+       fput(file);
+       return buffer;
 }
 
 /* return --->-1:fail; >=0:successful */
index f5f120a62460a36f4aa9085797a481399fee01de..c4264e8c877d614cc1fa184630effac90fc6d718 100644 (file)
@@ -73,6 +73,7 @@
 
 #include <linux/module.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 // #include <linux/sched.h>
 void wl_isr_handler( unsigned long p );
 
 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
-//int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
-int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
+static int scull_read_procmem(struct seq_file *m, void *v);
 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
-static void proc_write(const char *name, write_proc_t *w, void *data);
+
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int scull_read_procmem_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, scull_read_procmem, PDE_DATA(inode));
+}
+
+static const struct file_operations scull_read_procmem_fops = {
+       .open           = scull_read_procmem_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
 #endif /* SCULL_USE_PROC */
 
@@ -908,9 +922,8 @@ int wl_insert( struct net_device *dev )
        }
 
 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
-       create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
+       proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
        proc_mkdir("driver/wlags49", 0);
-       proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
 #endif /* SCULL_USE_PROC */
 
        DBG_LEAVE( DbgInfo );
@@ -2097,7 +2110,7 @@ static void __exit wl_module_exit( void )
 
        wl_adapter_cleanup_module( );
 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
-       remove_proc_entry( "wlags", NULL );             //;?why so a-symmetric compared to location of create_proc_read_entry
+       remove_proc_entry( "wlags", NULL );             //;?why so a-symmetric compared to location of proc_create_data
 #endif
 
        DBG_LEAVE( DbgInfo );
@@ -3531,229 +3544,215 @@ void wl_wds_netdev_deregister( struct wl_private *lp )
 /*
  * The proc filesystem: function to read and entry
  */
-int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
-int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
+static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
+{
+       int i, len;
 
-int i, len;
+       seq_printf(m, "%-20.20s: ", s);
+       len = 22;
 
-       len = sprintf(buf, "%s", s );
-       while ( len < 20 ) len += sprintf(buf+len, " " );
-       len += sprintf(buf+len,": " );
-       for ( i = 0; i < n; i++ ) {
-               if ( len % 80 > 75 ) {
-                       len += sprintf(buf+len,"\n" );
-               }
-               len += sprintf(buf+len,"%04X ", p[i] );
+       for (i = 0; i < n; i++) {
+               if (len % 80 > 75)
+                       seq_putc(m, '\n');
+               seq_printf(m, "%04X ", p[i]);
        }
-       len += sprintf(buf+len,"\n" );
-       return len;
-} // printf_hcf_16
+       seq_putc(m, '\n');
+}
 
-int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
-int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
+static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
+{
+       int i, len;
 
-int i, len;
+       seq_printf(m, "%-20.20s: ", s);
+       len = 22;
 
-       len = sprintf(buf, "%s", s );
-       while ( len < 20 ) len += sprintf(buf+len, " " );
-       len += sprintf(buf+len,": " );
-       for ( i = 0; i <= n; i++ ) {
-               if ( len % 80 > 77 ) {
-                       len += sprintf(buf+len,"\n" );
-               }
-               len += sprintf(buf+len,"%02X ", p[i] );
+       for (i = 0; i <= n; i++) {
+               if (len % 80 > 77)
+                       seq_putc(m, '\n');
+               seq_printf(m, "%02X ", p[i]);
        }
-       len += sprintf(buf+len,"\n" );
-       return len;
-} // printf_hcf8
+       seq_putc(m, '\n');
+}
 
-int printf_strct( char *s, char *buf, hcf_16* p );
-int printf_strct( char *s, char *buf, hcf_16* p ) {
+static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
+{
+       int i, len;
 
-int i, len;
+       seq_printf(m, "%-20.20s: ", s);
+       len = 22;
 
-       len = sprintf(buf, "%s", s );
-       while ( len < 20 ) len += sprintf(buf+len, " " );
-       len += sprintf(buf+len,": " );
        for ( i = 0; i <= *p; i++ ) {
-               if ( len % 80 > 75 ) {
-                       len += sprintf(buf+len,"\n" );
-               }
-               len += sprintf(buf+len,"%04X ", p[i] );
+               if (len % 80 > 75)
+                       seq_putc(m, '\n');
+               seq_printf(m,"%04X ", p[i]);
        }
-       len += sprintf(buf+len,"\n" );
-       return len;
-} // printf_strct
+       seq_putc(m, '\n');
+}
 
-int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
+int scull_read_procmem(struct seq_file *m, void *v)
 {
-       struct wl_private       *lp = NULL;
+       struct wl_private       *lp = m->private;
        IFBP                            ifbp;
        CFG_HERMES_TALLIES_STRCT *p;
 
-    #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
-
-    len=0;
-
-       lp = ((struct net_device *)data)->priv;
        if (lp == NULL) {
-        len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
+               seq_puts(m, "No wl_private in scull_read_procmem\n" );
        } else if ( lp->wlags49_type == 0 ){
-           ifbp = &lp->hcfCtx;
-           len += sprintf(buf+len,"Magic:               0x%04X\n", ifbp->IFB_Magic );
-           len += sprintf(buf+len,"IOBase:              0x%04X\n", ifbp->IFB_IOBase );
-           len += sprintf(buf+len,"LinkStat:            0x%04X\n", ifbp->IFB_LinkStat );
-           len += sprintf(buf+len,"DSLinkStat:          0x%04X\n", ifbp->IFB_DSLinkStat );
-           len += sprintf(buf+len,"TickIni:         0x%08lX\n", ifbp->IFB_TickIni );
-           len += sprintf(buf+len,"TickCnt:             0x%04X\n", ifbp->IFB_TickCnt );
-           len += sprintf(buf+len,"IntOffCnt:           0x%04X\n", ifbp->IFB_IntOffCnt );
-               len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
-                                                         &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
+               ifbp = &lp->hcfCtx;
+               seq_printf(m, "Magic:               0x%04X\n", ifbp->IFB_Magic );
+               seq_printf(m, "IOBase:              0x%04X\n", ifbp->IFB_IOBase );
+               seq_printf(m, "LinkStat:            0x%04X\n", ifbp->IFB_LinkStat );
+               seq_printf(m, "DSLinkStat:          0x%04X\n", ifbp->IFB_DSLinkStat );
+               seq_printf(m, "TickIni:         0x%08lX\n", ifbp->IFB_TickIni );
+               seq_printf(m, "TickCnt:             0x%04X\n", ifbp->IFB_TickCnt );
+               seq_printf(m, "IntOffCnt:           0x%04X\n", ifbp->IFB_IntOffCnt );
+               printf_hcf_16(m, "IFB_FWIdentity",
+                             &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
        } else if ( lp->wlags49_type == 1 ) {
-           len += sprintf(buf+len,"Channel:              0x%04X\n", lp->Channel );
-/****** len += sprintf(buf+len,"slock:                  %d\n", lp->slock );            */
+               seq_printf(m, "Channel:              0x%04X\n", lp->Channel );
+/****** seq_printf(m, "slock:                  %d\n", lp->slock );             */
 //x            struct tq_struct            "task:               0x%04X\n", lp->task );
 //x            struct net_device_stats     "stats:              0x%04X\n", lp->stats );
 #ifdef WIRELESS_EXT
 //x            struct iw_statistics        "wstats:             0x%04X\n", lp->wstats );
-//x        len += sprintf(buf+len,"spy_number:           0x%04X\n", lp->spy_number );
+//x        seq_printf(m, "spy_number:           0x%04X\n", lp->spy_number );
 //x            u_char                      spy_address[IW_MAX_SPY][ETH_ALEN];
 //x            struct iw_quality           spy_stat[IW_MAX_SPY];
 #endif // WIRELESS_EXT
-           len += sprintf(buf+len,"IFB:                  0x%p\n", &lp->hcfCtx );
-           len += sprintf(buf+len,"flags:                %#.8lX\n", lp->flags );  //;?use this format from now on
-           len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
+               seq_printf(m, "IFB:                  0x%p\n", &lp->hcfCtx );
+               seq_printf(m, "flags:                %#.8lX\n", lp->flags );  //;?use this format from now on
+               seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
 #if DBG
-           len += sprintf(buf+len,"DebugFlag (DbgInfo):   0x%08lX\n", DbgInfo->DebugFlag );
+               seq_printf(m, "DebugFlag (DbgInfo):   0x%08lX\n", DbgInfo->DebugFlag );
 #endif // DBG
-           len += sprintf(buf+len,"is_registered:        0x%04X\n", lp->is_registered );
+               seq_printf(m, "is_registered:        0x%04X\n", lp->is_registered );
 //x            CFG_DRV_INFO_STRCT          "driverInfo:         0x%04X\n", lp->driverInfo );
-               len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
+               printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
 //x            CFG_IDENTITY_STRCT          "driverIdentity:     0x%04X\n", lp->driverIdentity );
-               len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
+               printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
 //x            CFG_FW_IDENTITY_STRCT       "StationIdentity:    0x%04X\n", lp->StationIdentity );
-               len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
+               printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
 //x            CFG_PRI_IDENTITY_STRCT      "PrimaryIdentity:    0x%04X\n", lp->PrimaryIdentity );
-               len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
-               len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
+               printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
+               printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
 //x            CFG_PRI_IDENTITY_STRCT      "NICIdentity:        0x%04X\n", lp->NICIdentity );
-               len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
+               printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
 //x            ltv_t                       "ltvRecord:          0x%04X\n", lp->ltvRecord );
-           len += sprintf(buf+len,"txBytes:              0x%08lX\n", lp->txBytes );
-           len += sprintf(buf+len,"maxPort:              0x%04X\n", lp->maxPort );        /* 0 for STA, 6 for AP */
-       /* Elements used for async notification from hardware */
+               seq_printf(m, "txBytes:              0x%08lX\n", lp->txBytes );
+               seq_printf(m, "maxPort:              0x%04X\n", lp->maxPort );        /* 0 for STA, 6 for AP */
+               /* Elements used for async notification from hardware */
 //x            RID_LOG_STRCT                           RidList[10];
 //x            ltv_t                       "updatedRecord:      0x%04X\n", lp->updatedRecord );
 //x            PROBE_RESP                                  "ProbeResp:                    0x%04X\n", lp->ProbeResp );
 //x            ASSOC_STATUS_STRCT          "assoc_stat:         0x%04X\n", lp->assoc_stat );
 //x            SECURITY_STATUS_STRCT       "sec_stat:           0x%04X\n", lp->sec_stat );
 //x            u_char                      lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
-           len += sprintf(buf+len,"PortType:             0x%04X\n", lp->PortType );           // 1 - 3 (1 [Normal] | 3 [AdHoc])
-           len += sprintf(buf+len,"Channel:              0x%04X\n", lp->Channel );            // 0 - 14 (0)
+               seq_printf(m, "PortType:             0x%04X\n", lp->PortType );           // 1 - 3 (1 [Normal] | 3 [AdHoc])
+               seq_printf(m, "Channel:              0x%04X\n", lp->Channel );            // 0 - 14 (0)
 //x            hcf_16                      TxRateControl[2];
-           len += sprintf(buf+len,"TxRateControl[2]:     0x%04X 0x%04X\n",
-                                               lp->TxRateControl[0], lp->TxRateControl[1] );
-           len += sprintf(buf+len,"DistanceBetweenAPs:   0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
-           len += sprintf(buf+len,"RTSThreshold:         0x%04X\n", lp->RTSThreshold );       // 0 - 2347 (2347)
-           len += sprintf(buf+len,"PMEnabled:            0x%04X\n", lp->PMEnabled );          // 0 - 2, 8001 - 8002 (0)
-           len += sprintf(buf+len,"MicrowaveRobustness:  0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
-           len += sprintf(buf+len,"CreateIBSS:           0x%04X\n", lp->CreateIBSS );         // 0 - 1 (0)
-           len += sprintf(buf+len,"MulticastReceive:     0x%04X\n", lp->MulticastReceive );   // 0 - 1 (1)
-           len += sprintf(buf+len,"MaxSleepDuration:     0x%04X\n", lp->MaxSleepDuration );   // 0 - 65535 (100)
+               seq_printf(m, "TxRateControl[2]:     0x%04X 0x%04X\n",
+                              lp->TxRateControl[0], lp->TxRateControl[1] );
+               seq_printf(m, "DistanceBetweenAPs:   0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
+               seq_printf(m, "RTSThreshold:         0x%04X\n", lp->RTSThreshold );       // 0 - 2347 (2347)
+               seq_printf(m, "PMEnabled:            0x%04X\n", lp->PMEnabled );          // 0 - 2, 8001 - 8002 (0)
+               seq_printf(m, "MicrowaveRobustness:  0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
+               seq_printf(m, "CreateIBSS:           0x%04X\n", lp->CreateIBSS );         // 0 - 1 (0)
+               seq_printf(m, "MulticastReceive:     0x%04X\n", lp->MulticastReceive );   // 0 - 1 (1)
+               seq_printf(m, "MaxSleepDuration:     0x%04X\n", lp->MaxSleepDuration );   // 0 - 65535 (100)
 //x            hcf_8                       MACAddress[ETH_ALEN];
-               len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
+               printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
 //x            char                        NetworkName[HCF_MAX_NAME_LEN+1];
-           len += sprintf(buf+len,"NetworkName:          %.32s\n", lp->NetworkName );
+               seq_printf(m, "NetworkName:          %.32s\n", lp->NetworkName );
 //x            char                        StationName[HCF_MAX_NAME_LEN+1];
-           len += sprintf(buf+len,"EnableEncryption:     0x%04X\n", lp->EnableEncryption );   // 0 - 1 (0)
+               seq_printf(m, "EnableEncryption:     0x%04X\n", lp->EnableEncryption );   // 0 - 1 (0)
 //x            char                        Key1[MAX_KEY_LEN+1];
-               len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
+               printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
 //x            char                        Key2[MAX_KEY_LEN+1];
 //x            char                        Key3[MAX_KEY_LEN+1];
 //x            char                        Key4[MAX_KEY_LEN+1];
-           len += sprintf(buf+len,"TransmitKeyID:        0x%04X\n", lp->TransmitKeyID );      // 1 - 4 (1)
+               seq_printf(m, "TransmitKeyID:        0x%04X\n", lp->TransmitKeyID );      // 1 - 4 (1)
 //x            CFG_DEFAULT_KEYS_STRCT      "DefaultKeys:         0x%04X\n", lp->DefaultKeys );
 //x            u_char                      mailbox[MB_SIZE];
 //x            char                        szEncryption[MAX_ENC_LEN];
-           len += sprintf(buf+len,"driverEnable:         0x%04X\n", lp->driverEnable );
-           len += sprintf(buf+len,"wolasEnable:          0x%04X\n", lp->wolasEnable );
-           len += sprintf(buf+len,"atimWindow:           0x%04X\n", lp->atimWindow );
-           len += sprintf(buf+len,"holdoverDuration:     0x%04X\n", lp->holdoverDuration );
+               seq_printf(m, "driverEnable:         0x%04X\n", lp->driverEnable );
+               seq_printf(m, "wolasEnable:          0x%04X\n", lp->wolasEnable );
+               seq_printf(m, "atimWindow:           0x%04X\n", lp->atimWindow );
+               seq_printf(m, "holdoverDuration:     0x%04X\n", lp->holdoverDuration );
 //x            hcf_16                      MulticastRate[2];
-           len += sprintf(buf+len,"authentication:       0x%04X\n", lp->authentication ); // is this AP specific?
-           len += sprintf(buf+len,"promiscuousMode:      0x%04X\n", lp->promiscuousMode );
-           len += sprintf(buf+len,"DownloadFirmware:     0x%04X\n", lp->DownloadFirmware );   // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
-           len += sprintf(buf+len,"AuthKeyMgmtSuite:     0x%04X\n", lp->AuthKeyMgmtSuite );
-           len += sprintf(buf+len,"loadBalancing:        0x%04X\n", lp->loadBalancing );
-           len += sprintf(buf+len,"mediumDistribution:   0x%04X\n", lp->mediumDistribution );
-           len += sprintf(buf+len,"txPowLevel:           0x%04X\n", lp->txPowLevel );
-//         len += sprintf(buf+len,"shortRetryLimit:    0x%04X\n", lp->shortRetryLimit );
-//         len += sprintf(buf+len,"longRetryLimit:     0x%04X\n", lp->longRetryLimit );
+               seq_printf(m, "authentication:       0x%04X\n", lp->authentication ); // is this AP specific?
+               seq_printf(m, "promiscuousMode:      0x%04X\n", lp->promiscuousMode );
+               seq_printf(m, "DownloadFirmware:     0x%04X\n", lp->DownloadFirmware );   // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
+               seq_printf(m, "AuthKeyMgmtSuite:     0x%04X\n", lp->AuthKeyMgmtSuite );
+               seq_printf(m, "loadBalancing:        0x%04X\n", lp->loadBalancing );
+               seq_printf(m, "mediumDistribution:   0x%04X\n", lp->mediumDistribution );
+               seq_printf(m, "txPowLevel:           0x%04X\n", lp->txPowLevel );
+//         seq_printf(m, "shortRetryLimit:    0x%04X\n", lp->shortRetryLimit );
+//         seq_printf(m, "longRetryLimit:     0x%04X\n", lp->longRetryLimit );
 //x            hcf_16                      srsc[2];
 //x            hcf_16                      brsc[2];
-           len += sprintf(buf+len,"connectionControl:    0x%04X\n", lp->connectionControl );
+               seq_printf(m, "connectionControl:    0x%04X\n", lp->connectionControl );
 //x            //hcf_16                      probeDataRates[2];
-           len += sprintf(buf+len,"ownBeaconInterval:    0x%04X\n", lp->ownBeaconInterval );
-           len += sprintf(buf+len,"coexistence:          0x%04X\n", lp->coexistence );
+               seq_printf(m, "ownBeaconInterval:    0x%04X\n", lp->ownBeaconInterval );
+               seq_printf(m, "coexistence:          0x%04X\n", lp->coexistence );
 //x            WVLAN_FRAME                 "txF:                0x%04X\n", lp->txF );
 //x            WVLAN_LFRAME                txList[DEFAULT_NUM_TX_FRAMES];
 //x            struct list_head            "txFree:             0x%04X\n", lp->txFree );
 //x            struct list_head            txQ[WVLAN_MAX_TX_QUEUES];
-           len += sprintf(buf+len,"netif_queue_on:       0x%04X\n", lp->netif_queue_on );
-           len += sprintf(buf+len,"txQ_count:            0x%04X\n", lp->txQ_count );
+               seq_printf(m, "netif_queue_on:       0x%04X\n", lp->netif_queue_on );
+               seq_printf(m, "txQ_count:            0x%04X\n", lp->txQ_count );
 //x            DESC_STRCT                  "desc_rx:            0x%04X\n", lp->desc_rx );
 //x            DESC_STRCT                  "desc_tx:            0x%04X\n", lp->desc_tx );
 //x            WVLAN_PORT_STATE            "portState:          0x%04X\n", lp->portState );
 //x            ScanResult                  "scan_results:       0x%04X\n", lp->scan_results );
 //x            ProbeResult                 "probe_results:      0x%04X\n", lp->probe_results );
-           len += sprintf(buf+len,"probe_num_aps:        0x%04X\n", lp->probe_num_aps );
-           len += sprintf(buf+len,"use_dma:              0x%04X\n", lp->use_dma );
+               seq_printf(m, "probe_num_aps:        0x%04X\n", lp->probe_num_aps );
+               seq_printf(m, "use_dma:              0x%04X\n", lp->use_dma );
 //x            DMA_STRCT                   "dma:                0x%04X\n", lp->dma );
 #ifdef USE_RTS
-           len += sprintf(buf+len,"useRTS:               0x%04X\n", lp->useRTS );
+               seq_printf(m, "useRTS:               0x%04X\n", lp->useRTS );
 #endif  // USE_RTS
 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
                //;?should we restore this to allow smaller memory footprint
                //;?I guess not. This should be brought under Debug mode only
-           len += sprintf(buf+len,"DTIMPeriod:           0x%04X\n", lp->DTIMPeriod );         // 1 - 255 (1)
-           len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
-           len += sprintf(buf+len,"RejectAny:            0x%04X\n", lp->RejectAny );          // 0 - 1 (0)
-           len += sprintf(buf+len,"ExcludeUnencrypted:   0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
-           len += sprintf(buf+len,"intraBSSRelay:        0x%04X\n", lp->intraBSSRelay );
-           len += sprintf(buf+len,"wlags49_type:             0x%08lX\n", lp->wlags49_type );
+               seq_printf(m, "DTIMPeriod:           0x%04X\n", lp->DTIMPeriod );         // 1 - 255 (1)
+               seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
+               seq_printf(m, "RejectAny:            0x%04X\n", lp->RejectAny );          // 0 - 1 (0)
+               seq_printf(m, "ExcludeUnencrypted:   0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
+               seq_printf(m, "intraBSSRelay:        0x%04X\n", lp->intraBSSRelay );
+               seq_printf(m, "wlags49_type:             0x%08lX\n", lp->wlags49_type );
 #ifdef USE_WDS
 //x            WVLAN_WDS_IF                wds_port[NUM_WDS_PORTS];
 #endif // USE_WDS
 #endif // HCF_AP
        } else if ( lp->wlags49_type == 2 ){
-        len += sprintf(buf+len,"tallies to be added\n" );
+               seq_printf(m, "tallies to be added\n" );
 //Hermes Tallies (IFB substructure) {
-           p = &lp->hcfCtx.IFB_NIC_Tallies;
-        len += sprintf(buf+len,"TxUnicastFrames:          %08lX\n", p->TxUnicastFrames );
-        len += sprintf(buf+len,"TxMulticastFrames:        %08lX\n", p->TxMulticastFrames );
-        len += sprintf(buf+len,"TxFragments:              %08lX\n", p->TxFragments );
-        len += sprintf(buf+len,"TxUnicastOctets:          %08lX\n", p->TxUnicastOctets );
-        len += sprintf(buf+len,"TxMulticastOctets:        %08lX\n", p->TxMulticastOctets );
-        len += sprintf(buf+len,"TxDeferredTransmissions:  %08lX\n", p->TxDeferredTransmissions );
-        len += sprintf(buf+len,"TxSingleRetryFrames:      %08lX\n", p->TxSingleRetryFrames );
-        len += sprintf(buf+len,"TxMultipleRetryFrames:    %08lX\n", p->TxMultipleRetryFrames );
-        len += sprintf(buf+len,"TxRetryLimitExceeded:     %08lX\n", p->TxRetryLimitExceeded );
-        len += sprintf(buf+len,"TxDiscards:               %08lX\n", p->TxDiscards );
-        len += sprintf(buf+len,"RxUnicastFrames:          %08lX\n", p->RxUnicastFrames );
-        len += sprintf(buf+len,"RxMulticastFrames:        %08lX\n", p->RxMulticastFrames );
-        len += sprintf(buf+len,"RxFragments:              %08lX\n", p->RxFragments );
-        len += sprintf(buf+len,"RxUnicastOctets:          %08lX\n", p->RxUnicastOctets );
-        len += sprintf(buf+len,"RxMulticastOctets:        %08lX\n", p->RxMulticastOctets );
-        len += sprintf(buf+len,"RxFCSErrors:              %08lX\n", p->RxFCSErrors );
-        len += sprintf(buf+len,"RxDiscardsNoBuffer:       %08lX\n", p->RxDiscardsNoBuffer );
-        len += sprintf(buf+len,"TxDiscardsWrongSA:        %08lX\n", p->TxDiscardsWrongSA );
-        len += sprintf(buf+len,"RxWEPUndecryptable:       %08lX\n", p->RxWEPUndecryptable );
-        len += sprintf(buf+len,"RxMsgInMsgFragments:      %08lX\n", p->RxMsgInMsgFragments );
-        len += sprintf(buf+len,"RxMsgInBadMsgFragments:   %08lX\n", p->RxMsgInBadMsgFragments );
-        len += sprintf(buf+len,"RxDiscardsWEPICVError:    %08lX\n", p->RxDiscardsWEPICVError );
-        len += sprintf(buf+len,"RxDiscardsWEPExcluded:    %08lX\n", p->RxDiscardsWEPExcluded );
+               p = &lp->hcfCtx.IFB_NIC_Tallies;
+               seq_printf(m, "TxUnicastFrames:          %08lX\n", p->TxUnicastFrames );
+               seq_printf(m, "TxMulticastFrames:        %08lX\n", p->TxMulticastFrames );
+               seq_printf(m, "TxFragments:              %08lX\n", p->TxFragments );
+               seq_printf(m, "TxUnicastOctets:          %08lX\n", p->TxUnicastOctets );
+               seq_printf(m, "TxMulticastOctets:        %08lX\n", p->TxMulticastOctets );
+               seq_printf(m, "TxDeferredTransmissions:  %08lX\n", p->TxDeferredTransmissions );
+               seq_printf(m, "TxSingleRetryFrames:      %08lX\n", p->TxSingleRetryFrames );
+               seq_printf(m, "TxMultipleRetryFrames:    %08lX\n", p->TxMultipleRetryFrames );
+               seq_printf(m, "TxRetryLimitExceeded:     %08lX\n", p->TxRetryLimitExceeded );
+               seq_printf(m, "TxDiscards:               %08lX\n", p->TxDiscards );
+               seq_printf(m, "RxUnicastFrames:          %08lX\n", p->RxUnicastFrames );
+               seq_printf(m, "RxMulticastFrames:        %08lX\n", p->RxMulticastFrames );
+               seq_printf(m, "RxFragments:              %08lX\n", p->RxFragments );
+               seq_printf(m, "RxUnicastOctets:          %08lX\n", p->RxUnicastOctets );
+               seq_printf(m, "RxMulticastOctets:        %08lX\n", p->RxMulticastOctets );
+               seq_printf(m, "RxFCSErrors:              %08lX\n", p->RxFCSErrors );
+               seq_printf(m, "RxDiscardsNoBuffer:       %08lX\n", p->RxDiscardsNoBuffer );
+               seq_printf(m, "TxDiscardsWrongSA:        %08lX\n", p->TxDiscardsWrongSA );
+               seq_printf(m, "RxWEPUndecryptable:       %08lX\n", p->RxWEPUndecryptable );
+               seq_printf(m, "RxMsgInMsgFragments:      %08lX\n", p->RxMsgInMsgFragments );
+               seq_printf(m, "RxMsgInBadMsgFragments:   %08lX\n", p->RxMsgInBadMsgFragments );
+               seq_printf(m, "RxDiscardsWEPICVError:    %08lX\n", p->RxDiscardsWEPICVError );
+               seq_printf(m, "RxDiscardsWEPExcluded:    %08lX\n", p->RxDiscardsWEPExcluded );
 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
-        //to be added ;?
+               //to be added ;?
 #endif // HCF_EXT_TALLIES_FW
        } else if ( lp->wlags49_type & 0x8000 ) {       //;?kludgy but it is unclear to me were else to place this
 #if DBG
@@ -3761,27 +3760,19 @@ int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof,
 #endif // DBG
                lp->wlags49_type = 0;                           //default to IFB again ;?
        } else {
-        len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
-        len += sprintf(buf+len,"0x0000 - IFB\n" );
-        len += sprintf(buf+len,"0x0001 - wl_private\n" );
-        len += sprintf(buf+len,"0x0002 - Tallies\n" );
-        len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
-        len += sprintf(buf+len,"ERROR    0001\nWARNING  0002\nNOTICE   0004\nTRACE    0008\n" );
-        len += sprintf(buf+len,"VERBOSE  0010\nPARAM    0020\nBREAK    0040\nRX       0100\n" );
-        len += sprintf(buf+len,"TX       0200\nDS       0400\n" );
-       }
-    return len;
+               seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
+               seq_puts(m,
+                        "0x0000 - IFB\n"
+                        "0x0001 - wl_private\n"
+                        "0x0002 - Tallies\n"
+                        "0x8xxx - Change debufflag\n"
+                        "ERROR    0001\nWARNING  0002\nNOTICE   0004\nTRACE    0008\n"
+                        "VERBOSE  0010\nPARAM    0020\nBREAK    0040\nRX       0100\n"
+                        "TX       0200\nDS       0400\n");
+       }
+       return 0;
 } // scull_read_procmem
 
-static void proc_write(const char *name, write_proc_t *w, void *data)
-{
-       struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
-       if (entry) {
-               entry->write_proc = w;
-               entry->data = data;
-       }
-} // proc_write
-
 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
 {
        static char             proc_number[11];
index aa2a1a763aa41440a1663e0c5e8b45153294708c..f6e1e5209d88586f6e33fc43138bed199fb239af 100644 (file)
@@ -300,27 +300,22 @@ static u8 r2net_num_from_nn(struct r2net_node *nn)
 
 static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw)
 {
-       int ret = 0;
+       int ret;
 
-       do {
-               if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) {
-                       ret = -EAGAIN;
-                       break;
-               }
-               spin_lock(&nn->nn_lock);
-               ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id);
-               if (ret == 0)
-                       list_add_tail(&nsw->ns_node_item,
-                                     &nn->nn_status_list);
-               spin_unlock(&nn->nn_lock);
-       } while (ret == -EAGAIN);
+       spin_lock(&nn->nn_lock);
+       ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC);
+       if (ret >= 0) {
+               nsw->ns_id = ret;
+               list_add_tail(&nsw->ns_node_item, &nn->nn_status_list);
+       }
+       spin_unlock(&nn->nn_lock);
 
-       if (ret == 0)  {
+       if (ret >= 0) {
                init_waitqueue_head(&nsw->ns_wq);
                nsw->ns_sys_status = R2NET_ERR_NONE;
                nsw->ns_status = 0;
+               return 0;
        }
-
        return ret;
 }
 
index db0cf7c8adde04db2b272660a6047297fa848a78..a0fc7b9eea652c570419052deff33fec88210209 100644 (file)
@@ -166,6 +166,7 @@ static int chap_server_compute_md5(
 {
        char *endptr;
        unsigned long id;
+       unsigned char id_as_uchar;
        unsigned char digest[MD5_SIGNATURE_SIZE];
        unsigned char type, response[MD5_SIGNATURE_SIZE * 2 + 2];
        unsigned char identifier[10], *challenge = NULL;
@@ -355,7 +356,9 @@ static int chap_server_compute_md5(
                goto out;
        }
 
-       sg_init_one(&sg, &id, 1);
+       /* To handle both endiannesses */
+       id_as_uchar = id;
+       sg_init_one(&sg, &id_as_uchar, 1);
        ret = crypto_hash_update(&desc, &sg, 1);
        if (ret < 0) {
                pr_err("crypto_hash_update() failed for id\n");
index 2d444b1ccd33231a57a6bd8f8eb57456ed8f61da..7c908141cc8a7980d29f151960369c063e06a122 100644 (file)
@@ -79,11 +79,10 @@ static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
        kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
 }
 
-static int tcm_loop_proc_info(struct Scsi_Host *host, char *buffer,
-                               char **start, off_t offset,
-                               int length, int inout)
+static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host)
 {
-       return sprintf(buffer, "tcm_loop_proc_info()\n");
+       seq_printf(m, "tcm_loop_proc_info()\n");
+       return 0;
 }
 
 static int tcm_loop_driver_probe(struct device *);
@@ -336,7 +335,7 @@ static int tcm_loop_slave_configure(struct scsi_device *sd)
 }
 
 static struct scsi_host_template tcm_loop_driver_template = {
-       .proc_info              = tcm_loop_proc_info,
+       .show_info              = tcm_loop_show_info,
        .proc_name              = "tcm_loopback",
        .name                   = "TCM_Loopback",
        .queuecommand           = tcm_loop_queuecommand,
index bc02b018ae46b0d0340db390adbf518990e77174..37ffc5bd23992a5f1e1124b2c6eba9889e7119ff 100644 (file)
@@ -7,7 +7,7 @@
 #define FD_DEVICE_QUEUE_DEPTH  32
 #define FD_MAX_DEVICE_QUEUE_DEPTH 128
 #define FD_BLOCKSIZE           512
-#define FD_MAX_SECTORS         1024
+#define FD_MAX_SECTORS         2048
 
 #define RRF_EMULATE_CDB                0x01
 #define RRF_GOT_LBA            0x02
index 82e78d72fdb61f1849f1204e6d02d0970fdb7b41..e992b27aa0904b75320991b0adbb65b3d84037b6 100644 (file)
@@ -883,7 +883,14 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
                pr_debug("PSCSI: i: %d page: %p len: %d off: %d\n", i,
                        page, len, off);
 
-               while (len > 0 && data_len > 0) {
+               /*
+                * We only have one page of data in each sg element,
+                * we can not cross a page boundary.
+                */
+               if (off + len > PAGE_SIZE)
+                       goto fail;
+
+               if (len > 0 && data_len > 0) {
                        bytes = min_t(unsigned int, len, PAGE_SIZE - off);
                        bytes = min(bytes, data_len);
 
@@ -940,9 +947,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
                                bio = NULL;
                        }
 
-                       len -= bytes;
                        data_len -= bytes;
-                       off = 0;
                }
        }
 
index 290230de2c53c72c0c192930c7b2dff63a3b24a9..60d4b5185f32979739c01e04c5aa94de6fcd838f 100644 (file)
@@ -464,8 +464,11 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
                break;
        case SYNCHRONIZE_CACHE:
        case SYNCHRONIZE_CACHE_16:
-               if (!ops->execute_sync_cache)
-                       return TCM_UNSUPPORTED_SCSI_OPCODE;
+               if (!ops->execute_sync_cache) {
+                       size = 0;
+                       cmd->execute_cmd = sbc_emulate_noop;
+                       break;
+               }
 
                /*
                 * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE
index 9169d6a5d7e4bff83f2aec0ecfc84c8667f9bab6..aac9d2727e3c8584a20db563ef5c914bc758de19 100644 (file)
@@ -711,7 +711,8 @@ int core_tpg_register(
 
        if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) {
                if (core_tpg_setup_virtual_lun0(se_tpg) < 0) {
-                       kfree(se_tpg);
+                       array_free(se_tpg->tpg_lun_list,
+                                  TRANSPORT_MAX_LUNS_PER_TPG);
                        return -ENOMEM;
                }
        }
index 7b0bfa0e7a9c231a450012d104e6de093ca2c001..3078c403b42d84029968b23ff20b39ebd4af295d 100644 (file)
@@ -143,22 +143,18 @@ static int dove_thermal_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
-       priv->sensor = devm_request_and_ioremap(&pdev->dev, res);
-       if (!priv->sensor) {
-               dev_err(&pdev->dev, "Failed to request_ioremap memory\n");
-               return -EADDRNOTAVAIL;
-       }
+       priv->sensor = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->sensor))
+               return PTR_ERR(priv->sensor);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        if (!res) {
                dev_err(&pdev->dev, "Failed to get platform resource\n");
                return -ENODEV;
        }
-       priv->control = devm_request_and_ioremap(&pdev->dev, res);
-       if (!priv->control) {
-               dev_err(&pdev->dev, "Failed to request_ioremap memory\n");
-               return -EADDRNOTAVAIL;
-       }
+       priv->control = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->control))
+               return PTR_ERR(priv->control);
 
        ret = dove_init_sensor(priv);
        if (ret) {
index e04ebd8671aca27dc390c32d6ec00d6033c7d7ae..46568c078dee8d2fe4c195cc4659e68e6653f36d 100644 (file)
@@ -476,7 +476,7 @@ static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
 
        if (IS_ERR(th_zone->therm_dev)) {
                pr_err("Failed to register thermal zone device\n");
-               ret = -EINVAL;
+               ret = PTR_ERR(th_zone->therm_dev);
                goto err_unregister;
        }
        th_zone->mode = THERMAL_DEVICE_ENABLED;
index 65cb4f09e8f6ffb19123c6aaa2a7a55f3442323b..e5500edb528568a009597b9336fa3d951df852ac 100644 (file)
@@ -85,11 +85,9 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
-       priv->sensor = devm_request_and_ioremap(&pdev->dev, res);
-       if (!priv->sensor) {
-               dev_err(&pdev->dev, "Failed to request_ioremap memory\n");
-               return -EADDRNOTAVAIL;
-       }
+       priv->sensor = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->sensor))
+               return PTR_ERR(priv->sensor);
 
        thermal = thermal_zone_device_register("kirkwood_thermal", 0, 0,
                                               priv, &ops, NULL, 0, 0);
index 28f0919940137dcaf57fce04df69ddcdecfc173f..2cc5b6115e3e200d13955f8103b97a2ddf3c0514 100644 (file)
@@ -145,6 +145,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
        struct device *dev = rcar_priv_to_dev(priv);
        int i;
        int ctemp, old, new;
+       int ret = -EINVAL;
 
        mutex_lock(&priv->lock);
 
@@ -174,7 +175,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
 
        if (!ctemp) {
                dev_err(dev, "thermal sensor was broken\n");
-               return -EINVAL;
+               goto err_out_unlock;
        }
 
        /*
@@ -192,10 +193,10 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
        dev_dbg(dev, "thermal%d  %d -> %d\n", priv->id, priv->ctemp, ctemp);
 
        priv->ctemp = ctemp;
-
+       ret = 0;
+err_out_unlock:
        mutex_unlock(&priv->lock);
-
-       return 0;
+       return ret;
 }
 
 static int rcar_thermal_get_temp(struct thermal_zone_device *zone,
@@ -363,6 +364,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
        struct resource *res, *irq;
        int mres = 0;
        int i;
+       int ret = -ENODEV;
        int idle = IDLE_INTERVAL;
 
        common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
@@ -399,11 +401,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
                /*
                 * rcar_has_irq_support() will be enabled
                 */
-               common->base = devm_request_and_ioremap(dev, res);
-               if (!common->base) {
-                       dev_err(dev, "Unable to ioremap thermal register\n");
-                       return -ENOMEM;
-               }
+               common->base = devm_ioremap_resource(dev, res);
+               if (IS_ERR(common->base))
+                       return PTR_ERR(common->base);
 
                /* enable temperature comparation */
                rcar_thermal_common_write(common, ENR, 0x00030303);
@@ -422,11 +422,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
                        return -ENOMEM;
                }
 
-               priv->base = devm_request_and_ioremap(dev, res);
-               if (!priv->base) {
-                       dev_err(dev, "Unable to ioremap priv register\n");
-                       return -ENOMEM;
-               }
+               priv->base = devm_ioremap_resource(dev, res);
+               if (IS_ERR(priv->base))
+                       return PTR_ERR(priv->base);
 
                priv->common = common;
                priv->id = i;
@@ -441,6 +439,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
                                                idle);
                if (IS_ERR(priv->zone)) {
                        dev_err(dev, "can't register thermal zone\n");
+                       ret = PTR_ERR(priv->zone);
                        goto error_unregister;
                }
 
@@ -460,7 +459,7 @@ error_unregister:
        rcar_thermal_for_each_priv(priv, common)
                thermal_zone_device_unregister(priv->zone);
 
-       return -ENODEV;
+       return ret;
 }
 
 static int rcar_thermal_remove(struct platform_device *pdev)
index 1956593ee89d17b13d24e13c725eef8dd59cf7e7..81e939e90c4c44f7ead9bad36eac03f98f998421 100644 (file)
@@ -881,17 +881,12 @@ static struct vio_driver hvcs_vio_driver = {
 /* Only called from hvcs_get_pi please */
 static void hvcs_set_pi(struct hvcs_partner_info *pi, struct hvcs_struct *hvcsd)
 {
-       int clclength;
-
        hvcsd->p_unit_address = pi->unit_address;
        hvcsd->p_partition_ID  = pi->partition_ID;
-       clclength = strlen(&pi->location_code[0]);
-       if (clclength > HVCS_CLC_LENGTH)
-               clclength = HVCS_CLC_LENGTH;
 
        /* copy the null-term char too */
-       strncpy(&hvcsd->p_location_code[0],
-                       &pi->location_code[0], clclength + 1);
+       strlcpy(&hvcsd->p_location_code[0],
+                       &pi->location_code[0], sizeof(hvcsd->p_location_code));
 }
 
 /*
index 0efc815a496869fbe80cec247fb99af9286105f9..cf6a5383748aa6cf468a76e72e1c575497031eed 100644 (file)
@@ -301,7 +301,28 @@ static const struct serial8250_config uart_config[] = {
        },
        [PORT_8250_CIR] = {
                .name           = "CIR port"
-       }
+       },
+       [PORT_ALTR_16550_F32] = {
+               .name           = "Altera 16550 FIFO32",
+               .fifo_size      = 32,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_ALTR_16550_F64] = {
+               .name           = "Altera 16550 FIFO64",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_ALTR_16550_F128] = {
+               .name           = "Altera 16550 FIFO128",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
 };
 
 /* Uart divisor latch read */
@@ -3396,3 +3417,32 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
 MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
 #endif
 MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+
+#ifndef MODULE
+/* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name
+ * working as well for the module options so we don't break people.  We
+ * need to keep the names identical and the convenient macros will happily
+ * refuse to let us do that by failing the build with redefinition errors
+ * of global variables.  So we stick them inside a dummy function to avoid
+ * those conflicts.  The options still get parsed, and the redefined
+ * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
+ *
+ * This is hacky.  I'm sorry.
+ */
+static void __used s8250_options(void)
+{
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "8250."
+
+       module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
+       module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
+       module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
+#ifdef CONFIG_SERIAL_8250_RSA
+       __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
+               &param_array_ops, .arr = &__param_arr_probe_rsa,
+               0444, -1);
+#endif
+}
+#else
+MODULE_ALIAS("8250");
+#endif
index 791c5a77ec61d473495190049ab5776e8a02a846..aa76825229dca32d612781f877b1d1167add71af 100644 (file)
@@ -1571,6 +1571,7 @@ pci_wch_ch353_setup(struct serial_private *priv,
 
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588        0x1588
 
 /*
  * Master list of serial port init/setup/exit quirks.
@@ -1850,15 +1851,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .setup          = pci_default_setup,
                .exit           = pci_plx9050_exit,
        },
-       {
-               .vendor         = PCI_VENDOR_ID_PLX,
-               .device         = PCI_DEVICE_ID_PLX_9050,
-               .subvendor      = PCI_VENDOR_ID_PLX,
-               .subdevice      = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = pci_plx9050_exit,
-       },
        {
                .vendor         = PCI_VENDOR_ID_PLX,
                .device         = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -3733,7 +3725,12 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
                PCI_VENDOR_ID_PLX,
                PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
-               pbn_b0_4_115200 },
+               pbn_b2_4_115200 },
+       /* Unknown card - subdevice 0x1588 */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_VENDOR_ID_PLX,
+               PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0,
+               pbn_b2_8_115200 },
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
                PCI_SUBVENDOR_ID_KEYSPAN,
                PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
@@ -4791,6 +4788,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_VENDOR_ID_IBM, 0x0299,
                0, 0, pbn_b0_bt_2_115200 },
 
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+               0x1000, 0x0012,
+               0, 0, pbn_b0_bt_2_115200 },
+
        {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
                0xA000, 0x1000,
                0, 0, pbn_b0_1_115200 },
index 35d9ab95c5cbb51d6092f67540678f00e4ee52bd..b3455a970a1da01c0afcf013d8c31a49e1004005 100644 (file)
@@ -429,6 +429,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
        struct uart_8250_port uart;
        int ret, line, flags = dev_id->driver_data;
+       struct resource *res = NULL;
 
        if (flags & UNKNOWN_DEV) {
                ret = serial_pnp_guess_board(dev);
@@ -439,11 +440,12 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
        memset(&uart, 0, sizeof(uart));
        if (pnp_irq_valid(dev, 0))
                uart.port.irq = pnp_irq(dev, 0);
-       if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
-               uart.port.iobase = pnp_port_start(dev, 2);
-               uart.port.iotype = UPIO_PORT;
-       } else if (pnp_port_valid(dev, 0)) {
-               uart.port.iobase = pnp_port_start(dev, 0);
+       if ((flags & CIR_PORT) && pnp_port_valid(dev, 2))
+               res = pnp_get_resource(dev, IORESOURCE_IO, 2);
+       else if (pnp_port_valid(dev, 0))
+               res = pnp_get_resource(dev, IORESOURCE_IO, 0);
+       if (pnp_resource_enabled(res)) {
+               uart.port.iobase = res->start;
                uart.port.iotype = UPIO_PORT;
        } else if (pnp_mem_valid(dev, 0)) {
                uart.port.mapbase = pnp_mem_start(dev, 0);
index cf9210db9fa917cd213559ec2c0cffd53c9f123b..7e7006fd404e62000b19b728274c0abf8a51bf38 100644 (file)
@@ -211,14 +211,14 @@ config SERIAL_SAMSUNG
 config SERIAL_SAMSUNG_UARTS_4
        bool
        depends on PLAT_SAMSUNG
-       default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
+       default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
        help
          Internal node for the common case of 4 Samsung compatible UARTs
 
 config SERIAL_SAMSUNG_UARTS
        int
        depends on PLAT_SAMSUNG
-       default 6 if ARCH_S5P6450
+       default 6 if CPU_S5P6450
        default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
        default 3
        help
index 719594e5fc219aafe5826730e1a4af659f7639b9..52a3ecd404219c7365850debe309d06b99a2d8c8 100644 (file)
@@ -235,7 +235,7 @@ static const char *bcm_uart_type(struct uart_port *port)
  */
 static void bcm_uart_do_rx(struct uart_port *port)
 {
-       struct tty_port *port = &port->state->port;
+       struct tty_port *tty_port = &port->state->port;
        unsigned int max_count;
 
        /* limit number of char read in interrupt, should not be
@@ -260,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
                        bcm_uart_writel(port, val, UART_CTL_REG);
 
                        port->icount.overrun++;
-                       tty_insert_flip_char(port, 0, TTY_OVERRUN);
+                       tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);
                }
 
                if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
@@ -299,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port)
 
 
                if ((cstat & port->ignore_status_mask) == 0)
-                       tty_insert_flip_char(port, c, flag);
+                       tty_insert_flip_char(tty_port, c, flag);
 
        } while (--max_count);
 
-       tty_flip_buffer_push(port);
+       tty_flip_buffer_push(tty_port);
 }
 
 /*
index c0e1fad51be76f5969b71b561983cf6b6bba9b92..018bad922554fc45b9ad711bcab2a106fc683b6e 100644 (file)
@@ -550,7 +550,7 @@ static int mpc512x_psc_clock(struct uart_port *port, int enable)
                return 0;
 
        psc_num = (port->mapbase & 0xf00) >> 8;
-       snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num);
+       snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
        psc_clk = clk_get(port->dev, clk_name);
        if (IS_ERR(psc_clk)) {
                dev_err(port->dev, "Failed to get PSC clock entry!\n");
index d5874605682b77c69a272d71307fc24c70289b24..b025d54382754456efbb021e466079727381bcba 100644 (file)
@@ -241,6 +241,12 @@ static struct of_device_id of_platform_serial_table[] = {
        { .compatible = "ns16850",  .data = (void *)PORT_16850, },
        { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
        { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
+       { .compatible = "altr,16550-FIFO32",
+               .data = (void *)PORT_ALTR_16550_F32, },
+       { .compatible = "altr,16550-FIFO64",
+               .data = (void *)PORT_ALTR_16550_F64, },
+       { .compatible = "altr,16550-FIFO128",
+               .data = (void *)PORT_ALTR_16550_F128, },
 #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
        { .compatible = "ibm,qpace-nwp-serial",
                .data = (void *)PORT_NWPSERIAL, },
index a400002dfa84633fc6032b9da82da068af07e107..19cc749f83863ec451b91c6910114255a0334f56 100644 (file)
@@ -1711,7 +1711,7 @@ static int uart_proc_show(struct seq_file *m, void *v)
 
 static int uart_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, uart_proc_show, PDE(inode)->data);
+       return single_open(file, uart_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations uart_proc_fops = {
index e343d6670854e3b0fa097a0e66135daa065ce2b9..451687cb96850cd55c1fdd15f4832e591eae8f5d 100644 (file)
@@ -968,6 +968,7 @@ static struct uart_ops sunsu_pops = {
 #define UART_NR        4
 
 static struct uart_sunsu_port sunsu_ports[UART_NR];
+static int nr_inst; /* Number of already registered ports */
 
 #ifdef CONFIG_SERIO
 
@@ -1337,13 +1338,8 @@ static int __init sunsu_console_setup(struct console *co, char *options)
        printk("Console: ttyS%d (SU)\n",
               (sunsu_reg.minor - 64) + co->index);
 
-       /*
-        * Check whether an invalid uart number has been specified, and
-        * if so, search for the first available port that does have
-        * console support.
-        */
-       if (co->index >= UART_NR)
-               co->index = 0;
+       if (co->index > nr_inst)
+               return -ENODEV;
        port = &sunsu_ports[co->index].port;
 
        /*
@@ -1408,7 +1404,6 @@ static enum su_type su_get_type(struct device_node *dp)
 
 static int su_probe(struct platform_device *op)
 {
-       static int inst;
        struct device_node *dp = op->dev.of_node;
        struct uart_sunsu_port *up;
        struct resource *rp;
@@ -1418,16 +1413,16 @@ static int su_probe(struct platform_device *op)
 
        type = su_get_type(dp);
        if (type == SU_PORT_PORT) {
-               if (inst >= UART_NR)
+               if (nr_inst >= UART_NR)
                        return -EINVAL;
-               up = &sunsu_ports[inst];
+               up = &sunsu_ports[nr_inst];
        } else {
                up = kzalloc(sizeof(*up), GFP_KERNEL);
                if (!up)
                        return -ENOMEM;
        }
 
-       up->port.line = inst;
+       up->port.line = nr_inst;
 
        spin_lock_init(&up->port.lock);
 
@@ -1461,6 +1456,8 @@ static int su_probe(struct platform_device *op)
                }
                dev_set_drvdata(&op->dev, up);
 
+               nr_inst++;
+
                return 0;
        }
 
@@ -1488,7 +1485,7 @@ static int su_probe(struct platform_device *op)
 
        dev_set_drvdata(&op->dev, up);
 
-       inst++;
+       nr_inst++;
 
        return 0;
 
index a3f9dd5c9dff40dacf86966ae3d6ff1335055f97..705240e6c4ec1714fb0c367e9f226eb23d705464 100644 (file)
@@ -611,14 +611,7 @@ static int vt8500_serial_probe(struct platform_device *pdev)
        vt8500_port->uart.dev = &pdev->dev;
        vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
 
-       vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
-       if (!IS_ERR(vt8500_port->clk)) {
-               vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
-       } else {
-               /* use the default of 24Mhz if not specified and warn */
-               pr_warn("%s: serial clock source not specified\n", __func__);
-               vt8500_port->uart.uartclk = 24000000;
-       }
+       vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
 
        snprintf(vt8500_port->name, sizeof(vt8500_port->name),
                 "VT8500 UART%d", pdev->id);
index bb119934e76cd8c70bdde28038553b60867b3282..578aa7594b11febce9cf50b6f5863bc8a34dfe8c 100644 (file)
@@ -425,7 +425,7 @@ static void flush_to_ldisc(struct work_struct *work)
        struct tty_ldisc *disc;
 
        tty = port->itty;
-       if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n"))
+       if (tty == NULL)
                return;
 
        disc = tty_ldisc_ref(tty);
index e4ca345873c3279761f8dcf6cee3f06053205088..d7799deacb21a66805d8e4308bcc199b64894fbf 100644 (file)
@@ -93,7 +93,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll)
 static struct vcs_poll_data *
 vcs_poll_data_get(struct file *file)
 {
-       struct vcs_poll_data *poll = file->private_data;
+       struct vcs_poll_data *poll = file->private_data, *kill = NULL;
 
        if (poll)
                return poll;
@@ -122,10 +122,12 @@ vcs_poll_data_get(struct file *file)
                file->private_data = poll;
        } else {
                /* someone else raced ahead of us */
-               vcs_poll_data_free(poll);
+               kill = poll;
                poll = file->private_data;
        }
        spin_unlock(&file->f_lock);
+       if (kill)
+               vcs_poll_data_free(kill);
 
        return poll;
 }
index f5ed3d75fa5a2ce615f32b10b7f0461f839e5757..8f5ebced5df0010e4d881c7978a5e132d92c8306 100644 (file)
@@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK)    += image/
 obj-$(CONFIG_USB_SERIAL)       += serial/
 
 obj-$(CONFIG_USB)              += misc/
-obj-$(CONFIG_USB_COMMON)       += phy/
+obj-$(CONFIG_USB_OTG_UTILS)    += phy/
 obj-$(CONFIG_EARLY_PRINTK_DBGP)        += early/
 
 obj-$(CONFIG_USB_ATM)          += atm/
index a03fbc15fa9cce3ed28f209380f2a091e73223c7..aa491627a45ba83b51a881e0f5b7226a26139933 100644 (file)
@@ -100,7 +100,7 @@ struct c67x00_urb_priv {
 #define TD_PIDEP_OFFSET                0x04
 #define TD_PIDEPMASK_PID       0xF0
 #define TD_PIDEPMASK_EP                0x0F
-#define TD_PORTLENMASK_DL      0x02FF
+#define TD_PORTLENMASK_DL      0x03FF
 #define TD_PORTLENMASK_PN      0xC000
 
 #define TD_STATUS_OFFSET       0x07
@@ -590,7 +590,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb,
 {
        struct c67x00_td *td;
        struct c67x00_urb_priv *urbp = urb->hcpriv;
-       const __u8 active_flag = 1, retry_cnt = 1;
+       const __u8 active_flag = 1, retry_cnt = 3;
        __u8 cmd = 0;
        int tt = 0;
 
index 2f45bba8561d10a5f8b52607344cfdeb957a540e..f64fbea1cf20aa689452ea50198ea9f8f70701b3 100644 (file)
@@ -1767,7 +1767,7 @@ static int udc_start(struct ci13xxx *ci)
                goto put_transceiver;
        }
 
-       retval = dbg_create_files(&ci->gadget.dev);
+       retval = dbg_create_files(ci->dev);
        if (retval)
                goto unreg_device;
 
@@ -1796,7 +1796,7 @@ remove_trans:
 
        dev_err(dev, "error = %i\n", retval);
 remove_dbg:
-       dbg_remove_files(&ci->gadget.dev);
+       dbg_remove_files(ci->dev);
 unreg_device:
        device_unregister(&ci->gadget.dev);
 put_transceiver:
@@ -1836,7 +1836,7 @@ static void udc_stop(struct ci13xxx *ci)
                if (ci->global_phy)
                        usb_put_phy(ci->transceiver);
        }
-       dbg_remove_files(&ci->gadget.dev);
+       dbg_remove_files(ci->dev);
        device_unregister(&ci->gadget.dev);
        /* my kobject is dynamic, I swear! */
        memset(&ci->gadget, 0, sizeof(ci->gadget));
index 8ac25adf31b41d857a6919299f1848cf2ee43710..387dc6c8ad25b0d43a7d954ce71d877618fcb63d 100644 (file)
@@ -593,7 +593,6 @@ static void acm_port_destruct(struct tty_port *port)
 
        dev_dbg(&acm->control->dev, "%s\n", __func__);
 
-       tty_unregister_device(acm_tty_driver, acm->minor);
        acm_release_minor(acm);
        usb_put_intf(acm->control);
        kfree(acm->country_codes);
@@ -977,6 +976,8 @@ static int acm_probe(struct usb_interface *intf,
        int num_rx_buf;
        int i;
        int combined_interfaces = 0;
+       struct device *tty_dev;
+       int rv = -ENOMEM;
 
        /* normal quirks */
        quirks = (unsigned long)id->driver_info;
@@ -1339,11 +1340,24 @@ skip_countries:
        usb_set_intfdata(data_interface, acm);
 
        usb_get_intf(control_interface);
-       tty_port_register_device(&acm->port, acm_tty_driver, minor,
+       tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
                        &control_interface->dev);
+       if (IS_ERR(tty_dev)) {
+               rv = PTR_ERR(tty_dev);
+               goto alloc_fail8;
+       }
 
        return 0;
+alloc_fail8:
+       if (acm->country_codes) {
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_wCountryCodes);
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_iCountryCodeRelDate);
+       }
+       device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
 alloc_fail7:
+       usb_set_intfdata(intf, NULL);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
 alloc_fail6:
@@ -1359,7 +1373,7 @@ alloc_fail2:
        acm_release_minor(acm);
        kfree(acm);
 alloc_fail:
-       return -ENOMEM;
+       return rv;
 }
 
 static void stop_data_traffic(struct acm *acm)
@@ -1411,6 +1425,8 @@ static void acm_disconnect(struct usb_interface *intf)
 
        stop_data_traffic(acm);
 
+       tty_unregister_device(acm_tty_driver, acm->minor);
+
        usb_free_urb(acm->ctrlurb);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
index 5f0cb417b736bb4b61c73afc52672029af59cbda..122d056d96d570c2d59762fda22e0e973ac081b5 100644 (file)
@@ -56,6 +56,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
 #define WDM_RESPONDING         7
 #define WDM_SUSPENDING         8
 #define WDM_RESETTING          9
+#define WDM_OVERFLOW           10
 
 #define WDM_MAX                        16
 
@@ -155,6 +156,7 @@ static void wdm_in_callback(struct urb *urb)
 {
        struct wdm_device *desc = urb->context;
        int status = urb->status;
+       int length = urb->actual_length;
 
        spin_lock(&desc->iuspin);
        clear_bit(WDM_RESPONDING, &desc->flags);
@@ -185,9 +187,17 @@ static void wdm_in_callback(struct urb *urb)
        }
 
        desc->rerr = status;
-       desc->reslength = urb->actual_length;
-       memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
-       desc->length += desc->reslength;
+       if (length + desc->length > desc->wMaxCommand) {
+               /* The buffer would overflow */
+               set_bit(WDM_OVERFLOW, &desc->flags);
+       } else {
+               /* we may already be in overflow */
+               if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
+                       memmove(desc->ubuf + desc->length, desc->inbuf, length);
+                       desc->length += length;
+                       desc->reslength = length;
+               }
+       }
 skip_error:
        wake_up(&desc->wait);
 
@@ -435,6 +445,11 @@ retry:
                        rv = -ENODEV;
                        goto err;
                }
+               if (test_bit(WDM_OVERFLOW, &desc->flags)) {
+                       clear_bit(WDM_OVERFLOW, &desc->flags);
+                       rv = -ENOBUFS;
+                       goto err;
+               }
                i++;
                if (file->f_flags & O_NONBLOCK) {
                        if (!test_bit(WDM_READ, &desc->flags)) {
@@ -478,6 +493,7 @@ retry:
                        spin_unlock_irq(&desc->iuspin);
                        goto retry;
                }
+
                if (!desc->reslength) { /* zero length read */
                        dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
                        clear_bit(WDM_READ, &desc->flags);
@@ -1004,6 +1020,7 @@ static int wdm_post_reset(struct usb_interface *intf)
        struct wdm_device *desc = wdm_find_device(intf);
        int rv;
 
+       clear_bit(WDM_OVERFLOW, &desc->flags);
        clear_bit(WDM_RESETTING, &desc->flags);
        rv = recover_from_urb_loss(desc);
        mutex_unlock(&desc->wlock);
index 622b4a48e732e7a83b6c760d6563994394b0caa9..2b487d4797bd74057a9ad88148af199360d9de1d 100644 (file)
@@ -173,6 +173,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        struct hc_driver        *driver;
        struct usb_hcd          *hcd;
        int                     retval;
+       int                     hcd_irq = 0;
 
        if (usb_disabled())
                return -ENODEV;
@@ -187,15 +188,19 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
                return -ENODEV;
        dev->current_state = PCI_D0;
 
-       /* The xHCI driver supports MSI and MSI-X,
-        * so don't fail if the BIOS doesn't provide a legacy IRQ.
+       /*
+        * The xHCI driver has its own irq management
+        * make sure irq setup is not touched for xhci in generic hcd code
         */
-       if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
-               dev_err(&dev->dev,
-                       "Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
-                       pci_name(dev));
-               retval = -ENODEV;
-               goto disable_pci;
+       if ((driver->flags & HCD_MASK) != HCD_USB3) {
+               if (!dev->irq) {
+                       dev_err(&dev->dev,
+                       "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
+                               pci_name(dev));
+                       retval = -ENODEV;
+                       goto disable_pci;
+               }
+               hcd_irq = dev->irq;
        }
 
        hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
@@ -245,7 +250,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
        pci_set_master(dev);
 
-       retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
+       retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
        if (retval != 0)
                goto unmap_registers;
        set_hs_companion(dev, hcd);
index cef4252bb31a3c4cfcc1ccd4ce6338bde51fd33d..b6f4bad3f756eefb173097767ffde6970e06220e 100644 (file)
@@ -210,9 +210,14 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
        return 0;
 }
 
+static bool usb_acpi_bus_match(struct device *dev)
+{
+       return is_usb_device(dev) || is_usb_port(dev);
+}
+
 static struct acpi_bus_type usb_acpi_bus = {
-       .bus = &usb_bus_type,
-       .find_bridge = usb_acpi_find_device,
+       .name = "USB",
+       .match = usb_acpi_bus_match,
        .find_device = usb_acpi_find_device,
 };
 
index 999909451e37ef75e9fb49d42f35fc34bceb646f..ffa6b004a84bec3b4d58b9e5b6bd515d499e603d 100644 (file)
@@ -583,6 +583,7 @@ static int dwc3_remove(struct platform_device *pdev)
                break;
        }
 
+       dwc3_free_event_buffers(dwc);
        dwc3_core_exit(dwc);
 
        return 0;
index b50da53e9a52046a5441a9ea230e267d6a476c93..b082bec7343e0e79cd3e1d062c2aba16173ffbab 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/usb/nop-usb-xceiv.h>
 #include <linux/of.h>
 
-#include "core.h"
-
 struct dwc3_exynos {
        struct platform_device  *dwc3;
        struct platform_device  *usb2_phy;
index 22f337f572190234c4f75fd06a78b14ce4a2faf9..afa05e3c9cf40b9b731e6d16f8543c07a6cb62c8 100644 (file)
@@ -54,8 +54,6 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/nop-usb-xceiv.h>
 
-#include "core.h"
-
 /*
  * All these registers belong to OMAP's Wrapper around the
  * DesignWare USB3 Core.
@@ -465,20 +463,20 @@ static int dwc3_omap_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id of_dwc3_matach[] = {
+static const struct of_device_id of_dwc3_match[] = {
        {
                "ti,dwc3",
        },
        { },
 };
-MODULE_DEVICE_TABLE(of, of_dwc3_matach);
+MODULE_DEVICE_TABLE(of, of_dwc3_match);
 
 static struct platform_driver dwc3_omap_driver = {
        .probe          = dwc3_omap_probe,
        .remove         = dwc3_omap_remove,
        .driver         = {
                .name   = "omap-dwc3",
-               .of_match_table = of_dwc3_matach,
+               .of_match_table = of_dwc3_match,
        },
 };
 
index 7d70f44567d2a80fb9b5cf459f36ac0f61dafdf3..e8d77689a322d941042643a980e423545f7bc365 100644 (file)
@@ -45,8 +45,6 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/nop-usb-xceiv.h>
 
-#include "core.h"
-
 /* FIXME define these in <linux/pci_ids.h> */
 #define PCI_VENDOR_ID_SYNOPSYS         0x16c3
 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3        0xabcd
index d7da073a23fee142edc051e562d5cba498c97e63..1d139ca05ef17bdd56cdfa3ba9027ea70c337d88 100644 (file)
@@ -891,7 +891,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
                                DWC3_TRBCTL_CONTROL_DATA);
        } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
                        && (dep->number == 0)) {
-               u32             transfer_size;
+               u32     transfer_size;
+               u32     maxpacket;
 
                ret = usb_gadget_map_request(&dwc->gadget, &req->request,
                                dep->number);
@@ -902,8 +903,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 
                WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE);
 
-               transfer_size = roundup(req->request.length,
-                               (u32) dep->endpoint.maxpacket);
+               maxpacket = dep->endpoint.maxpacket;
+               transfer_size = roundup(req->request.length, maxpacket);
 
                dwc->ep0_bounced = true;
 
index a04342f6cbfae6979f1f053776e7e1297ca1bdfb..82e160e96fcafd20f15c4443cba953d569c071f1 100644 (file)
@@ -2159,7 +2159,6 @@ static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed)
 
 static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 {
-       struct dwc3_gadget_ep_cmd_params params;
        struct dwc3_ep          *dep;
        int                     ret;
        u32                     reg;
@@ -2167,8 +2166,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 
        dev_vdbg(dwc->dev, "%s\n", __func__);
 
-       memset(&params, 0x00, sizeof(params));
-
        reg = dwc3_readl(dwc->regs, DWC3_DSTS);
        speed = reg & DWC3_DSTS_CONNECTSPD;
        dwc->speed = speed;
index 97a13c349cc52bfa4928c6eab5fd11470bcc5a26..82fb22511356d4ffd610d57b2787f457a93e5f9e 100644 (file)
@@ -35,6 +35,12 @@ mv_udc-y                     := mv_udc_core.o
 obj-$(CONFIG_USB_FUSB300)      += fusb300_udc.o
 obj-$(CONFIG_USB_MV_U3D)       += mv_u3d_core.o
 
+# USB Functions
+obj-$(CONFIG_USB_F_ACM)                += f_acm.o
+f_ss_lb-y                      := f_loopback.o f_sourcesink.o
+obj-$(CONFIG_USB_F_SS_LB)      += f_ss_lb.o
+obj-$(CONFIG_USB_U_SERIAL)     += u_serial.o
+
 #
 # USB gadget drivers
 #
@@ -74,9 +80,3 @@ obj-$(CONFIG_USB_G_WEBCAM)    += g_webcam.o
 obj-$(CONFIG_USB_G_NCM)                += g_ncm.o
 obj-$(CONFIG_USB_G_ACM_MS)     += g_acm_ms.o
 obj-$(CONFIG_USB_GADGET_TARGET)        += tcm_usb_gadget.o
-
-# USB Functions
-obj-$(CONFIG_USB_F_ACM)                += f_acm.o
-f_ss_lb-y                      := f_loopback.o f_sourcesink.o
-obj-$(CONFIG_USB_F_SS_LB)      += f_ss_lb.o
-obj-$(CONFIG_USB_U_SERIAL)     += u_serial.o
index 45dd2929a6710227fc13761503177774153539a8..88966e0508a5a28f556310498452dce318e96912 100644 (file)
@@ -221,7 +221,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
 
 static int proc_udc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, proc_udc_show, PDE(inode)->data);
+       return single_open(file, proc_udc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations proc_ops = {
index 7c821de8ce3d95d53d03beffd85e4ab9f962f571..c0d62b2786104a6ed2a3501d2bd74e739841c970 100644 (file)
@@ -1757,10 +1757,7 @@ static const struct usb_gadget_driver composite_driver_template = {
 /**
  * usb_composite_probe() - register a composite driver
  * @driver: the driver to register
- * @bind: the callback used to allocate resources that are shared across the
- *     whole device, such as string IDs, and add its configurations using
- *     @usb_add_config().  This may fail by returning a negative errno
- *     value; it should return zero on successful initialization.
+ *
  * Context: single threaded during gadget setup
  *
  * This function is used to register drivers using the composite driver
index 38388d7844fc75ff2287f3be4502b69b797efd28..f394f295d63d1b87927fb49fe9ebe3234fe0c635 100644 (file)
@@ -727,7 +727,6 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
 }
 
 static const struct file_operations ffs_ep0_operations = {
-       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
 
        .open =         ffs_ep0_open,
@@ -947,7 +946,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
 }
 
 static const struct file_operations ffs_epfile_operations = {
-       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
 
        .open =         ffs_epfile_open,
@@ -1235,6 +1233,7 @@ static struct file_system_type ffs_fs_type = {
        .mount          = ffs_fs_mount,
        .kill_sb        = ffs_fs_kill_sb,
 };
+MODULE_ALIAS_FS("functionfs");
 
 
 /* Driver's main init/cleanup functions *************************************/
index 71beeb83355874b601998a5764abddc076515138..cc9c49c57c803a9e787887fd8977e05c585d630e 100644 (file)
@@ -447,14 +447,13 @@ static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
 static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
 {
        struct f_rndis                  *rndis = req->context;
-       struct usb_composite_dev        *cdev = rndis->port.func.config->cdev;
        int                             status;
 
        /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
 //     spin_lock(&dev->lock);
        status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
        if (status < 0)
-               ERROR(cdev, "RNDIS command error %d, %d/%d\n",
+               pr_err("RNDIS command error %d, %d/%d\n",
                        status, req->actual, req->length);
 //     spin_unlock(&dev->lock);
 }
index f570e667a640d0619cd6abaffaf9705738fcab24..fa8ea4ea00c1a3014be0fdc35dfcc52bb17af166 100644 (file)
@@ -418,6 +418,7 @@ static int audio_get_intf_req(struct usb_function *f,
 
        req->context = audio;
        req->complete = f_audio_complete;
+       len = min_t(size_t, sizeof(value), len);
        memcpy(req->buf, &value, len);
 
        return len;
index 04d5fef1440cf591d923b88e0099473610c53ef1..ede70ffe1ab49934f995f86287f178746f1b3420 100644 (file)
@@ -2038,47 +2038,37 @@ static int fsl_udc_stop(struct usb_gadget *g,
 
 static const char proc_filename[] = "driver/fsl_usb2_udc";
 
-static int fsl_proc_read(char *page, char **start, off_t off, int count,
-               int *eof, void *_dev)
+static int fsl_proc_read(struct seq_file *m, void *v)
 {
-       char *buf = page;
-       char *next = buf;
-       unsigned size = count;
        unsigned long flags;
-       int t, i;
+       int i;
        u32 tmp_reg;
        struct fsl_ep *ep = NULL;
        struct fsl_req *req;
 
        struct fsl_udc *udc = udc_controller;
-       if (off != 0)
-               return 0;
 
        spin_lock_irqsave(&udc->lock, flags);
 
        /* ------basic driver information ---- */
-       t = scnprintf(next, size,
+       seq_printf(m,
                        DRIVER_DESC "\n"
                        "%s version: %s\n"
                        "Gadget driver: %s\n\n",
                        driver_name, DRIVER_VERSION,
                        udc->driver ? udc->driver->driver.name : "(none)");
-       size -= t;
-       next += t;
 
        /* ------ DR Registers ----- */
        tmp_reg = fsl_readl(&dr_regs->usbcmd);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USBCMD reg:\n"
                        "SetupTW: %d\n"
                        "Run/Stop: %s\n\n",
                        (tmp_reg & USB_CMD_SUTW) ? 1 : 0,
                        (tmp_reg & USB_CMD_RUN_STOP) ? "Run" : "Stop");
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->usbsts);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USB Status Reg:\n"
                        "Dr Suspend: %d Reset Received: %d System Error: %s "
                        "USB Error Interrupt: %s\n\n",
@@ -2086,11 +2076,9 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
                        (tmp_reg & USB_STS_RESET) ? 1 : 0,
                        (tmp_reg & USB_STS_SYS_ERR) ? "Err" : "Normal",
                        (tmp_reg & USB_STS_ERR) ? "Err detected" : "No err");
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->usbintr);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USB Interrupt Enable Reg:\n"
                        "Sleep Enable: %d SOF Received Enable: %d "
                        "Reset Enable: %d\n"
@@ -2104,33 +2092,25 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
                        (tmp_reg & USB_INTR_PTC_DETECT_EN) ? 1 : 0,
                        (tmp_reg & USB_INTR_ERR_INT_EN) ? 1 : 0,
                        (tmp_reg & USB_INTR_INT_EN) ? 1 : 0);
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->frindex);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USB Frame Index Reg: Frame Number is 0x%x\n\n",
                        (tmp_reg & USB_FRINDEX_MASKS));
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->deviceaddr);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USB Device Address Reg: Device Addr is 0x%x\n\n",
                        (tmp_reg & USB_DEVICE_ADDRESS_MASK));
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->endpointlistaddr);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USB Endpoint List Address Reg: "
                        "Device Addr is 0x%x\n\n",
                        (tmp_reg & USB_EP_LIST_ADDRESS_MASK));
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->portsc1);
-       t = scnprintf(next, size,
+       seq_printf(m,
                "USB Port Status&Control Reg:\n"
                "Port Transceiver Type : %s Port Speed: %s\n"
                "PHY Low Power Suspend: %s Port Reset: %s "
@@ -2139,7 +2119,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
                "Port Enable/Disable Change: %s\n"
                "Port Enabled/Disabled: %s "
                "Current Connect Status: %s\n\n", ( {
-                       char *s;
+                       const char *s;
                        switch (tmp_reg & PORTSCX_PTS_FSLS) {
                        case PORTSCX_PTS_UTMI:
                                s = "UTMI"; break;
@@ -2165,13 +2145,11 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
                "Not correct",
                (tmp_reg & PORTSCX_CURRENT_CONNECT_STATUS) ?
                "Attached" : "Not-Att");
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->usbmode);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "USB Mode Reg: Controller Mode is: %s\n\n", ( {
-                               char *s;
+                               const char *s;
                                switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
                                case USB_MODE_CTRL_MODE_IDLE:
                                        s = "Idle"; break;
@@ -2184,103 +2162,87 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
                                }
                                s;
                        } ));
-       size -= t;
-       next += t;
 
        tmp_reg = fsl_readl(&dr_regs->endptsetupstat);
-       t = scnprintf(next, size,
+       seq_printf(m,
                        "Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n",
                        (tmp_reg & EP_SETUP_STATUS_MASK));
-       size -= t;
-       next += t;
 
        for (i = 0; i < udc->max_ep / 2; i++) {
                tmp_reg = fsl_readl(&dr_regs->endptctrl[i]);
-               t = scnprintf(next, size, "EP Ctrl Reg [0x%x]: = [0x%x]\n",
-                               i, tmp_reg);
-               size -= t;
-               next += t;
+               seq_printf(m, "EP Ctrl Reg [0x%x]: = [0x%x]\n", i, tmp_reg);
        }
        tmp_reg = fsl_readl(&dr_regs->endpointprime);
-       t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n\n", tmp_reg);
-       size -= t;
-       next += t;
+       seq_printf(m, "EP Prime Reg = [0x%x]\n\n", tmp_reg);
 
 #ifndef CONFIG_ARCH_MXC
        if (udc->pdata->have_sysif_regs) {
                tmp_reg = usb_sys_regs->snoop1;
-               t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
-               size -= t;
-               next += t;
+               seq_printf(m, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
 
                tmp_reg = usb_sys_regs->control;
-               t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n",
-                               tmp_reg);
-               size -= t;
-               next += t;
+               seq_printf(m, "General Control Reg : = [0x%x]\n\n", tmp_reg);
        }
 #endif
 
        /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */
        ep = &udc->eps[0];
-       t = scnprintf(next, size, "For %s Maxpkt is 0x%x index is 0x%x\n",
+       seq_printf(m, "For %s Maxpkt is 0x%x index is 0x%x\n",
                        ep->ep.name, ep_maxpacket(ep), ep_index(ep));
-       size -= t;
-       next += t;
 
        if (list_empty(&ep->queue)) {
-               t = scnprintf(next, size, "its req queue is empty\n\n");
-               size -= t;
-               next += t;
+               seq_puts(m, "its req queue is empty\n\n");
        } else {
                list_for_each_entry(req, &ep->queue, queue) {
-                       t = scnprintf(next, size,
+                       seq_printf(m,
                                "req %p actual 0x%x length 0x%x buf %p\n",
                                &req->req, req->req.actual,
                                req->req.length, req->req.buf);
-                       size -= t;
-                       next += t;
                }
        }
        /* other gadget->eplist ep */
        list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
                if (ep->ep.desc) {
-                       t = scnprintf(next, size,
+                       seq_printf(m,
                                        "\nFor %s Maxpkt is 0x%x "
                                        "index is 0x%x\n",
                                        ep->ep.name, ep_maxpacket(ep),
                                        ep_index(ep));
-                       size -= t;
-                       next += t;
 
                        if (list_empty(&ep->queue)) {
-                               t = scnprintf(next, size,
-                                               "its req queue is empty\n\n");
-                               size -= t;
-                               next += t;
+                               seq_puts(m, "its req queue is empty\n\n");
                        } else {
                                list_for_each_entry(req, &ep->queue, queue) {
-                                       t = scnprintf(next, size,
+                                       seq_printf(m,
                                                "req %p actual 0x%x length "
                                                "0x%x  buf %p\n",
                                                &req->req, req->req.actual,
                                                req->req.length, req->req.buf);
-                                       size -= t;
-                                       next += t;
-                                       }       /* end for each_entry of ep req */
-                               }       /* end for else */
-                       }       /* end for if(ep->queue) */
-               }               /* end (ep->desc) */
+                               }       /* end for each_entry of ep req */
+                       }       /* end for else */
+               }       /* end for if(ep->queue) */
+       }       /* end (ep->desc) */
 
        spin_unlock_irqrestore(&udc->lock, flags);
+       return 0;
+}
 
-       *eof = 1;
-       return count - size;
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int fsl_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, fsl_proc_read, NULL);
 }
 
-#define create_proc_file()     create_proc_read_entry(proc_filename, \
-                               0, NULL, fsl_proc_read, NULL)
+static const struct file_operations fsl_proc_fops = {
+       .open           = fsl_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 
+#define create_proc_file()     proc_create(proc_filename, 0, NULL, &fsl_proc_fops)
 #define remove_proc_file()     remove_proc_entry(proc_filename, NULL)
 
 #else                          /* !CONFIG_USB_GADGET_DEBUG_FILES */
index 3953dd4d7186827d0ee65b3e631701a093e7f618..3b343b23e4b0cfee227fc56965565bb0fb768d33 100644 (file)
@@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite_dev *cdev)
                goto error;
        gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
 
-       for (i = func_num; --i; ) {
+       for (i = func_num; i--; ) {
                ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
                if (unlikely(ret < 0)) {
                        while (++i < func_num)
@@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
                gether_cleanup();
        gfs_ether_setup = false;
 
-       for (i = func_num; --i; )
+       for (i = func_num; i--; )
                if (ffs_tab[i].ffs_data)
                        functionfs_unbind(ffs_tab[i].ffs_data);
 
index 85742d4c67dfa2708a763bd607d580936c38cd88..57a547049df57a828f838892a003bf36577ceb4c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -1008,7 +1009,7 @@ static const struct usb_gadget_ops goku_ops = {
 
 /*-------------------------------------------------------------------------*/
 
-static inline char *dmastr(void)
+static inline const char *dmastr(void)
 {
        if (use_dma == 0)
                return "(dma disabled)";
@@ -1025,13 +1026,10 @@ static const char proc_node_name [] = "driver/udc";
 #define FOURBITS "%s%s%s%s"
 #define EIGHTBITS FOURBITS FOURBITS
 
-static void
-dump_intmask(const char *label, u32 mask, char **next, unsigned *size)
+static void dump_intmask(struct seq_file *m, const char *label, u32 mask)
 {
-       int t;
-
        /* int_status is the same format ... */
-       t = scnprintf(*next, *size,
+       seq_printf(m,
                "%s %05X =" FOURBITS EIGHTBITS EIGHTBITS "\n",
                label, mask,
                (mask & INT_PWRDETECT) ? " power" : "",
@@ -1058,33 +1056,23 @@ dump_intmask(const char *label, u32 mask, char **next, unsigned *size)
                (mask & INT_ENDPOINT0) ? " ep0" : "",
                (mask & INT_USBRESET) ? " reset" : "",
                (mask & INT_SUSPEND) ? " suspend" : "");
-       *size -= t;
-       *next += t;
 }
 
 
-static int
-udc_proc_read(char *buffer, char **start, off_t off, int count,
-               int *eof, void *_dev)
+static int udc_proc_read(struct seq_file *m, void *v)
 {
-       char                            *buf = buffer;
-       struct goku_udc                 *dev = _dev;
+       struct goku_udc                 *dev = m->private;
        struct goku_udc_regs __iomem    *regs = dev->regs;
-       char                            *next = buf;
-       unsigned                        size = count;
        unsigned long                   flags;
-       int                             i, t, is_usb_connected;
+       int                             i, is_usb_connected;
        u32                             tmp;
 
-       if (off != 0)
-               return 0;
-
        local_irq_save(flags);
 
        /* basic device status */
        tmp = readl(&regs->power_detect);
        is_usb_connected = tmp & PW_DETECT;
-       t = scnprintf(next, size,
+       seq_printf(m,
                "%s - %s\n"
                "%s version: %s %s\n"
                "Gadget driver: %s\n"
@@ -1096,7 +1084,7 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                is_usb_connected
                        ? ((tmp & PW_PULLUP) ? "full speed" : "powered")
                        : "disconnected",
-               ({char *state;
+               ({const char *state;
                switch(dev->ep0state){
                case EP0_DISCONNECT:    state = "ep0_disconnect"; break;
                case EP0_IDLE:          state = "ep0_idle"; break;
@@ -1108,27 +1096,24 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                default:                state = "ep0_?"; break;
                } state; })
                );
-       size -= t;
-       next += t;
 
-       dump_intmask("int_status", readl(&regs->int_status), &next, &size);
-       dump_intmask("int_enable", readl(&regs->int_enable), &next, &size);
+       dump_intmask(m, "int_status", readl(&regs->int_status));
+       dump_intmask(m, "int_enable", readl(&regs->int_enable));
 
        if (!is_usb_connected || !dev->driver || (tmp & PW_PULLUP) == 0)
                goto done;
 
        /* registers for (active) device and ep0 */
-       t = scnprintf(next, size, "\nirqs %lu\ndataset %02x "
+       if (seq_printf(m, "\nirqs %lu\ndataset %02x "
                        "single.bcs %02x.%02x state %x addr %u\n",
                        dev->irqs, readl(&regs->DataSet),
                        readl(&regs->EPxSingle), readl(&regs->EPxBCS),
                        readl(&regs->UsbState),
-                       readl(&regs->address));
-       size -= t;
-       next += t;
+                       readl(&regs->address)) < 0)
+               goto done;
 
        tmp = readl(&regs->dma_master);
-       t = scnprintf(next, size,
+       if (seq_printf(m,
                "dma %03X =" EIGHTBITS "%s %s\n", tmp,
                (tmp & MST_EOPB_DIS) ? " eopb-" : "",
                (tmp & MST_EOPB_ENA) ? " eopb+" : "",
@@ -1143,9 +1128,8 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                (tmp & MST_WR_ENA) ? " OUT" : "",
                (tmp & MST_CONNECTION)
                        ? "ep1in/ep2out"
-                       : "ep1out/ep2in");
-       size -= t;
-       next += t;
+                       : "ep1out/ep2in") < 0)
+               goto done;
 
        /* dump endpoint queues */
        for (i = 0; i < 4; i++) {
@@ -1156,7 +1140,7 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                        continue;
 
                tmp = readl(ep->reg_status);
-               t = scnprintf(next, size,
+               if (seq_printf(m,
                        "%s %s max %u %s, irqs %lu, "
                        "status %02x (%s) " FOURBITS "\n",
                        ep->ep.name,
@@ -1189,18 +1173,12 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                        (tmp & EPxSTATUS_SUSPEND) ? " suspend" : "",
                        (tmp & EPxSTATUS_FIFO_DISABLE) ? " disable" : "",
                        (tmp & EPxSTATUS_STAGE_ERROR) ? " ep0stat" : ""
-                       );
-               if (t <= 0 || t > size)
+                       ) < 0)
                        goto done;
-               size -= t;
-               next += t;
 
                if (list_empty(&ep->queue)) {
-                       t = scnprintf(next, size, "\t(nothing queued)\n");
-                       if (t <= 0 || t > size)
+                       if (seq_puts(m, "\t(nothing queued)\n") < 0)
                                goto done;
-                       size -= t;
-                       next += t;
                        continue;
                }
                list_for_each_entry(req, &ep->queue, queue) {
@@ -1214,23 +1192,34 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
                        } else
                                tmp = req->req.actual;
 
-                       t = scnprintf(next, size,
+                       if (seq_printf(m,
                                "\treq %p len %u/%u buf %p\n",
                                &req->req, tmp, req->req.length,
-                               req->req.buf);
-                       if (t <= 0 || t > size)
+                               req->req.buf) < 0)
                                goto done;
-                       size -= t;
-                       next += t;
                }
        }
 
 done:
        local_irq_restore(flags);
-       *eof = 1;
-       return count - size;
+       return 0;
+}
+
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int udc_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, udc_proc_read, PDE_DATA(file_inode(file)));
 }
 
+static const struct file_operations udc_proc_fops = {
+       .open           = udc_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
 
 /*-------------------------------------------------------------------------*/
@@ -1807,7 +1796,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
-       create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev);
+       proc_create_data(proc_node_name, 0, NULL, &udc_proc_fops, dev);
 #endif
 
        retval = device_register(&dev->gadget.dev);
index 8efd7555fa21a93884a48a52eb743d28407f2410..5bd930d779b9dd957b51d610469b4e6e4ead5663 100644 (file)
@@ -1334,27 +1334,18 @@ static int imx_udc_start(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct imx_udc_struct *imx_usb;
-       int retval;
 
        imx_usb = container_of(gadget, struct imx_udc_struct, gadget);
        /* first hook up the driver ... */
        imx_usb->driver = driver;
        imx_usb->gadget.dev.driver = &driver->driver;
 
-       retval = device_add(&imx_usb->gadget.dev);
-       if (retval)
-               goto fail;
-
        D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n",
                __func__, driver->driver.name);
 
        imx_udc_enable(imx_usb);
 
        return 0;
-fail:
-       imx_usb->driver = NULL;
-       imx_usb->gadget.dev.driver = NULL;
-       return retval;
 }
 
 static int imx_udc_stop(struct usb_gadget *gadget,
@@ -1370,8 +1361,6 @@ static int imx_udc_stop(struct usb_gadget *gadget,
        imx_usb->gadget.dev.driver = NULL;
        imx_usb->driver = NULL;
 
-       device_del(&imx_usb->gadget.dev);
-
        D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n",
                __func__, driver->driver.name);
 
@@ -1477,6 +1466,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
        imx_usb->gadget.dev.parent = &pdev->dev;
        imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask;
 
+       ret = device_add(&imx_usb->gadget.dev);
+       if (retval)
+               goto fail4;
+
        platform_set_drvdata(pdev, imx_usb);
 
        usb_init_data(imx_usb);
@@ -1488,9 +1481,11 @@ static int __init imx_udc_probe(struct platform_device *pdev)
 
        ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget);
        if (ret)
-               goto fail4;
+               goto fail5;
 
        return 0;
+fail5:
+       device_unregister(&imx_usb->gadget.dev);
 fail4:
        for (i = 0; i < IMX_USB_NB_EP + 1; i++)
                free_irq(imx_usb->usbd_int[i], imx_usb);
@@ -1514,6 +1509,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
        int i;
 
        usb_del_gadget_udc(&imx_usb->gadget);
+       device_unregister(&imx_usb->gadget.dev);
        imx_udc_disable(imx_usb);
        del_timer(&imx_usb->timer);
 
index 8ac840f25ba9641f2939f807af8f4d768169702e..dda0dc4a55674756c76cb0efdf0dd6973d1b6109 100644 (file)
@@ -887,7 +887,6 @@ ep_open (struct inode *inode, struct file *fd)
 
 /* used before endpoint configuration */
 static const struct file_operations ep_config_operations = {
-       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
 
        .open =         ep_open,
@@ -1940,7 +1939,6 @@ dev_open (struct inode *inode, struct file *fd)
 }
 
 static const struct file_operations dev_init_operations = {
-       .owner =        THIS_MODULE,
        .llseek =       no_llseek,
 
        .open =         dev_open,
@@ -2105,6 +2103,7 @@ static struct file_system_type gadgetfs_type = {
        .mount          = gadgetfs_mount,
        .kill_sb        = gadgetfs_kill_sb,
 };
+MODULE_ALIAS_FS("gadgetfs");
 
 /*----------------------------------------------------------------------*/
 
index aa04089d6899fc4768537eb6257700acf91ad71e..1049d3745d7af39452824f5474af6e40ce3ee147 100644 (file)
@@ -565,7 +565,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
 
 static int proc_udc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, proc_udc_show, PDE(inode)->data);
+       return single_open(file, proc_udc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations proc_ops = {
index d226058e3b88ab7a3f6d07783886d8f23e8b7365..32524b631959eda7a62e2e2b005c3ba7a2e88f4b 100644 (file)
@@ -59,7 +59,7 @@ static const char * const ep_name[] = {
 };
 
 #define DMA_ADDR_INVALID       (~(dma_addr_t)0)
-#ifdef CONFIG_USB_GADGET_NET2272_DMA
+#ifdef CONFIG_USB_NET2272_DMA
 /*
  * use_dma: the NET2272 can use an external DMA controller.
  * Note that since there is no generic DMA api, some functions,
@@ -1495,6 +1495,13 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver)
        for (i = 0; i < 4; ++i)
                net2272_dequeue_all(&dev->ep[i]);
 
+       /* report disconnect; the driver is already quiesced */
+       if (driver) {
+               spin_unlock(&dev->lock);
+               driver->disconnect(&dev->gadget);
+               spin_lock(&dev->lock);
+       }
+
        net2272_usb_reinit(dev);
 }
 
index a1b650e11339797ca9a17ca41e6de5cd8ab07ca2..3bd0f992fb49aebe5b5c4dc9e45356bb77c01581 100644 (file)
@@ -1924,7 +1924,6 @@ static int net2280_start(struct usb_gadget *_gadget,
 err_func:
        device_remove_file (&dev->pdev->dev, &dev_attr_function);
 err_unbind:
-       driver->unbind (&dev->gadget);
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
        return retval;
@@ -1946,6 +1945,13 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
        for (i = 0; i < 7; i++)
                nuke (&dev->ep [i]);
 
+       /* report disconnect; the driver is already quiesced */
+       if (driver) {
+               spin_unlock(&dev->lock);
+               driver->disconnect(&dev->gadget);
+               spin_lock(&dev->lock);
+       }
+
        usb_reinit (dev);
 }
 
index 06be85c2b2337a7b9f909822fb3f8ab37313ad0c..f8445653577fbb107256576fec5481b4b94f758f 100644 (file)
@@ -62,6 +62,7 @@
 #define        DRIVER_VERSION  "4 October 2004"
 
 #define OMAP_DMA_USB_W2FC_TX0          29
+#define OMAP_DMA_USB_W2FC_RX0          26
 
 /*
  * The OMAP UDC needs _very_ early endpoint setup:  before enabling the
@@ -1310,7 +1311,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on)
 }
 
 static int omap_udc_start(struct usb_gadget *g,
-               struct usb_gadget_driver *driver)
+               struct usb_gadget_driver *driver);
 static int omap_udc_stop(struct usb_gadget *g,
                struct usb_gadget_driver *driver);
 
index 2bbcdce942dc2b7a8c29f17361e2a95fd59f47db..d0f37484b6b0cf67faf1875db8440521b030f1a2 100644 (file)
@@ -1266,13 +1266,6 @@ static int pxa25x_udc_start(struct usb_gadget *g,
        dev->gadget.dev.driver = &driver->driver;
        dev->pullup = 1;
 
-       retval = device_add (&dev->gadget.dev);
-       if (retval) {
-               dev->driver = NULL;
-               dev->gadget.dev.driver = NULL;
-               return retval;
-       }
-
        /* ... then enable host detection and ep0; and we're ready
         * for set_configuration as well as eventual disconnect.
         */
@@ -1310,6 +1303,10 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
        }
        del_timer_sync(&dev->timer);
 
+       /* report disconnect; the driver is already quiesced */
+       if (driver)
+               driver->disconnect(&dev->gadget);
+
        /* re-init driver-visible data structures */
        udc_reinit(dev);
 }
@@ -1331,7 +1328,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g,
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
 
-       device_del (&dev->gadget.dev);
        dump_state(dev);
 
        return 0;
@@ -2146,6 +2142,13 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        dev->gadget.dev.parent = &pdev->dev;
        dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
 
+       retval = device_add(&dev->gadget.dev);
+       if (retval) {
+               dev->driver = NULL;
+               dev->gadget.dev.driver = NULL;
+               goto err_device_add;
+       }
+
        the_controller = dev;
        platform_set_drvdata(pdev, dev);
 
@@ -2196,6 +2199,8 @@ lubbock_fail0:
        free_irq(irq, dev);
 #endif
  err_irq1:
+       device_unregister(&dev->gadget.dev);
+ err_device_add:
        if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
@@ -2217,10 +2222,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
 {
        struct pxa25x_udc *dev = platform_get_drvdata(pdev);
 
-       usb_del_gadget_udc(&dev->gadget);
        if (dev->driver)
                return -EBUSY;
 
+       usb_del_gadget_udc(&dev->gadget);
+       device_unregister(&dev->gadget.dev);
        dev->pullup = 0;
        pullup(dev);
 
index f7d25795821ac2830aa6ae587eda30c714c16342..2fc867652ef5df8f97e55c7c3ebe45196c672ab7 100644 (file)
@@ -1814,11 +1814,6 @@ static int pxa27x_udc_start(struct usb_gadget *g,
        udc->gadget.dev.driver = &driver->driver;
        dplus_pullup(udc, 1);
 
-       retval = device_add(&udc->gadget.dev);
-       if (retval) {
-               dev_err(udc->dev, "device_add error %d\n", retval);
-               goto fail;
-       }
        if (!IS_ERR_OR_NULL(udc->transceiver)) {
                retval = otg_set_peripheral(udc->transceiver->otg,
                                                &udc->gadget);
@@ -1876,7 +1871,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g,
 
        udc->driver = NULL;
 
-       device_del(&udc->gadget.dev);
 
        if (!IS_ERR_OR_NULL(udc->transceiver))
                return otg_set_peripheral(udc->transceiver->otg, NULL);
@@ -2480,13 +2474,24 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
                        driver_name, udc->irq, retval);
                goto err_irq;
        }
+
+       retval = device_add(&udc->gadget.dev);
+       if (retval) {
+               dev_err(udc->dev, "device_add error %d\n", retval);
+               goto err_dev_add;
+       }
+
        retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
        if (retval)
                goto err_add_udc;
 
        pxa_init_debugfs(udc);
+
        return 0;
+
 err_add_udc:
+       device_unregister(&udc->gadget.dev);
+err_dev_add:
        free_irq(udc->irq, udc);
 err_irq:
        iounmap(udc->regs);
@@ -2507,6 +2512,7 @@ static int __exit pxa_udc_remove(struct platform_device *_dev)
        int gpio = udc->mach->gpio_pullup;
 
        usb_del_gadget_udc(&udc->gadget);
+       device_del(&udc->gadget.dev);
        usb_gadget_unregister_driver(udc->driver);
        free_irq(udc->irq, udc);
        pxa_cleanup_debugfs(udc);
index d9297eebbf732f4cd889e5b377dae389532ecf92..1e4cfb05f70b9a0bba6a2fa421ef696d7649e8e8 100644 (file)
@@ -1065,7 +1065,7 @@ static int rndis_proc_show(struct seq_file *m, void *v)
 static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
                                size_t count, loff_t *ppos)
 {
-       rndis_params *p = PDE(file_inode(file))->data;
+       rndis_params *p = PDE_DATA(file_inode(file));
        u32 speed = 0;
        int i, fl_speed = 0;
 
@@ -1109,7 +1109,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
 
 static int rndis_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, rndis_proc_show, PDE(inode)->data);
+       return single_open(file, rndis_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations rndis_proc_fops = {
index fc07b43812867d4070143093060be8d328fad9ff..08f89652533baa0702bf4a85429d282b56973695 100644 (file)
@@ -1668,8 +1668,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev)
 static int s3c2410_udc_start(struct usb_gadget *g,
                struct usb_gadget_driver *driver)
 {
-       struct s3c2410_udc *udc = to_s3c2410(g)
-       int             retval;
+       struct s3c2410_udc *udc = to_s3c2410(g);
 
        dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name);
 
@@ -1677,22 +1676,10 @@ static int s3c2410_udc_start(struct usb_gadget *g,
        udc->driver = driver;
        udc->gadget.dev.driver = &driver->driver;
 
-       /* Bind the driver */
-       retval = device_add(&udc->gadget.dev);
-       if (retval) {
-               dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval);
-               goto register_error;
-       }
-
        /* Enable udc */
        s3c2410_udc_enable(udc);
 
        return 0;
-
-register_error:
-       udc->driver = NULL;
-       udc->gadget.dev.driver = NULL;
-       return retval;
 }
 
 static int s3c2410_udc_stop(struct usb_gadget *g,
@@ -1700,7 +1687,6 @@ static int s3c2410_udc_stop(struct usb_gadget *g,
 {
        struct s3c2410_udc *udc = to_s3c2410(g);
 
-       device_del(&udc->gadget.dev);
        udc->driver = NULL;
 
        /* Disable udc */
@@ -1842,6 +1828,13 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
        udc->gadget.dev.parent = &pdev->dev;
        udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
 
+       /* Bind the driver */
+       retval = device_add(&udc->gadget.dev);
+       if (retval) {
+               dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval);
+               goto err_device_add;
+       }
+
        the_controller = udc;
        platform_set_drvdata(pdev, udc);
 
@@ -1930,6 +1923,8 @@ err_gpio_claim:
 err_int:
        free_irq(IRQ_USBD, udc);
 err_map:
+       device_unregister(&udc->gadget.dev);
+err_device_add:
        iounmap(base_addr);
 err_mem:
        release_mem_region(rsrc_start, rsrc_len);
@@ -1947,10 +1942,11 @@ static int s3c2410_udc_remove(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "%s()\n", __func__);
 
-       usb_del_gadget_udc(&udc->gadget);
        if (udc->driver)
                return -EBUSY;
 
+       usb_del_gadget_udc(&udc->gadget);
+       device_unregister(&udc->gadget.dev);
        debugfs_remove(udc->regs_info);
 
        if (udc_info && !udc_info->udc_command &&
index c5034d9c946b479b52e7e06cba68729392727d07..b369292d4b90cd0c5c66dd147434f5d8aadbd752 100644 (file)
@@ -136,7 +136,7 @@ static struct portmaster {
        pr_debug(fmt, ##arg)
 #endif /* pr_vdebug */
 #else
-#ifndef pr_vdebig
+#ifndef pr_vdebug
 #define pr_vdebug(fmt, arg...) \
        ({ if (0) pr_debug(fmt, ##arg); })
 #endif /* pr_vdebug */
index e0c5e88e03ed30dc02c533d0eae3a41b94bcb00b..c7d460f43390da9dd5bfad40774f8c6b3fccf54d 100644 (file)
@@ -240,8 +240,11 @@ static int gaudio_open_snd_dev(struct gaudio *card)
        snd = &card->playback;
        snd->filp = filp_open(fn_play, O_WRONLY, 0);
        if (IS_ERR(snd->filp)) {
+               int ret = PTR_ERR(snd->filp);
+
                ERROR(card, "No such PCM playback device: %s\n", fn_play);
                snd->filp = NULL;
+               return ret;
        }
        pcm_file = snd->filp->private_data;
        snd->substream = pcm_file->substream;
index 2a9cd369f71cd857cce96f48acb4b600a828c981..f8f62c3ed65e7a468b97f7348aac97ea133bbcf1 100644 (file)
@@ -216,7 +216,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
        usb_gadget_disconnect(udc->gadget);
        udc->driver->disconnect(udc->gadget);
        udc->driver->unbind(udc->gadget);
-       usb_gadget_udc_stop(udc->gadget, udc->driver);
+       usb_gadget_udc_stop(udc->gadget, NULL);
 
        udc->driver = NULL;
        udc->dev.driver = NULL;
index b416a3fc99594f30afbb15995191313f6c9315a6..416a6dce5e11c8adeeed2eef487b93c93dd5d728 100644 (file)
@@ -302,6 +302,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
 
 static void end_unlink_async(struct ehci_hcd *ehci);
 static void unlink_empty_async(struct ehci_hcd *ehci);
+static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
 static void ehci_work(struct ehci_hcd *ehci);
 static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
 static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
@@ -748,11 +749,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                /* guard against (alleged) silicon errata */
                if (cmd & CMD_IAAD)
                        ehci_dbg(ehci, "IAA with IAAD still set?\n");
-               if (ehci->async_iaa) {
+               if (ehci->async_iaa)
                        COUNT(ehci->stats.iaa);
-                       end_unlink_async(ehci);
-               } else
-                       ehci_dbg(ehci, "IAA with nothing unlinked?\n");
+               end_unlink_async(ehci);
        }
 
        /* remote wakeup [4.3.1] */
index 4d3b294f203e3acefe469db340d695786b2ffc3f..7d06e77f6c4fa0116ea69ad239753ea4dffe20fd 100644 (file)
@@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        ehci->rh_state = EHCI_RH_SUSPENDED;
 
        end_unlink_async(ehci);
-       unlink_empty_async(ehci);
+       unlink_empty_async_suspended(ehci);
        ehci_handle_intr_unlinks(ehci);
        end_free_itds(ehci);
 
index fd252f0cfb3a7873ec7bad8226a036a9668b182e..23d13690428591b3c71d6c10bc9b29a4ffd0c973 100644 (file)
@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
                 * qtd is updated in qh_completions(). Update the QH
                 * overlay here.
                 */
-               if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
+               if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
                        qh->hw->hw_qtd_next = qtd->hw_next;
                        qtd = NULL;
                }
@@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                        else if (last_status == -EINPROGRESS && !urb->unlinked)
                                continue;
 
-                       /* qh unlinked; token in overlay may be most current */
-                       if (state == QH_STATE_IDLE
-                                       && cpu_to_hc32(ehci, qtd->qtd_dma)
-                                               == hw->hw_current) {
+                       /*
+                        * If this was the active qtd when the qh was unlinked
+                        * and the overlay's token is active, then the overlay
+                        * hasn't been written back to the qtd yet so use its
+                        * token instead of the qtd's.  After the qtd is
+                        * processed and removed, the overlay won't be valid
+                        * any more.
+                        */
+                       if (state == QH_STATE_IDLE &&
+                                       qh->qtd_list.next == &qtd->qtd_list &&
+                                       (hw->hw_token & ACTIVE_BIT(ehci))) {
                                token = hc32_to_cpu(ehci, hw->hw_token);
+                               hw->hw_token &= ~ACTIVE_BIT(ehci);
 
                                /* An unlink may leave an incomplete
                                 * async transaction in the TT buffer.
@@ -1170,7 +1178,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
        struct ehci_qh          *prev;
 
        /* Add to the end of the list of QHs waiting for the next IAAD */
-       qh->qh_state = QH_STATE_UNLINK;
+       qh->qh_state = QH_STATE_UNLINK_WAIT;
        if (ehci->async_unlink)
                ehci->async_unlink_last->unlink_next = qh;
        else
@@ -1213,9 +1221,19 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
 
                /* Do only the first waiting QH (nVidia bug?) */
                qh = ehci->async_unlink;
-               ehci->async_iaa = qh;
-               ehci->async_unlink = qh->unlink_next;
-               qh->unlink_next = NULL;
+
+               /*
+                * Intel (?) bug: The HC can write back the overlay region
+                * even after the IAA interrupt occurs.  In self-defense,
+                * always go through two IAA cycles for each QH.
+                */
+               if (qh->qh_state == QH_STATE_UNLINK_WAIT) {
+                       qh->qh_state = QH_STATE_UNLINK;
+               } else {
+                       ehci->async_iaa = qh;
+                       ehci->async_unlink = qh->unlink_next;
+                       qh->unlink_next = NULL;
+               }
 
                /* Make sure the unlinks are all visible to the hardware */
                wmb();
@@ -1298,6 +1316,19 @@ static void unlink_empty_async(struct ehci_hcd *ehci)
        }
 }
 
+/* The root hub is suspended; unlink all the async QHs */
+static void unlink_empty_async_suspended(struct ehci_hcd *ehci)
+{
+       struct ehci_qh          *qh;
+
+       while (ehci->async->qh_next.qh) {
+               qh = ehci->async->qh_next.qh;
+               WARN_ON(!list_empty(&qh->qtd_list));
+               single_unlink_async(ehci, qh);
+       }
+       start_iaa_cycle(ehci, false);
+}
+
 /* makes sure the async qh will become idle */
 /* caller must own ehci->lock */
 
index 20dbdcbe9b0fc1fb1330da115bebb3546e45b8f2..c3fa1305f830bf53070a6553446428368553691d 100644 (file)
@@ -304,7 +304,7 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
         * (a) SMP races against real IAA firing and retriggering, and
         * (b) clean HC shutdown, when IAA watchdog was pending.
         */
-       if (ehci->async_iaa) {
+       if (1) {
                u32 cmd, status;
 
                /* If we get here, IAA is *REALLY* late.  It's barely
index 974480c516fabc956f200f2c42941f281d792238..b04e8ece4d35f448c6b8ac5b23b9c198b0702702 100644 (file)
@@ -2175,7 +2175,7 @@ static int proc_isp1362_show(struct seq_file *s, void *unused)
 
 static int proc_isp1362_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, proc_isp1362_show, PDE(inode)->data);
+       return single_open(file, proc_isp1362_show, PDE_DATA(inode));
 }
 
 static const struct file_operations proc_ops = {
@@ -2192,14 +2192,11 @@ static void create_debug_file(struct isp1362_hcd *isp1362_hcd)
 {
        struct proc_dir_entry *pde;
 
-       pde = create_proc_entry(proc_filename, 0, NULL);
+       pde = proc_create_data(proc_filename, 0, NULL, &proc_ops, isp1362_hcd);
        if (pde == NULL) {
                pr_warning("%s: Failed to create debug file '%s'\n", __func__, proc_filename);
                return;
        }
-
-       pde->proc_fops = &proc_ops;
-       pde->data = isp1362_hcd;
        isp1362_hcd->pde = pde;
 }
 
index d62f0404baaa636d82e3b409edf4581c7e92ab03..313d0bbfff29a098dbd87bc5e088f6f7351762b7 100644 (file)
@@ -1494,7 +1494,7 @@ static int proc_sl811h_show(struct seq_file *s, void *unused)
 
 static int proc_sl811h_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, proc_sl811h_show, PDE(inode)->data);
+       return single_open(file, proc_sl811h_show, PDE_DATA(inode));
 }
 
 static const struct file_operations proc_ops = {
index f1f01a834ba792cee0935c5ffb9373d53fb368bd..849470b188313ece555d4a9c20aa9e70bb92ff2a 100644 (file)
@@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
         * generate interrupts.  Don't even try to enable MSI.
         */
        if (xhci->quirks & XHCI_BROKEN_MSI)
-               return 0;
+               goto legacy_irq;
 
        /* unregister the legacy interrupt */
        if (hcd->irq)
@@ -371,6 +371,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
                return -EINVAL;
        }
 
+ legacy_irq:
        /* fall back to legacy interrupt*/
        ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
                        hcd->irq_descr, hcd);
index f791bd0aee6cda4ad2bf5407ba5ad71b912cc5f5..2c510e4a7d4c61b92df567c83d01ffba96aa849c 100644 (file)
@@ -206,8 +206,8 @@ struct xhci_op_regs {
 /* bits 12:31 are reserved (and should be preserved on writes). */
 
 /* IMAN - Interrupt Management Register */
-#define IMAN_IP                (1 << 1)
-#define IMAN_IE                (1 << 0)
+#define IMAN_IE                (1 << 1)
+#define IMAN_IP                (1 << 0)
 
 /* USBSTS - USB status - status bitmasks */
 /* HC not running - set to 1 when run/stop bit is cleared. */
index 42ad2e6d86c4c30cb08caa98fe9dfedd7249701c..b6ab515bfc6c0b1be593ed99e10e86391e012525 100644 (file)
@@ -407,8 +407,6 @@ static int yurex_release(struct inode *inode, struct file *file)
        if (dev == NULL)
                return -ENODEV;
 
-       yurex_fasync(-1, file, 0);
-
        /* decrement the count on our device */
        kref_put(&dev->kref, yurex_delete);
        return 0;
index 45b19e2c60bacfe396469c2d4ea426c3ff68c830..05e51432dd2f77eb08bda0b43293df5363425ef0 100644 (file)
@@ -7,11 +7,6 @@
 config USB_MUSB_HDRC
        tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        depends on USB && USB_GADGET
-       select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
-       select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX)
-       select TWL4030_USB if MACH_OMAP_3430SDP
-       select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
-       select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
        select USB_OTG_UTILS
        help
          Say Y here if your system has a dual role high speed USB
index 7c71769d71ff37370e6e8bf23be5c837bd72a677..41613a2b35e8530d8278bd8e4191bafae5617828 100644 (file)
@@ -327,7 +327,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
                u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
                int err;
 
-               err = musb->int_usb & USB_INTR_VBUSERROR;
+               err = musb->int_usb & MUSB_INTR_VBUSERROR;
                if (err) {
                        /*
                         * The Mentor core doesn't debounce VBUS as needed
index 60b41cc28da446558690f0e37bff33111823f281..daec6e0f7e381e52750cffab9112488c3af1e01d 100644 (file)
@@ -1624,8 +1624,6 @@ EXPORT_SYMBOL_GPL(musb_dma_completion);
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_SYSFS
-
 static ssize_t
 musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1742,8 +1740,6 @@ static const struct attribute_group musb_attr_group = {
        .attrs = musb_attributes,
 };
 
-#endif /* sysfs */
-
 /* Only used to provide driver mode change events */
 static void musb_irq_work(struct work_struct *data)
 {
@@ -1968,11 +1964,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        if (status < 0)
                goto fail4;
 
-#ifdef CONFIG_SYSFS
        status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
        if (status)
                goto fail5;
-#endif
 
        pm_runtime_put(musb->controller);
 
index be18537c5f1407cca17b31f65965863c0fa47385..83eddedcd9be5895908672b329ebf881d26d8f2f 100644 (file)
@@ -141,7 +141,9 @@ static inline void map_dma_buffer(struct musb_request *request,
 static inline void unmap_dma_buffer(struct musb_request *request,
                                struct musb *musb)
 {
-       if (!is_buffer_mapped(request))
+       struct musb_ep *musb_ep = request->ep;
+
+       if (!is_buffer_mapped(request) || !musb_ep->dma)
                return;
 
        if (request->request.dma == DMA_ADDR_INVALID) {
@@ -195,7 +197,10 @@ __acquires(ep->musb->lock)
 
        ep->busy = 1;
        spin_unlock(&musb->lock);
-       unmap_dma_buffer(req, musb);
+
+       if (!dma_mapping_error(&musb->g.dev, request->dma))
+               unmap_dma_buffer(req, musb);
+
        if (request->status == 0)
                dev_dbg(musb->controller, "%s done request %p,  %d/%d\n",
                                ep->end_point.name, request,
index 1762354fe793198fbfc075fb95ab22468dc34a8b..1a42a458f2c4ff64cb8e9e3492bf368cf79cf0c3 100644 (file)
@@ -51,7 +51,7 @@ struct omap2430_glue {
 };
 #define glue_to_musb(g)                platform_get_drvdata(g->musb)
 
-struct omap2430_glue           *_glue;
+static struct omap2430_glue    *_glue;
 
 static struct timer_list musb_idle_timer;
 
@@ -237,9 +237,13 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 {
        struct omap2430_glue    *glue = _glue;
 
-       if (glue && glue_to_musb(glue)) {
-               glue->status = status;
-       } else {
+       if (!glue) {
+               pr_err("%s: musb core is not yet initialized\n", __func__);
+               return;
+       }
+       glue->status = status;
+
+       if (!glue_to_musb(glue)) {
                pr_err("%s: musb core is not yet ready\n", __func__);
                return;
        }
index e1814397ca3ab9631872a481d0a60c2b77b89afc..2bd03d261a50f4f8f8df3583dcc57961c3b8ec34 100644 (file)
@@ -130,7 +130,7 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type)
        spin_lock_irqsave(&phy_lock, flags);
 
        phy = __usb_find_phy(&phy_list, type);
-       if (IS_ERR(phy)) {
+       if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
                pr_err("unable to find transceiver of type %s\n",
                        usb_phy_type_string(type));
                goto err0;
@@ -228,7 +228,7 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
        spin_lock_irqsave(&phy_lock, flags);
 
        phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
-       if (IS_ERR(phy)) {
+       if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
                pr_err("unable to find transceiver\n");
                goto err0;
        }
@@ -301,8 +301,12 @@ EXPORT_SYMBOL(devm_usb_put_phy);
  */
 void usb_put_phy(struct usb_phy *x)
 {
-       if (x)
+       if (x) {
+               struct module *owner = x->dev->driver->owner;
+
                put_device(x->dev);
+               module_put(owner);
+       }
 }
 EXPORT_SYMBOL(usb_put_phy);
 
index 5323b71c3521f4ebe41ad74260787103e6933ce5..1419ceda9759c591f5036dddda8c5c673a2d7fa4 100644 (file)
@@ -219,32 +219,26 @@ static int omap_control_usb_probe(struct platform_device *pdev)
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                "control_dev_conf");
-       control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res);
-       if (!control_usb->dev_conf) {
-               dev_err(&pdev->dev, "Failed to obtain io memory\n");
-               return -EADDRNOTAVAIL;
-       }
+       control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(control_usb->dev_conf))
+               return PTR_ERR(control_usb->dev_conf);
 
        if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                        "otghs_control");
-               control_usb->otghs_control = devm_request_and_ioremap(
+               control_usb->otghs_control = devm_ioremap_resource(
                        &pdev->dev, res);
-               if (!control_usb->otghs_control) {
-                       dev_err(&pdev->dev, "Failed to obtain io memory\n");
-                       return -EADDRNOTAVAIL;
-               }
+               if (IS_ERR(control_usb->otghs_control))
+                       return PTR_ERR(control_usb->otghs_control);
        }
 
        if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                        "phy_power_usb");
-               control_usb->phy_power = devm_request_and_ioremap(
+               control_usb->phy_power = devm_ioremap_resource(
                        &pdev->dev, res);
-               if (!control_usb->phy_power) {
-                       dev_dbg(&pdev->dev, "Failed to obtain io memory\n");
-                       return -EADDRNOTAVAIL;
-               }
+               if (IS_ERR(control_usb->phy_power))
+                       return PTR_ERR(control_usb->phy_power);
 
                control_usb->sys_clk = devm_clk_get(control_usb->dev,
                        "sys_clkin");
index fadc0c2b65bb7baf6b633c97cb187a16c4bd9d93..a6e60b1e102e84c070a44e139d8e9ac2b1ff01c7 100644 (file)
@@ -212,11 +212,9 @@ static int omap_usb3_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
-       phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
-       if (!phy->pll_ctrl_base) {
-               dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n");
-               return -ENOMEM;
-       }
+       phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(phy->pll_ctrl_base))
+               return PTR_ERR(phy->pll_ctrl_base);
 
        phy->dev                = &pdev->dev;
 
index 6ea5537338325f6f8ed9fe10cb7756bb79f2daf2..967101ec15fdf268cc8d2a73493be36df718d687 100644 (file)
@@ -787,11 +787,9 @@ static int samsung_usbphy_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       phy_base = devm_request_and_ioremap(dev, phy_mem);
-       if (!phy_base) {
-               dev_err(dev, "%s: register mapping failed\n", __func__);
-               return -ENXIO;
-       }
+       phy_base = devm_ioremap_resource(dev, phy_mem);
+       if (IS_ERR(phy_base))
+               return PTR_ERR(phy_base);
 
        sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
        if (!sphy)
index cbd904b8fba55f42ec07ed0d3a741878b516157c..4775f8209e5502b7f893d0a00a8f51622746a138 100644 (file)
@@ -62,7 +62,6 @@ static int is_irda(struct usb_serial *serial)
 }
 
 struct ark3116_private {
-       wait_queue_head_t       delta_msr_wait;
        struct async_icount     icount;
        int                     irda;   /* 1 for irda device */
 
@@ -146,7 +145,6 @@ static int ark3116_port_probe(struct usb_serial_port *port)
        if (!priv)
                return -ENOMEM;
 
-       init_waitqueue_head(&priv->delta_msr_wait);
        mutex_init(&priv->hw_lock);
        spin_lock_init(&priv->status_lock);
 
@@ -456,10 +454,14 @@ static int ark3116_ioctl(struct tty_struct *tty,
        case TIOCMIWAIT:
                for (;;) {
                        struct async_icount prev = priv->icount;
-                       interruptible_sleep_on(&priv->delta_msr_wait);
+                       interruptible_sleep_on(&port->delta_msr_wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        if ((prev.rng == priv->icount.rng) &&
                            (prev.dsr == priv->icount.dsr) &&
                            (prev.dcd == priv->icount.dcd) &&
@@ -580,7 +582,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
                        priv->icount.dcd++;
                if (msr & UART_MSR_TERI)
                        priv->icount.rng++;
-               wake_up_interruptible(&priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
        }
 }
 
index d255f66e708e80ee78d72bc052bef4e71ba578e2..07d4650a32abe2d89149ef8fc2a22bc17bebe8b2 100644 (file)
@@ -80,7 +80,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
 
 struct ch341_private {
        spinlock_t lock; /* access lock */
-       wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
        unsigned baud_rate; /* set baud rate */
        u8 line_control; /* set line control value RTS/DTR */
        u8 line_status; /* active status of modem control inputs */
@@ -252,7 +251,6 @@ static int ch341_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
        priv->baud_rate = DEFAULT_BAUD_RATE;
        priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
@@ -298,7 +296,7 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on)
                priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
        spin_unlock_irqrestore(&priv->lock, flags);
        ch341_set_handshake(port->serial->dev, priv->line_control);
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 }
 
 static void ch341_close(struct usb_serial_port *port)
@@ -491,7 +489,7 @@ static void ch341_read_int_callback(struct urb *urb)
                        tty_kref_put(tty);
                }
 
-               wake_up_interruptible(&priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
        }
 
 exit:
@@ -517,11 +515,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (!multi_change) {
-               interruptible_sleep_on(&priv->delta_msr_wait);
+               interruptible_sleep_on(&port->delta_msr_wait);
                /* see if a signal did it */
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                status = priv->line_status;
                multi_change = priv->multi_status_change;
index edc0f0dcad8378f4298d68815d2935404d8fedac..4747d1c328ffbdc13e1ca4337dc11a6c557711f5 100644 (file)
@@ -85,6 +85,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+       { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */
        { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
        { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
@@ -150,6 +151,25 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
        { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
        { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
+       { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */
+       { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */
+       { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */
+       { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */
+       { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */
+       { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */
+       { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */
+       { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */
+       { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */
+       { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */
+       { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */
+       { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
+       { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
+       { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
        { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
        { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
        { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
index 8efa19d0e9fba756d37f7ea1f0b0d7e813ab9610..ba7352e4187efbd1ef73a09297d1cbb1825a4b08 100644 (file)
@@ -111,7 +111,6 @@ struct cypress_private {
        int baud_rate;                     /* stores current baud rate in
                                              integer form */
        int isthrottled;                   /* if throttled, discard reads */
-       wait_queue_head_t delta_msr_wait;  /* used for TIOCMIWAIT */
        char prev_status, diff_status;     /* used for TIOCMIWAIT */
        /* we pass a pointer to this as the argument sent to
           cypress_set_termios old_termios */
@@ -449,7 +448,6 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
                kfree(priv);
                return -ENOMEM;
        }
-       init_waitqueue_head(&priv->delta_msr_wait);
 
        usb_reset_configuration(serial->dev);
 
@@ -868,12 +866,16 @@ static int cypress_ioctl(struct tty_struct *tty,
        switch (cmd) {
        /* This code comes from drivers/char/serial.c and ftdi_sio.c */
        case TIOCMIWAIT:
-               while (priv != NULL) {
-                       interruptible_sleep_on(&priv->delta_msr_wait);
+               for (;;) {
+                       interruptible_sleep_on(&port->delta_msr_wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
-                       else {
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
+                       {
                                char diff = priv->diff_status;
                                if (diff == 0)
                                        return -EIO; /* no change => error */
@@ -1187,7 +1189,7 @@ static void cypress_read_int_callback(struct urb *urb)
        if (priv->current_status != priv->prev_status) {
                priv->diff_status |= priv->current_status ^
                        priv->prev_status;
-               wake_up_interruptible(&priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
                priv->prev_status = priv->current_status;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
index b1b2dc64b50be013eab09a2dd5ce535875aeeb5a..a172ad5c5ce80c1c00983960a04339ac3c13fb24 100644 (file)
@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
 
 struct f81232_private {
        spinlock_t lock;
-       wait_queue_head_t delta_msr_wait;
        u8 line_control;
        u8 line_status;
 };
@@ -111,7 +110,7 @@ static void f81232_process_read_urb(struct urb *urb)
        line_status = priv->line_status;
        priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
        spin_unlock_irqrestore(&priv->lock, flags);
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        if (!urb->actual_length)
                return;
@@ -256,11 +255,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (1) {
-               interruptible_sleep_on(&priv->delta_msr_wait);
+               interruptible_sleep_on(&port->delta_msr_wait);
                /* see if a signal did it */
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                status = priv->line_status;
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -322,7 +324,6 @@ static int f81232_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
 
        usb_set_serial_port_data(port, priv);
 
index edd162df49caed8b02a1c0823a497c6c5d9d180e..d4809d5514738a15496c216eea033ef788baaf62 100644 (file)
@@ -69,9 +69,7 @@ struct ftdi_private {
        int flags;              /* some ASYNC_xxxx flags are supported */
        unsigned long last_dtr_rts;     /* saved modem control outputs */
        struct async_icount     icount;
-       wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
        char prev_status;        /* Used for TIOCMIWAIT */
-       bool dev_gone;        /* Used to abort TIOCMIWAIT */
        char transmit_empty;    /* If transmitter is empty or not */
        __u16 interface;        /* FT2232C, FT2232H or FT4232H port interface
                                   (0 for FT232/245) */
@@ -1691,10 +1689,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
 
        kref_init(&priv->kref);
        mutex_init(&priv->cfg_lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
 
        priv->flags = ASYNC_LOW_LATENCY;
-       priv->dev_gone = false;
 
        if (quirk && quirk->port_probe)
                quirk->port_probe(priv);
@@ -1840,8 +1836,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
 
-       priv->dev_gone = true;
-       wake_up_interruptible_all(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        remove_sysfs_attrs(port);
 
@@ -1989,7 +1984,7 @@ static int ftdi_process_packet(struct usb_serial_port *port,
                if (diff_status & FTDI_RS0_RLSD)
                        priv->icount.dcd++;
 
-               wake_up_interruptible_all(&priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
                priv->prev_status = status;
        }
 
@@ -2440,11 +2435,15 @@ static int ftdi_ioctl(struct tty_struct *tty,
         */
        case TIOCMIWAIT:
                cprev = priv->icount;
-               while (!priv->dev_gone) {
-                       interruptible_sleep_on(&priv->delta_msr_wait);
+               for (;;) {
+                       interruptible_sleep_on(&port->delta_msr_wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        cnow = priv->icount;
                        if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
                            ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
@@ -2454,8 +2453,6 @@ static int ftdi_ioctl(struct tty_struct *tty,
                        }
                        cprev = cnow;
                }
-               return -EIO;
-               break;
        case TIOCSERGETLSR:
                return get_lsr_info(port, (struct serial_struct __user *)arg);
                break;
index 1a07b12ef341a08e2bdb880d3d446054dccd5339..81caf5623ee295d609acce00a1e06a20ef34c20f 100644 (file)
@@ -956,10 +956,7 @@ static void garmin_close(struct usb_serial_port *port)
        if (!serial)
                return;
 
-       mutex_lock(&port->serial->disc_mutex);
-
-       if (!port->serial->disconnected)
-               garmin_clear(garmin_data_p);
+       garmin_clear(garmin_data_p);
 
        /* shutdown our urbs */
        usb_kill_urb(port->read_urb);
@@ -968,8 +965,6 @@ static void garmin_close(struct usb_serial_port *port)
        /* keep reset state so we know that we must start a new session */
        if (garmin_data_p->state != STATE_RESET)
                garmin_data_p->state = STATE_DISCONNECTED;
-
-       mutex_unlock(&port->serial->disc_mutex);
 }
 
 
index b00e5cbf741f16b63071c8273c7f69eaa279ca6d..efd8b978128c1d86412322f0c37e9da32b00610a 100644 (file)
@@ -110,7 +110,6 @@ struct edgeport_port {
        wait_queue_head_t       wait_chase;             /* for handling sleeping while waiting for chase to finish */
        wait_queue_head_t       wait_open;              /* for handling sleeping while waiting for open to finish */
        wait_queue_head_t       wait_command;           /* for handling sleeping while waiting for command to finish */
-       wait_queue_head_t       delta_msr_wait;         /* for handling sleeping while waiting for msr change to happen */
 
        struct async_icount     icount;
        struct usb_serial_port  *port;                  /* loop back to the owner of this object */
@@ -884,7 +883,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
        /* initialize our wait queues */
        init_waitqueue_head(&edge_port->wait_open);
        init_waitqueue_head(&edge_port->wait_chase);
-       init_waitqueue_head(&edge_port->delta_msr_wait);
        init_waitqueue_head(&edge_port->wait_command);
 
        /* initialize our icount structure */
@@ -1669,13 +1667,17 @@ static int edge_ioctl(struct tty_struct *tty,
                dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__,  port->number);
                cprev = edge_port->icount;
                while (1) {
-                       prepare_to_wait(&edge_port->delta_msr_wait,
+                       prepare_to_wait(&port->delta_msr_wait,
                                                &wait, TASK_INTERRUPTIBLE);
                        schedule();
-                       finish_wait(&edge_port->delta_msr_wait, &wait);
+                       finish_wait(&port->delta_msr_wait, &wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        cnow = edge_port->icount;
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -2051,7 +2053,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
                        icount->dcd++;
                if (newMsr & EDGEPORT_MSR_DELTA_RI)
                        icount->rng++;
-               wake_up_interruptible(&edge_port->delta_msr_wait);
+               wake_up_interruptible(&edge_port->port->delta_msr_wait);
        }
 
        /* Save the new modem status */
index c23776679f7029a37598e5cea826060670be7e64..7777172206de1b42a971acb0747d97180230d670 100644 (file)
@@ -87,9 +87,6 @@ struct edgeport_port {
        int close_pending;
        int lsr_event;
        struct async_icount     icount;
-       wait_queue_head_t       delta_msr_wait; /* for handling sleeping while
-                                                  waiting for msr change to
-                                                  happen */
        struct edgeport_serial  *edge_serial;
        struct usb_serial_port  *port;
        __u8 bUartMode;         /* Port type, 0: RS232, etc. */
@@ -1459,7 +1456,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
                        icount->dcd++;
                if (msr & EDGEPORT_MSR_DELTA_RI)
                        icount->rng++;
-               wake_up_interruptible(&edge_port->delta_msr_wait);
+               wake_up_interruptible(&edge_port->port->delta_msr_wait);
        }
 
        /* Save the new modem status */
@@ -1754,7 +1751,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
        dev = port->serial->dev;
 
        memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
-       init_waitqueue_head(&edge_port->delta_msr_wait);
 
        /* turn off loopback */
        status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
@@ -2434,10 +2430,14 @@ static int edge_ioctl(struct tty_struct *tty,
                dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
                cprev = edge_port->icount;
                while (1) {
-                       interruptible_sleep_on(&edge_port->delta_msr_wait);
+                       interruptible_sleep_on(&port->delta_msr_wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        cnow = edge_port->icount;
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -2649,6 +2649,7 @@ static struct usb_serial_driver edgeport_2port_device = {
        .set_termios            = edge_set_termios,
        .tiocmget               = edge_tiocmget,
        .tiocmset               = edge_tiocmset,
+       .get_icount             = edge_get_icount,
        .write                  = edge_write,
        .write_room             = edge_write_room,
        .chars_in_buffer        = edge_chars_in_buffer,
index a64d420f687b0a198ded7bac0cd38a17b89494c0..06d5a60be2c4cb87279744372edef4a41864b74b 100644 (file)
@@ -114,8 +114,6 @@ struct mct_u232_private {
        unsigned char        last_msr;      /* Modem Status Register */
        unsigned int         rx_flags;      /* Throttling flags */
        struct async_icount  icount;
-       wait_queue_head_t    msr_wait;  /* for handling sleeping while waiting
-                                               for msr change to happen */
 };
 
 #define THROTTLED              0x01
@@ -409,7 +407,6 @@ static int mct_u232_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->msr_wait);
 
        usb_set_serial_port_data(port, priv);
 
@@ -601,7 +598,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
                tty_kref_put(tty);
        }
 #endif
-       wake_up_interruptible(&priv->msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
        spin_unlock_irqrestore(&priv->lock, flags);
 exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -810,13 +807,17 @@ static int  mct_u232_ioctl(struct tty_struct *tty,
                cprev = mct_u232_port->icount;
                spin_unlock_irqrestore(&mct_u232_port->lock, flags);
                for ( ; ; ) {
-                       prepare_to_wait(&mct_u232_port->msr_wait,
+                       prepare_to_wait(&port->delta_msr_wait,
                                        &wait, TASK_INTERRUPTIBLE);
                        schedule();
-                       finish_wait(&mct_u232_port->msr_wait, &wait);
+                       finish_wait(&port->delta_msr_wait, &wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        spin_lock_irqsave(&mct_u232_port->lock, flags);
                        cnow = mct_u232_port->icount;
                        spin_unlock_irqrestore(&mct_u232_port->lock, flags);
index 809fb329eca5f945d13c25e75f74bf79145389df..b8051fa61911a54a23de8f9a1662518181b6c084 100644 (file)
@@ -219,7 +219,6 @@ struct moschip_port {
        char open;
        char open_ports;
        wait_queue_head_t wait_chase;   /* for handling sleeping while waiting for chase to finish */
-       wait_queue_head_t delta_msr_wait;       /* for handling sleeping while waiting for msr change to happen */
        int delta_msr_cond;
        struct async_icount icount;
        struct usb_serial_port *port;   /* loop back to the owner of this object */
@@ -423,6 +422,9 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
                        icount->rng++;
                        smp_wmb();
                }
+
+               mos7840_port->delta_msr_cond = 1;
+               wake_up_interruptible(&port->port->delta_msr_wait);
        }
 }
 
@@ -1127,7 +1129,6 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        /* initialize our wait queues */
        init_waitqueue_head(&mos7840_port->wait_chase);
-       init_waitqueue_head(&mos7840_port->delta_msr_wait);
 
        /* initialize our icount structure */
        memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
@@ -2017,8 +2018,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
                        mos7840_port->read_urb_busy = false;
                }
        }
-       wake_up(&mos7840_port->delta_msr_wait);
-       mos7840_port->delta_msr_cond = 1;
        dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__,
                mos7840_port->shadowLCR);
 }
@@ -2219,13 +2218,18 @@ static int mos7840_ioctl(struct tty_struct *tty,
                while (1) {
                        /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
                        mos7840_port->delta_msr_cond = 0;
-                       wait_event_interruptible(mos7840_port->delta_msr_wait,
-                                                (mos7840_port->
+                       wait_event_interruptible(port->delta_msr_wait,
+                                                (port->serial->disconnected ||
+                                                 mos7840_port->
                                                  delta_msr_cond == 1));
 
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        cnow = mos7840_port->icount;
                        smp_rmb();
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
index f7d339d8187bd690b86b22ccf85b740781257226..558adfc05007dbdf46f2dc9a5280579b3cdbdab2 100644 (file)
@@ -341,6 +341,8 @@ static void option_instat_callback(struct urb *urb);
 #define CINTERION_PRODUCT_EU3_E                        0x0051
 #define CINTERION_PRODUCT_EU3_P                        0x0052
 #define CINTERION_PRODUCT_PH8                  0x0053
+#define CINTERION_PRODUCT_AH6                  0x0055
+#define CINTERION_PRODUCT_PLS8                 0x0060
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
@@ -579,6 +581,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
                .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
@@ -1260,6 +1263,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
index a958fd41b5b312a699b5d963d8db1a49ea56810b..87c71ccfee87bfd06d41034a52a6e5dc27a21c7f 100644 (file)
@@ -188,7 +188,6 @@ struct oti6858_private {
        u8 setup_done;
        struct delayed_work delayed_setup_work;
 
-       wait_queue_head_t intr_wait;
        struct usb_serial_port *port;   /* USB port with which associated */
 };
 
@@ -339,7 +338,6 @@ static int oti6858_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->intr_wait);
        priv->port = port;
        INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
        INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
@@ -664,11 +662,15 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (1) {
-               wait_event_interruptible(priv->intr_wait,
+               wait_event_interruptible(port->delta_msr_wait,
+                                       port->serial->disconnected ||
                                        priv->status.pin_state != prev);
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                status = priv->status.pin_state & PIN_MASK;
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -763,7 +765,7 @@ static void oti6858_read_int_callback(struct urb *urb)
 
                if (!priv->transient) {
                        if (xs->pin_state != priv->status.pin_state)
-                               wake_up_interruptible(&priv->intr_wait);
+                               wake_up_interruptible(&port->delta_msr_wait);
                        memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
                }
 
index 54adc9125e5c1e9eb29b37573433e0d6324dce0e..3b10018d89a34e44e03b5ffb5562c34c7e4e6b85 100644 (file)
@@ -139,7 +139,6 @@ struct pl2303_serial_private {
 
 struct pl2303_private {
        spinlock_t lock;
-       wait_queue_head_t delta_msr_wait;
        u8 line_control;
        u8 line_status;
 };
@@ -233,7 +232,6 @@ static int pl2303_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
 
        usb_set_serial_port_data(port, priv);
 
@@ -607,11 +605,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (1) {
-               interruptible_sleep_on(&priv->delta_msr_wait);
+               interruptible_sleep_on(&port->delta_msr_wait);
                /* see if a signal did it */
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                status = priv->line_status;
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -719,7 +720,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        spin_unlock_irqrestore(&priv->lock, flags);
        if (priv->line_status & UART_BREAK_ERROR)
                usb_serial_handle_break(port);
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        tty = tty_port_tty_get(&port->port);
        if (!tty)
@@ -783,7 +784,7 @@ static void pl2303_process_read_urb(struct urb *urb)
        line_status = priv->line_status;
        priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
        spin_unlock_irqrestore(&priv->lock, flags);
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        if (!urb->actual_length)
                return;
index 9b1b96f2d0955d8d8e98a284bf0fda6123c6c900..31f81c3c15eb780a10eccaa3b937cebb9f713df3 100644 (file)
@@ -69,6 +69,7 @@ static struct usb_device_id id_table[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) },  /* NMEA */
        { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) },  /* WMC */
        { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) },  /* DIAG */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index 24662547dc5b2e60ffc51abc846e930e0afc1182..59b32b7821264d6d02b34fe4df881496ebf271b2 100644 (file)
@@ -197,12 +197,15 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 
        if (is_gobi1k) {
                /* Gobi 1K USB layout:
-                * 0: serial port (doesn't respond)
+                * 0: DM/DIAG (use libqcdm from ModemManager for communication)
                 * 1: serial port (doesn't respond)
                 * 2: AT-capable modem port
                 * 3: QMI/net
                 */
-               if (ifnum == 2)
+               if (ifnum == 0) {
+                       dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n");
+                       altsetting = 1;
+               } else if (ifnum == 2)
                        dev_dbg(dev, "Modem port found\n");
                else
                        altsetting = -1;
index 00e6c9bac8a309b0df675903654ce0521f991cad..75f125ddb0c94136da28ebf5fa5d4e4200a0b410 100644 (file)
@@ -128,7 +128,6 @@ struct qt2_port_private {
        u8          shadowLSR;
        u8          shadowMSR;
 
-       wait_queue_head_t   delta_msr_wait; /* Used for TIOCMIWAIT */
        struct async_icount icount;
 
        struct usb_serial_port *port;
@@ -506,8 +505,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (1) {
-               wait_event_interruptible(priv->delta_msr_wait,
-                                        ((priv->icount.rng != prev.rng) ||
+               wait_event_interruptible(port->delta_msr_wait,
+                                        (port->serial->disconnected ||
+                                         (priv->icount.rng != prev.rng) ||
                                          (priv->icount.dsr != prev.dsr) ||
                                          (priv->icount.dcd != prev.dcd) ||
                                          (priv->icount.cts != prev.cts)));
@@ -515,6 +515,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                cur = priv->icount;
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -661,7 +664,9 @@ void qt2_process_read_urb(struct urb *urb)
                                                 __func__);
                                        break;
                                }
-                               tty_flip_buffer_push(&port->port);
+
+                               if (port_priv->is_open)
+                                       tty_flip_buffer_push(&port->port);
 
                                newport = *(ch + 3);
 
@@ -704,7 +709,8 @@ void qt2_process_read_urb(struct urb *urb)
                tty_insert_flip_string(&port->port, ch, 1);
        }
 
-       tty_flip_buffer_push(&port->port);
+       if (port_priv->is_open)
+               tty_flip_buffer_push(&port->port);
 }
 
 static void qt2_write_bulk_callback(struct urb *urb)
@@ -824,7 +830,6 @@ static int qt2_port_probe(struct usb_serial_port *port)
 
        spin_lock_init(&port_priv->lock);
        spin_lock_init(&port_priv->urb_lock);
-       init_waitqueue_head(&port_priv->delta_msr_wait);
        port_priv->port = port;
 
        port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -967,7 +972,7 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
                if (newMSR & UART_MSR_TERI)
                        port_priv->icount.rng++;
 
-               wake_up_interruptible(&port_priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
        }
 }
 
index 91ff8e3bddbd76a4daa3502d17dd2aaab96ac154..549ef68ff5fa2ea156fa31ea65f3b823353b1cfa 100644 (file)
@@ -149,7 +149,6 @@ enum spcp8x5_type {
 struct spcp8x5_private {
        spinlock_t      lock;
        enum spcp8x5_type       type;
-       wait_queue_head_t       delta_msr_wait;
        u8                      line_control;
        u8                      line_status;
 };
@@ -179,7 +178,6 @@ static int spcp8x5_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
        priv->type = type;
 
        usb_set_serial_port_data(port , priv);
@@ -475,7 +473,7 @@ static void spcp8x5_process_read_urb(struct urb *urb)
        priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
        spin_unlock_irqrestore(&priv->lock, flags);
        /* wake up the wait for termios */
-       wake_up_interruptible(&priv->delta_msr_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
 
        if (!urb->actual_length)
                return;
@@ -526,12 +524,15 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port,
 
        while (1) {
                /* wake up in bulk read */
-               interruptible_sleep_on(&priv->delta_msr_wait);
+               interruptible_sleep_on(&port->delta_msr_wait);
 
                /* see if a signal did it */
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->lock, flags);
                status = priv->line_status;
                spin_unlock_irqrestore(&priv->lock, flags);
index b57cf841c5b6aa2ab1c21e13c12e063d51a2a9e7..4b2a19757b4d531baa8dfb48c8009517d2d21cb5 100644 (file)
@@ -61,7 +61,6 @@ struct ssu100_port_private {
        spinlock_t status_lock;
        u8 shadowLSR;
        u8 shadowMSR;
-       wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
        struct async_icount icount;
 };
 
@@ -355,8 +354,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->status_lock, flags);
 
        while (1) {
-               wait_event_interruptible(priv->delta_msr_wait,
-                                        ((priv->icount.rng != prev.rng) ||
+               wait_event_interruptible(port->delta_msr_wait,
+                                        (port->serial->disconnected ||
+                                         (priv->icount.rng != prev.rng) ||
                                          (priv->icount.dsr != prev.dsr) ||
                                          (priv->icount.dcd != prev.dcd) ||
                                          (priv->icount.cts != prev.cts)));
@@ -364,6 +364,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
+               if (port->serial->disconnected)
+                       return -EIO;
+
                spin_lock_irqsave(&priv->status_lock, flags);
                cur = priv->icount;
                spin_unlock_irqrestore(&priv->status_lock, flags);
@@ -445,7 +448,6 @@ static int ssu100_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
 
        spin_lock_init(&priv->status_lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
 
        usb_set_serial_port_data(port, priv);
 
@@ -537,7 +539,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
                        priv->icount.dcd++;
                if (msr & UART_MSR_TERI)
                        priv->icount.rng++;
-               wake_up_interruptible(&priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
        }
 }
 
index 39cb9b807c3cf998842c39267e9d217b82460e59..73deb029fc05d3d9c9b728f1fae1616a8efee6e4 100644 (file)
@@ -74,7 +74,6 @@ struct ti_port {
        int                     tp_flags;
        int                     tp_closing_wait;/* in .01 secs */
        struct async_icount     tp_icount;
-       wait_queue_head_t       tp_msr_wait;    /* wait for msr change */
        wait_queue_head_t       tp_write_wait;
        struct ti_device        *tp_tdev;
        struct usb_serial_port  *tp_port;
@@ -432,7 +431,6 @@ static int ti_port_probe(struct usb_serial_port *port)
        else
                tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
        tport->tp_closing_wait = closing_wait;
-       init_waitqueue_head(&tport->tp_msr_wait);
        init_waitqueue_head(&tport->tp_write_wait);
        if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
                kfree(tport);
@@ -784,9 +782,13 @@ static int ti_ioctl(struct tty_struct *tty,
                dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
                cprev = tport->tp_icount;
                while (1) {
-                       interruptible_sleep_on(&tport->tp_msr_wait);
+                       interruptible_sleep_on(&port->delta_msr_wait);
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+
+                       if (port->serial->disconnected)
+                               return -EIO;
+
                        cnow = tport->tp_icount;
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -1392,7 +1394,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
                        icount->dcd++;
                if (msr & TI_MSR_DELTA_RI)
                        icount->rng++;
-               wake_up_interruptible(&tport->tp_msr_wait);
+               wake_up_interruptible(&tport->tp_port->delta_msr_wait);
                spin_unlock_irqrestore(&tport->tp_lock, flags);
        }
 
index a19ed74d770d73b016e69070cb27e282bbc21fad..2e70efa08b77121f5d248413a95b14ea79095dda 100644 (file)
@@ -151,6 +151,7 @@ static void destroy_serial(struct kref *kref)
                }
        }
 
+       usb_put_intf(serial->interface);
        usb_put_dev(serial->dev);
        kfree(serial);
 }
@@ -620,7 +621,7 @@ static struct usb_serial *create_serial(struct usb_device *dev,
        }
        serial->dev = usb_get_dev(dev);
        serial->type = driver;
-       serial->interface = interface;
+       serial->interface = usb_get_intf(interface);
        kref_init(&serial->kref);
        mutex_init(&serial->disc_mutex);
        serial->minor = SERIAL_TTY_NO_MINOR;
index 7ab9046ae0eca5fe64ea930206c18a7cdeda1420..105d900150c1a80155c2afcec6a61f4fb07fd0b4 100644 (file)
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
        return 0;
 }
 
-/* This places the HUAWEI usb dongles in multi-port mode */
-static int usb_stor_huawei_feature_init(struct us_data *us)
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us)
 {
        int result;
 
@@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us)
        US_DEBUGP("Huawei mode set result is %d\n", result);
        return 0;
 }
-
-/*
- * It will send a scsi switch command called rewind' to huawei dongle.
- * When the dongle receives this command at the first time,
- * it will reboot immediately. After rebooted, it will ignore this command.
- * So it is  unnecessary to read its response.
- */
-static int usb_stor_huawei_scsi_init(struct us_data *us)
-{
-       int result = 0;
-       int act_len = 0;
-       struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
-       char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
-                       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-       bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
-       bcbw->Tag = 0;
-       bcbw->DataTransferLength = 0;
-       bcbw->Flags = bcbw->Lun = 0;
-       bcbw->Length = sizeof(rewind_cmd);
-       memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
-       memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
-
-       result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
-                                       US_BULK_CB_WRAP_LEN, &act_len);
-       US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
-       return result;
-}
-
-/*
- * It tries to find the supported Huawei USB dongles.
- * In Huawei, they assign the following product IDs
- * for all of their mobile broadband dongles,
- * including the new dongles in the future.
- * So if the product ID is not included in this list,
- * it means it is not Huawei's mobile broadband dongles.
- */
-static int usb_stor_huawei_dongles_pid(struct us_data *us)
-{
-       struct usb_interface_descriptor *idesc;
-       int idProduct;
-
-       idesc = &us->pusb_intf->cur_altsetting->desc;
-       idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
-       /* The first port is CDROM,
-        * means the dongle in the single port mode,
-        * and a switch command is required to be sent. */
-       if (idesc && idesc->bInterfaceNumber == 0) {
-               if ((idProduct == 0x1001)
-                       || (idProduct == 0x1003)
-                       || (idProduct == 0x1004)
-                       || (idProduct >= 0x1401 && idProduct <= 0x1500)
-                       || (idProduct >= 0x1505 && idProduct <= 0x1600)
-                       || (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-int usb_stor_huawei_init(struct us_data *us)
-{
-       int result = 0;
-
-       if (usb_stor_huawei_dongles_pid(us)) {
-               if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446)
-                       result = usb_stor_huawei_scsi_init(us);
-               else
-                       result = usb_stor_huawei_feature_init(us);
-       }
-       return result;
-}
index 5376d4fc76f04c25092244765237f94f44456ba1..529327fbb06be1b6876e8802b84bd281287291c3 100644 (file)
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
 
-/* This places the HUAWEI usb dongles in multi-port mode */
-int usb_stor_huawei_init(struct us_data *us);
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us);
index 92f35abee92d281990e17ccdb4f388d33ed67f0e..615c66eaedebb7f05e25f50a6c0f9c88f96a2de3 100644 (file)
@@ -438,22 +438,21 @@ void usb_stor_report_bus_reset(struct us_data *us)
  * /proc/scsi/ functions
  ***********************************************************************/
 
+static int write_info(struct Scsi_Host *host, char *buffer, int length)
+{
+       /* if someone is sending us data, just throw it away */
+       return length;
+}
+
 /* we use this macro to help us write into the buffer */
 #undef SPRINTF
-#define SPRINTF(args...) \
-       do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
+#define SPRINTF(args...) seq_printf(m, ## args)
 
-static int proc_info (struct Scsi_Host *host, char *buffer,
-               char **start, off_t offset, int length, int inout)
+static int show_info (struct seq_file *m, struct Scsi_Host *host)
 {
        struct us_data *us = host_to_us(host);
-       char *pos = buffer;
        const char *string;
 
-       /* if someone is sending us data, just throw it away */
-       if (inout)
-               return length;
-
        /* print the controller name */
        SPRINTF("   Host scsi%d: usb-storage\n", host->host_no);
 
@@ -483,28 +482,14 @@ static int proc_info (struct Scsi_Host *host, char *buffer,
        SPRINTF("    Transport: %s\n", us->transport_name);
 
        /* show the device flags */
-       if (pos < buffer + length) {
-               pos += sprintf(pos, "       Quirks:");
+       SPRINTF("       Quirks:");
 
 #define US_FLAG(name, value) \
-       if (us->fflags & value) pos += sprintf(pos, " " #name);
+       if (us->fflags & value) seq_printf(m, " " #name);
 US_DO_ALL_FLAGS
 #undef US_FLAG
-
-               *(pos++) = '\n';
-       }
-
-       /*
-        * Calculate start of next buffer, and return value.
-        */
-       *start = buffer + offset;
-
-       if ((pos - buffer) < offset)
-               return (0);
-       else if ((pos - buffer - offset) < length)
-               return (pos - buffer - offset);
-       else
-               return (length);
+       seq_putc(m, '\n');
+       return 0;
 }
 
 /***********************************************************************
@@ -549,7 +534,8 @@ struct scsi_host_template usb_stor_host_template = {
        /* basic userland interface stuff */
        .name =                         "usb-storage",
        .proc_name =                    "usb-storage",
-       .proc_info =                    proc_info,
+       .show_info =                    show_info,
+       .write_info =                   write_info,
        .info =                         host_info,
 
        /* command interface -- queued only */
index 72923b56bbf6b871a6da926168d43cf8db3e6383..1799335288bd5e60522a60def1c311f07df62286 100644 (file)
  * as opposed to devices that do something strangely or wrongly.
  */
 
+/* In-kernel mode switching is deprecated.  Do not add new devices to
+ * this list for the sole purpose of switching them to a different
+ * mode.  Existing userspace solutions are superior.
+ *
+ * New mode switching devices should instead be added to the database
+ * maintained at http://www.draisberghof.de/usb_modeswitch/
+ */
+
 #if !defined(CONFIG_USB_STORAGE_SDDR09) && \
                !defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
 #define NO_SDDR09
@@ -488,6 +496,13 @@ UNUSUAL_DEV(  0x04e8, 0x5122, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG),
 
+/* Added by Dmitry Artamonow <mad_soft@inbox.ru> */
+UNUSUAL_DEV(  0x04e8, 0x5136, 0x0000, 0x9999,
+               "Samsung",
+               "YP-Z3",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64),
+
 /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
  * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
  * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
@@ -1527,10 +1542,335 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,
 /* Reported by fangxiaozhi <huananhu@huawei.com>
  * This brings the HUAWEI data card devices into multi-port mode
  */
-UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
+UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1003, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1004, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1401, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1402, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1403, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1404, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1405, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1406, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1407, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1408, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1409, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1410, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1411, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1412, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1413, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1414, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1415, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1416, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1417, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1418, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1419, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1420, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1421, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1422, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1423, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1424, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1425, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1426, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1427, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1428, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1429, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1430, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1431, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1432, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1433, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1434, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1435, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1436, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1437, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1438, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1439, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143F, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
 
 /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
index 964ff22bf2819e5de87786e517fefe2bc50956af..aeb00fc2d3bea2caf19a650d30e4517caf89a76d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/uaccess.h>
 #include <linux/vfio.h>
+#include <linux/slab.h>
 
 #include "vfio_pci_private.h"
 
index 3639371fa697e63e9bf6d3e5ccc49453e5ecff76..a96509187deb677a03e0a7e4902d76fe1f3c81a5 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/vfio.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #include "vfio_pci_private.h"
 
index 959b1cd89e6a5be5a402a79089077609f8e30716..ec6fb3fa59bb5962281bb6277220941b91df053c 100644 (file)
@@ -339,7 +339,8 @@ static void handle_tx(struct vhost_net *net)
                                msg.msg_controllen = 0;
                                ubufs = NULL;
                        } else {
-                               struct ubuf_info *ubuf = &vq->ubuf_info[head];
+                               struct ubuf_info *ubuf;
+                               ubuf = vq->ubuf_info + vq->upend_idx;
 
                                vq->heads[vq->upend_idx].len =
                                        VHOST_DMA_IN_PROGRESS;
index 9951297b24279105aa118c1e9bba1c0320972a15..43fb11ee2e8ded2cc2c70b954e3b68bdc06e1760 100644 (file)
@@ -850,7 +850,7 @@ static int vhost_scsi_clear_endpoint(
        for (index = 0; index < vs->dev.nvqs; ++index) {
                if (!vhost_vq_access_ok(&vs->vqs[index])) {
                        ret = -EFAULT;
-                       goto err;
+                       goto err_dev;
                }
        }
        for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) {
@@ -860,10 +860,11 @@ static int vhost_scsi_clear_endpoint(
                if (!tv_tpg)
                        continue;
 
+               mutex_lock(&tv_tpg->tv_tpg_mutex);
                tv_tport = tv_tpg->tport;
                if (!tv_tport) {
                        ret = -ENODEV;
-                       goto err;
+                       goto err_tpg;
                }
 
                if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
@@ -872,16 +873,19 @@ static int vhost_scsi_clear_endpoint(
                                tv_tport->tport_name, tv_tpg->tport_tpgt,
                                t->vhost_wwpn, t->vhost_tpgt);
                        ret = -EINVAL;
-                       goto err;
+                       goto err_tpg;
                }
                tv_tpg->tv_tpg_vhost_count--;
                vs->vs_tpg[target] = NULL;
                vs->vs_endpoint = false;
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
        }
        mutex_unlock(&vs->dev.mutex);
        return 0;
 
-err:
+err_tpg:
+       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+err_dev:
        mutex_unlock(&vs->dev.mutex);
        return ret;
 }
@@ -937,6 +941,7 @@ static void vhost_scsi_flush(struct vhost_scsi *vs)
 
        for (i = 0; i < VHOST_SCSI_MAX_VQ; i++)
                vhost_scsi_flush_vq(vs, i);
+       vhost_work_flush(&vs->dev, &vs->vs_completion_work);
 }
 
 static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
index 12cf5f31ee8f008158dfbee172b077185f3ef241..025428e04c33c7bb99a80f2310b5dfdf8c936c2b 100644 (file)
@@ -422,17 +422,22 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
                        = var->bits_per_pixel;
                break;
        case 16:
+               /* Older SOCs use IBGR:555 rather than BGR:565. */
+               if (sinfo->have_intensity_bit)
+                       var->green.length = 5;
+               else
+                       var->green.length = 6;
+
                if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
-                       /* RGB:565 mode */
-                       var->red.offset = 11;
+                       /* RGB:5X5 mode */
+                       var->red.offset = var->green.length + 5;
                        var->blue.offset = 0;
                } else {
-                       /* BGR:565 mode */
+                       /* BGR:5X5 mode */
                        var->red.offset = 0;
-                       var->blue.offset = 11;
+                       var->blue.offset = var->green.length + 5;
                }
                var->green.offset = 5;
-               var->green.length = 6;
                var->red.length = var->blue.length = 5;
                break;
        case 32:
@@ -679,8 +684,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
 
        case FB_VISUAL_PSEUDOCOLOR:
                if (regno < 256) {
-                       if (cpu_is_at91sam9261() || cpu_is_at91sam9263()
-                           || cpu_is_at91sam9rl()) {
+                       if (sinfo->have_intensity_bit) {
                                /* old style I+BGR:555 */
                                val  = ((red   >> 11) & 0x001f);
                                val |= ((green >>  6) & 0x03e0);
@@ -870,6 +874,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
        }
        sinfo->info = info;
        sinfo->pdev = pdev;
+       if (cpu_is_at91sam9261() || cpu_is_at91sam9263() ||
+                                                       cpu_is_at91sam9rl()) {
+               sinfo->have_intensity_bit = true;
+       }
 
        strcpy(info->fix.id, sinfo->pdev->name);
        info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
index 8d411a3c9966763a84ad4d1f4025b94593481f70..a54f7f7d763b0ae52f21530ce50ee829bd9fc2cb 100644 (file)
@@ -333,29 +333,23 @@ static int proc_output(char *buf)
        return p - buf;
 }
 
-static int
-adv7393_read_proc(char *page, char **start, off_t off,
-                 int count, int *eof, void *data)
+static ssize_t
+adv7393_read_proc(struct file *file, char __user *buf,
+                 size_t size, loff_t *ppos)
 {
-       int len;
-
-       len = proc_output(page);
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
-       return len;
+       static const char message[] = "Usage:\n"
+               "echo 0x[REG][Value] > adv7393\n"
+               "example: echo 0x1234 >adv7393\n"
+               "writes 0x34 into Register 0x12\n";
+       return simple_read_from_buffer(buf, size, ppos, message,
+                                       sizeof(message));
 }
 
-static int
+static ssize_t
 adv7393_write_proc(struct file *file, const char __user * buffer,
-                  size_t count, void *data)
+                  size_t count, loff_t *ppos)
 {
-       struct adv7393fb_device *fbdev = data;
+       struct adv7393fb_device *fbdev = PDE_DATA(file_inode(file));
        unsigned int val;
        int ret;
 
@@ -368,6 +362,12 @@ adv7393_write_proc(struct file *file, const char __user * buffer,
        return count;
 }
 
+static const struct file_operations fops = {
+       .read = adv7393_read_proc,
+       .write = adv7393_write_proc,
+       .llseek = default_llseek,
+};
+
 static int bfin_adv7393_fb_probe(struct i2c_client *client,
                                 const struct i2c_device_id *id)
 {
@@ -506,17 +506,12 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client,
               fbdev->info.node, fbdev->info.fix.id);
        dev_info(&client->dev, "fb memory address : 0x%p\n", fbdev->fb_mem);
 
-       entry = create_proc_entry("driver/adv7393", 0, NULL);
+       entry = proc_create_data("driver/adv7393", 0, NULL, &fops, fbdev);
        if (!entry) {
                dev_err(&client->dev, "unable to create /proc entry\n");
                ret = -EFAULT;
                goto free_fb;
        }
-
-       entry->read_proc = adv7393_read_proc;
-       entry->write_proc = adv7393_write_proc;
-       entry->data = fbdev;
-
        return 0;
 
 free_fb:
index 3f2519d3071574bd42dbe646afbf24dd1ba3d034..e06cd5d90c97806cb38c76f458c004a20b4acca0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/fb.h>
+#include <linux/io.h>
 
 #include <linux/platform_data/video-ep93xx.h>
 
index 755556ca5b2d988ec68b8cc3c1f9bbe7aadf6a34..45169cbaba6e288e714e2ce414dff1061a4569af 100644 (file)
@@ -169,6 +169,7 @@ struct mxsfb_info {
        unsigned dotclk_delay;
        const struct mxsfb_devdata *devdata;
        int mapped;
+       u32 sync;
 };
 
 #define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
@@ -456,9 +457,9 @@ static int mxsfb_set_par(struct fb_info *fb_info)
                vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
        if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
                vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
-       if (fb_info->var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT)
+       if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
                vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
-       if (fb_info->var.sync & FB_SYNC_DOTCLK_FAILING_ACT)
+       if (host->sync & MXSFB_SYNC_DOTCLK_FAILING_ACT)
                vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING;
 
        writel(vdctrl0, host->base + LCDC_VDCTRL0);
@@ -861,6 +862,8 @@ static int mxsfb_probe(struct platform_device *pdev)
 
        INIT_LIST_HEAD(&fb_info->modelist);
 
+       host->sync = pdata->sync;
+
        ret = mxsfb_init_fbinfo(host);
        if (ret != 0)
                goto error_init_fb;
index ed4cad87fbcdb39717e283ed8b764312b745fff3..4a5f2cd3d3bf01a5776df21c137ce11586109689 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/lcd.h>
 #include <linux/gpio.h>
 
+#include <mach/hardware.h>
 #include <mach/board-ams-delta.h>
 
 #include "omapfb.h"
index 3aa62da89195949d89e7dd3bb4d44cc60342c7d4..7fbe04bce0ed6402371edf515641175c4d8320bf 100644 (file)
 #include <linux/platform_device.h>
 
 #include <asm/gpio.h>
+
+#include <mach/hardware.h>
 #include <mach/mux.h>
+
 #include "omapfb.h"
 
 static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
index 6c984eacc7e350bf87a8a6078cb7f4fadc845d8c..97563c55af63e46d8a6a00cf6f036b3df6e8e203 100644 (file)
@@ -101,7 +101,6 @@ struct pxa3xx_gcu_priv {
        dma_addr_t                shared_phys;
        struct resource          *resource_mem;
        struct miscdevice         misc_dev;
-       struct file_operations    misc_fops;
        wait_queue_head_t         wait_idle;
        wait_queue_head_t         wait_free;
        spinlock_t                spinlock;
@@ -369,15 +368,20 @@ pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)
 
 /* Misc device layer */
 
+static inline struct pxa3xx_gcu_priv *file_dev(struct file *file)
+{
+       struct miscdevice *dev = file->private_data;
+       return container_of(dev, struct pxa3xx_gcu_priv, misc_dev);
+}
+
 static ssize_t
-pxa3xx_gcu_misc_write(struct file *filp, const char *buff,
+pxa3xx_gcu_misc_write(struct file *file, const char *buff,
                      size_t count, loff_t *offp)
 {
        int ret;
        unsigned long flags;
        struct pxa3xx_gcu_batch *buffer;
-       struct pxa3xx_gcu_priv *priv =
-               container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
+       struct pxa3xx_gcu_priv *priv = file_dev(file);
 
        int words = count / 4;
 
@@ -450,11 +454,10 @@ pxa3xx_gcu_misc_write(struct file *filp, const char *buff,
 
 
 static long
-pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        unsigned long flags;
-       struct pxa3xx_gcu_priv *priv =
-               container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
+       struct pxa3xx_gcu_priv *priv = file_dev(file);
 
        switch (cmd) {
        case PXA3XX_GCU_IOCTL_RESET:
@@ -471,11 +474,10 @@ pxa3xx_gcu_misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 }
 
 static int
-pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma)
+pxa3xx_gcu_misc_mmap(struct file *file, struct vm_area_struct *vma)
 {
        unsigned int size = vma->vm_end - vma->vm_start;
-       struct pxa3xx_gcu_priv *priv =
-               container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
+       struct pxa3xx_gcu_priv *priv = file_dev(file);
 
        switch (vma->vm_pgoff) {
        case 0:
@@ -574,6 +576,13 @@ free_buffers(struct platform_device *dev,
        priv->free = NULL;
 }
 
+static const struct file_operations misc_fops = {
+       .owner  = THIS_MODULE,
+       .write  = pxa3xx_gcu_misc_write,
+       .unlocked_ioctl = pxa3xx_gcu_misc_ioctl,
+       .mmap   = pxa3xx_gcu_misc_mmap
+};
+
 static int pxa3xx_gcu_probe(struct platform_device *dev)
 {
        int i, ret, irq;
@@ -601,14 +610,9 @@ static int pxa3xx_gcu_probe(struct platform_device *dev)
         * container_of(). This isn't really necessary as we have a fixed minor
         * number anyway, but this is to avoid statics. */
 
-       priv->misc_fops.owner   = THIS_MODULE;
-       priv->misc_fops.write   = pxa3xx_gcu_misc_write;
-       priv->misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl;
-       priv->misc_fops.mmap    = pxa3xx_gcu_misc_mmap;
-
        priv->misc_dev.minor    = MISCDEV_MINOR,
        priv->misc_dev.name     = DRV_NAME,
-       priv->misc_dev.fops     = &priv->misc_fops,
+       priv->misc_dev.fops     = &misc_fops,
 
        /* register misc device */
        ret = misc_register(&priv->misc_dev);
index d39dfa4cc23570b9c6cc8e57e7aa3a8d759a007b..46d97014342ef1f27f37046332e35d6e40a5b108 100644 (file)
@@ -47,11 +47,13 @@ static u8 w1_gpio_read_bit(void *data)
        return gpio_get_value(pdata->pin) ? 1 : 0;
 }
 
+#if defined(CONFIG_OF)
 static struct of_device_id w1_gpio_dt_ids[] = {
        { .compatible = "w1-gpio" },
        {}
 };
 MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
+#endif
 
 static int w1_gpio_probe_dt(struct platform_device *pdev)
 {
@@ -158,7 +160,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
        return err;
 }
 
-static int __exit w1_gpio_remove(struct platform_device *pdev)
+static int w1_gpio_remove(struct platform_device *pdev)
 {
        struct w1_bus_master *master = platform_get_drvdata(pdev);
        struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
@@ -210,7 +212,7 @@ static struct platform_driver w1_gpio_driver = {
                .of_match_table = of_match_ptr(w1_gpio_dt_ids),
        },
        .probe = w1_gpio_probe,
-       .remove = __exit_p(w1_gpio_remove),
+       .remove = w1_gpio_remove,
        .suspend = w1_gpio_suspend,
        .resume = w1_gpio_resume,
 };
index 7994d933f040bd85ef9f26dfee1587c38e37cba5..7ce277d2bb676182dcbcddae1f500a77ae038842 100644 (file)
@@ -924,7 +924,8 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
                        tmp64 = (triplet_ret >> 2);
                        rn |= (tmp64 << i);
 
-                       if (kthread_should_stop()) {
+                       /* ensure we're called from kthread and not by netlink callback */
+                       if (!dev->priv && kthread_should_stop()) {
                                mutex_unlock(&dev->bus_mutex);
                                dev_dbg(&dev->dev, "Abort w1_search\n");
                                return;
index e3b8f757d2d3f641810cece7a0423fa268cf2b88..0e9d8c479c3551e2bb5a51cb9bfcd055f2bcb3e7 100644 (file)
 #include "sp5100_tco.h"
 
 /* Module and version information */
-#define TCO_VERSION "0.03"
+#define TCO_VERSION "0.05"
 #define TCO_MODULE_NAME "SP5100 TCO timer"
 #define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
 
 /* internal variables */
 static u32 tcobase_phys;
-static u32 resbase_phys;
 static u32 tco_wdt_fired;
 static void __iomem *tcobase;
 static unsigned int pm_iobase;
@@ -54,10 +53,6 @@ static DEFINE_SPINLOCK(tco_lock);    /* Guards the hardware */
 static unsigned long timer_alive;
 static char tco_expect_close;
 static struct pci_dev *sp5100_tco_pci;
-static struct resource wdt_res = {
-       .name = "Watchdog Timer",
-       .flags = IORESOURCE_MEM,
-};
 
 /* the watchdog platform device */
 static struct platform_device *sp5100_tco_platform_device;
@@ -75,12 +70,6 @@ module_param(nowayout, bool, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
                " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
-static unsigned int force_addr;
-module_param(force_addr, uint, 0);
-MODULE_PARM_DESC(force_addr, "Force the use of specified MMIO address."
-               " ONLY USE THIS PARAMETER IF YOU REALLY KNOW"
-               " WHAT YOU ARE DOING (default=none)");
-
 /*
  * Some TCO specific functions
  */
@@ -176,39 +165,6 @@ static void tco_timer_enable(void)
        }
 }
 
-static void tco_timer_disable(void)
-{
-       int val;
-
-       if (sp5100_tco_pci->revision >= 0x40) {
-               /* For SB800 or later */
-               /* Enable watchdog decode bit and Disable watchdog timer */
-               outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG);
-               val = inb(SB800_IO_PM_DATA_REG);
-               val |= SB800_PCI_WATCHDOG_DECODE_EN;
-               val |= SB800_PM_WATCHDOG_DISABLE;
-               outb(val, SB800_IO_PM_DATA_REG);
-       } else {
-               /* For SP5100 or SB7x0 */
-               /* Enable watchdog decode bit */
-               pci_read_config_dword(sp5100_tco_pci,
-                                     SP5100_PCI_WATCHDOG_MISC_REG,
-                                     &val);
-
-               val |= SP5100_PCI_WATCHDOG_DECODE_EN;
-
-               pci_write_config_dword(sp5100_tco_pci,
-                                      SP5100_PCI_WATCHDOG_MISC_REG,
-                                      val);
-
-               /* Disable Watchdog timer */
-               outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
-               val = inb(SP5100_IO_PM_DATA_REG);
-               val |= SP5100_PM_WATCHDOG_DISABLE;
-               outb(val, SP5100_IO_PM_DATA_REG);
-       }
-}
-
 /*
  *     /dev/watchdog handling
  */
@@ -361,7 +317,7 @@ static unsigned char sp5100_tco_setupdevice(void)
 {
        struct pci_dev *dev = NULL;
        const char *dev_name = NULL;
-       u32 val, tmp_val;
+       u32 val;
        u32 index_reg, data_reg, base_addr;
 
        /* Match the PCI device */
@@ -459,63 +415,8 @@ static unsigned char sp5100_tco_setupdevice(void)
        } else
                pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val);
 
-       /*
-        * Lastly re-programming the watchdog timer MMIO address,
-        * This method is a last resort...
-        *
-        * Before re-programming, to ensure that the watchdog timer
-        * is disabled, disable the watchdog timer.
-        */
-       tco_timer_disable();
-
-       if (force_addr) {
-               /*
-                * Force the use of watchdog timer MMIO address, and aligned to
-                * 8byte boundary.
-                */
-               force_addr &= ~0x7;
-               val = force_addr;
-
-               pr_info("Force the use of 0x%04x as MMIO address\n", val);
-       } else {
-               /*
-                * Get empty slot into the resource tree for watchdog timer.
-                */
-               if (allocate_resource(&iomem_resource,
-                                     &wdt_res,
-                                     SP5100_WDT_MEM_MAP_SIZE,
-                                     0xf0000000,
-                                     0xfffffff8,
-                                     0x8,
-                                     NULL,
-                                     NULL)) {
-                       pr_err("MMIO allocation failed\n");
-                       goto unreg_region;
-               }
-
-               val = resbase_phys = wdt_res.start;
-               pr_debug("Got 0x%04x from resource tree\n", val);
-       }
-
-       /* Restore to the low three bits */
-       outb(base_addr+0, index_reg);
-       tmp_val = val | (inb(data_reg) & 0x7);
-
-       /* Re-programming the watchdog timer base address */
-       outb(base_addr+0, index_reg);
-       outb((tmp_val >>  0) & 0xff, data_reg);
-       outb(base_addr+1, index_reg);
-       outb((tmp_val >>  8) & 0xff, data_reg);
-       outb(base_addr+2, index_reg);
-       outb((tmp_val >> 16) & 0xff, data_reg);
-       outb(base_addr+3, index_reg);
-       outb((tmp_val >> 24) & 0xff, data_reg);
-
-       if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
-                                                                  dev_name)) {
-               pr_err("MMIO address 0x%04x already in use\n", val);
-               goto unreg_resource;
-       }
+       pr_notice("failed to find MMIO address, giving up.\n");
+       goto  unreg_region;
 
 setup_wdt:
        tcobase_phys = val;
@@ -555,9 +456,6 @@ setup_wdt:
 
 unreg_mem_region:
        release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-unreg_resource:
-       if (resbase_phys)
-               release_resource(&wdt_res);
 unreg_region:
        release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
 exit:
@@ -567,7 +465,6 @@ exit:
 static int sp5100_tco_init(struct platform_device *dev)
 {
        int ret;
-       char addr_str[16];
 
        /*
         * Check whether or not the hardware watchdog is there. If found, then
@@ -599,23 +496,14 @@ static int sp5100_tco_init(struct platform_device *dev)
        clear_bit(0, &timer_alive);
 
        /* Show module parameters */
-       if (force_addr == tcobase_phys)
-               /* The force_addr is vaild */
-               sprintf(addr_str, "0x%04x", force_addr);
-       else
-               strcpy(addr_str, "none");
-
-       pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, "
-               "force_addr=%s)\n",
-               tcobase, heartbeat, nowayout, addr_str);
+       pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
+               tcobase, heartbeat, nowayout);
 
        return 0;
 
 exit:
        iounmap(tcobase);
        release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-       if (resbase_phys)
-               release_resource(&wdt_res);
        release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
        return ret;
 }
@@ -630,8 +518,6 @@ static void sp5100_tco_cleanup(void)
        misc_deregister(&sp5100_tco_miscdev);
        iounmap(tcobase);
        release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-       if (resbase_phys)
-               release_resource(&wdt_res);
        release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
 }
 
index 71594a0c14b735f56decde5e1ac5e01543fbda6c..2b28c00da0df00d2f99a8c5283b2d2b7c84a9ffa 100644 (file)
@@ -57,7 +57,7 @@
 #define SB800_PM_WATCHDOG_DISABLE      (1 << 2)
 #define SB800_PM_WATCHDOG_SECOND_RES   (3 << 0)
 #define SB800_ACPI_MMIO_DECODE_EN      (1 << 0)
-#define SB800_ACPI_MMIO_SEL            (1 << 2)
+#define SB800_ACPI_MMIO_SEL            (1 << 1)
 
 
 #define SB800_PM_WDT_MMIO_OFFSET       0xB00
index 316df65163cfa5d6485a256edf2cdab24e8805d6..f3278a6603ca3b0913280f4bfa5c7e07c0eff47a 100644 (file)
@@ -500,16 +500,16 @@ static int __init xen_acpi_processor_init(void)
        (void)acpi_processor_preregister_performance(acpi_perf_data);
 
        for_each_possible_cpu(i) {
+               struct acpi_processor *pr;
                struct acpi_processor_performance *perf;
 
+               pr = per_cpu(processors, i);
                perf = per_cpu_ptr(acpi_perf_data, i);
-               rc = acpi_processor_register_performance(perf, i);
+               pr->performance = perf;
+               rc = acpi_processor_get_performance_info(pr);
                if (rc)
                        goto err_out;
        }
-       rc = acpi_processor_notify_smm(THIS_MODULE);
-       if (rc)
-               goto err_unregister;
 
        for_each_possible_cpu(i) {
                struct acpi_processor *_pr;
index 37c1f825f513764c998e808acf482d9d20cda7e0..b98cf0c35725a1714afbc498ee1ab49864eb1ff3 100644 (file)
@@ -113,7 +113,8 @@ void xen_pcibk_reset_device(struct pci_dev *dev)
                if (dev->msi_enabled)
                        pci_disable_msi(dev);
 #endif
-               pci_disable_device(dev);
+               if (pci_is_enabled(dev))
+                       pci_disable_device(dev);
 
                pci_write_config_word(dev, PCI_COMMAND, 0);
 
index d85e411cbf8924ceaf8e3947ab961e1c5ea68744..bbef194c5b0183181f74405103ebeb782935c33f 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_drivers.h>
 #include <xen/acpi.h>
 
 #ifdef CONFIG_ACPI
index ec0abb6df3c303fa7ace7b0e8b6e018f39ce8fb7..71679875f056ccaf92eafba1b0a194cd7f177429 100644 (file)
@@ -75,6 +75,7 @@ static struct file_system_type xenfs_type = {
        .mount =        xenfs_mount,
        .kill_sb =      kill_litter_super,
 };
+MODULE_ALIAS_FS("xenfs");
 
 static int __init xenfs_init(void)
 {
index 73b33837e12c43d717153d985f1310e9b248dc84..1c15ee7456b6cdce859189daaafd9dd7177f831e 100644 (file)
@@ -47,9 +47,7 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
 static ssize_t
 proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
-       struct inode *ino = file_inode(file);
-       struct proc_dir_entry *dp = PDE(ino);
-       struct zorro_dev *z = dp->data;
+       struct zorro_dev *z = PDE_DATA(file_inode(file));
        struct ConfigDev cd;
        loff_t pos = *ppos;
 
@@ -141,7 +139,7 @@ static int __init zorro_proc_attach_device(unsigned int slot)
                                 &zorro_autocon[slot]);
        if (!entry)
                return -ENOMEM;
-       entry->size = sizeof(struct zorro_dev);
+       proc_set_size(entry, sizeof(struct zorro_dev));
        return 0;
 }
 
index cbb09ce9730ac0494dc43fbef5d7d6f2ddd05b0b..5d8ee1319b5c1878c5b82f82bb150dfece7b2cf8 100644 (file)
@@ -82,7 +82,7 @@ fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
 fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
                                         qlogic/12160.bin
 fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin
-fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw
+fw-shipped-$(CONFIG_INFINIBAND_QIB) += intel/sd7220.fw
 fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp
 fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
                                     ess/maestro3_assp_minisrc.fw
index 91dad63e5a2db0cddc1bb9c43ad0bca0694ec9c9..2756dcd5de6e0ed0306e148682bc51d4749e121a 100644 (file)
@@ -365,3 +365,4 @@ struct file_system_type v9fs_fs_type = {
        .owner = THIS_MODULE,
        .fs_flags = FS_RENAME_DOES_D_MOVE,
 };
+MODULE_ALIAS_FS("9p");
index 9d53192236fc5ca2ffd6507ebd7d17e4109e582d..b691a965dc1a6c6dc3bc1860697ed24805b4335f 100644 (file)
@@ -7,7 +7,7 @@
 
 obj-y :=       open.o read_write.o file_table.o super.o \
                char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
-               ioctl.o readdir.o select.o fifo.o dcache.o inode.o \
+               ioctl.o readdir.o select.o dcache.o inode.o \
                attr.o bad_inode.o file.o filesystems.o namespace.o \
                seq_file.o xattr.o libfs.o fs-writeback.o \
                pnode.o drop_caches.o splice.o sync.o utimes.o \
index d5712293579376a89a99befc8eb59e5ecded02bb..0ff4bae2c2a2c2372a75bc5486a4920672aef0bf 100644 (file)
@@ -524,6 +524,7 @@ static struct file_system_type adfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("adfs");
 
 static int __init init_adfs_fs(void)
 {
index b84dc7352502df2976438435b2523f98d5d55966..45161a832bbc9e4aa2d7f6b72a950273e0af7062 100644 (file)
@@ -622,6 +622,7 @@ static struct file_system_type affs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("affs");
 
 static int __init init_affs_fs(void)
 {
index 096b23f821a1081a2370df2de59276c9d08b807f..526e4bbbde59e4936f91367101adac8c7373053e 100644 (file)
@@ -190,7 +190,7 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file)
                return ret;
 
        m = file->private_data;
-       m->private = PDE(inode)->data;
+       m->private = PDE_DATA(inode);
 
        return 0;
 }
@@ -448,7 +448,7 @@ static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file)
        struct seq_file *m;
        int ret;
 
-       cell = PDE(inode)->data;
+       cell = PDE_DATA(inode);
        if (!cell)
                return -ENOENT;
 
@@ -554,7 +554,7 @@ static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file)
        struct seq_file *m;
        int ret;
 
-       cell = PDE(inode)->data;
+       cell = PDE_DATA(inode);
        if (!cell)
                return -ENOENT;
 
@@ -659,7 +659,7 @@ static int afs_proc_cell_servers_open(struct inode *inode, struct file *file)
        struct seq_file *m;
        int ret;
 
-       cell = PDE(inode)->data;
+       cell = PDE_DATA(inode);
        if (!cell)
                return -ENOENT;
 
index 7c31ec39957587a59062b3f81dd338aa57e575aa..c4861557e38573796dd20237ff90938ee5f1429e 100644 (file)
@@ -45,6 +45,7 @@ struct file_system_type afs_fs_type = {
        .kill_sb        = afs_kill_super,
        .fs_flags       = 0,
 };
+MODULE_ALIAS_FS("afs");
 
 static const struct super_operations afs_super_ops = {
        .statfs         = afs_statfs,
index 3f941f2a305949f31ba9dce2a4e87f6849e8ab71..4ec28f13a92eac078bda9e468954bf1f87d75b2d 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1324,6 +1324,8 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb)
        if (iocb->ki_pos < 0)
                return -EINVAL;
 
+       if (opcode == IOCB_CMD_PWRITEV)
+               file_start_write(file);
        do {
                ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg],
                            iocb->ki_nr_segs - iocb->ki_cur_seg,
@@ -1336,6 +1338,8 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb)
        } while (ret > 0 && iocb->ki_left > 0 &&
                 (opcode == IOCB_CMD_PWRITEV ||
                  (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))));
+       if (opcode == IOCB_CMD_PWRITEV)
+               file_end_write(file);
 
        /* This means we must have transferred all that we could */
        /* No need to retry anymore */
index cddc74b9cdb2d03f6e2203666c86118ef60596c6..b3db517e89ec12b771a77f46deb2572782b83e09 100644 (file)
@@ -26,6 +26,7 @@ static struct file_system_type autofs_fs_type = {
        .mount          = autofs_mount,
        .kill_sb        = autofs4_kill_sb,
 };
+MODULE_ALIAS_FS("autofs");
 
 static int __init init_autofs4_fs(void)
 {
index c8f4e25eb9e2f6e2818b17de47adb4a61e82eeca..8615ee89ab55d8c6d96a26556327b31c3967c0b6 100644 (file)
@@ -951,6 +951,7 @@ static struct file_system_type befs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,      
 };
+MODULE_ALIAS_FS("befs");
 
 static int __init
 init_befs_fs(void)
index 737aaa3f709062a9d8aec826c26e956b18eb2bcf..5e376bb934196d2b8a0e104473c637439e5e2244 100644 (file)
@@ -473,6 +473,7 @@ static struct file_system_type bfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("bfs");
 
 static int __init init_bfs_fs(void)
 {
index bbc8f8827eac6acef8254ace738230ae07043038..b23253df87568b783fcbea09110fb138ee57fa8f 100644 (file)
@@ -287,15 +287,12 @@ static int load_aout_binary(struct linux_binprm * bprm)
                        return error;
                }
 
-               error = bprm->file->f_op->read(bprm->file,
-                         (char __user *)text_addr,
-                         ex.a_text+ex.a_data, &pos);
+               error = read_code(bprm->file, text_addr, pos,
+                                 ex.a_text+ex.a_data);
                if ((signed long)error < 0) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
-                        
-               flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
        } else {
                if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
                    (N_MAGIC(ex) != NMAGIC) && printk_ratelimit())
@@ -311,14 +308,9 @@ static int load_aout_binary(struct linux_binprm * bprm)
                }
 
                if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
-                       loff_t pos = fd_offset;
                        vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
-                       bprm->file->f_op->read(bprm->file,
-                                       (char __user *)N_TXTADDR(ex),
-                                       ex.a_text+ex.a_data, &pos);
-                       flush_icache_range((unsigned long) N_TXTADDR(ex),
-                                          (unsigned long) N_TXTADDR(ex) +
-                                          ex.a_text+ex.a_data);
+                       read_code(bprm->file, N_TXTADDR(ex), fd_offset,
+                                 ex.a_text + ex.a_data);
                        goto beyond_if;
                }
 
@@ -397,8 +389,6 @@ static int load_aout_library(struct file *file)
        start_addr =  ex.a_entry & 0xfffff000;
 
        if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
-               loff_t pos = N_TXTOFF(ex);
-
                if (printk_ratelimit())
                {
                        printk(KERN_WARNING 
@@ -407,11 +397,8 @@ static int load_aout_library(struct file *file)
                }
                vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
                
-               file->f_op->read(file, (char __user *)start_addr,
-                       ex.a_text + ex.a_data, &pos);
-               flush_icache_range((unsigned long) start_addr,
-                                  (unsigned long) start_addr + ex.a_text + ex.a_data);
-
+               read_code(file, start_addr, N_TXTOFF(ex),
+                         ex.a_text + ex.a_data);
                retval = 0;
                goto out;
        }
index 9c13e023e2b72368004bad13033a7709ee5c62a6..2711d990163241a973e2443d7c9e0a9be0cd94ae 100644 (file)
@@ -926,7 +926,6 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
        struct elf32_fdpic_loadseg *seg;
        struct elf32_phdr *phdr;
        unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0, mflags;
-       loff_t fpos;
        int loop, ret;
 
        load_addr = params->load_addr;
@@ -964,14 +963,12 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
                if (params->phdrs[loop].p_type != PT_LOAD)
                        continue;
 
-               fpos = phdr->p_offset;
-
                seg->addr = maddr + (phdr->p_vaddr - base);
                seg->p_vaddr = phdr->p_vaddr;
                seg->p_memsz = phdr->p_memsz;
 
-               ret = file->f_op->read(file, (void *) seg->addr,
-                                      phdr->p_filesz, &fpos);
+               ret = read_code(file, seg->addr, phdr->p_offset,
+                                      phdr->p_filesz);
                if (ret < 0)
                        return ret;
 
index 2036d21baaefc60f0a028792323b1cec52784245..d50bbe59da1e339cc325846c6daed9669c0d6c04 100644 (file)
@@ -207,11 +207,12 @@ static int decompress_exec(
 
        /* Read in first chunk of data and parse gzip header. */
        fpos = offset;
-       ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
+       ret = kernel_read(bprm->file, offset, buf, LBUFSIZE);
 
        strm.next_in = buf;
        strm.avail_in = ret;
        strm.total_in = 0;
+       fpos += ret;
 
        retval = -ENOEXEC;
 
@@ -277,7 +278,7 @@ static int decompress_exec(
        }
 
        while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) {
-               ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
+               ret = kernel_read(bprm->file, fpos, buf, LBUFSIZE);
                if (ret <= 0)
                        break;
                len -= ret;
@@ -285,6 +286,7 @@ static int decompress_exec(
                strm.next_in = buf;
                strm.avail_in = ret;
                strm.total_in = 0;
+               fpos += ret;
        }
 
        if (ret < 0) {
@@ -428,6 +430,7 @@ static int load_flat_file(struct linux_binprm * bprm,
        unsigned long textpos = 0, datapos = 0, result;
        unsigned long realdatastart = 0;
        unsigned long text_len, data_len, bss_len, stack_len, flags;
+       unsigned long full_data;
        unsigned long len, memp = 0;
        unsigned long memp_size, extra, rlim;
        unsigned long *reloc = 0, *rp;
@@ -451,6 +454,7 @@ static int load_flat_file(struct linux_binprm * bprm,
        relocs    = ntohl(hdr->reloc_count);
        flags     = ntohl(hdr->flags);
        rev       = ntohl(hdr->rev);
+       full_data = data_len + relocs * sizeof(unsigned long);
 
        if (strncmp(hdr->magic, "bFLT", 4)) {
                /*
@@ -577,12 +581,12 @@ static int load_flat_file(struct linux_binprm * bprm,
 #ifdef CONFIG_BINFMT_ZFLAT
                if (flags & FLAT_FLAG_GZDATA) {
                        result = decompress_exec(bprm, fpos, (char *) datapos, 
-                                                data_len + (relocs * sizeof(unsigned long)), 0);
+                                                full_data, 0);
                } else
 #endif
                {
-                       result = bprm->file->f_op->read(bprm->file, (char *) datapos,
-                                       data_len + (relocs * sizeof(unsigned long)), &fpos);
+                       result = read_code(bprm->file, datapos, fpos,
+                                       full_data);
                }
                if (IS_ERR_VALUE(result)) {
                        printk("Unable to read data+bss, errno %d\n", (int)-result);
@@ -627,30 +631,25 @@ static int load_flat_file(struct linux_binprm * bprm,
                if (flags & FLAT_FLAG_GZIP) {
                        result = decompress_exec(bprm, sizeof (struct flat_hdr),
                                         (((char *) textpos) + sizeof (struct flat_hdr)),
-                                        (text_len + data_len + (relocs * sizeof(unsigned long))
+                                        (text_len + full_data
                                                  - sizeof (struct flat_hdr)),
                                         0);
                        memmove((void *) datapos, (void *) realdatastart,
-                                       data_len + (relocs * sizeof(unsigned long)));
+                                       full_data);
                } else if (flags & FLAT_FLAG_GZDATA) {
-                       fpos = 0;
-                       result = bprm->file->f_op->read(bprm->file,
-                                       (char *) textpos, text_len, &fpos);
+                       result = read_code(bprm->file, textpos, 0, text_len);
                        if (!IS_ERR_VALUE(result))
                                result = decompress_exec(bprm, text_len, (char *) datapos,
-                                                data_len + (relocs * sizeof(unsigned long)), 0);
+                                                full_data, 0);
                }
                else
 #endif
                {
-                       fpos = 0;
-                       result = bprm->file->f_op->read(bprm->file,
-                                       (char *) textpos, text_len, &fpos);
-                       if (!IS_ERR_VALUE(result)) {
-                               fpos = ntohl(hdr->data_start);
-                               result = bprm->file->f_op->read(bprm->file, (char *) datapos,
-                                       data_len + (relocs * sizeof(unsigned long)), &fpos);
-                       }
+                       result = read_code(bprm->file, textpos, 0, text_len);
+                       if (!IS_ERR_VALUE(result))
+                               result = read_code(bprm->file, datapos,
+                                                  ntohl(hdr->data_start),
+                                                  full_data);
                }
                if (IS_ERR_VALUE(result)) {
                        printk("Unable to read code+data+bss, errno %d\n",(int)-result);
index fecbbf3f8ff24340ab4b84e95ace2339a3f631a4..751df5e4f61a71f2a8eac366ebb3e8a040a3fc53 100644 (file)
@@ -720,6 +720,7 @@ static struct file_system_type bm_fs_type = {
        .mount          = bm_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("binfmt_misc");
 
 static int __init init_misc_binfmt(void)
 {
index 0b278b117cbe609611764cf45127f89a133eed5f..14fce27b4780803c53d0a04b5b8557c1096e61fb 100644 (file)
@@ -22,8 +22,9 @@
 #include "disk-io.h"
 #include "transaction.h"
 
-#define BTRFS_DELAYED_WRITEBACK                400
-#define BTRFS_DELAYED_BACKGROUND       100
+#define BTRFS_DELAYED_WRITEBACK                512
+#define BTRFS_DELAYED_BACKGROUND       128
+#define BTRFS_DELAYED_BATCH            16
 
 static struct kmem_cache *delayed_node_cache;
 
@@ -494,6 +495,15 @@ static int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node,
                                        BTRFS_DELAYED_DELETION_ITEM);
 }
 
+static void finish_one_item(struct btrfs_delayed_root *delayed_root)
+{
+       int seq = atomic_inc_return(&delayed_root->items_seq);
+       if ((atomic_dec_return(&delayed_root->items) <
+           BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0) &&
+           waitqueue_active(&delayed_root->wait))
+               wake_up(&delayed_root->wait);
+}
+
 static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
 {
        struct rb_root *root;
@@ -512,10 +522,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
 
        rb_erase(&delayed_item->rb_node, root);
        delayed_item->delayed_node->count--;
-       if (atomic_dec_return(&delayed_root->items) <
-           BTRFS_DELAYED_BACKGROUND &&
-           waitqueue_active(&delayed_root->wait))
-               wake_up(&delayed_root->wait);
+
+       finish_one_item(delayed_root);
 }
 
 static void btrfs_release_delayed_item(struct btrfs_delayed_item *item)
@@ -1056,10 +1064,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
                delayed_node->count--;
 
                delayed_root = delayed_node->root->fs_info->delayed_root;
-               if (atomic_dec_return(&delayed_root->items) <
-                   BTRFS_DELAYED_BACKGROUND &&
-                   waitqueue_active(&delayed_root->wait))
-                       wake_up(&delayed_root->wait);
+               finish_one_item(delayed_root);
        }
 }
 
@@ -1304,35 +1309,44 @@ void btrfs_remove_delayed_node(struct inode *inode)
        btrfs_release_delayed_node(delayed_node);
 }
 
-struct btrfs_async_delayed_node {
-       struct btrfs_root *root;
-       struct btrfs_delayed_node *delayed_node;
+struct btrfs_async_delayed_work {
+       struct btrfs_delayed_root *delayed_root;
+       int nr;
        struct btrfs_work work;
 };
 
-static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
+static void btrfs_async_run_delayed_root(struct btrfs_work *work)
 {
-       struct btrfs_async_delayed_node *async_node;
+       struct btrfs_async_delayed_work *async_work;
+       struct btrfs_delayed_root *delayed_root;
        struct btrfs_trans_handle *trans;
        struct btrfs_path *path;
        struct btrfs_delayed_node *delayed_node = NULL;
        struct btrfs_root *root;
        struct btrfs_block_rsv *block_rsv;
-       int need_requeue = 0;
+       int total_done = 0;
 
-       async_node = container_of(work, struct btrfs_async_delayed_node, work);
+       async_work = container_of(work, struct btrfs_async_delayed_work, work);
+       delayed_root = async_work->delayed_root;
 
        path = btrfs_alloc_path();
        if (!path)
                goto out;
-       path->leave_spinning = 1;
 
-       delayed_node = async_node->delayed_node;
+again:
+       if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND / 2)
+               goto free_path;
+
+       delayed_node = btrfs_first_prepared_delayed_node(delayed_root);
+       if (!delayed_node)
+               goto free_path;
+
+       path->leave_spinning = 1;
        root = delayed_node->root;
 
        trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
-               goto free_path;
+               goto release_path;
 
        block_rsv = trans->block_rsv;
        trans->block_rsv = &root->fs_info->delayed_block_rsv;
@@ -1363,57 +1377,47 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
         * Task1 will sleep until the transaction is commited.
         */
        mutex_lock(&delayed_node->mutex);
-       if (delayed_node->count)
-               need_requeue = 1;
-       else
-               btrfs_dequeue_delayed_node(root->fs_info->delayed_root,
-                                          delayed_node);
+       btrfs_dequeue_delayed_node(root->fs_info->delayed_root, delayed_node);
        mutex_unlock(&delayed_node->mutex);
 
        trans->block_rsv = block_rsv;
        btrfs_end_transaction_dmeta(trans, root);
        btrfs_btree_balance_dirty_nodelay(root);
+
+release_path:
+       btrfs_release_path(path);
+       total_done++;
+
+       btrfs_release_prepared_delayed_node(delayed_node);
+       if (async_work->nr == 0 || total_done < async_work->nr)
+               goto again;
+
 free_path:
        btrfs_free_path(path);
 out:
-       if (need_requeue)
-               btrfs_requeue_work(&async_node->work);
-       else {
-               btrfs_release_prepared_delayed_node(delayed_node);
-               kfree(async_node);
-       }
+       wake_up(&delayed_root->wait);
+       kfree(async_work);
 }
 
+
 static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
-                                    struct btrfs_root *root, int all)
+                                    struct btrfs_root *root, int nr)
 {
-       struct btrfs_async_delayed_node *async_node;
-       struct btrfs_delayed_node *curr;
-       int count = 0;
+       struct btrfs_async_delayed_work *async_work;
 
-again:
-       curr = btrfs_first_prepared_delayed_node(delayed_root);
-       if (!curr)
+       if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
                return 0;
 
-       async_node = kmalloc(sizeof(*async_node), GFP_NOFS);
-       if (!async_node) {
-               btrfs_release_prepared_delayed_node(curr);
+       async_work = kmalloc(sizeof(*async_work), GFP_NOFS);
+       if (!async_work)
                return -ENOMEM;
-       }
-
-       async_node->root = root;
-       async_node->delayed_node = curr;
-
-       async_node->work.func = btrfs_async_run_delayed_node_done;
-       async_node->work.flags = 0;
 
-       btrfs_queue_worker(&root->fs_info->delayed_workers, &async_node->work);
-       count++;
-
-       if (all || count < 4)
-               goto again;
+       async_work->delayed_root = delayed_root;
+       async_work->work.func = btrfs_async_run_delayed_root;
+       async_work->work.flags = 0;
+       async_work->nr = nr;
 
+       btrfs_queue_worker(&root->fs_info->delayed_workers, &async_work->work);
        return 0;
 }
 
@@ -1424,30 +1428,55 @@ void btrfs_assert_delayed_root_empty(struct btrfs_root *root)
        WARN_ON(btrfs_first_delayed_node(delayed_root));
 }
 
+static int refs_newer(struct btrfs_delayed_root *delayed_root,
+                     int seq, int count)
+{
+       int val = atomic_read(&delayed_root->items_seq);
+
+       if (val < seq || val >= seq + count)
+               return 1;
+       return 0;
+}
+
 void btrfs_balance_delayed_items(struct btrfs_root *root)
 {
        struct btrfs_delayed_root *delayed_root;
+       int seq;
 
        delayed_root = btrfs_get_delayed_root(root);
 
        if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
                return;
 
+       seq = atomic_read(&delayed_root->items_seq);
+
        if (atomic_read(&delayed_root->items) >= BTRFS_DELAYED_WRITEBACK) {
                int ret;
-               ret = btrfs_wq_run_delayed_node(delayed_root, root, 1);
+               DEFINE_WAIT(__wait);
+
+               ret = btrfs_wq_run_delayed_node(delayed_root, root, 0);
                if (ret)
                        return;
 
-               wait_event_interruptible_timeout(
-                               delayed_root->wait,
-                               (atomic_read(&delayed_root->items) <
-                                BTRFS_DELAYED_BACKGROUND),
-                               HZ);
-               return;
+               while (1) {
+                       prepare_to_wait(&delayed_root->wait, &__wait,
+                                       TASK_INTERRUPTIBLE);
+
+                       if (refs_newer(delayed_root, seq,
+                                      BTRFS_DELAYED_BATCH) ||
+                           atomic_read(&delayed_root->items) <
+                           BTRFS_DELAYED_BACKGROUND) {
+                               break;
+                       }
+                       if (!signal_pending(current))
+                               schedule();
+                       else
+                               break;
+               }
+               finish_wait(&delayed_root->wait, &__wait);
        }
 
-       btrfs_wq_run_delayed_node(delayed_root, root, 0);
+       btrfs_wq_run_delayed_node(delayed_root, root, BTRFS_DELAYED_BATCH);
 }
 
 /* Will return 0 or -ENOMEM */
index 78b6ad0fc6699c5c59d5f9ccddef641aa80c5d09..1d5c5f7abe3e01bf872913d123f5c43b2797fd2b 100644 (file)
@@ -43,6 +43,7 @@ struct btrfs_delayed_root {
         */
        struct list_head prepare_list;
        atomic_t items;         /* for delayed items */
+       atomic_t items_seq;     /* for delayed items */
        int nodes;              /* for delayed nodes */
        wait_queue_head_t wait;
 };
@@ -86,6 +87,7 @@ static inline void btrfs_init_delayed_root(
                                struct btrfs_delayed_root *delayed_root)
 {
        atomic_set(&delayed_root->items, 0);
+       atomic_set(&delayed_root->items_seq, 0);
        delayed_root->nodes = 0;
        spin_lock_init(&delayed_root->lock);
        init_waitqueue_head(&delayed_root->wait);
index 02369a3c162e0e891a09c3f893f277c5ec907635..7d84651e850b22cb937b29c68d34c1119af1e4a0 100644 (file)
@@ -62,7 +62,7 @@ static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t,
 static void btrfs_destroy_ordered_extents(struct btrfs_root *root);
 static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
                                      struct btrfs_root *root);
-static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t);
+static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t);
 static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root);
 static int btrfs_destroy_marked_extents(struct btrfs_root *root,
                                        struct extent_io_tree *dirty_pages,
@@ -3687,7 +3687,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
        return ret;
 }
 
-static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)
+static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t)
 {
        struct btrfs_pending_snapshot *snapshot;
        struct list_head splice;
@@ -3700,10 +3700,8 @@ static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)
                snapshot = list_entry(splice.next,
                                      struct btrfs_pending_snapshot,
                                      list);
-
+               snapshot->error = -ECANCELED;
                list_del_init(&snapshot->list);
-
-               kfree(snapshot);
        }
 }
 
@@ -3840,6 +3838,8 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
        cur_trans->blocked = 1;
        wake_up(&root->fs_info->transaction_blocked_wait);
 
+       btrfs_evict_pending_snapshots(cur_trans);
+
        cur_trans->blocked = 0;
        wake_up(&root->fs_info->transaction_wait);
 
@@ -3849,8 +3849,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
        btrfs_destroy_delayed_inodes(root);
        btrfs_assert_delayed_root_empty(root);
 
-       btrfs_destroy_pending_snapshots(cur_trans);
-
        btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages,
                                     EXTENT_DIRTY);
        btrfs_destroy_pinned_extent(root,
@@ -3894,6 +3892,8 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
                if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
                        wake_up(&root->fs_info->transaction_blocked_wait);
 
+               btrfs_evict_pending_snapshots(t);
+
                t->blocked = 0;
                smp_mb();
                if (waitqueue_active(&root->fs_info->transaction_wait))
@@ -3907,8 +3907,6 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
                btrfs_destroy_delayed_inodes(root);
                btrfs_assert_delayed_root_empty(root);
 
-               btrfs_destroy_pending_snapshots(t);
-
                btrfs_destroy_delalloc_inodes(root);
 
                spin_lock(&root->fs_info->trans_lock);
index 3e074dab2d57a3e39ad16538f7a51bfde8e4ed91..9ac2eca681ebb09c605612dd563bc4417e4fc587 100644 (file)
@@ -1467,8 +1467,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
        if (ret && !insert) {
                err = -ENOENT;
                goto out;
+       } else if (ret) {
+               err = -EIO;
+               WARN_ON(1);
+               goto out;
        }
-       BUG_ON(ret); /* Corruption */
 
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
index af1d0605a5c1e74b3f30392d4e28c0faf34400ad..254aeb72915ff5ba16ff1bc5460f03da8a06da73 100644 (file)
@@ -591,6 +591,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                }
                compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
                clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+               clear_bit(EXTENT_FLAG_LOGGING, &flags);
                remove_extent_mapping(em_tree, em);
                if (no_splits)
                        goto next;
@@ -1513,8 +1514,6 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        size_t count, ocount;
        bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
 
-       sb_start_write(inode->i_sb);
-
        mutex_lock(&inode->i_mutex);
 
        err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
@@ -1616,7 +1615,6 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        if (sync)
                atomic_dec(&BTRFS_I(inode)->sync_writers);
 out:
-       sb_end_write(inode->i_sb);
        current->backing_dev_info = NULL;
        return num_written ? num_written : err;
 }
index c226daefd65d20a7c635723926f978172f53aaa6..ca1b767d51f760672f8de72c48efbf3df8e58a75 100644 (file)
@@ -2312,6 +2312,7 @@ again:
        key.type = BTRFS_EXTENT_DATA_KEY;
        key.offset = start;
 
+       path->leave_spinning = 1;
        if (merge) {
                struct btrfs_file_extent_item *fi;
                u64 extent_len;
@@ -2368,6 +2369,7 @@ again:
 
        btrfs_mark_buffer_dirty(leaf);
        inode_add_bytes(inode, len);
+       btrfs_release_path(path);
 
        ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
                        new->disk_len, 0,
@@ -2381,6 +2383,7 @@ again:
        ret = 1;
 out_free_path:
        btrfs_release_path(path);
+       path->leave_spinning = 0;
        btrfs_end_transaction(trans, root);
 out_unlock:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end,
@@ -8502,6 +8505,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
        struct btrfs_key ins;
        u64 cur_offset = start;
        u64 i_size;
+       u64 cur_bytes;
        int ret = 0;
        bool own_trans = true;
 
@@ -8516,8 +8520,9 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                        }
                }
 
-               ret = btrfs_reserve_extent(trans, root,
-                                          min(num_bytes, 256ULL * 1024 * 1024),
+               cur_bytes = min(num_bytes, 256ULL * 1024 * 1024);
+               cur_bytes = max(cur_bytes, min_size);
+               ret = btrfs_reserve_extent(trans, root, cur_bytes,
                                           min_size, 0, *alloc_hint, &ins, 1);
                if (ret) {
                        if (own_trans)
index c83086fdda055e25f2f9c378ca71fc420f807ed3..2c02310ff2d96320ebf2d348ed339dd0ea047e0f 100644 (file)
@@ -527,6 +527,8 @@ fail:
        if (async_transid) {
                *async_transid = trans->transid;
                err = btrfs_commit_transaction_async(trans, root, 1);
+               if (err)
+                       err = btrfs_commit_transaction(trans, root);
        } else {
                err = btrfs_commit_transaction(trans, root);
        }
@@ -592,16 +594,14 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                *async_transid = trans->transid;
                ret = btrfs_commit_transaction_async(trans,
                                     root->fs_info->extent_root, 1);
+               if (ret)
+                       ret = btrfs_commit_transaction(trans, root);
        } else {
                ret = btrfs_commit_transaction(trans,
                                               root->fs_info->extent_root);
        }
-       if (ret) {
-               /* cleanup_transaction has freed this for us */
-               if (trans->aborted)
-                       pending_snapshot = NULL;
+       if (ret)
                goto fail;
-       }
 
        ret = pending_snapshot->error;
        if (ret)
@@ -2245,13 +2245,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
        if (ret)
                return ret;
 
-       if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
-                       1)) {
-               pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n");
-               mnt_drop_write_file(file);
-               return -EINVAL;
-       }
-
        if (btrfs_root_readonly(root)) {
                ret = -EROFS;
                goto out;
@@ -2306,7 +2299,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
                ret = -EINVAL;
        }
 out:
-       atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
        mnt_drop_write_file(file);
        return ret;
 }
index ca52681e5f4049c45f2a228a3f8237ca23815772..b81e0e9a48941891681eef385d10d071f6cbe51b 100644 (file)
@@ -26,7 +26,6 @@
 
 void btrfs_tree_lock(struct extent_buffer *eb);
 void btrfs_tree_unlock(struct extent_buffer *eb);
-int btrfs_try_spin_lock(struct extent_buffer *eb);
 
 void btrfs_tree_read_lock(struct extent_buffer *eb);
 void btrfs_tree_read_unlock(struct extent_buffer *eb);
index aee4b1cc3d988ccc0dbde615000d07bcf5d35051..5471e47d6559eafeb36e55035cb427710c5ee4ba 100644 (file)
@@ -1525,21 +1525,23 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
 
                if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
                    qg->reserved + qg->rfer + num_bytes >
-                   qg->max_rfer)
+                   qg->max_rfer) {
                        ret = -EDQUOT;
+                       goto out;
+               }
 
                if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
                    qg->reserved + qg->excl + num_bytes >
-                   qg->max_excl)
+                   qg->max_excl) {
                        ret = -EDQUOT;
+                       goto out;
+               }
 
                list_for_each_entry(glist, &qg->groups, next_group) {
                        ulist_add(ulist, glist->group->qgroupid,
                                  (uintptr_t)glist->group, GFP_ATOMIC);
                }
        }
-       if (ret)
-               goto out;
 
        /*
         * no limits exceeded, now record the reservation into all qgroups
index 50695dc5e2abb273a221a1d03446016b66039c53..b67171e6d688362167fed9db03cdc659b88061ea 100644 (file)
@@ -1269,6 +1269,8 @@ static int __update_reloc_root(struct btrfs_root *root, int del)
        }
        spin_unlock(&rc->reloc_root_tree.lock);
 
+       if (!node)
+               return 0;
        BUG_ON((struct btrfs_root *)node->data != root);
 
        if (!del) {
@@ -2237,6 +2239,21 @@ again:
        return err;
 }
 
+static noinline_for_stack
+void free_reloc_roots(struct list_head *list)
+{
+       struct btrfs_root *reloc_root;
+
+       while (!list_empty(list)) {
+               reloc_root = list_entry(list->next, struct btrfs_root,
+                                       root_list);
+               __update_reloc_root(reloc_root, 1);
+               free_extent_buffer(reloc_root->node);
+               free_extent_buffer(reloc_root->commit_root);
+               kfree(reloc_root);
+       }
+}
+
 static noinline_for_stack
 int merge_reloc_roots(struct reloc_control *rc)
 {
@@ -2244,7 +2261,7 @@ int merge_reloc_roots(struct reloc_control *rc)
        struct btrfs_root *reloc_root;
        LIST_HEAD(reloc_roots);
        int found = 0;
-       int ret;
+       int ret = 0;
 again:
        root = rc->extent_root;
 
@@ -2270,20 +2287,33 @@ again:
                        BUG_ON(root->reloc_root != reloc_root);
 
                        ret = merge_reloc_root(rc, root);
-                       BUG_ON(ret);
+                       if (ret)
+                               goto out;
                } else {
                        list_del_init(&reloc_root->root_list);
                }
                ret = btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1);
-               BUG_ON(ret < 0);
+               if (ret < 0) {
+                       if (list_empty(&reloc_root->root_list))
+                               list_add_tail(&reloc_root->root_list,
+                                             &reloc_roots);
+                       goto out;
+               }
        }
 
        if (found) {
                found = 0;
                goto again;
        }
+out:
+       if (ret) {
+               btrfs_std_error(root->fs_info, ret);
+               if (!list_empty(&reloc_roots))
+                       free_reloc_roots(&reloc_roots);
+       }
+
        BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
-       return 0;
+       return ret;
 }
 
 static void free_block_list(struct rb_root *blocks)
@@ -2818,8 +2848,10 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
        int err = 0;
 
        path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
+       if (!path) {
+               err = -ENOMEM;
+               goto out_path;
+       }
 
        rb_node = rb_first(blocks);
        while (rb_node) {
@@ -2858,10 +2890,11 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
                rb_node = rb_next(rb_node);
        }
 out:
-       free_block_list(blocks);
        err = finish_pending_nodes(trans, rc, path, err);
 
        btrfs_free_path(path);
+out_path:
+       free_block_list(blocks);
        return err;
 }
 
@@ -3698,7 +3731,15 @@ int prepare_to_relocate(struct reloc_control *rc)
        set_reloc_control(rc);
 
        trans = btrfs_join_transaction(rc->extent_root);
-       BUG_ON(IS_ERR(trans));
+       if (IS_ERR(trans)) {
+               unset_reloc_control(rc);
+               /*
+                * extent tree is not a ref_cow tree and has no reloc_root to
+                * cleanup.  And callers are responsible to free the above
+                * block rsv.
+                */
+               return PTR_ERR(trans);
+       }
        btrfs_commit_transaction(trans, rc->extent_root);
        return 0;
 }
@@ -3730,7 +3771,11 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
        while (1) {
                progress++;
                trans = btrfs_start_transaction(rc->extent_root, 0);
-               BUG_ON(IS_ERR(trans));
+               if (IS_ERR(trans)) {
+                       err = PTR_ERR(trans);
+                       trans = NULL;
+                       break;
+               }
 restart:
                if (update_backref_cache(trans, &rc->backref_cache)) {
                        btrfs_end_transaction(trans, rc->extent_root);
@@ -4264,14 +4309,9 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 out_free:
        kfree(rc);
 out:
-       while (!list_empty(&reloc_roots)) {
-               reloc_root = list_entry(reloc_roots.next,
-                                       struct btrfs_root, root_list);
-               list_del(&reloc_root->root_list);
-               free_extent_buffer(reloc_root->node);
-               free_extent_buffer(reloc_root->commit_root);
-               kfree(reloc_root);
-       }
+       if (!list_empty(&reloc_roots))
+               free_reloc_roots(&reloc_roots);
+
        btrfs_free_path(path);
 
        if (err == 0) {
index 68a29a1ea0688b868a0b33b8298b38159be5ec80..f6b88595f858b08f47fd530f3409124c288eb852 100644 (file)
@@ -1558,6 +1558,7 @@ static struct file_system_type btrfs_fs_type = {
        .kill_sb        = btrfs_kill_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("btrfs");
 
 /*
  * used by btrfsctl to scan devices when no FS is mounted
index e52da6fb11659e3b1b893086581b7c5a85d8eeb6..50767bbaad6c6bfeb40e4d0e815446effd5392b3 100644 (file)
@@ -625,14 +625,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_trans_release_metadata(trans, root);
        trans->block_rsv = NULL;
-       /*
-        * the same root has to be passed to start_transaction and
-        * end_transaction. Subvolume quota depends on this.
-        */
-       WARN_ON(trans->root != root);
 
        if (trans->qgroup_reserved) {
-               btrfs_qgroup_free(root, trans->qgroup_reserved);
+               /*
+                * the same root has to be passed here between start_transaction
+                * and end_transaction. Subvolume quota depends on this.
+                */
+               btrfs_qgroup_free(trans->root, trans->qgroup_reserved);
                trans->qgroup_reserved = 0;
        }
 
@@ -1052,7 +1051,12 @@ int btrfs_defrag_root(struct btrfs_root *root)
 
 /*
  * new snapshots need to be created at a very specific time in the
- * transaction commit.  This does the actual creation
+ * transaction commit.  This does the actual creation.
+ *
+ * Note:
+ * If the error which may affect the commitment of the current transaction
+ * happens, we should return the error number. If the error which just affect
+ * the creation of the pending snapshots, just return 0.
  */
 static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                   struct btrfs_fs_info *fs_info,
@@ -1071,7 +1075,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        struct extent_buffer *tmp;
        struct extent_buffer *old;
        struct timespec cur_time = CURRENT_TIME;
-       int ret;
+       int ret = 0;
        u64 to_reserve = 0;
        u64 index = 0;
        u64 objectid;
@@ -1080,40 +1084,36 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 
        path = btrfs_alloc_path();
        if (!path) {
-               ret = pending->error = -ENOMEM;
-               return ret;
+               pending->error = -ENOMEM;
+               return 0;
        }
 
        new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
        if (!new_root_item) {
-               ret = pending->error = -ENOMEM;
+               pending->error = -ENOMEM;
                goto root_item_alloc_fail;
        }
 
-       ret = btrfs_find_free_objectid(tree_root, &objectid);
-       if (ret) {
-               pending->error = ret;
+       pending->error = btrfs_find_free_objectid(tree_root, &objectid);
+       if (pending->error)
                goto no_free_objectid;
-       }
 
        btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
 
        if (to_reserve > 0) {
-               ret = btrfs_block_rsv_add(root, &pending->block_rsv,
-                                         to_reserve,
-                                         BTRFS_RESERVE_NO_FLUSH);
-               if (ret) {
-                       pending->error = ret;
+               pending->error = btrfs_block_rsv_add(root,
+                                                    &pending->block_rsv,
+                                                    to_reserve,
+                                                    BTRFS_RESERVE_NO_FLUSH);
+               if (pending->error)
                        goto no_free_objectid;
-               }
        }
 
-       ret = btrfs_qgroup_inherit(trans, fs_info, root->root_key.objectid,
-                                  objectid, pending->inherit);
-       if (ret) {
-               pending->error = ret;
+       pending->error = btrfs_qgroup_inherit(trans, fs_info,
+                                             root->root_key.objectid,
+                                             objectid, pending->inherit);
+       if (pending->error)
                goto no_free_objectid;
-       }
 
        key.objectid = objectid;
        key.offset = (u64)-1;
@@ -1141,7 +1141,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                         dentry->d_name.len, 0);
        if (dir_item != NULL && !IS_ERR(dir_item)) {
                pending->error = -EEXIST;
-               goto fail;
+               goto dir_item_existed;
        } else if (IS_ERR(dir_item)) {
                ret = PTR_ERR(dir_item);
                btrfs_abort_transaction(trans, root, ret);
@@ -1272,6 +1272,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        if (ret)
                btrfs_abort_transaction(trans, root, ret);
 fail:
+       pending->error = ret;
+dir_item_existed:
        trans->block_rsv = rsv;
        trans->bytes_reserved = 0;
 no_free_objectid:
@@ -1287,12 +1289,17 @@ root_item_alloc_fail:
 static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
                                             struct btrfs_fs_info *fs_info)
 {
-       struct btrfs_pending_snapshot *pending;
+       struct btrfs_pending_snapshot *pending, *next;
        struct list_head *head = &trans->transaction->pending_snapshots;
+       int ret = 0;
 
-       list_for_each_entry(pending, head, list)
-               create_pending_snapshot(trans, fs_info, pending);
-       return 0;
+       list_for_each_entry_safe(pending, next, head, list) {
+               list_del(&pending->list);
+               ret = create_pending_snapshot(trans, fs_info, pending);
+               if (ret)
+                       break;
+       }
+       return ret;
 }
 
 static void update_super_roots(struct btrfs_root *root)
@@ -1448,6 +1455,13 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
        btrfs_abort_transaction(trans, root, err);
 
        spin_lock(&root->fs_info->trans_lock);
+
+       if (list_empty(&cur_trans->list)) {
+               spin_unlock(&root->fs_info->trans_lock);
+               btrfs_end_transaction(trans, root);
+               return;
+       }
+
        list_del_init(&cur_trans->list);
        if (cur_trans == root->fs_info->running_transaction) {
                root->fs_info->trans_no_join = 1;
index c7ef569eb22a8b71a455721edc57a61acc66a226..451fad96ecd115393207e69433162b7328f74923 100644 (file)
@@ -1382,7 +1382,10 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
 
        btrfs_release_path(path);
        if (ret == 0) {
-               btrfs_inc_nlink(inode);
+               if (!inode->i_nlink)
+                       set_nlink(inode, 1);
+               else
+                       btrfs_inc_nlink(inode);
                ret = btrfs_update_inode(trans, root, inode);
        } else if (ret == -EEXIST) {
                ret = 0;
index 35bb2d4ed29f6ed1a00fabb5491fc40d5d669994..5989a92236f7f1b578ec3ccf88078bb69c1093d3 100644 (file)
@@ -684,6 +684,12 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
                __btrfs_close_devices(fs_devices);
                free_fs_devices(fs_devices);
        }
+       /*
+        * Wait for rcu kworkers under __btrfs_close_devices
+        * to finish all blkdev_puts so device is really
+        * free when umount is done.
+        */
+       rcu_barrier();
        return ret;
 }
 
@@ -2379,7 +2385,11 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,
                return ret;
 
        trans = btrfs_start_transaction(root, 0);
-       BUG_ON(IS_ERR(trans));
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               btrfs_std_error(root->fs_info, ret);
+               return ret;
+       }
 
        lock_chunks(root);
 
@@ -3050,7 +3060,8 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
 
        unset_balance_control(fs_info);
        ret = del_balance_item(fs_info->tree_root);
-       BUG_ON(ret);
+       if (ret)
+               btrfs_std_error(fs_info, ret);
 
        atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
 }
@@ -3230,6 +3241,11 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
                update_ioctl_balance_args(fs_info, 0, bargs);
        }
 
+       if ((ret && ret != -ECANCELED && ret != -ENOSPC) ||
+           balance_need_close(fs_info)) {
+               __cancel_balance(fs_info);
+       }
+
        wake_up(&fs_info->balance_wait_q);
 
        return ret;
index 480992259707fe4f932646353245a640c5c9dfec..317f9ee9c99178d7afd774ff424bbd63fab2ff17 100644 (file)
@@ -962,12 +962,14 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
                        }
 
                        data = kmap(page);
+                       file_start_write(file);
                        old_fs = get_fs();
                        set_fs(KERNEL_DS);
                        ret = file->f_op->write(
                                file, (const void __user *) data, len, &pos);
                        set_fs(old_fs);
                        kunmap(page);
+                       file_end_write(file);
                        if (ret != len)
                                ret = -EIO;
                }
index 9fe17c6c2876c0cbec11b57b6e5de76349320244..6ddc0bca56b2e61abda40b5ad8194be95f73c152 100644 (file)
@@ -952,6 +952,7 @@ static struct file_system_type ceph_fs_type = {
        .kill_sb        = ceph_kill_sb,
        .fs_flags       = FS_RENAME_DOES_D_MOVE,
 };
+MODULE_ALIAS_FS("ceph");
 
 #define _STRINGIFY(x) #x
 #define STRINGIFY(x) _STRINGIFY(x)
index cfd1ce34e0bc7b8c4794c81e1aa937e7f009ca75..1d36db114772b953065555cd7e80aa5abca36a7d 100644 (file)
@@ -614,53 +614,10 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                }
        }
 
-       /* mechlistMIC */
-       if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               /* Check if we have reached the end of the blob, but with
-                  no mechListMic (e.g. NTLMSSP instead of KRB5) */
-               if (ctx.error == ASN1_ERR_DEC_EMPTY)
-                       goto decode_negtoken_exit;
-               cFYI(1, "Error decoding last part negTokenInit exit3");
-               return 0;
-       } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
-               /* tag = 3 indicating mechListMIC */
-               cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
-                       cls, con, tag, end, *end);
-               return 0;
-       }
-
-       /* sequence */
-       if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, "Error decoding last part negTokenInit exit5");
-               return 0;
-       } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
-                  || (tag != ASN1_SEQ)) {
-               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)",
-                       cls, con, tag, end, *end);
-       }
-
-       /* sequence of */
-       if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, "Error decoding last part negTokenInit exit 7");
-               return 0;
-       } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
-               cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
-                       cls, con, tag, end, *end);
-               return 0;
-       }
-
-       /* general string */
-       if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, "Error decoding last part negTokenInit exit9");
-               return 0;
-       } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
-                  || (tag != ASN1_GENSTR)) {
-               cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)",
-                       cls, con, tag, end, *end);
-               return 0;
-       }
-       cFYI(1, "Need to call asn1_octets_decode() function for %s",
-               ctx.pointer);   /* is this UTF-8 or ASCII? */
-decode_negtoken_exit:
+       /*
+        * We currently ignore anything at the end of the SPNEGO blob after
+        * the mechTypes have been parsed, since none of that info is
+        * used at the moment.
+        */
        return 1;
 }
index 1a052c0eee8eae9181e0e58ac5d0ff8852c0db8e..345fc89c4286985ed55cd972410c287a09c440f3 100644 (file)
@@ -91,6 +91,30 @@ struct workqueue_struct      *cifsiod_wq;
 __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE];
 #endif
 
+/*
+ * Bumps refcount for cifs super block.
+ * Note that it should be only called if a referece to VFS super block is
+ * already held, e.g. in open-type syscalls context. Otherwise it can race with
+ * atomic_dec_and_test in deactivate_locked_super.
+ */
+void
+cifs_sb_active(struct super_block *sb)
+{
+       struct cifs_sb_info *server = CIFS_SB(sb);
+
+       if (atomic_inc_return(&server->active) == 1)
+               atomic_inc(&sb->s_active);
+}
+
+void
+cifs_sb_deactive(struct super_block *sb)
+{
+       struct cifs_sb_info *server = CIFS_SB(sb);
+
+       if (atomic_dec_and_test(&server->active))
+               deactivate_super(sb);
+}
+
 static int
 cifs_read_super(struct super_block *sb)
 {
@@ -777,6 +801,7 @@ struct file_system_type cifs_fs_type = {
        .kill_sb = cifs_kill_sb,
        /*  .fs_flags */
 };
+MODULE_ALIAS_FS("cifs");
 const struct inode_operations cifs_dir_inode_ops = {
        .create = cifs_create,
        .atomic_open = cifs_atomic_open,
index 7163419cecd95186f912522ba1736eb4e8c95454..0e32c3446ce9330b21898c59e72bd5430c47e48b 100644 (file)
@@ -41,6 +41,10 @@ extern struct file_system_type cifs_fs_type;
 extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
 
+/* Functions related to super block operations */
+extern void cifs_sb_active(struct super_block *sb);
+extern void cifs_sb_deactive(struct super_block *sb);
+
 /* Functions related to inodes */
 extern const struct inode_operations cifs_dir_inode_ops;
 extern struct inode *cifs_root_iget(struct super_block *);
index 7353bc5d73d7cfcdba7125b8e83d783f639619ca..8e2e799e7a2451e5dd7300a57fbf81b32a28bf94 100644 (file)
@@ -1909,12 +1909,12 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
        } while (rc == -EAGAIN);
 
        for (i = 0; i < wdata->nr_pages; i++) {
+               unlock_page(wdata->pages[i]);
                if (rc != 0) {
                        SetPageError(wdata->pages[i]);
                        end_page_writeback(wdata->pages[i]);
                        page_cache_release(wdata->pages[i]);
                }
-               unlock_page(wdata->pages[i]);
        }
 
        mapping_set_error(inode->i_mapping, rc);
index 54125e04fd0c88d4c17d7833b557e21c1696bcb3..991c63c6bdd053189082c6208407a5df55b29053 100644 (file)
@@ -97,7 +97,7 @@ enum {
        Opt_user, Opt_pass, Opt_ip,
        Opt_unc, Opt_domain,
        Opt_srcaddr, Opt_prefixpath,
-       Opt_iocharset, Opt_sockopt,
+       Opt_iocharset,
        Opt_netbiosname, Opt_servern,
        Opt_ver, Opt_vers, Opt_sec, Opt_cache,
 
@@ -202,7 +202,6 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_srcaddr, "srcaddr=%s" },
        { Opt_prefixpath, "prefixpath=%s" },
        { Opt_iocharset, "iocharset=%s" },
-       { Opt_sockopt, "sockopt=%s" },
        { Opt_netbiosname, "netbiosname=%s" },
        { Opt_servern, "servern=%s" },
        { Opt_ver, "ver=%s" },
@@ -1752,19 +1751,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                         */
                        cFYI(1, "iocharset set to %s", string);
                        break;
-               case Opt_sockopt:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-
-                       if (strnicmp(string, "TCP_NODELAY", 11) == 0) {
-                               printk(KERN_WARNING "CIFS: the "
-                                       "sockopt=TCP_NODELAY option has been "
-                                       "deprecated and will be removed "
-                                       "in 3.9\n");
-                               vol->sockopt_tcp_nodelay = 1;
-                       }
-                       break;
                case Opt_netbiosname:
                        string = match_strdup(args);
                        if (string == NULL)
index 8c0d8557731443ffb564905bb1ad0a9c64b8169b..2d4a231dd70b09de5651e813e2082060bac4dc6b 100644 (file)
@@ -300,6 +300,8 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
        INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
        mutex_init(&cfile->fh_mutex);
 
+       cifs_sb_active(inode->i_sb);
+
        /*
         * If the server returned a read oplock and we have mandatory brlocks,
         * set oplock level to None.
@@ -349,7 +351,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
        struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
        struct TCP_Server_Info *server = tcon->ses->server;
        struct cifsInodeInfo *cifsi = CIFS_I(inode);
-       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct super_block *sb = inode->i_sb;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct cifsLockInfo *li, *tmp;
        struct cifs_fid fid;
        struct cifs_pending_open open;
@@ -414,6 +417,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
 
        cifs_put_tlink(cifs_file->tlink);
        dput(cifs_file->dentry);
+       cifs_sb_deactive(sb);
        kfree(cifs_file);
 }
 
@@ -2516,8 +2520,6 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
 
        BUG_ON(iocb->ki_pos != pos);
 
-       sb_start_write(inode->i_sb);
-
        /*
         * We need to hold the sem to be sure nobody modifies lock list
         * with a brlock that prevents writing.
@@ -2541,7 +2543,6 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
        }
 
        up_read(&cinode->lock_sem);
-       sb_end_write(inode->i_sb);
        return rc;
 }
 
index 83f2606c76d00f090ec6a5b8e550a102de3fadbc..20887bf63121286e3d52f582db922ec64f4a71e5 100644 (file)
@@ -995,6 +995,15 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
                return PTR_ERR(tlink);
        tcon = tlink_tcon(tlink);
 
+       /*
+        * We cannot rename the file if the server doesn't support
+        * CAP_INFOLEVEL_PASSTHRU
+        */
+       if (!(tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)) {
+               rc = -EBUSY;
+               goto out;
+       }
+
        rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
                         DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
                         &netfid, &oplock, NULL, cifs_sb->local_nls,
@@ -1023,7 +1032,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
                                        current->tgid);
                /* although we would like to mark the file hidden
                   if that fails we will still try to rename it */
-               if (rc != 0)
+               if (!rc)
                        cifsInode->cifsAttrs = dosattr;
                else
                        dosattr = origattr; /* since not able to change them */
@@ -1034,7 +1043,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
                                   cifs_sb->mnt_cifs_flags &
                                            CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc != 0) {
-               rc = -ETXTBSY;
+               rc = -EBUSY;
                goto undo_setattr;
        }
 
@@ -1053,7 +1062,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
                if (rc == -ENOENT)
                        rc = 0;
                else if (rc != 0) {
-                       rc = -ETXTBSY;
+                       rc = -EBUSY;
                        goto undo_rename;
                }
                cifsInode->delete_pending = true;
@@ -1160,15 +1169,13 @@ psx_del_no_retry:
                        cifs_drop_nlink(inode);
        } else if (rc == -ENOENT) {
                d_drop(dentry);
-       } else if (rc == -ETXTBSY) {
+       } else if (rc == -EBUSY) {
                if (server->ops->rename_pending_delete) {
                        rc = server->ops->rename_pending_delete(full_path,
                                                                dentry, xid);
                        if (rc == 0)
                                cifs_drop_nlink(inode);
                }
-               if (rc == -ETXTBSY)
-                       rc = -EBUSY;
        } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
                attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
                if (attrs == NULL) {
@@ -1509,7 +1516,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
         * source. Note that cross directory moves do not work with
         * rename by filehandle to various Windows servers.
         */
-       if (rc == 0 || rc != -ETXTBSY)
+       if (rc == 0 || rc != -EBUSY)
                goto do_rename_exit;
 
        /* open-file renames don't work across directories */
index a82bc51fdc82abad102b286399fd037ef10428c5..c0b25b28be6ccc1079185bc3effd6672c56976de 100644 (file)
@@ -62,7 +62,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
        {ERRdiffdevice, -EXDEV},
        {ERRnofiles, -ENOENT},
        {ERRwriteprot, -EROFS},
-       {ERRbadshare, -ETXTBSY},
+       {ERRbadshare, -EBUSY},
        {ERRlock, -EACCES},
        {ERRunsup, -EINVAL},
        {ERRnosuchshare, -ENXIO},
index c9c7aa7ed96685bc94b36103350204c68a19b827..bceffe7b8f8d2fdcda17aafd8c5069ea079c111d 100644 (file)
@@ -744,4 +744,5 @@ struct smb_version_values smb30_values = {
        .cap_unix = 0,
        .cap_nt_find = SMB2_NT_FIND,
        .cap_large_files = SMB2_LARGE_FILES,
+       .oplock_read = SMB2_OPLOCK_LEVEL_II,
 };
index fa4c100bdc7d08db45d66a37d8e692356c45d82f..380b798f8443360a9788a13b7de4ad4ea16fd255 100644 (file)
@@ -79,6 +79,7 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo
                return -EINVAL;
 
        host_inode = file_inode(host_file);
+       file_start_write(host_file);
        mutex_lock(&coda_inode->i_mutex);
 
        ret = host_file->f_op->write(host_file, buf, count, ppos);
@@ -87,6 +88,7 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo
        coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
        coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
        mutex_unlock(&coda_inode->i_mutex);
+       file_end_write(host_file);
 
        return ret;
 }
index dada9d0abedeb9f3d5ae29b0d0d9bde577975f63..4dcc0d81a7aa511069869141d0d1470800a82e54 100644 (file)
@@ -329,4 +329,5 @@ struct file_system_type coda_fs_type = {
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("coda");
 
index fe40fde291111b0f4d521756403dbc530be4da8a..5058345dc27975931f280b8660a78281793ea171 100644 (file)
@@ -558,6 +558,10 @@ ssize_t compat_rw_copy_check_uvector(int type,
        }
        *ret_pointer = iov;
 
+       ret = -EFAULT;
+       if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+               goto out;
+
        /*
         * Single unix specification:
         * We should -EINVAL if an element length is not >= 0 and fitting an
@@ -1065,195 +1069,6 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
 }
 #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */
 
-static ssize_t compat_do_readv_writev(int type, struct file *file,
-                              const struct compat_iovec __user *uvector,
-                              unsigned long nr_segs, loff_t *pos)
-{
-       compat_ssize_t tot_len;
-       struct iovec iovstack[UIO_FASTIOV];
-       struct iovec *iov = iovstack;
-       ssize_t ret;
-       io_fn_t fn;
-       iov_fn_t fnv;
-
-       ret = -EINVAL;
-       if (!file->f_op)
-               goto out;
-
-       ret = -EFAULT;
-       if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
-               goto out;
-
-       tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
-                                              UIO_FASTIOV, iovstack, &iov);
-       if (tot_len == 0) {
-               ret = 0;
-               goto out;
-       }
-
-       ret = rw_verify_area(type, file, pos, tot_len);
-       if (ret < 0)
-               goto out;
-
-       fnv = NULL;
-       if (type == READ) {
-               fn = file->f_op->read;
-               fnv = file->f_op->aio_read;
-       } else {
-               fn = (io_fn_t)file->f_op->write;
-               fnv = file->f_op->aio_write;
-       }
-
-       if (fnv)
-               ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
-                                               pos, fnv);
-       else
-               ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
-
-out:
-       if (iov != iovstack)
-               kfree(iov);
-       if ((ret + (type == READ)) > 0) {
-               if (type == READ)
-                       fsnotify_access(file);
-               else
-                       fsnotify_modify(file);
-       }
-       return ret;
-}
-
-static size_t compat_readv(struct file *file,
-                          const struct compat_iovec __user *vec,
-                          unsigned long vlen, loff_t *pos)
-{
-       ssize_t ret = -EBADF;
-
-       if (!(file->f_mode & FMODE_READ))
-               goto out;
-
-       ret = -EINVAL;
-       if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
-               goto out;
-
-       ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
-
-out:
-       if (ret > 0)
-               add_rchar(current, ret);
-       inc_syscr(current);
-       return ret;
-}
-
-asmlinkage ssize_t
-compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
-                unsigned long vlen)
-{
-       struct fd f = fdget(fd);
-       ssize_t ret;
-       loff_t pos;
-
-       if (!f.file)
-               return -EBADF;
-       pos = f.file->f_pos;
-       ret = compat_readv(f.file, vec, vlen, &pos);
-       f.file->f_pos = pos;
-       fdput(f);
-       return ret;
-}
-
-asmlinkage ssize_t
-compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
-                   unsigned long vlen, loff_t pos)
-{
-       struct fd f;
-       ssize_t ret;
-
-       if (pos < 0)
-               return -EINVAL;
-       f = fdget(fd);
-       if (!f.file)
-               return -EBADF;
-       ret = -ESPIPE;
-       if (f.file->f_mode & FMODE_PREAD)
-               ret = compat_readv(f.file, vec, vlen, &pos);
-       fdput(f);
-       return ret;
-}
-
-asmlinkage ssize_t
-compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
-                 unsigned long vlen, u32 pos_low, u32 pos_high)
-{
-       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
-       return compat_sys_preadv64(fd, vec, vlen, pos);
-}
-
-static size_t compat_writev(struct file *file,
-                           const struct compat_iovec __user *vec,
-                           unsigned long vlen, loff_t *pos)
-{
-       ssize_t ret = -EBADF;
-
-       if (!(file->f_mode & FMODE_WRITE))
-               goto out;
-
-       ret = -EINVAL;
-       if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
-               goto out;
-
-       ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
-
-out:
-       if (ret > 0)
-               add_wchar(current, ret);
-       inc_syscw(current);
-       return ret;
-}
-
-asmlinkage ssize_t
-compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
-                 unsigned long vlen)
-{
-       struct fd f = fdget(fd);
-       ssize_t ret;
-       loff_t pos;
-
-       if (!f.file)
-               return -EBADF;
-       pos = f.file->f_pos;
-       ret = compat_writev(f.file, vec, vlen, &pos);
-       f.file->f_pos = pos;
-       fdput(f);
-       return ret;
-}
-
-asmlinkage ssize_t
-compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
-                    unsigned long vlen, loff_t pos)
-{
-       struct fd f;
-       ssize_t ret;
-
-       if (pos < 0)
-               return -EINVAL;
-       f = fdget(fd);
-       if (!f.file)
-               return -EBADF;
-       ret = -ESPIPE;
-       if (f.file->f_mode & FMODE_PWRITE)
-               ret = compat_writev(f.file, vec, vlen, &pos);
-       fdput(f);
-       return ret;
-}
-
-asmlinkage ssize_t
-compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
-                  unsigned long vlen, u32 pos_low, u32 pos_high)
-{
-       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
-       return compat_sys_pwritev64(fd, vec, vlen, pos);
-}
-
 asmlinkage long
 compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
                    unsigned int nr_segs, unsigned int flags)
index aee0a7ebbd8ee2d410fe4e72e1c9faf3bb1e1616..7f26c3cf75ae67e2e25788276ba6c379df4f8d61 100644 (file)
@@ -114,6 +114,7 @@ static struct file_system_type configfs_fs_type = {
        .mount          = configfs_do_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("configfs");
 
 struct dentry *configfs_pin_fs(void)
 {
index c6479658d4875c0eac32db5c262f515468d3ec76..a987f3d39d93cbc1b0fe82d8cd08ad6bb2898226 100644 (file)
@@ -409,9 +409,7 @@ static void coredump_finish(struct mm_struct *mm)
 
 static void wait_for_dump_helpers(struct file *file)
 {
-       struct pipe_inode_info *pipe;
-
-       pipe = file_inode(file)->i_pipe;
+       struct pipe_inode_info *pipe = file->private_data;
 
        pipe_lock(pipe);
        pipe->readers++;
@@ -629,9 +627,11 @@ void do_coredump(siginfo_t *siginfo)
                goto close_fail;
        if (displaced)
                put_files_struct(displaced);
+       file_start_write(cprm.file);
        retval = binfmt->core_dump(&cprm);
        if (retval)
                current->signal->group_exit_code |= 0x80;
+       file_end_write(cprm.file);
 
        if (ispipe && core_pipe_limit)
                wait_for_dump_helpers(cprm.file);
index 3ceb9ec976e182202cb40b0632f6693086272d92..35b1c7bd18b758a30fc03fd4267151d18fcb2281 100644 (file)
@@ -573,6 +573,7 @@ static struct file_system_type cramfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("cramfs");
 
 static int __init init_cramfs_fs(void)
 {
index fbfae008ba44e3e8223f42d4823cfeae2a673ac9..e8bc3420d63edcc28f0992217c860082fe424261 100644 (file)
@@ -2542,7 +2542,6 @@ static int prepend_path(const struct path *path,
        bool slash = false;
        int error = 0;
 
-       br_read_lock(&vfsmount_lock);
        while (dentry != root->dentry || vfsmnt != root->mnt) {
                struct dentry * parent;
 
@@ -2572,8 +2571,6 @@ static int prepend_path(const struct path *path,
        if (!error && !slash)
                error = prepend(buffer, buflen, "/", 1);
 
-out:
-       br_read_unlock(&vfsmount_lock);
        return error;
 
 global_root:
@@ -2590,7 +2587,7 @@ global_root:
                error = prepend(buffer, buflen, "/", 1);
        if (!error)
                error = is_mounted(vfsmnt) ? 1 : 2;
-       goto out;
+       return error;
 }
 
 /**
@@ -2617,9 +2614,11 @@ char *__d_path(const struct path *path,
        int error;
 
        prepend(&res, &buflen, "\0", 1);
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        error = prepend_path(path, root, &res, &buflen);
        write_sequnlock(&rename_lock);
+       br_read_unlock(&vfsmount_lock);
 
        if (error < 0)
                return ERR_PTR(error);
@@ -2636,9 +2635,11 @@ char *d_absolute_path(const struct path *path,
        int error;
 
        prepend(&res, &buflen, "\0", 1);
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        error = prepend_path(path, &root, &res, &buflen);
        write_sequnlock(&rename_lock);
+       br_read_unlock(&vfsmount_lock);
 
        if (error > 1)
                error = -EINVAL;
@@ -2702,11 +2703,13 @@ char *d_path(const struct path *path, char *buf, int buflen)
                return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
        get_fs_root(current->fs, &root);
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        error = path_with_deleted(path, &root, &res, &buflen);
+       write_sequnlock(&rename_lock);
+       br_read_unlock(&vfsmount_lock);
        if (error < 0)
                res = ERR_PTR(error);
-       write_sequnlock(&rename_lock);
        path_put(&root);
        return res;
 }
@@ -2830,6 +2833,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
        get_fs_root_and_pwd(current->fs, &root, &pwd);
 
        error = -ENOENT;
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        if (!d_unlinked(pwd.dentry)) {
                unsigned long len;
@@ -2839,6 +2843,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
                prepend(&cwd, &buflen, "\0", 1);
                error = prepend_path(&pwd, &root, &cwd, &buflen);
                write_sequnlock(&rename_lock);
+               br_read_unlock(&vfsmount_lock);
 
                if (error < 0)
                        goto out;
@@ -2859,6 +2864,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
                }
        } else {
                write_sequnlock(&rename_lock);
+               br_read_unlock(&vfsmount_lock);
        }
 
 out:
index 0c4f80b447fb28d2dd7958613152542f03241e03..4888cb3fdef76037b7af5f9db898bdcb82ce48c2 100644 (file)
@@ -299,6 +299,7 @@ static struct file_system_type debug_fs_type = {
        .mount =        debug_mount,
        .kill_sb =      kill_litter_super,
 };
+MODULE_ALIAS_FS("debugfs");
 
 static struct dentry *__create_file(const char *name, umode_t mode,
                                    struct dentry *parent, void *data,
index e15ef38c24fa4b91ee0dfe5e62eece16200807b4..434aa313f077c2789bdef6e1cba0bf2725c37b7b 100644 (file)
@@ -12,3 +12,11 @@ config ECRYPT_FS
 
          To compile this file system support as a module, choose M here: the
          module will be called ecryptfs.
+
+config ECRYPT_FS_MESSAGING
+       bool "Enable notifications for userspace key wrap/unwrap"
+       depends on ECRYPT_FS
+       help
+         Enables the /dev/ecryptfs entry for use by ecryptfsd. This allows
+         for userspace to wrap/unwrap file encryption keys by other
+         backends, like OpenSSL.
index 2cc9ee4ad2eb774f144e1d706276c7d037c6bb7d..49678a69947dac7ce580941799cba91d51a5cdae 100644 (file)
@@ -1,7 +1,10 @@
 #
-# Makefile for the Linux 2.6 eCryptfs
+# Makefile for the Linux eCryptfs
 #
 
 obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
 
-ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o miscdev.o kthread.o debug.o
+ecryptfs-y := dentry.o file.o inode.o main.o super.o mmap.o read_write.o \
+             crypto.o keystore.o kthread.o debug.o
+
+ecryptfs-$(CONFIG_ECRYPT_FS_MESSAGING) += messaging.o miscdev.o
index a7b0c2dfb3db76066703076ab43f4d589637523d..d5c25db4398f0244f0f1d0c1f1e20a55f8f51aa9 100644 (file)
@@ -301,17 +301,14 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
        while (size > 0 && i < sg_size) {
                pg = virt_to_page(addr);
                offset = offset_in_page(addr);
-               if (sg)
-                       sg_set_page(&sg[i], pg, 0, offset);
+               sg_set_page(&sg[i], pg, 0, offset);
                remainder_of_page = PAGE_CACHE_SIZE - offset;
                if (size >= remainder_of_page) {
-                       if (sg)
-                               sg[i].length = remainder_of_page;
+                       sg[i].length = remainder_of_page;
                        addr += remainder_of_page;
                        size -= remainder_of_page;
                } else {
-                       if (sg)
-                               sg[i].length = size;
+                       sg[i].length = size;
                        addr += size;
                        size = 0;
                }
index 1b5d9af937dfc4a33015eaa154a8956857381749..bf12ba5dd223befe93ce786c3a3848cdf5e38fcd 100644 (file)
 static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct dentry *lower_dentry;
-       struct vfsmount *lower_mnt;
        int rc = 1;
 
        if (flags & LOOKUP_RCU)
                return -ECHILD;
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
        if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
                goto out;
        rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
index 7e2c6f5d7985ffc3fae9482a6eb952b58621e278..dd299b389d4e4fc36b7694dbf6acac0dcf9742f7 100644 (file)
@@ -172,6 +172,19 @@ ecryptfs_get_key_payload_data(struct key *key)
 #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE 24
 #define ECRYPTFS_ENCRYPTED_DENTRY_NAME_LEN (18 + 1 + 4 + 1 + 32)
 
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
+# define ECRYPTFS_VERSIONING_MASK_MESSAGING (ECRYPTFS_VERSIONING_DEVMISC \
+                                            | ECRYPTFS_VERSIONING_PUBKEY)
+#else
+# define ECRYPTFS_VERSIONING_MASK_MESSAGING 0
+#endif
+
+#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
+                                 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
+                                 | ECRYPTFS_VERSIONING_XATTR \
+                                 | ECRYPTFS_VERSIONING_MULTKEY \
+                                 | ECRYPTFS_VERSIONING_MASK_MESSAGING \
+                                 | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION)
 struct ecryptfs_key_sig {
        struct list_head crypt_stat_list;
        char keysig[ECRYPTFS_SIG_SIZE_HEX + 1];
@@ -399,7 +412,9 @@ struct ecryptfs_daemon {
        struct hlist_node euid_chain;
 };
 
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
 extern struct mutex ecryptfs_daemon_hash_mux;
+#endif
 
 static inline size_t
 ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
@@ -610,6 +625,7 @@ int
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
                  size_t size, int flags);
 int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
 int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
                              struct ecryptfs_message *msg, u32 seq);
 int ecryptfs_send_message(char *data, int data_len,
@@ -618,6 +634,24 @@ int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
                               struct ecryptfs_message **emsg);
 int ecryptfs_init_messaging(void);
 void ecryptfs_release_messaging(void);
+#else
+static inline int ecryptfs_init_messaging(void)
+{
+       return 0;
+}
+static inline void ecryptfs_release_messaging(void)
+{ }
+static inline int ecryptfs_send_message(char *data, int data_len,
+                                       struct ecryptfs_msg_ctx **msg_ctx)
+{
+       return -ENOTCONN;
+}
+static inline int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
+                                            struct ecryptfs_message **emsg)
+{
+       return -ENOMSG;
+}
+#endif
 
 void
 ecryptfs_write_header_metadata(char *virt,
@@ -655,12 +689,11 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
                                     size_t offset_in_page, size_t size,
                                     struct inode *ecryptfs_inode);
 struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index);
-int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon);
-int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon);
 int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
                                 size_t *length_size);
 int ecryptfs_write_packet_length(char *dest, size_t size,
                                 size_t *packet_size_length);
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
 int ecryptfs_init_ecryptfs_miscdev(void);
 void ecryptfs_destroy_ecryptfs_miscdev(void);
 int ecryptfs_send_miscdev(char *data, size_t data_size,
@@ -669,6 +702,9 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
 void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx);
 int
 ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file);
+int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon);
+int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon);
+#endif
 int ecryptfs_init_kthread(void);
 void ecryptfs_destroy_kthread(void);
 int ecryptfs_privileged_open(struct file **lower_file,
index 53acc9d0c1384ff8030a17e922a7e6fb45dcf081..63b1f54b6a1ff01862f381ae678afa3d46e4c15e 100644 (file)
@@ -199,7 +199,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
        struct dentry *ecryptfs_dentry = file->f_path.dentry;
        /* Private value of ecryptfs_dentry allocated in
         * ecryptfs_lookup() */
-       struct dentry *lower_dentry;
        struct ecryptfs_file_info *file_info;
 
        mount_crypt_stat = &ecryptfs_superblock_to_private(
@@ -222,7 +221,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
                rc = -ENOMEM;
                goto out;
        }
-       lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
        crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
        mutex_lock(&crypt_stat->cs_mutex);
        if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
index e0f07fb6d56b65fbca944e52512d3d5239d600bb..5eab400e25903b71641d4a056254c79f3a776885 100644 (file)
@@ -999,8 +999,8 @@ out:
        return rc;
 }
 
-int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
-                         struct kstat *stat)
+static int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+                                struct kstat *stat)
 {
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
        int rc = 0;
@@ -1021,8 +1021,8 @@ int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
        return rc;
 }
 
-int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                    struct kstat *stat)
+static int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                           struct kstat *stat)
 {
        struct kstat lower_stat;
        int rc;
index 2333203a120b3b853f71ef011a0755a3be04fd6a..7d52806c21197206a5932b08a68e7dc9d6899253 100644 (file)
@@ -1150,7 +1150,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
        struct ecryptfs_message *msg = NULL;
        char *auth_tok_sig;
        char *payload;
-       size_t payload_len;
+       size_t payload_len = 0;
        int rc;
 
        rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
@@ -1168,7 +1168,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
        rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error sending message to "
-                               "ecryptfsd\n");
+                               "ecryptfsd: %d\n", rc);
                goto out;
        }
        rc = ecryptfs_wait_for_response(msg_ctx, &msg);
@@ -1202,8 +1202,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
                                  crypt_stat->key_size);
        }
 out:
-       if (msg)
-               kfree(msg);
+       kfree(msg);
        return rc;
 }
 
@@ -1989,7 +1988,7 @@ pki_encrypt_session_key(struct key *auth_tok_key,
        rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error sending message to "
-                               "ecryptfsd\n");
+                               "ecryptfsd: %d\n", rc);
                goto out;
        }
        rc = ecryptfs_wait_for_response(msg_ctx, &msg);
index 4e0886c9e5c476059346f5a0d520257418ce03ba..e924cf45aad9559533214814cccbb05aa7a06b44 100644 (file)
@@ -629,6 +629,7 @@ static struct file_system_type ecryptfs_fs_type = {
        .kill_sb = ecryptfs_kill_block_super,
        .fs_flags = 0
 };
+MODULE_ALIAS_FS("ecryptfs");
 
 /**
  * inode_info_init_once
index 8d7a577ae49782f8398a21315301ea254f68fc71..49ff8ea08f1ca88252d82a34c98d77d0c490ff86 100644 (file)
@@ -97,8 +97,7 @@ static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx)
 void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx)
 {
        list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list);
-       if (msg_ctx->msg)
-               kfree(msg_ctx->msg);
+       kfree(msg_ctx->msg);
        msg_ctx->msg = NULL;
        msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE;
 }
@@ -283,7 +282,7 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
        int rc;
 
        rc = ecryptfs_find_daemon_by_euid(&daemon);
-       if (rc || !daemon) {
+       if (rc) {
                rc = -ENOTCONN;
                goto out;
        }
index 412e6eda25f813e037f3d18936e7ed860793a443..e4141f2574953893377939f2362a673a62a609b9 100644 (file)
@@ -80,13 +80,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
        int rc;
 
        mutex_lock(&ecryptfs_daemon_hash_mux);
-       rc = try_module_get(THIS_MODULE);
-       if (rc == 0) {
-               rc = -EIO;
-               printk(KERN_ERR "%s: Error attempting to increment module use "
-                      "count; rc = [%d]\n", __func__, rc);
-               goto out_unlock_daemon_list;
-       }
        rc = ecryptfs_find_daemon_by_euid(&daemon);
        if (!rc) {
                rc = -EINVAL;
@@ -96,7 +89,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
        if (rc) {
                printk(KERN_ERR "%s: Error attempting to spawn daemon; "
                       "rc = [%d]\n", __func__, rc);
-               goto out_module_put_unlock_daemon_list;
+               goto out_unlock_daemon_list;
        }
        mutex_lock(&daemon->mux);
        if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) {
@@ -108,9 +101,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
        atomic_inc(&ecryptfs_num_miscdev_opens);
 out_unlock_daemon:
        mutex_unlock(&daemon->mux);
-out_module_put_unlock_daemon_list:
-       if (rc)
-               module_put(THIS_MODULE);
 out_unlock_daemon_list:
        mutex_unlock(&ecryptfs_daemon_hash_mux);
        return rc;
@@ -147,7 +137,6 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file)
                       "bug.\n", __func__, rc);
                BUG();
        }
-       module_put(THIS_MODULE);
        return rc;
 }
 
@@ -471,6 +460,7 @@ out_free:
 
 
 static const struct file_operations ecryptfs_miscdev_fops = {
+       .owner   = THIS_MODULE,
        .open    = ecryptfs_miscdev_open,
        .poll    = ecryptfs_miscdev_poll,
        .read    = ecryptfs_miscdev_read,
index 2002431ef9a0ff238d838b9d4c2f8bb9760007fa..c6f57a74a559da265bc8f062eab06488d8d7c00a 100644 (file)
@@ -33,6 +33,7 @@ static struct file_system_type efs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("efs");
 
 static struct pt_types sgi_pt_types[] = {
        {0x00,          "SGI vh"},
index a96a4885bbbfa130750caa70b9b3f504ea10b244..77dc9096440fbd8ec7aefe695bcb0d763431e51e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -802,6 +802,15 @@ int kernel_read(struct file *file, loff_t offset,
 
 EXPORT_SYMBOL(kernel_read);
 
+ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
+{
+       ssize_t res = file->f_op->read(file, (void __user *)addr, len, &pos);
+       if (res > 0)
+               flush_icache_range(addr, addr + len);
+       return res;
+}
+EXPORT_SYMBOL(read_code);
+
 static int exec_mmap(struct mm_struct *mm)
 {
        struct task_struct *tsk;
index 5e59280d42d779fb13fe9171d22d24ea4fc81095..9d9763328734e63e27ce6ef6f364518cb7f602c0 100644 (file)
@@ -1010,6 +1010,7 @@ static struct file_system_type exofs_type = {
        .mount          = exofs_mount,
        .kill_sb        = generic_shutdown_super,
 };
+MODULE_ALIAS_FS("exofs");
 
 static int __init init_exofs(void)
 {
index 8f370e012e613e73016856a9cab3c6257666a1a1..7cadd823bb311643a6cb7042222870767224b4c9 100644 (file)
@@ -118,7 +118,6 @@ void ext2_free_inode (struct inode * inode)
         * as writing the quota to disk may need the lock as well.
         */
        /* Quota is already initialized in iput() */
-       ext2_xattr_delete_inode(inode);
        dquot_free_inode(inode);
        dquot_drop(inode);
 
index c3881e56662efac8c80ec409c5808771303ed24f..fe60cc1117d834a1fbdc086b9aad01367518903b 100644 (file)
@@ -34,6 +34,7 @@
 #include "ext2.h"
 #include "acl.h"
 #include "xip.h"
+#include "xattr.h"
 
 static int __ext2_write_inode(struct inode *inode, int do_sync);
 
@@ -88,6 +89,7 @@ void ext2_evict_inode(struct inode * inode)
                inode->i_size = 0;
                if (inode->i_blocks)
                        ext2_truncate_blocks(inode, 0);
+               ext2_xattr_delete_inode(inode);
        }
 
        invalidate_inode_buffers(inode);
index 7f68c8114026a7521ca1808775a89cc1e3765542..288534920fe5cc4960f99ae636777344c5d42db6 100644 (file)
@@ -1536,6 +1536,7 @@ static struct file_system_type ext2_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext2");
 
 static int __init init_ext2_fs(void)
 {
index 5546ca225ffe19ee3e53d75ee4e18936fa47cc83..fb5120a5505c055b9de9e7b948713256329cf690 100644 (file)
@@ -353,7 +353,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
        return bdev;
 
 fail:
-       ext3_msg(sb, "error: failed to open journal device %s: %ld",
+       ext3_msg(sb, KERN_ERR, "error: failed to open journal device %s: %ld",
                __bdevname(dev, b), PTR_ERR(bdev));
 
        return NULL;
@@ -887,7 +887,7 @@ static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb)
        /*todo: use simple_strtoll with >32bit ext3 */
        sb_block = simple_strtoul(options, &options, 0);
        if (*options && *options != ',') {
-               ext3_msg(sb, "error: invalid sb specification: %s",
+               ext3_msg(sb, KERN_ERR, "error: invalid sb specification: %s",
                       (char *) *data);
                return 1;
        }
@@ -3068,6 +3068,7 @@ static struct file_system_type ext3_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext3");
 
 static int __init init_ext3_fs(void)
 {
index 4a01ba315262259241081ec695c1f1d3d179eb32..3b83cd6047964ab7218aeb26ab73bce7be472430 100644 (file)
@@ -335,9 +335,9 @@ struct ext4_group_desc
  */
 
 struct flex_groups {
-       atomic_t free_inodes;
-       atomic_t free_clusters;
-       atomic_t used_dirs;
+       atomic64_t      free_clusters;
+       atomic_t        free_inodes;
+       atomic_t        used_dirs;
 };
 
 #define EXT4_BG_INODE_UNINIT   0x0001 /* Inode table/bitmap not in use */
@@ -2617,7 +2617,7 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
 extern int __init ext4_init_pageio(void);
 extern void ext4_add_complete_io(ext4_io_end_t *io_end);
 extern void ext4_exit_pageio(void);
-extern void ext4_ioend_wait(struct inode *);
+extern void ext4_ioend_shutdown(struct inode *);
 extern void ext4_free_io_end(ext4_io_end_t *io);
 extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
 extern void ext4_end_io_work(struct work_struct *work);
index 28dd8eeea6a93f2ce5ae727777ede13582e2038f..56efcaadf8485a5887ae04493b9cacf28b5c73ef 100644 (file)
@@ -1584,10 +1584,12 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
        unsigned short ext1_ee_len, ext2_ee_len, max_len;
 
        /*
-        * Make sure that either both extents are uninitialized, or
-        * both are _not_.
+        * Make sure that both extents are initialized. We don't merge
+        * uninitialized extents so that we can be sure that end_io code has
+        * the extent that was written properly split out and conversion to
+        * initialized is trivial.
         */
-       if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2))
+       if (ext4_ext_is_uninitialized(ex1) || ext4_ext_is_uninitialized(ex2))
                return 0;
 
        if (ext4_ext_is_uninitialized(ex1))
@@ -2923,7 +2925,7 @@ static int ext4_split_extent_at(handle_t *handle,
 {
        ext4_fsblk_t newblock;
        ext4_lblk_t ee_block;
-       struct ext4_extent *ex, newex, orig_ex;
+       struct ext4_extent *ex, newex, orig_ex, zero_ex;
        struct ext4_extent *ex2 = NULL;
        unsigned int ee_len, depth;
        int err = 0;
@@ -2943,6 +2945,10 @@ static int ext4_split_extent_at(handle_t *handle,
        newblock = split - ee_block + ext4_ext_pblock(ex);
 
        BUG_ON(split < ee_block || split >= (ee_block + ee_len));
+       BUG_ON(!ext4_ext_is_uninitialized(ex) &&
+              split_flag & (EXT4_EXT_MAY_ZEROOUT |
+                            EXT4_EXT_MARK_UNINIT1 |
+                            EXT4_EXT_MARK_UNINIT2));
 
        err = ext4_ext_get_access(handle, inode, path + depth);
        if (err)
@@ -2990,12 +2996,26 @@ static int ext4_split_extent_at(handle_t *handle,
        err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
        if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
                if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
-                       if (split_flag & EXT4_EXT_DATA_VALID1)
+                       if (split_flag & EXT4_EXT_DATA_VALID1) {
                                err = ext4_ext_zeroout(inode, ex2);
-                       else
+                               zero_ex.ee_block = ex2->ee_block;
+                               zero_ex.ee_len = ext4_ext_get_actual_len(ex2);
+                               ext4_ext_store_pblock(&zero_ex,
+                                                     ext4_ext_pblock(ex2));
+                       } else {
                                err = ext4_ext_zeroout(inode, ex);
-               } else
+                               zero_ex.ee_block = ex->ee_block;
+                               zero_ex.ee_len = ext4_ext_get_actual_len(ex);
+                               ext4_ext_store_pblock(&zero_ex,
+                                                     ext4_ext_pblock(ex));
+                       }
+               } else {
                        err = ext4_ext_zeroout(inode, &orig_ex);
+                       zero_ex.ee_block = orig_ex.ee_block;
+                       zero_ex.ee_len = ext4_ext_get_actual_len(&orig_ex);
+                       ext4_ext_store_pblock(&zero_ex,
+                                             ext4_ext_pblock(&orig_ex));
+               }
 
                if (err)
                        goto fix_extent_len;
@@ -3003,6 +3023,12 @@ static int ext4_split_extent_at(handle_t *handle,
                ex->ee_len = cpu_to_le16(ee_len);
                ext4_ext_try_to_merge(handle, inode, path, ex);
                err = ext4_ext_dirty(handle, inode, path + path->p_depth);
+               if (err)
+                       goto fix_extent_len;
+
+               /* update extent status tree */
+               err = ext4_es_zeroout(inode, &zero_ex);
+
                goto out;
        } else if (err)
                goto fix_extent_len;
@@ -3041,6 +3067,7 @@ static int ext4_split_extent(handle_t *handle,
        int err = 0;
        int uninitialized;
        int split_flag1, flags1;
+       int allocated = map->m_len;
 
        depth = ext_depth(inode);
        ex = path[depth].p_ext;
@@ -3060,20 +3087,29 @@ static int ext4_split_extent(handle_t *handle,
                                map->m_lblk + map->m_len, split_flag1, flags1);
                if (err)
                        goto out;
+       } else {
+               allocated = ee_len - (map->m_lblk - ee_block);
        }
-
+       /*
+        * Update path is required because previous ext4_split_extent_at() may
+        * result in split of original leaf or extent zeroout.
+        */
        ext4_ext_drop_refs(path);
        path = ext4_ext_find_extent(inode, map->m_lblk, path);
        if (IS_ERR(path))
                return PTR_ERR(path);
+       depth = ext_depth(inode);
+       ex = path[depth].p_ext;
+       uninitialized = ext4_ext_is_uninitialized(ex);
+       split_flag1 = 0;
 
        if (map->m_lblk >= ee_block) {
-               split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT |
-                                           EXT4_EXT_DATA_VALID2);
-               if (uninitialized)
+               split_flag1 = split_flag & EXT4_EXT_DATA_VALID2;
+               if (uninitialized) {
                        split_flag1 |= EXT4_EXT_MARK_UNINIT1;
-               if (split_flag & EXT4_EXT_MARK_UNINIT2)
-                       split_flag1 |= EXT4_EXT_MARK_UNINIT2;
+                       split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT |
+                                                    EXT4_EXT_MARK_UNINIT2);
+               }
                err = ext4_split_extent_at(handle, inode, path,
                                map->m_lblk, split_flag1, flags);
                if (err)
@@ -3082,7 +3118,7 @@ static int ext4_split_extent(handle_t *handle,
 
        ext4_ext_show_leaf(inode, path);
 out:
-       return err ? err : map->m_len;
+       return err ? err : allocated;
 }
 
 /*
@@ -3137,6 +3173,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
        ee_block = le32_to_cpu(ex->ee_block);
        ee_len = ext4_ext_get_actual_len(ex);
        allocated = ee_len - (map->m_lblk - ee_block);
+       zero_ex.ee_len = 0;
 
        trace_ext4_ext_convert_to_initialized_enter(inode, map, ex);
 
@@ -3227,13 +3264,16 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
 
        if (EXT4_EXT_MAY_ZEROOUT & split_flag)
                max_zeroout = sbi->s_extent_max_zeroout_kb >>
-                       inode->i_sb->s_blocksize_bits;
+                       (inode->i_sb->s_blocksize_bits - 10);
 
        /* If extent is less than s_max_zeroout_kb, zeroout directly */
        if (max_zeroout && (ee_len <= max_zeroout)) {
                err = ext4_ext_zeroout(inode, ex);
                if (err)
                        goto out;
+               zero_ex.ee_block = ex->ee_block;
+               zero_ex.ee_len = ext4_ext_get_actual_len(ex);
+               ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex));
 
                err = ext4_ext_get_access(handle, inode, path + depth);
                if (err)
@@ -3292,6 +3332,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                err = allocated;
 
 out:
+       /* If we have gotten a failure, don't zero out status tree */
+       if (!err)
+               err = ext4_es_zeroout(inode, &zero_ex);
        return err ? err : allocated;
 }
 
@@ -3374,8 +3417,19 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
                "block %llu, max_blocks %u\n", inode->i_ino,
                  (unsigned long long)ee_block, ee_len);
 
-       /* If extent is larger than requested then split is required */
+       /* If extent is larger than requested it is a clear sign that we still
+        * have some extent state machine issues left. So extent_split is still
+        * required.
+        * TODO: Once all related issues will be fixed this situation should be
+        * illegal.
+        */
        if (ee_block != map->m_lblk || ee_len > map->m_len) {
+#ifdef EXT4_DEBUG
+               ext4_warning("Inode (%ld) finished: extent logical block %llu,"
+                            " len %u; IO logical block %llu, len %u\n",
+                            inode->i_ino, (unsigned long long)ee_block, ee_len,
+                            (unsigned long long)map->m_lblk, map->m_len);
+#endif
                err = ext4_split_unwritten_extents(handle, inode, map, path,
                                                   EXT4_GET_BLOCKS_CONVERT);
                if (err < 0)
@@ -3626,6 +3680,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
                                                 path, map->m_len);
                } else
                        err = ret;
+               map->m_flags |= EXT4_MAP_MAPPED;
+               if (allocated > map->m_len)
+                       allocated = map->m_len;
+               map->m_len = allocated;
                goto out2;
        }
        /* buffered IO case */
@@ -3675,6 +3733,7 @@ out:
                                        allocated - map->m_len);
                allocated = map->m_len;
        }
+       map->m_len = allocated;
 
        /*
         * If we have done fallocate with the offset that is already
@@ -4106,9 +4165,6 @@ got_allocated_blocks:
                        }
                } else {
                        BUG_ON(allocated_clusters < reserved_clusters);
-                       /* We will claim quota for all newly allocated blocks.*/
-                       ext4_da_update_reserve_space(inode, allocated_clusters,
-                                                       1);
                        if (reserved_clusters < allocated_clusters) {
                                struct ext4_inode_info *ei = EXT4_I(inode);
                                int reservation = allocated_clusters -
@@ -4159,6 +4215,15 @@ got_allocated_blocks:
                                ei->i_reserved_data_blocks += reservation;
                                spin_unlock(&ei->i_block_reservation_lock);
                        }
+                       /*
+                        * We will claim quota for all newly allocated blocks.
+                        * We're updating the reserved space *after* the
+                        * correction above so we do not accidentally free
+                        * all the metadata reservation because we might
+                        * actually need it later on.
+                        */
+                       ext4_da_update_reserve_space(inode, allocated_clusters,
+                                                       1);
                }
        }
 
@@ -4368,8 +4433,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        if (len <= EXT_UNINIT_MAX_LEN << blkbits)
                flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
 
-       /* Prevent race condition between unwritten */
-       ext4_flush_unwritten_io(inode);
 retry:
        while (ret >= 0 && ret < max_blocks) {
                map.m_lblk = map.m_lblk + ret;
index 95796a1b7522b7e02dd72dfab15fbf2cebdb6b13..fe3337a85edeaecd6135333759173d8c6fbc0e78 100644 (file)
@@ -333,17 +333,27 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es)
 static int ext4_es_can_be_merged(struct extent_status *es1,
                                 struct extent_status *es2)
 {
-       if (es1->es_lblk + es1->es_len != es2->es_lblk)
+       if (ext4_es_status(es1) != ext4_es_status(es2))
                return 0;
 
-       if (ext4_es_status(es1) != ext4_es_status(es2))
+       if (((__u64) es1->es_len) + es2->es_len > 0xFFFFFFFFULL)
                return 0;
 
-       if ((ext4_es_is_written(es1) || ext4_es_is_unwritten(es1)) &&
-           (ext4_es_pblock(es1) + es1->es_len != ext4_es_pblock(es2)))
+       if (((__u64) es1->es_lblk) + es1->es_len != es2->es_lblk)
                return 0;
 
-       return 1;
+       if ((ext4_es_is_written(es1) || ext4_es_is_unwritten(es1)) &&
+           (ext4_es_pblock(es1) + es1->es_len == ext4_es_pblock(es2)))
+               return 1;
+
+       if (ext4_es_is_hole(es1))
+               return 1;
+
+       /* we need to check delayed extent is without unwritten status */
+       if (ext4_es_is_delayed(es1) && !ext4_es_is_unwritten(es1))
+               return 1;
+
+       return 0;
 }
 
 static struct extent_status *
@@ -389,6 +399,179 @@ ext4_es_try_to_merge_right(struct inode *inode, struct extent_status *es)
        return es;
 }
 
+#ifdef ES_AGGRESSIVE_TEST
+static void ext4_es_insert_extent_ext_check(struct inode *inode,
+                                           struct extent_status *es)
+{
+       struct ext4_ext_path *path = NULL;
+       struct ext4_extent *ex;
+       ext4_lblk_t ee_block;
+       ext4_fsblk_t ee_start;
+       unsigned short ee_len;
+       int depth, ee_status, es_status;
+
+       path = ext4_ext_find_extent(inode, es->es_lblk, NULL);
+       if (IS_ERR(path))
+               return;
+
+       depth = ext_depth(inode);
+       ex = path[depth].p_ext;
+
+       if (ex) {
+
+               ee_block = le32_to_cpu(ex->ee_block);
+               ee_start = ext4_ext_pblock(ex);
+               ee_len = ext4_ext_get_actual_len(ex);
+
+               ee_status = ext4_ext_is_uninitialized(ex) ? 1 : 0;
+               es_status = ext4_es_is_unwritten(es) ? 1 : 0;
+
+               /*
+                * Make sure ex and es are not overlap when we try to insert
+                * a delayed/hole extent.
+                */
+               if (!ext4_es_is_written(es) && !ext4_es_is_unwritten(es)) {
+                       if (in_range(es->es_lblk, ee_block, ee_len)) {
+                               pr_warn("ES insert assertation failed for "
+                                       "inode: %lu we can find an extent "
+                                       "at block [%d/%d/%llu/%c], but we "
+                                       "want to add an delayed/hole extent "
+                                       "[%d/%d/%llu/%llx]\n",
+                                       inode->i_ino, ee_block, ee_len,
+                                       ee_start, ee_status ? 'u' : 'w',
+                                       es->es_lblk, es->es_len,
+                                       ext4_es_pblock(es), ext4_es_status(es));
+                       }
+                       goto out;
+               }
+
+               /*
+                * We don't check ee_block == es->es_lblk, etc. because es
+                * might be a part of whole extent, vice versa.
+                */
+               if (es->es_lblk < ee_block ||
+                   ext4_es_pblock(es) != ee_start + es->es_lblk - ee_block) {
+                       pr_warn("ES insert assertation failed for inode: %lu "
+                               "ex_status [%d/%d/%llu/%c] != "
+                               "es_status [%d/%d/%llu/%c]\n", inode->i_ino,
+                               ee_block, ee_len, ee_start,
+                               ee_status ? 'u' : 'w', es->es_lblk, es->es_len,
+                               ext4_es_pblock(es), es_status ? 'u' : 'w');
+                       goto out;
+               }
+
+               if (ee_status ^ es_status) {
+                       pr_warn("ES insert assertation failed for inode: %lu "
+                               "ex_status [%d/%d/%llu/%c] != "
+                               "es_status [%d/%d/%llu/%c]\n", inode->i_ino,
+                               ee_block, ee_len, ee_start,
+                               ee_status ? 'u' : 'w', es->es_lblk, es->es_len,
+                               ext4_es_pblock(es), es_status ? 'u' : 'w');
+               }
+       } else {
+               /*
+                * We can't find an extent on disk.  So we need to make sure
+                * that we don't want to add an written/unwritten extent.
+                */
+               if (!ext4_es_is_delayed(es) && !ext4_es_is_hole(es)) {
+                       pr_warn("ES insert assertation failed for inode: %lu "
+                               "can't find an extent at block %d but we want "
+                               "to add an written/unwritten extent "
+                               "[%d/%d/%llu/%llx]\n", inode->i_ino,
+                               es->es_lblk, es->es_lblk, es->es_len,
+                               ext4_es_pblock(es), ext4_es_status(es));
+               }
+       }
+out:
+       if (path) {
+               ext4_ext_drop_refs(path);
+               kfree(path);
+       }
+}
+
+static void ext4_es_insert_extent_ind_check(struct inode *inode,
+                                           struct extent_status *es)
+{
+       struct ext4_map_blocks map;
+       int retval;
+
+       /*
+        * Here we call ext4_ind_map_blocks to lookup a block mapping because
+        * 'Indirect' structure is defined in indirect.c.  So we couldn't
+        * access direct/indirect tree from outside.  It is too dirty to define
+        * this function in indirect.c file.
+        */
+
+       map.m_lblk = es->es_lblk;
+       map.m_len = es->es_len;
+
+       retval = ext4_ind_map_blocks(NULL, inode, &map, 0);
+       if (retval > 0) {
+               if (ext4_es_is_delayed(es) || ext4_es_is_hole(es)) {
+                       /*
+                        * We want to add a delayed/hole extent but this
+                        * block has been allocated.
+                        */
+                       pr_warn("ES insert assertation failed for inode: %lu "
+                               "We can find blocks but we want to add a "
+                               "delayed/hole extent [%d/%d/%llu/%llx]\n",
+                               inode->i_ino, es->es_lblk, es->es_len,
+                               ext4_es_pblock(es), ext4_es_status(es));
+                       return;
+               } else if (ext4_es_is_written(es)) {
+                       if (retval != es->es_len) {
+                               pr_warn("ES insert assertation failed for "
+                                       "inode: %lu retval %d != es_len %d\n",
+                                       inode->i_ino, retval, es->es_len);
+                               return;
+                       }
+                       if (map.m_pblk != ext4_es_pblock(es)) {
+                               pr_warn("ES insert assertation failed for "
+                                       "inode: %lu m_pblk %llu != "
+                                       "es_pblk %llu\n",
+                                       inode->i_ino, map.m_pblk,
+                                       ext4_es_pblock(es));
+                               return;
+                       }
+               } else {
+                       /*
+                        * We don't need to check unwritten extent because
+                        * indirect-based file doesn't have it.
+                        */
+                       BUG_ON(1);
+               }
+       } else if (retval == 0) {
+               if (ext4_es_is_written(es)) {
+                       pr_warn("ES insert assertation failed for inode: %lu "
+                               "We can't find the block but we want to add "
+                               "an written extent [%d/%d/%llu/%llx]\n",
+                               inode->i_ino, es->es_lblk, es->es_len,
+                               ext4_es_pblock(es), ext4_es_status(es));
+                       return;
+               }
+       }
+}
+
+static inline void ext4_es_insert_extent_check(struct inode *inode,
+                                              struct extent_status *es)
+{
+       /*
+        * We don't need to worry about the race condition because
+        * caller takes i_data_sem locking.
+        */
+       BUG_ON(!rwsem_is_locked(&EXT4_I(inode)->i_data_sem));
+       if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
+               ext4_es_insert_extent_ext_check(inode, es);
+       else
+               ext4_es_insert_extent_ind_check(inode, es);
+}
+#else
+static inline void ext4_es_insert_extent_check(struct inode *inode,
+                                              struct extent_status *es)
+{
+}
+#endif
+
 static int __es_insert_extent(struct inode *inode, struct extent_status *newes)
 {
        struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree;
@@ -471,6 +654,8 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
        ext4_es_store_status(&newes, status);
        trace_ext4_es_insert_extent(inode, &newes);
 
+       ext4_es_insert_extent_check(inode, &newes);
+
        write_lock(&EXT4_I(inode)->i_es_lock);
        err = __es_remove_extent(inode, lblk, end);
        if (err != 0)
@@ -669,6 +854,23 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
        return err;
 }
 
+int ext4_es_zeroout(struct inode *inode, struct ext4_extent *ex)
+{
+       ext4_lblk_t  ee_block;
+       ext4_fsblk_t ee_pblock;
+       unsigned int ee_len;
+
+       ee_block  = le32_to_cpu(ex->ee_block);
+       ee_len    = ext4_ext_get_actual_len(ex);
+       ee_pblock = ext4_ext_pblock(ex);
+
+       if (ee_len == 0)
+               return 0;
+
+       return ext4_es_insert_extent(inode, ee_block, ee_len, ee_pblock,
+                                    EXTENT_STATUS_WRITTEN);
+}
+
 static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
 {
        struct ext4_sb_info *sbi = container_of(shrink,
index f190dfe969dacc59e34d15f03e2a7c5e3c5ef5e2..d8e2d4dc311e62c99843fa16c7fc8d4a0798bddb 100644 (file)
 #define es_debug(fmt, ...)     no_printk(fmt, ##__VA_ARGS__)
 #endif
 
+/*
+ * With ES_AGGRESSIVE_TEST defined, the result of es caching will be
+ * checked with old map_block's result.
+ */
+#define ES_AGGRESSIVE_TEST__
+
 /*
  * These flags live in the high bits of extent_status.es_pblk
  */
@@ -33,6 +39,8 @@
                                 EXTENT_STATUS_DELAYED | \
                                 EXTENT_STATUS_HOLE)
 
+struct ext4_extent;
+
 struct extent_status {
        struct rb_node rb_node;
        ext4_lblk_t es_lblk;    /* first logical block extent covers */
@@ -58,6 +66,7 @@ extern void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
                                        struct extent_status *es);
 extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
                                 struct extent_status *es);
+extern int ext4_es_zeroout(struct inode *inode, struct ext4_extent *ex);
 
 static inline int ext4_es_is_written(struct extent_status *es)
 {
index 32fd2b9075dd4029925d11adb0b84df1a399a8b1..6c5bb8d993fe8ebb07ae48dab2697e247c78ea01 100644 (file)
@@ -324,8 +324,8 @@ error_return:
 }
 
 struct orlov_stats {
+       __u64 free_clusters;
        __u32 free_inodes;
-       __u32 free_clusters;
        __u32 used_dirs;
 };
 
@@ -342,7 +342,7 @@ static void get_orlov_stats(struct super_block *sb, ext4_group_t g,
 
        if (flex_size > 1) {
                stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
-               stats->free_clusters = atomic_read(&flex_group[g].free_clusters);
+               stats->free_clusters = atomic64_read(&flex_group[g].free_clusters);
                stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
                return;
        }
index 9ea0cde3fa9e0ffe7aebc28940293c422ae75a63..b3a5213bc73eac2082cbfa16bad66bba89c32ed4 100644 (file)
@@ -185,8 +185,6 @@ void ext4_evict_inode(struct inode *inode)
 
        trace_ext4_evict_inode(inode);
 
-       ext4_ioend_wait(inode);
-
        if (inode->i_nlink) {
                /*
                 * When journalling data dirty buffers are tracked only in the
@@ -207,7 +205,8 @@ void ext4_evict_inode(struct inode *inode)
                 * don't use page cache.
                 */
                if (ext4_should_journal_data(inode) &&
-                   (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
+                   (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
+                   inode->i_ino != EXT4_JOURNAL_INO) {
                        journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
                        tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;
 
@@ -216,6 +215,7 @@ void ext4_evict_inode(struct inode *inode)
                        filemap_write_and_wait(&inode->i_data);
                }
                truncate_inode_pages(&inode->i_data, 0);
+               ext4_ioend_shutdown(inode);
                goto no_delete;
        }
 
@@ -225,6 +225,7 @@ void ext4_evict_inode(struct inode *inode)
        if (ext4_should_order_data(inode))
                ext4_begin_ordered_truncate(inode, 0);
        truncate_inode_pages(&inode->i_data, 0);
+       ext4_ioend_shutdown(inode);
 
        if (is_bad_inode(inode))
                goto no_delete;
@@ -482,6 +483,58 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
        return num;
 }
 
+#ifdef ES_AGGRESSIVE_TEST
+static void ext4_map_blocks_es_recheck(handle_t *handle,
+                                      struct inode *inode,
+                                      struct ext4_map_blocks *es_map,
+                                      struct ext4_map_blocks *map,
+                                      int flags)
+{
+       int retval;
+
+       map->m_flags = 0;
+       /*
+        * There is a race window that the result is not the same.
+        * e.g. xfstests #223 when dioread_nolock enables.  The reason
+        * is that we lookup a block mapping in extent status tree with
+        * out taking i_data_sem.  So at the time the unwritten extent
+        * could be converted.
+        */
+       if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
+               down_read((&EXT4_I(inode)->i_data_sem));
+       if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
+               retval = ext4_ext_map_blocks(handle, inode, map, flags &
+                                            EXT4_GET_BLOCKS_KEEP_SIZE);
+       } else {
+               retval = ext4_ind_map_blocks(handle, inode, map, flags &
+                                            EXT4_GET_BLOCKS_KEEP_SIZE);
+       }
+       if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
+               up_read((&EXT4_I(inode)->i_data_sem));
+       /*
+        * Clear EXT4_MAP_FROM_CLUSTER and EXT4_MAP_BOUNDARY flag
+        * because it shouldn't be marked in es_map->m_flags.
+        */
+       map->m_flags &= ~(EXT4_MAP_FROM_CLUSTER | EXT4_MAP_BOUNDARY);
+
+       /*
+        * We don't check m_len because extent will be collpased in status
+        * tree.  So the m_len might not equal.
+        */
+       if (es_map->m_lblk != map->m_lblk ||
+           es_map->m_flags != map->m_flags ||
+           es_map->m_pblk != map->m_pblk) {
+               printk("ES cache assertation failed for inode: %lu "
+                      "es_cached ex [%d/%d/%llu/%x] != "
+                      "found ex [%d/%d/%llu/%x] retval %d flags %x\n",
+                      inode->i_ino, es_map->m_lblk, es_map->m_len,
+                      es_map->m_pblk, es_map->m_flags, map->m_lblk,
+                      map->m_len, map->m_pblk, map->m_flags,
+                      retval, flags);
+       }
+}
+#endif /* ES_AGGRESSIVE_TEST */
+
 /*
  * The ext4_map_blocks() function tries to look up the requested blocks,
  * and returns if the blocks are already mapped.
@@ -509,6 +562,11 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 {
        struct extent_status es;
        int retval;
+#ifdef ES_AGGRESSIVE_TEST
+       struct ext4_map_blocks orig_map;
+
+       memcpy(&orig_map, map, sizeof(*map));
+#endif
 
        map->m_flags = 0;
        ext_debug("ext4_map_blocks(): inode %lu, flag %d, max_blocks %u,"
@@ -531,6 +589,10 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                } else {
                        BUG_ON(1);
                }
+#ifdef ES_AGGRESSIVE_TEST
+               ext4_map_blocks_es_recheck(handle, inode, map,
+                                          &orig_map, flags);
+#endif
                goto found;
        }
 
@@ -551,6 +613,15 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                int ret;
                unsigned long long status;
 
+#ifdef ES_AGGRESSIVE_TEST
+               if (retval != map->m_len) {
+                       printk("ES len assertation failed for inode: %lu "
+                              "retval %d != map->m_len %d "
+                              "in %s (lookup)\n", inode->i_ino, retval,
+                              map->m_len, __func__);
+               }
+#endif
+
                status = map->m_flags & EXT4_MAP_UNWRITTEN ?
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
                if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
@@ -643,6 +714,24 @@ found:
                int ret;
                unsigned long long status;
 
+#ifdef ES_AGGRESSIVE_TEST
+               if (retval != map->m_len) {
+                       printk("ES len assertation failed for inode: %lu "
+                              "retval %d != map->m_len %d "
+                              "in %s (allocation)\n", inode->i_ino, retval,
+                              map->m_len, __func__);
+               }
+#endif
+
+               /*
+                * If the extent has been zeroed out, we don't need to update
+                * extent status tree.
+                */
+               if ((flags & EXT4_GET_BLOCKS_PRE_IO) &&
+                   ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
+                       if (ext4_es_is_written(&es))
+                               goto has_zeroout;
+               }
                status = map->m_flags & EXT4_MAP_UNWRITTEN ?
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
                if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
@@ -655,6 +744,7 @@ found:
                        retval = ret;
        }
 
+has_zeroout:
        up_write((&EXT4_I(inode)->i_data_sem));
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
                int ret = check_block_validity(inode, map);
@@ -1215,6 +1305,55 @@ static int ext4_journalled_write_end(struct file *file,
        return ret ? ret : copied;
 }
 
+/*
+ * Reserve a metadata for a single block located at lblock
+ */
+static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock)
+{
+       int retries = 0;
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       unsigned int md_needed;
+       ext4_lblk_t save_last_lblock;
+       int save_len;
+
+       /*
+        * recalculate the amount of metadata blocks to reserve
+        * in order to allocate nrblocks
+        * worse case is one extent per block
+        */
+repeat:
+       spin_lock(&ei->i_block_reservation_lock);
+       /*
+        * ext4_calc_metadata_amount() has side effects, which we have
+        * to be prepared undo if we fail to claim space.
+        */
+       save_len = ei->i_da_metadata_calc_len;
+       save_last_lblock = ei->i_da_metadata_calc_last_lblock;
+       md_needed = EXT4_NUM_B2C(sbi,
+                                ext4_calc_metadata_amount(inode, lblock));
+       trace_ext4_da_reserve_space(inode, md_needed);
+
+       /*
+        * We do still charge estimated metadata to the sb though;
+        * we cannot afford to run out of free blocks.
+        */
+       if (ext4_claim_free_clusters(sbi, md_needed, 0)) {
+               ei->i_da_metadata_calc_len = save_len;
+               ei->i_da_metadata_calc_last_lblock = save_last_lblock;
+               spin_unlock(&ei->i_block_reservation_lock);
+               if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
+                       cond_resched();
+                       goto repeat;
+               }
+               return -ENOSPC;
+       }
+       ei->i_reserved_meta_blocks += md_needed;
+       spin_unlock(&ei->i_block_reservation_lock);
+
+       return 0;       /* success */
+}
+
 /*
  * Reserve a single cluster located at lblock
  */
@@ -1263,7 +1402,7 @@ repeat:
                ei->i_da_metadata_calc_last_lblock = save_last_lblock;
                spin_unlock(&ei->i_block_reservation_lock);
                if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
-                       yield();
+                       cond_resched();
                        goto repeat;
                }
                dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1));
@@ -1768,6 +1907,11 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
        struct extent_status es;
        int retval;
        sector_t invalid_block = ~((sector_t) 0xffff);
+#ifdef ES_AGGRESSIVE_TEST
+       struct ext4_map_blocks orig_map;
+
+       memcpy(&orig_map, map, sizeof(*map));
+#endif
 
        if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es))
                invalid_block = ~0;
@@ -1809,6 +1953,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
                else
                        BUG_ON(1);
 
+#ifdef ES_AGGRESSIVE_TEST
+               ext4_map_blocks_es_recheck(NULL, inode, map, &orig_map, 0);
+#endif
                return retval;
        }
 
@@ -1843,8 +1990,11 @@ add_delayed:
                 * XXX: __block_prepare_write() unmaps passed block,
                 * is it OK?
                 */
-               /* If the block was allocated from previously allocated cluster,
-                * then we dont need to reserve it again. */
+               /*
+                * If the block was allocated from previously allocated cluster,
+                * then we don't need to reserve it again. However we still need
+                * to reserve metadata for every block we're going to write.
+                */
                if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) {
                        ret = ext4_da_reserve_space(inode, iblock);
                        if (ret) {
@@ -1852,6 +2002,13 @@ add_delayed:
                                retval = ret;
                                goto out_unlock;
                        }
+               } else {
+                       ret = ext4_da_reserve_metadata(inode, iblock);
+                       if (ret) {
+                               /* not enough space to reserve */
+                               retval = ret;
+                               goto out_unlock;
+                       }
                }
 
                ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
@@ -1873,6 +2030,15 @@ add_delayed:
                int ret;
                unsigned long long status;
 
+#ifdef ES_AGGRESSIVE_TEST
+               if (retval != map->m_len) {
+                       printk("ES len assertation failed for inode: %lu "
+                              "retval %d != map->m_len %d "
+                              "in %s (lookup)\n", inode->i_ino, retval,
+                              map->m_len, __func__);
+               }
+#endif
+
                status = map->m_flags & EXT4_MAP_UNWRITTEN ?
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
                ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
@@ -2908,8 +3074,8 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
 
        trace_ext4_releasepage(page);
 
-       WARN_ON(PageChecked(page));
-       if (!page_has_buffers(page))
+       /* Page has dirty journalled data -> cannot release */
+       if (PageChecked(page))
                return 0;
        if (journal)
                return jbd2_journal_try_to_free_buffers(journal, page, wait);
index 7bb713a46fe4c3f85ae9d35bd15bea73aa7957f5..28e421c208a5fd8c259ef24243c32f87a51290bc 100644 (file)
@@ -2149,7 +2149,7 @@ static const struct seq_operations ext4_mb_seq_groups_ops = {
 
 static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file)
 {
-       struct super_block *sb = PDE(inode)->data;
+       struct super_block *sb = PDE_DATA(inode);
        int rc;
 
        rc = seq_open(file, &ext4_mb_seq_groups_ops);
@@ -2804,8 +2804,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi,
                                                          ac->ac_b_ex.fe_group);
-               atomic_sub(ac->ac_b_ex.fe_len,
-                          &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic64_sub(ac->ac_b_ex.fe_len,
+                            &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
        err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
@@ -3692,11 +3692,7 @@ repeat:
        if (free < needed && busy) {
                busy = 0;
                ext4_unlock_group(sb, group);
-               /*
-                * Yield the CPU here so that we don't get soft lockup
-                * in non preempt case.
-                */
-               yield();
+               cond_resched();
                goto repeat;
        }
 
@@ -4246,7 +4242,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
                        ext4_claim_free_clusters(sbi, ar->len, ar->flags)) {
 
                        /* let others to free the space */
-                       yield();
+                       cond_resched();
                        ar->len = ar->len >> 1;
                }
                if (!ar->len) {
@@ -4464,7 +4460,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        struct buffer_head *bitmap_bh = NULL;
        struct super_block *sb = inode->i_sb;
        struct ext4_group_desc *gdp;
-       unsigned long freed = 0;
        unsigned int overflow;
        ext4_grpblk_t bit;
        struct buffer_head *gd_bh;
@@ -4666,14 +4661,12 @@ do_more:
 
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
-               atomic_add(count_clusters,
-                          &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic64_add(count_clusters,
+                            &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
        ext4_mb_unload_buddy(&e4b);
 
-       freed += count;
-
        if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
                dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
 
@@ -4811,8 +4804,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
 
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
-               atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
-                          &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed),
+                            &sbi->s_flex_groups[flex_group].free_clusters);
        }
 
        ext4_mb_unload_buddy(&e4b);
index 4e81d47aa8cb8af0553b93c1cb7dcbbea2d5d0a8..33e1c086858b54ad704e80345c92b946ae3c565b 100644 (file)
  */
 static inline int
 get_ext_path(struct inode *inode, ext4_lblk_t lblock,
-               struct ext4_ext_path **path)
+               struct ext4_ext_path **orig_path)
 {
        int ret = 0;
+       struct ext4_ext_path *path;
 
-       *path = ext4_ext_find_extent(inode, lblock, *path);
-       if (IS_ERR(*path)) {
-               ret = PTR_ERR(*path);
-               *path = NULL;
-       } else if ((*path)[ext_depth(inode)].p_ext == NULL)
+       path = ext4_ext_find_extent(inode, lblock, *orig_path);
+       if (IS_ERR(path))
+               ret = PTR_ERR(path);
+       else if (path[ext_depth(inode)].p_ext == NULL)
                ret = -ENODATA;
+       else
+               *orig_path = path;
 
        return ret;
 }
@@ -611,24 +613,25 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
 {
        struct ext4_ext_path *path = NULL;
        struct ext4_extent *ext;
+       int ret = 0;
        ext4_lblk_t last = from + count;
        while (from < last) {
                *err = get_ext_path(inode, from, &path);
                if (*err)
-                       return 0;
+                       goto out;
                ext = path[ext_depth(inode)].p_ext;
-               if (!ext) {
-                       ext4_ext_drop_refs(path);
-                       return 0;
-               }
-               if (uninit != ext4_ext_is_uninitialized(ext)) {
-                       ext4_ext_drop_refs(path);
-                       return 0;
-               }
+               if (uninit != ext4_ext_is_uninitialized(ext))
+                       goto out;
                from += ext4_ext_get_actual_len(ext);
                ext4_ext_drop_refs(path);
        }
-       return 1;
+       ret = 1;
+out:
+       if (path) {
+               ext4_ext_drop_refs(path);
+               kfree(path);
+       }
+       return ret;
 }
 
 /**
@@ -666,6 +669,14 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
        int replaced_count = 0;
        int dext_alen;
 
+       *err = ext4_es_remove_extent(orig_inode, from, count);
+       if (*err)
+               goto out;
+
+       *err = ext4_es_remove_extent(donor_inode, from, count);
+       if (*err)
+               goto out;
+
        /* Get the original extent for the block "orig_off" */
        *err = get_ext_path(orig_inode, orig_off, &orig_path);
        if (*err)
index 809b31003ecc0fedd35d71e8abed4047bbe18beb..047a6de04a0ac8195d5453de514a8e95526fcce4 100644 (file)
@@ -50,11 +50,21 @@ void ext4_exit_pageio(void)
        kmem_cache_destroy(io_page_cachep);
 }
 
-void ext4_ioend_wait(struct inode *inode)
+/*
+ * This function is called by ext4_evict_inode() to make sure there is
+ * no more pending I/O completion work left to do.
+ */
+void ext4_ioend_shutdown(struct inode *inode)
 {
        wait_queue_head_t *wq = ext4_ioend_wq(inode);
 
        wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0));
+       /*
+        * We need to make sure the work structure is finished being
+        * used before we let the inode get destroyed.
+        */
+       if (work_pending(&EXT4_I(inode)->i_unwritten_work))
+               cancel_work_sync(&EXT4_I(inode)->i_unwritten_work);
 }
 
 static void put_io_page(struct ext4_io_page *io_page)
index b2c8ee56eb98744ab7481e4d0849e2fb5ca71365..c169477a62c987a1ba2d3362dde6bd8d3cd0f260 100644 (file)
@@ -1360,8 +1360,8 @@ static void ext4_update_super(struct super_block *sb,
            sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group;
                flex_group = ext4_flex_group(sbi, group_data[0].group);
-               atomic_add(EXT4_NUM_B2C(sbi, free_blocks),
-                          &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
+                            &sbi->s_flex_groups[flex_group].free_clusters);
                atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
                           &sbi->s_flex_groups[flex_group].free_inodes);
        }
index 5e6c878361935f405ccefd532b40d9c3101f0317..c65510548355470daf817b24f80b00a8ef4fd669 100644 (file)
@@ -90,6 +90,8 @@ static struct file_system_type ext2_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext2");
+MODULE_ALIAS("ext2");
 #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type)
 #else
 #define IS_EXT2_SB(sb) (0)
@@ -104,6 +106,8 @@ static struct file_system_type ext3_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext3");
+MODULE_ALIAS("ext3");
 #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
 #else
 #define IS_EXT3_SB(sb) (0)
@@ -1798,7 +1802,7 @@ static int options_seq_show(struct seq_file *seq, void *offset)
 
 static int options_open_fs(struct inode *inode, struct file *file)
 {
-       return single_open(file, options_seq_show, PDE(inode)->data);
+       return single_open(file, options_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations ext4_seq_options_fops = {
@@ -1923,8 +1927,8 @@ static int ext4_fill_flex_info(struct super_block *sb)
                flex_group = ext4_flex_group(sbi, i);
                atomic_add(ext4_free_inodes_count(sb, gdp),
                           &sbi->s_flex_groups[flex_group].free_inodes);
-               atomic_add(ext4_free_group_clusters(sb, gdp),
-                          &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic64_add(ext4_free_group_clusters(sb, gdp),
+                            &sbi->s_flex_groups[flex_group].free_clusters);
                atomic_add(ext4_used_dirs_count(sb, gdp),
                           &sbi->s_flex_groups[flex_group].used_dirs);
        }
@@ -5152,7 +5156,6 @@ static inline int ext2_feature_set_ok(struct super_block *sb)
                return 0;
        return 1;
 }
-MODULE_ALIAS("ext2");
 #else
 static inline void register_as_ext2(void) { }
 static inline void unregister_as_ext2(void) { }
@@ -5185,7 +5188,6 @@ static inline int ext3_feature_set_ok(struct super_block *sb)
                return 0;
        return 1;
 }
-MODULE_ALIAS("ext3");
 #else
 static inline void register_as_ext3(void) { }
 static inline void unregister_as_ext3(void) { }
@@ -5199,6 +5201,7 @@ static struct file_system_type ext4_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext4");
 
 static int __init ext4_init_feat_adverts(void)
 {
index 137af4255da6dfab591e4d640821539663d01a7c..44abc2f286e00ad4ecff03e0293f80ab8d3d19fd 100644 (file)
@@ -299,7 +299,7 @@ int f2fs_acl_chmod(struct inode *inode)
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct posix_acl *acl;
        int error;
-       mode_t mode = get_inode_mode(inode);
+       umode_t mode = get_inode_mode(inode);
 
        if (!test_opt(sbi, POSIX_ACL))
                return 0;
index a1f38443ecee39940d1a5dee6c167b54f9f50431..1be948768e2f1b04293ea19935db4eb244d62049 100644 (file)
@@ -60,7 +60,7 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = {
 
 static void set_de_type(struct f2fs_dir_entry *de, struct inode *inode)
 {
-       mode_t mode = inode->i_mode;
+       umode_t mode = inode->i_mode;
        de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
 }
 
index 958a46da19ae2fbae17f6a7bf25475cd061f8ad3..db626282d424e49fff3669a57f1d29dee1b08407 100644 (file)
@@ -590,7 +590,7 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        {
                unsigned int oldflags;
 
-               ret = mnt_want_write(filp->f_path.mnt);
+               ret = mnt_want_write_file(filp);
                if (ret)
                        return ret;
 
@@ -627,7 +627,7 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                inode->i_ctime = CURRENT_TIME;
                mark_inode_dirty(inode);
 out:
-               mnt_drop_write(filp->f_path.mnt);
+               mnt_drop_write_file(filp);
                return ret;
        }
        default:
index 8c117649a035dc5e5df58264c25b87c1d3a43ae5..fea6e582a2ed62995e1db703af39a2c436e9df4f 100644 (file)
@@ -687,6 +687,7 @@ static struct file_system_type f2fs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("f2fs");
 
 static int __init init_inodecache(void)
 {
index e2cfda94a28d249fd85961747b625a3c8b5bd100..081b759cff83fee7dc4fa3ba901b2ba9f92c888b 100644 (file)
@@ -668,6 +668,7 @@ static struct file_system_type msdos_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("msdos");
 
 static int __init init_msdos_fs(void)
 {
index ac959d655e7d7f7dd92448437b58ec4fe81ce1ab..2da952036a3d7527d98b527ff7114b6d14ec4d43 100644 (file)
@@ -1073,6 +1073,7 @@ static struct file_system_type vfat_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("vfat");
 
 static int __init init_vfat_fs(void)
 {
diff --git a/fs/fifo.c b/fs/fifo.c
deleted file mode 100644 (file)
index cf6f434..0000000
--- a/fs/fifo.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *  linux/fs/fifo.c
- *
- *  written by Paul H. Hargrove
- *
- *  Fixes:
- *     10-06-1999, AV: fixed OOM handling in fifo_open(), moved
- *                     initialization there, switched to external
- *                     allocation of pipe_inode_info.
- */
-
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/pipe_fs_i.h>
-
-static int wait_for_partner(struct inode* inode, unsigned int *cnt)
-{
-       int cur = *cnt; 
-
-       while (cur == *cnt) {
-               pipe_wait(inode->i_pipe);
-               if (signal_pending(current))
-                       break;
-       }
-       return cur == *cnt ? -ERESTARTSYS : 0;
-}
-
-static void wake_up_partner(struct inode* inode)
-{
-       wake_up_interruptible(&inode->i_pipe->wait);
-}
-
-static int fifo_open(struct inode *inode, struct file *filp)
-{
-       struct pipe_inode_info *pipe;
-       int ret;
-
-       mutex_lock(&inode->i_mutex);
-       pipe = inode->i_pipe;
-       if (!pipe) {
-               ret = -ENOMEM;
-               pipe = alloc_pipe_info(inode);
-               if (!pipe)
-                       goto err_nocleanup;
-               inode->i_pipe = pipe;
-       }
-       filp->f_version = 0;
-
-       /* We can only do regular read/write on fifos */
-       filp->f_mode &= (FMODE_READ | FMODE_WRITE);
-
-       switch (filp->f_mode) {
-       case FMODE_READ:
-       /*
-        *  O_RDONLY
-        *  POSIX.1 says that O_NONBLOCK means return with the FIFO
-        *  opened, even when there is no process writing the FIFO.
-        */
-               filp->f_op = &read_pipefifo_fops;
-               pipe->r_counter++;
-               if (pipe->readers++ == 0)
-                       wake_up_partner(inode);
-
-               if (!pipe->writers) {
-                       if ((filp->f_flags & O_NONBLOCK)) {
-                               /* suppress POLLHUP until we have
-                                * seen a writer */
-                               filp->f_version = pipe->w_counter;
-                       } else {
-                               if (wait_for_partner(inode, &pipe->w_counter))
-                                       goto err_rd;
-                       }
-               }
-               break;
-       
-       case FMODE_WRITE:
-       /*
-        *  O_WRONLY
-        *  POSIX.1 says that O_NONBLOCK means return -1 with
-        *  errno=ENXIO when there is no process reading the FIFO.
-        */
-               ret = -ENXIO;
-               if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
-                       goto err;
-
-               filp->f_op = &write_pipefifo_fops;
-               pipe->w_counter++;
-               if (!pipe->writers++)
-                       wake_up_partner(inode);
-
-               if (!pipe->readers) {
-                       if (wait_for_partner(inode, &pipe->r_counter))
-                               goto err_wr;
-               }
-               break;
-       
-       case FMODE_READ | FMODE_WRITE:
-       /*
-        *  O_RDWR
-        *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
-        *  This implementation will NEVER block on a O_RDWR open, since
-        *  the process can at least talk to itself.
-        */
-               filp->f_op = &rdwr_pipefifo_fops;
-
-               pipe->readers++;
-               pipe->writers++;
-               pipe->r_counter++;
-               pipe->w_counter++;
-               if (pipe->readers == 1 || pipe->writers == 1)
-                       wake_up_partner(inode);
-               break;
-
-       default:
-               ret = -EINVAL;
-               goto err;
-       }
-
-       /* Ok! */
-       mutex_unlock(&inode->i_mutex);
-       return 0;
-
-err_rd:
-       if (!--pipe->readers)
-               wake_up_interruptible(&pipe->wait);
-       ret = -ERESTARTSYS;
-       goto err;
-
-err_wr:
-       if (!--pipe->writers)
-               wake_up_interruptible(&pipe->wait);
-       ret = -ERESTARTSYS;
-       goto err;
-
-err:
-       if (!pipe->readers && !pipe->writers)
-               free_pipe_info(inode);
-
-err_nocleanup:
-       mutex_unlock(&inode->i_mutex);
-       return ret;
-}
-
-/*
- * Dummy default file-operations: the only thing this does
- * is contain the open that then fills in the correct operations
- * depending on the access mode of the file...
- */
-const struct file_operations def_fifo_fops = {
-       .open           = fifo_open,    /* will set read_ or write_pipefifo_fops */
-       .llseek         = noop_llseek,
-};
index da165f6adcbfa67a12f9f19363692ab6c5d00d19..92567d95ba6ab1adbf94c2ead01f94b60ae02a40 100644 (file)
@@ -273,7 +273,7 @@ struct file_system_type *get_fs_type(const char *name)
        int len = dot ? dot - name : strlen(name);
 
        fs = __get_fs_type(name, len);
-       if (!fs && (request_module("%.*s", len, name) == 0))
+       if (!fs && (request_module("fs-%.*s", len, name) == 0))
                fs = __get_fs_type(name, len);
 
        if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
index fed2c8afb3a9f401945ca5d8a226a4df5ebb4c9f..e37eb274e492a9dfd36d4f717d363b6932ae90b5 100644 (file)
@@ -52,7 +52,6 @@ MODULE_AUTHOR("Christoph Hellwig");
 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
 MODULE_LICENSE("Dual BSD/GPL");
 
-MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */
 
 
 static void            vxfs_put_super(struct super_block *);
@@ -258,6 +257,8 @@ static struct file_system_type vxfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */
+MODULE_ALIAS("vxfs");
 
 static int __init
 vxfs_init(void)
index b7978b9f75ef01e20e3c18afe20a27df9f6dbe6c..a0b0855d00a985c78288074f9adc813d14addfe1 100644 (file)
@@ -341,6 +341,7 @@ static struct file_system_type fuse_ctl_fs_type = {
        .mount          = fuse_ctl_mount,
        .kill_sb        = fuse_ctl_kill_sb,
 };
+MODULE_ALIAS_FS("fusectl");
 
 int __init fuse_ctl_init(void)
 {
index 11dfa0c3fb46a9fd1e89cc0b2de356c5fc62bec0..9bfd1a3214e663fb579ad3523f0f22eb082e5926 100644 (file)
@@ -1319,7 +1319,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
                page_nr++;
                ret += buf->len;
 
-               if (pipe->inode)
+               if (pipe->files)
                        do_wakeup = 1;
        }
 
index 34b80ba95bad8c189cfaaf7004a40ca00d8d2018..d15c6f21c17f6eefe1d90f16e77d59afe045394b 100644 (file)
@@ -971,7 +971,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                return err;
 
        count = ocount;
-       sb_start_write(inode->i_sb);
        mutex_lock(&inode->i_mutex);
 
        /* We can write back this queue in page reclaim */
@@ -1030,7 +1029,6 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 out:
        current->backing_dev_info = NULL;
        mutex_unlock(&inode->i_mutex);
-       sb_end_write(inode->i_sb);
 
        return written ? written : err;
 }
index df00993ed108816b6902080d0ac98fd742407c12..137185c3884fbbb9dfcab6115c78952d7aec7f08 100644 (file)
@@ -1117,6 +1117,7 @@ static struct file_system_type fuse_fs_type = {
        .mount          = fuse_mount,
        .kill_sb        = fuse_kill_sb_anon,
 };
+MODULE_ALIAS_FS("fuse");
 
 #ifdef CONFIG_BLOCK
 static struct dentry *fuse_mount_blk(struct file_system_type *fs_type,
@@ -1146,6 +1147,7 @@ static struct file_system_type fuseblk_fs_type = {
        .kill_sb        = fuse_kill_sb_blk,
        .fs_flags       = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
 };
+MODULE_ALIAS_FS("fuseblk");
 
 static inline int register_fuseblk(void)
 {
index 1b612be4b873c663640cbd1338d9ff2d5aaa5d8e..60ede2a0f43fbc498201cc3262da939110eac0bb 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/quotaops.h>
 #include <linux/lockdep.h>
+#include <linux/module.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -1425,6 +1426,7 @@ struct file_system_type gfs2_fs_type = {
        .kill_sb = gfs2_kill_sb,
        .owner = THIS_MODULE,
 };
+MODULE_ALIAS_FS("gfs2");
 
 struct file_system_type gfs2meta_fs_type = {
        .name = "gfs2meta",
@@ -1432,4 +1434,4 @@ struct file_system_type gfs2meta_fs_type = {
        .mount = gfs2_mount_meta,
        .owner = THIS_MODULE,
 };
-
+MODULE_ALIAS_FS("gfs2meta");
index e93ddaadfd1e445fa89e976c9692f2afa302094c..bbaaa8a4ee6445e90920da2431defcc064013ace 100644 (file)
@@ -466,6 +466,7 @@ static struct file_system_type hfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("hfs");
 
 static void hfs_init_once(void *p)
 {
index 974c26f96faeaa2575cdc80e81b36cbb955cf07e..7b87284e46dc9b0fb50e1f40dcfebe9f44547b93 100644 (file)
@@ -654,6 +654,7 @@ static struct file_system_type hfsplus_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("hfsplus");
 
 static void hfsplus_init_once(void *p)
 {
index fbabb906066fa4756c846e6c6e6e577f00f1b6ed..0f6e52d22b8420fdbd3e5b315fe403d742c0a52f 100644 (file)
@@ -845,15 +845,8 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
                return err;
 
        if ((attr->ia_valid & ATTR_SIZE) &&
-           attr->ia_size != i_size_read(inode)) {
-               int error;
-
-               error = inode_newsize_ok(inode, attr->ia_size);
-               if (error)
-                       return error;
-
+           attr->ia_size != i_size_read(inode))
                truncate_setsize(inode, attr->ia_size);
-       }
 
        setattr_copy(inode, attr);
        mark_inode_dirty(inode);
@@ -993,6 +986,7 @@ static struct file_system_type hostfs_type = {
        .kill_sb        = hostfs_kill_sb,
        .fs_flags       = 0,
 };
+MODULE_ALIAS_FS("hostfs");
 
 static int __init init_hostfs(void)
 {
index 9f9dbeceeee74717a4695f0a4a88d558c1d2b6b3..3027f4dbbab5195990a13d763055f229fa06213a 100644 (file)
@@ -131,6 +131,24 @@ static int hpfs_write_begin(struct file *file, struct address_space *mapping,
        return ret;
 }
 
+static int hpfs_write_end(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+                       struct page *pagep, void *fsdata)
+{
+       struct inode *inode = mapping->host;
+       int err;
+       err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
+       if (err < len)
+               hpfs_write_failed(mapping, pos + len);
+       if (!(err < 0)) {
+               /* make sure we write it on close, if not earlier */
+               hpfs_lock(inode->i_sb);
+               hpfs_i(inode)->i_dirty = 1;
+               hpfs_unlock(inode->i_sb);
+       }
+       return err;
+}
+
 static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
 {
        return generic_block_bmap(mapping,block,hpfs_get_block);
@@ -140,30 +158,16 @@ const struct address_space_operations hpfs_aops = {
        .readpage = hpfs_readpage,
        .writepage = hpfs_writepage,
        .write_begin = hpfs_write_begin,
-       .write_end = generic_write_end,
+       .write_end = hpfs_write_end,
        .bmap = _hpfs_bmap
 };
 
-static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
-                       size_t count, loff_t *ppos)
-{
-       ssize_t retval;
-
-       retval = do_sync_write(file, buf, count, ppos);
-       if (retval > 0) {
-               hpfs_lock(file->f_path.dentry->d_sb);
-               hpfs_i(file_inode(file))->i_dirty = 1;
-               hpfs_unlock(file->f_path.dentry->d_sb);
-       }
-       return retval;
-}
-
 const struct file_operations hpfs_file_ops =
 {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
        .aio_read       = generic_file_aio_read,
-       .write          = hpfs_file_write,
+       .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
        .release        = hpfs_file_release,
index a3076228523db4db7a105a966f6049a8570b705c..a0617e7069579c61baed047b3ba2992b294d6082 100644 (file)
@@ -688,6 +688,7 @@ static struct file_system_type hpfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("hpfs");
 
 static int __init init_hpfs_fs(void)
 {
index 74f55703be498ca0220f9150ed29a08818cd5dfd..cd3e38972c86a8ae27ed8abfcb90e8466eac3490 100644 (file)
@@ -436,7 +436,6 @@ static int hppfs_open(struct inode *inode, struct file *file)
        path.mnt = inode->i_sb->s_fs_info;
        path.dentry = HPPFS_I(inode)->proc_dentry;
 
-       /* XXX This isn't closed anywhere */
        data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred);
        err = PTR_ERR(data->proc_file);
        if (IS_ERR(data->proc_file))
@@ -523,12 +522,23 @@ static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
        return default_llseek(file, off, where);
 }
 
+static int hppfs_release(struct inode *inode, struct file *file)
+{
+       struct hppfs_private *data = file->private_data;
+       struct file *proc_file = data->proc_file;
+       if (proc_file)
+               fput(proc_file);
+       kfree(data);
+       return 0;
+}
+
 static const struct file_operations hppfs_file_fops = {
        .owner          = NULL,
        .llseek         = hppfs_llseek,
        .read           = hppfs_read,
        .write          = hppfs_write,
        .open           = hppfs_open,
+       .release        = hppfs_release,
 };
 
 struct hppfs_dirent {
@@ -570,18 +580,12 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
        return err;
 }
 
-static int hppfs_fsync(struct file *file, loff_t start, loff_t end,
-                      int datasync)
-{
-       return filemap_write_and_wait_range(file->f_mapping, start, end);
-}
-
 static const struct file_operations hppfs_dir_fops = {
        .owner          = NULL,
        .readdir        = hppfs_readdir,
        .open           = hppfs_dir_open,
-       .fsync          = hppfs_fsync,
        .llseek         = default_llseek,
+       .release        = hppfs_release,
 };
 
 static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
@@ -748,6 +752,7 @@ static struct file_system_type hppfs_type = {
        .kill_sb        = kill_anon_super,
        .fs_flags       = 0,
 };
+MODULE_ALIAS_FS("hppfs");
 
 static int __init init_hppfs(void)
 {
index 7f94e0cbc69c78bfda1431c85d1f9280315ded89..84e3d856e91d05c27aa182be0d28dead99128c93 100644 (file)
@@ -896,6 +896,7 @@ static struct file_system_type hugetlbfs_fs_type = {
        .mount          = hugetlbfs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("hugetlbfs");
 
 static struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE];
 
index f5f7c06c36fb159f89a793510c62f3f9170c3e4d..5b76d9b1a8843887845d1e3d095cbf7d33286653 100644 (file)
@@ -1803,7 +1803,7 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
                inode->i_fop = &def_blk_fops;
                inode->i_rdev = rdev;
        } else if (S_ISFIFO(mode))
-               inode->i_fop = &def_fifo_fops;
+               inode->i_fop = &pipefifo_fops;
        else if (S_ISSOCK(mode))
                inode->i_fop = &bad_sock_fops;
        else
index 507141fceb99669f7554e330d81605d2fff248b2..eaa75f75b625c572ec6e75650b3e6fb89d715a4a 100644 (file)
@@ -125,3 +125,13 @@ extern int invalidate_inodes(struct super_block *, bool);
  * dcache.c
  */
 extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
+
+/*
+ * read_write.c
+ */
+extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
+
+/*
+ * pipe.c
+ */
+extern const struct file_operations pipefifo_fops;
index 67ce52507d7dec7f2f009624979ffa4910f8ea36..d9b8aebdeb22b467eb9717996b823734f8446300 100644 (file)
@@ -1556,6 +1556,8 @@ static struct file_system_type iso9660_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("iso9660");
+MODULE_ALIAS("iso9660");
 
 static int __init init_iso9660_fs(void)
 {
@@ -1593,5 +1595,3 @@ static void __exit exit_iso9660_fs(void)
 module_init(init_iso9660_fs)
 module_exit(exit_iso9660_fs)
 MODULE_LICENSE("GPL");
-/* Actual filesystem name is iso9660, as requested in filesystems.c */
-MODULE_ALIAS("iso9660");
index ed10991ab0060c5fac4ed580301591f6996965ca..154592ea56322a40516f6e302af9b7dcf9cac398 100644 (file)
@@ -950,7 +950,7 @@ static const struct seq_operations jbd2_seq_info_ops = {
 
 static int jbd2_seq_info_open(struct inode *inode, struct file *file)
 {
-       journal_t *journal = PDE(inode)->data;
+       journal_t *journal = PDE_DATA(inode);
        struct jbd2_stats_proc_session *s;
        int rc, size;
 
index d6ee5aed56b178ef98850b3a9abc75f6afc54f7f..325bc019ed8813ea00321594405e86c739dad5fb 100644 (file)
@@ -1065,9 +1065,12 @@ out:
 void jbd2_journal_set_triggers(struct buffer_head *bh,
                               struct jbd2_buffer_trigger_type *type)
 {
-       struct journal_head *jh = bh2jh(bh);
+       struct journal_head *jh = jbd2_journal_grab_journal_head(bh);
 
+       if (WARN_ON(!jh))
+               return;
        jh->b_triggers = type;
+       jbd2_journal_put_journal_head(jh);
 }
 
 void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data,
@@ -1119,17 +1122,18 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
 {
        transaction_t *transaction = handle->h_transaction;
        journal_t *journal = transaction->t_journal;
-       struct journal_head *jh = bh2jh(bh);
+       struct journal_head *jh;
        int ret = 0;
 
-       jbd_debug(5, "journal_head %p\n", jh);
-       JBUFFER_TRACE(jh, "entry");
        if (is_handle_aborted(handle))
                goto out;
-       if (!buffer_jbd(bh)) {
+       jh = jbd2_journal_grab_journal_head(bh);
+       if (!jh) {
                ret = -EUCLEAN;
                goto out;
        }
+       jbd_debug(5, "journal_head %p\n", jh);
+       JBUFFER_TRACE(jh, "entry");
 
        jbd_lock_bh_state(bh);
 
@@ -1220,6 +1224,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
        spin_unlock(&journal->j_list_lock);
 out_unlock_bh:
        jbd_unlock_bh_state(bh);
+       jbd2_journal_put_journal_head(jh);
 out:
        JBUFFER_TRACE(jh, "exit");
        WARN_ON(ret);   /* All errors are bugs, so dump the stack */
index d3d8799e2187233e23e1614990443203d4fff1ad..0defb1cc2a3520d6f5f67cc880f91d0e9fe5b244 100644 (file)
@@ -356,6 +356,7 @@ static struct file_system_type jffs2_fs_type = {
        .mount =        jffs2_mount,
        .kill_sb =      jffs2_kill_sb,
 };
+MODULE_ALIAS_FS("jffs2");
 
 static int __init init_jffs2_fs(void)
 {
index 060ba638becbe39ee85104860d325b0f4e16a8f7..2003e830ed1c0d890f1fe0944db8dff04dab8ee6 100644 (file)
@@ -833,6 +833,7 @@ static struct file_system_type jfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("jfs");
 
 static void init_once(void *foo)
 {
index 345c24b8a6f86965b39d7dd017fb294908ddd8d0..54360293bcb5cd0680c3042e6f0b9b87e342c649 100644 (file)
@@ -608,6 +608,7 @@ static struct file_system_type logfs_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV,
 
 };
+MODULE_ALIAS_FS("logfs");
 
 static int __init logfs_init(void)
 {
index 99541cceb584966da9aba7b70dd094653cf158b9..df122496f32821bd145490800467d41d02c87f63 100644 (file)
@@ -660,6 +660,7 @@ static struct file_system_type minix_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("minix");
 
 static int __init init_minix_fs(void)
 {
index cd50079804003ece9325c5338089952f9fa0166b..64a858143ff923ab80499d5a865bde9de2257314 100644 (file)
@@ -18,6 +18,12 @@ struct mnt_pcp {
        int mnt_writers;
 };
 
+struct mountpoint {
+       struct list_head m_hash;
+       struct dentry *m_dentry;
+       int m_count;
+};
+
 struct mount {
        struct list_head mnt_hash;
        struct mount *mnt_parent;
@@ -40,6 +46,7 @@ struct mount {
        struct list_head mnt_slave;     /* slave list entry */
        struct mount *mnt_master;       /* slave is on master->mnt_slave_list */
        struct mnt_namespace *mnt_ns;   /* containing namespace */
+       struct mountpoint *mnt_mp;      /* where is it mounted */
 #ifdef CONFIG_FSNOTIFY
        struct hlist_head mnt_fsnotify_marks;
        __u32 mnt_fsnotify_mask;
index 961bc1268366d80c8b44adf5adc0aec26f59edbd..57ae9c8c66bfc6d98ae96643874710cdc3de321a 100644 (file)
@@ -689,8 +689,6 @@ void nd_jump_link(struct nameidata *nd, struct path *path)
        nd->path = *path;
        nd->inode = nd->path.dentry->d_inode;
        nd->flags |= LOOKUP_JUMPED;
-
-       BUG_ON(nd->inode->i_op->follow_link);
 }
 
 static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
index 50ca17d3cb4506de87465bb4d62f3da5f00553a5..0f0cf9379c9eed3d3d636fed3df56350a435c897 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/fs_struct.h>   /* get_fs_root et.al. */
 #include <linux/fsnotify.h>    /* fsnotify_vfsmount_delete */
 #include <linux/uaccess.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 #include "pnode.h"
 #include "internal.h"
 
@@ -36,6 +36,7 @@ static int mnt_id_start = 0;
 static int mnt_group_start = 1;
 
 static struct list_head *mount_hashtable __read_mostly;
+static struct list_head *mountpoint_hashtable __read_mostly;
 static struct kmem_cache *mnt_cache __read_mostly;
 static struct rw_semaphore namespace_sem;
 
@@ -605,6 +606,51 @@ struct vfsmount *lookup_mnt(struct path *path)
        }
 }
 
+static struct mountpoint *new_mountpoint(struct dentry *dentry)
+{
+       struct list_head *chain = mountpoint_hashtable + hash(NULL, dentry);
+       struct mountpoint *mp;
+
+       list_for_each_entry(mp, chain, m_hash) {
+               if (mp->m_dentry == dentry) {
+                       /* might be worth a WARN_ON() */
+                       if (d_unlinked(dentry))
+                               return ERR_PTR(-ENOENT);
+                       mp->m_count++;
+                       return mp;
+               }
+       }
+
+       mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL);
+       if (!mp)
+               return ERR_PTR(-ENOMEM);
+
+       spin_lock(&dentry->d_lock);
+       if (d_unlinked(dentry)) {
+               spin_unlock(&dentry->d_lock);
+               kfree(mp);
+               return ERR_PTR(-ENOENT);
+       }
+       dentry->d_flags |= DCACHE_MOUNTED;
+       spin_unlock(&dentry->d_lock);
+       mp->m_dentry = dentry;
+       mp->m_count = 1;
+       list_add(&mp->m_hash, chain);
+       return mp;
+}
+
+static void put_mountpoint(struct mountpoint *mp)
+{
+       if (!--mp->m_count) {
+               struct dentry *dentry = mp->m_dentry;
+               spin_lock(&dentry->d_lock);
+               dentry->d_flags &= ~DCACHE_MOUNTED;
+               spin_unlock(&dentry->d_lock);
+               list_del(&mp->m_hash);
+               kfree(mp);
+       }
+}
+
 static inline int check_mnt(struct mount *mnt)
 {
        return mnt->mnt_ns == current->nsproxy->mnt_ns;
@@ -632,27 +678,6 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
        }
 }
 
-/*
- * Clear dentry's mounted state if it has no remaining mounts.
- * vfsmount_lock must be held for write.
- */
-static void dentry_reset_mounted(struct dentry *dentry)
-{
-       unsigned u;
-
-       for (u = 0; u < HASH_SIZE; u++) {
-               struct mount *p;
-
-               list_for_each_entry(p, &mount_hashtable[u], mnt_hash) {
-                       if (p->mnt_mountpoint == dentry)
-                               return;
-               }
-       }
-       spin_lock(&dentry->d_lock);
-       dentry->d_flags &= ~DCACHE_MOUNTED;
-       spin_unlock(&dentry->d_lock);
-}
-
 /*
  * vfsmount lock must be held for write
  */
@@ -664,32 +689,35 @@ static void detach_mnt(struct mount *mnt, struct path *old_path)
        mnt->mnt_mountpoint = mnt->mnt.mnt_root;
        list_del_init(&mnt->mnt_child);
        list_del_init(&mnt->mnt_hash);
-       dentry_reset_mounted(old_path->dentry);
+       put_mountpoint(mnt->mnt_mp);
+       mnt->mnt_mp = NULL;
 }
 
 /*
  * vfsmount lock must be held for write
  */
-void mnt_set_mountpoint(struct mount *mnt, struct dentry *dentry,
+void mnt_set_mountpoint(struct mount *mnt,
+                       struct mountpoint *mp,
                        struct mount *child_mnt)
 {
+       mp->m_count++;
        mnt_add_count(mnt, 1);  /* essentially, that's mntget */
-       child_mnt->mnt_mountpoint = dget(dentry);
+       child_mnt->mnt_mountpoint = dget(mp->m_dentry);
        child_mnt->mnt_parent = mnt;
-       spin_lock(&dentry->d_lock);
-       dentry->d_flags |= DCACHE_MOUNTED;
-       spin_unlock(&dentry->d_lock);
+       child_mnt->mnt_mp = mp;
 }
 
 /*
  * vfsmount lock must be held for write
  */
-static void attach_mnt(struct mount *mnt, struct path *path)
+static void attach_mnt(struct mount *mnt,
+                       struct mount *parent,
+                       struct mountpoint *mp)
 {
-       mnt_set_mountpoint(real_mount(path->mnt), path->dentry, mnt);
+       mnt_set_mountpoint(parent, mp, mnt);
        list_add_tail(&mnt->mnt_hash, mount_hashtable +
-                       hash(path->mnt, path->dentry));
-       list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts);
+                       hash(&parent->mnt, mp->m_dentry));
+       list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
 }
 
 /*
@@ -1091,11 +1119,23 @@ int may_umount(struct vfsmount *mnt)
 
 EXPORT_SYMBOL(may_umount);
 
-void release_mounts(struct list_head *head)
+static LIST_HEAD(unmounted);   /* protected by namespace_sem */
+
+static void namespace_unlock(void)
 {
        struct mount *mnt;
-       while (!list_empty(head)) {
-               mnt = list_first_entry(head, struct mount, mnt_hash);
+       LIST_HEAD(head);
+
+       if (likely(list_empty(&unmounted))) {
+               up_write(&namespace_sem);
+               return;
+       }
+
+       list_splice_init(&unmounted, &head);
+       up_write(&namespace_sem);
+
+       while (!list_empty(&head)) {
+               mnt = list_first_entry(&head, struct mount, mnt_hash);
                list_del_init(&mnt->mnt_hash);
                if (mnt_has_parent(mnt)) {
                        struct dentry *dentry;
@@ -1115,11 +1155,16 @@ void release_mounts(struct list_head *head)
        }
 }
 
+static inline void namespace_lock(void)
+{
+       down_write(&namespace_sem);
+}
+
 /*
  * vfsmount lock must be held for write
  * namespace_sem must be held for write
  */
-void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
+void umount_tree(struct mount *mnt, int propagate)
 {
        LIST_HEAD(tmp_list);
        struct mount *p;
@@ -1138,20 +1183,20 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
                list_del_init(&p->mnt_child);
                if (mnt_has_parent(p)) {
                        p->mnt_parent->mnt_ghosts++;
-                       dentry_reset_mounted(p->mnt_mountpoint);
+                       put_mountpoint(p->mnt_mp);
+                       p->mnt_mp = NULL;
                }
                change_mnt_propagation(p, MS_PRIVATE);
        }
-       list_splice(&tmp_list, kill);
+       list_splice(&tmp_list, &unmounted);
 }
 
-static void shrink_submounts(struct mount *mnt, struct list_head *umounts);
+static void shrink_submounts(struct mount *mnt);
 
 static int do_umount(struct mount *mnt, int flags)
 {
        struct super_block *sb = mnt->mnt.mnt_sb;
        int retval;
-       LIST_HEAD(umount_list);
 
        retval = security_sb_umount(&mnt->mnt, flags);
        if (retval)
@@ -1218,22 +1263,21 @@ static int do_umount(struct mount *mnt, int flags)
                return retval;
        }
 
-       down_write(&namespace_sem);
+       namespace_lock();
        br_write_lock(&vfsmount_lock);
        event++;
 
        if (!(flags & MNT_DETACH))
-               shrink_submounts(mnt, &umount_list);
+               shrink_submounts(mnt);
 
        retval = -EBUSY;
        if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
                if (!list_empty(&mnt->mnt_list))
-                       umount_tree(mnt, 1, &umount_list);
+                       umount_tree(mnt, 1);
                retval = 0;
        }
        br_write_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
-       release_mounts(&umount_list);
+       namespace_unlock();
        return retval;
 }
 
@@ -1306,13 +1350,13 @@ static bool mnt_ns_loop(struct path *path)
         * mount namespace loop?
         */
        struct inode *inode = path->dentry->d_inode;
-       struct proc_inode *ei;
+       struct proc_ns *ei;
        struct mnt_namespace *mnt_ns;
 
        if (!proc_ns_inode(inode))
                return false;
 
-       ei = PROC_I(inode);
+       ei = get_proc_ns(inode);
        if (ei->ns_ops != &mntns_operations)
                return false;
 
@@ -1323,8 +1367,7 @@ static bool mnt_ns_loop(struct path *path)
 struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
                                        int flag)
 {
-       struct mount *res, *p, *q, *r;
-       struct path path;
+       struct mount *res, *p, *q, *r, *parent;
 
        if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
                return ERR_PTR(-EINVAL);
@@ -1351,25 +1394,22 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
                                q = q->mnt_parent;
                        }
                        p = s;
-                       path.mnt = &q->mnt;
-                       path.dentry = p->mnt_mountpoint;
+                       parent = q;
                        q = clone_mnt(p, p->mnt.mnt_root, flag);
                        if (IS_ERR(q))
                                goto out;
                        br_write_lock(&vfsmount_lock);
                        list_add_tail(&q->mnt_list, &res->mnt_list);
-                       attach_mnt(q, &path);
+                       attach_mnt(q, parent, p->mnt_mp);
                        br_write_unlock(&vfsmount_lock);
                }
        }
        return res;
 out:
        if (res) {
-               LIST_HEAD(umount_list);
                br_write_lock(&vfsmount_lock);
-               umount_tree(res, 0, &umount_list);
+               umount_tree(res, 0);
                br_write_unlock(&vfsmount_lock);
-               release_mounts(&umount_list);
        }
        return q;
 }
@@ -1379,10 +1419,10 @@ out:
 struct vfsmount *collect_mounts(struct path *path)
 {
        struct mount *tree;
-       down_write(&namespace_sem);
+       namespace_lock();
        tree = copy_tree(real_mount(path->mnt), path->dentry,
                         CL_COPY_ALL | CL_PRIVATE);
-       up_write(&namespace_sem);
+       namespace_unlock();
        if (IS_ERR(tree))
                return NULL;
        return &tree->mnt;
@@ -1390,13 +1430,11 @@ struct vfsmount *collect_mounts(struct path *path)
 
 void drop_collected_mounts(struct vfsmount *mnt)
 {
-       LIST_HEAD(umount_list);
-       down_write(&namespace_sem);
+       namespace_lock();
        br_write_lock(&vfsmount_lock);
-       umount_tree(real_mount(mnt), 0, &umount_list);
+       umount_tree(real_mount(mnt), 0);
        br_write_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
-       release_mounts(&umount_list);
+       namespace_unlock();
 }
 
 int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
@@ -1505,11 +1543,11 @@ static int invent_group_ids(struct mount *mnt, bool recurse)
  * in allocations.
  */
 static int attach_recursive_mnt(struct mount *source_mnt,
-                       struct path *path, struct path *parent_path)
+                       struct mount *dest_mnt,
+                       struct mountpoint *dest_mp,
+                       struct path *parent_path)
 {
        LIST_HEAD(tree_list);
-       struct mount *dest_mnt = real_mount(path->mnt);
-       struct dentry *dest_dentry = path->dentry;
        struct mount *child, *p;
        int err;
 
@@ -1518,7 +1556,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
                if (err)
                        goto out;
        }
-       err = propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list);
+       err = propagate_mnt(dest_mnt, dest_mp, source_mnt, &tree_list);
        if (err)
                goto out_cleanup_ids;
 
@@ -1530,10 +1568,10 @@ static int attach_recursive_mnt(struct mount *source_mnt,
        }
        if (parent_path) {
                detach_mnt(source_mnt, parent_path);
-               attach_mnt(source_mnt, path);
+               attach_mnt(source_mnt, dest_mnt, dest_mp);
                touch_mnt_namespace(source_mnt->mnt_ns);
        } else {
-               mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
+               mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
                commit_tree(source_mnt);
        }
 
@@ -1552,46 +1590,53 @@ static int attach_recursive_mnt(struct mount *source_mnt,
        return err;
 }
 
-static int lock_mount(struct path *path)
+static struct mountpoint *lock_mount(struct path *path)
 {
        struct vfsmount *mnt;
+       struct dentry *dentry = path->dentry;
 retry:
-       mutex_lock(&path->dentry->d_inode->i_mutex);
-       if (unlikely(cant_mount(path->dentry))) {
-               mutex_unlock(&path->dentry->d_inode->i_mutex);
-               return -ENOENT;
+       mutex_lock(&dentry->d_inode->i_mutex);
+       if (unlikely(cant_mount(dentry))) {
+               mutex_unlock(&dentry->d_inode->i_mutex);
+               return ERR_PTR(-ENOENT);
        }
-       down_write(&namespace_sem);
+       namespace_lock();
        mnt = lookup_mnt(path);
-       if (likely(!mnt))
-               return 0;
-       up_write(&namespace_sem);
+       if (likely(!mnt)) {
+               struct mountpoint *mp = new_mountpoint(dentry);
+               if (IS_ERR(mp)) {
+                       namespace_unlock();
+                       mutex_unlock(&dentry->d_inode->i_mutex);
+                       return mp;
+               }
+               return mp;
+       }
+       namespace_unlock();
        mutex_unlock(&path->dentry->d_inode->i_mutex);
        path_put(path);
        path->mnt = mnt;
-       path->dentry = dget(mnt->mnt_root);
+       dentry = path->dentry = dget(mnt->mnt_root);
        goto retry;
 }
 
-static void unlock_mount(struct path *path)
+static void unlock_mount(struct mountpoint *where)
 {
-       up_write(&namespace_sem);
-       mutex_unlock(&path->dentry->d_inode->i_mutex);
+       struct dentry *dentry = where->m_dentry;
+       put_mountpoint(where);
+       namespace_unlock();
+       mutex_unlock(&dentry->d_inode->i_mutex);
 }
 
-static int graft_tree(struct mount *mnt, struct path *path)
+static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
 {
        if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER)
                return -EINVAL;
 
-       if (S_ISDIR(path->dentry->d_inode->i_mode) !=
+       if (S_ISDIR(mp->m_dentry->d_inode->i_mode) !=
              S_ISDIR(mnt->mnt.mnt_root->d_inode->i_mode))
                return -ENOTDIR;
 
-       if (d_unlinked(path->dentry))
-               return -ENOENT;
-
-       return attach_recursive_mnt(mnt, path, NULL);
+       return attach_recursive_mnt(mnt, p, mp, NULL);
 }
 
 /*
@@ -1629,7 +1674,7 @@ static int do_change_type(struct path *path, int flag)
        if (!type)
                return -EINVAL;
 
-       down_write(&namespace_sem);
+       namespace_lock();
        if (type == MS_SHARED) {
                err = invent_group_ids(mnt, recurse);
                if (err)
@@ -1642,7 +1687,7 @@ static int do_change_type(struct path *path, int flag)
        br_write_unlock(&vfsmount_lock);
 
  out_unlock:
-       up_write(&namespace_sem);
+       namespace_unlock();
        return err;
 }
 
@@ -1652,9 +1697,9 @@ static int do_change_type(struct path *path, int flag)
 static int do_loopback(struct path *path, const char *old_name,
                                int recurse)
 {
-       LIST_HEAD(umount_list);
        struct path old_path;
-       struct mount *mnt = NULL, *old;
+       struct mount *mnt = NULL, *old, *parent;
+       struct mountpoint *mp;
        int err;
        if (!old_name || !*old_name)
                return -EINVAL;
@@ -1666,17 +1711,19 @@ static int do_loopback(struct path *path, const char *old_name,
        if (mnt_ns_loop(&old_path))
                goto out; 
 
-       err = lock_mount(path);
-       if (err)
+       mp = lock_mount(path);
+       err = PTR_ERR(mp);
+       if (IS_ERR(mp))
                goto out;
 
        old = real_mount(old_path.mnt);
+       parent = real_mount(path->mnt);
 
        err = -EINVAL;
        if (IS_MNT_UNBINDABLE(old))
                goto out2;
 
-       if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old))
+       if (!check_mnt(parent) || !check_mnt(old))
                goto out2;
 
        if (recurse)
@@ -1686,18 +1733,17 @@ static int do_loopback(struct path *path, const char *old_name,
 
        if (IS_ERR(mnt)) {
                err = PTR_ERR(mnt);
-               goto out;
+               goto out2;
        }
 
-       err = graft_tree(mnt, path);
+       err = graft_tree(mnt, parent, mp);
        if (err) {
                br_write_lock(&vfsmount_lock);
-               umount_tree(mnt, 0, &umount_list);
+               umount_tree(mnt, 0);
                br_write_unlock(&vfsmount_lock);
        }
 out2:
-       unlock_mount(path);
-       release_mounts(&umount_list);
+       unlock_mount(mp);
 out:
        path_put(&old_path);
        return err;
@@ -1779,6 +1825,7 @@ static int do_move_mount(struct path *path, const char *old_name)
        struct path old_path, parent_path;
        struct mount *p;
        struct mount *old;
+       struct mountpoint *mp;
        int err;
        if (!old_name || !*old_name)
                return -EINVAL;
@@ -1786,8 +1833,9 @@ static int do_move_mount(struct path *path, const char *old_name)
        if (err)
                return err;
 
-       err = lock_mount(path);
-       if (err < 0)
+       mp = lock_mount(path);
+       err = PTR_ERR(mp);
+       if (IS_ERR(mp))
                goto out;
 
        old = real_mount(old_path.mnt);
@@ -1797,9 +1845,6 @@ static int do_move_mount(struct path *path, const char *old_name)
        if (!check_mnt(p) || !check_mnt(old))
                goto out1;
 
-       if (d_unlinked(path->dentry))
-               goto out1;
-
        err = -EINVAL;
        if (old_path.dentry != old_path.mnt->mnt_root)
                goto out1;
@@ -1826,7 +1871,7 @@ static int do_move_mount(struct path *path, const char *old_name)
                if (p == old)
                        goto out1;
 
-       err = attach_recursive_mnt(old, path, &parent_path);
+       err = attach_recursive_mnt(old, real_mount(path->mnt), mp, &parent_path);
        if (err)
                goto out1;
 
@@ -1834,7 +1879,7 @@ static int do_move_mount(struct path *path, const char *old_name)
         * automatically */
        list_del_init(&old->mnt_expire);
 out1:
-       unlock_mount(path);
+       unlock_mount(mp);
 out:
        if (!err)
                path_put(&parent_path);
@@ -1870,21 +1915,24 @@ static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
  */
 static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags)
 {
+       struct mountpoint *mp;
+       struct mount *parent;
        int err;
 
        mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);
 
-       err = lock_mount(path);
-       if (err)
-               return err;
+       mp = lock_mount(path);
+       if (IS_ERR(mp))
+               return PTR_ERR(mp);
 
+       parent = real_mount(path->mnt);
        err = -EINVAL;
-       if (unlikely(!check_mnt(real_mount(path->mnt)))) {
+       if (unlikely(!check_mnt(parent))) {
                /* that's acceptable only for automounts done in private ns */
                if (!(mnt_flags & MNT_SHRINKABLE))
                        goto unlock;
                /* ... and for those we'd better have mountpoint still alive */
-               if (!real_mount(path->mnt)->mnt_ns)
+               if (!parent->mnt_ns)
                        goto unlock;
        }
 
@@ -1899,10 +1947,10 @@ static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags)
                goto unlock;
 
        newmnt->mnt.mnt_flags = mnt_flags;
-       err = graft_tree(newmnt, path);
+       err = graft_tree(newmnt, parent, mp);
 
 unlock:
-       unlock_mount(path);
+       unlock_mount(mp);
        return err;
 }
 
@@ -1975,11 +2023,11 @@ int finish_automount(struct vfsmount *m, struct path *path)
 fail:
        /* remove m from any expiration list it may be on */
        if (!list_empty(&mnt->mnt_expire)) {
-               down_write(&namespace_sem);
+               namespace_lock();
                br_write_lock(&vfsmount_lock);
                list_del_init(&mnt->mnt_expire);
                br_write_unlock(&vfsmount_lock);
-               up_write(&namespace_sem);
+               namespace_unlock();
        }
        mntput(m);
        mntput(m);
@@ -1993,13 +2041,13 @@ fail:
  */
 void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list)
 {
-       down_write(&namespace_sem);
+       namespace_lock();
        br_write_lock(&vfsmount_lock);
 
        list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list);
 
        br_write_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
+       namespace_unlock();
 }
 EXPORT_SYMBOL(mnt_set_expiry);
 
@@ -2012,12 +2060,11 @@ void mark_mounts_for_expiry(struct list_head *mounts)
 {
        struct mount *mnt, *next;
        LIST_HEAD(graveyard);
-       LIST_HEAD(umounts);
 
        if (list_empty(mounts))
                return;
 
-       down_write(&namespace_sem);
+       namespace_lock();
        br_write_lock(&vfsmount_lock);
 
        /* extract from the expiration list every vfsmount that matches the
@@ -2035,12 +2082,10 @@ void mark_mounts_for_expiry(struct list_head *mounts)
        while (!list_empty(&graveyard)) {
                mnt = list_first_entry(&graveyard, struct mount, mnt_expire);
                touch_mnt_namespace(mnt->mnt_ns);
-               umount_tree(mnt, 1, &umounts);
+               umount_tree(mnt, 1);
        }
        br_write_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
-
-       release_mounts(&umounts);
+       namespace_unlock();
 }
 
 EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
@@ -2097,7 +2142,7 @@ resume:
  *
  * vfsmount_lock must be held for write
  */
-static void shrink_submounts(struct mount *mnt, struct list_head *umounts)
+static void shrink_submounts(struct mount *mnt)
 {
        LIST_HEAD(graveyard);
        struct mount *m;
@@ -2108,7 +2153,7 @@ static void shrink_submounts(struct mount *mnt, struct list_head *umounts)
                        m = list_first_entry(&graveyard, struct mount,
                                                mnt_expire);
                        touch_mnt_namespace(m->mnt_ns);
-                       umount_tree(m, 1, umounts);
+                       umount_tree(m, 1);
                }
        }
 }
@@ -2335,14 +2380,14 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
        if (IS_ERR(new_ns))
                return new_ns;
 
-       down_write(&namespace_sem);
+       namespace_lock();
        /* First pass: copy the tree topology */
        copy_flags = CL_COPY_ALL | CL_EXPIRE;
        if (user_ns != mnt_ns->user_ns)
                copy_flags |= CL_SHARED_TO_SLAVE;
        new = copy_tree(old, old->mnt.mnt_root, copy_flags);
        if (IS_ERR(new)) {
-               up_write(&namespace_sem);
+               namespace_unlock();
                free_mnt_ns(new_ns);
                return ERR_CAST(new);
        }
@@ -2373,7 +2418,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
                p = next_mnt(p, old);
                q = next_mnt(q, new);
        }
-       up_write(&namespace_sem);
+       namespace_unlock();
 
        if (rootmnt)
                mntput(rootmnt);
@@ -2543,7 +2588,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
                const char __user *, put_old)
 {
        struct path new, old, parent_path, root_parent, root;
-       struct mount *new_mnt, *root_mnt;
+       struct mount *new_mnt, *root_mnt, *old_mnt;
+       struct mountpoint *old_mp, *root_mp;
        int error;
 
        if (!may_mount())
@@ -2562,14 +2608,16 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
                goto out2;
 
        get_fs_root(current->fs, &root);
-       error = lock_mount(&old);
-       if (error)
+       old_mp = lock_mount(&old);
+       error = PTR_ERR(old_mp);
+       if (IS_ERR(old_mp))
                goto out3;
 
        error = -EINVAL;
        new_mnt = real_mount(new.mnt);
        root_mnt = real_mount(root.mnt);
-       if (IS_MNT_SHARED(real_mount(old.mnt)) ||
+       old_mnt = real_mount(old.mnt);
+       if (IS_MNT_SHARED(old_mnt) ||
                IS_MNT_SHARED(new_mnt->mnt_parent) ||
                IS_MNT_SHARED(root_mnt->mnt_parent))
                goto out4;
@@ -2578,37 +2626,37 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
        error = -ENOENT;
        if (d_unlinked(new.dentry))
                goto out4;
-       if (d_unlinked(old.dentry))
-               goto out4;
        error = -EBUSY;
-       if (new.mnt == root.mnt ||
-           old.mnt == root.mnt)
+       if (new_mnt == root_mnt || old_mnt == root_mnt)
                goto out4; /* loop, on the same file system  */
        error = -EINVAL;
        if (root.mnt->mnt_root != root.dentry)
                goto out4; /* not a mountpoint */
        if (!mnt_has_parent(root_mnt))
                goto out4; /* not attached */
+       root_mp = root_mnt->mnt_mp;
        if (new.mnt->mnt_root != new.dentry)
                goto out4; /* not a mountpoint */
        if (!mnt_has_parent(new_mnt))
                goto out4; /* not attached */
        /* make sure we can reach put_old from new_root */
-       if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new))
+       if (!is_path_reachable(old_mnt, old.dentry, &new))
                goto out4;
+       root_mp->m_count++; /* pin it so it won't go away */
        br_write_lock(&vfsmount_lock);
        detach_mnt(new_mnt, &parent_path);
        detach_mnt(root_mnt, &root_parent);
        /* mount old root on put_old */
-       attach_mnt(root_mnt, &old);
+       attach_mnt(root_mnt, old_mnt, old_mp);
        /* mount new_root on / */
-       attach_mnt(new_mnt, &root_parent);
+       attach_mnt(new_mnt, real_mount(root_parent.mnt), root_mp);
        touch_mnt_namespace(current->nsproxy->mnt_ns);
        br_write_unlock(&vfsmount_lock);
        chroot_fs_refs(&root, &new);
+       put_mountpoint(root_mp);
        error = 0;
 out4:
-       unlock_mount(&old);
+       unlock_mount(old_mp);
        if (!error) {
                path_put(&root_parent);
                path_put(&parent_path);
@@ -2663,14 +2711,17 @@ void __init mnt_init(void)
                        0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
 
        mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
+       mountpoint_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
 
-       if (!mount_hashtable)
+       if (!mount_hashtable || !mountpoint_hashtable)
                panic("Failed to allocate mount hash table\n");
 
        printk(KERN_INFO "Mount-cache hash table entries: %lu\n", HASH_SIZE);
 
        for (u = 0; u < HASH_SIZE; u++)
                INIT_LIST_HEAD(&mount_hashtable[u]);
+       for (u = 0; u < HASH_SIZE; u++)
+               INIT_LIST_HEAD(&mountpoint_hashtable[u]);
 
        br_lock_init(&vfsmount_lock);
 
@@ -2687,16 +2738,13 @@ void __init mnt_init(void)
 
 void put_mnt_ns(struct mnt_namespace *ns)
 {
-       LIST_HEAD(umount_list);
-
        if (!atomic_dec_and_test(&ns->count))
                return;
-       down_write(&namespace_sem);
+       namespace_lock();
        br_write_lock(&vfsmount_lock);
-       umount_tree(ns->root, 0, &umount_list);
+       umount_tree(ns->root, 0);
        br_write_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
-       release_mounts(&umount_list);
+       namespace_unlock();
        free_mnt_ns(ns);
 }
 
index 7dafd6899a62a5893be0bd304d4e38e40a1957c8..26910c8154da1be65c0318eb088d5d69d3e08baf 100644 (file)
@@ -1051,6 +1051,7 @@ static struct file_system_type ncp_fs_type = {
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("ncpfs");
 
 static int __init init_ncp_fs(void)
 {
index 737d839bc17b5aa0ae58e5350a235af1f8adfb2b..6fc7b5cae92bf6526bee07696f12977322f2cb5e 100644 (file)
@@ -55,7 +55,8 @@ static void dev_remove(struct net *net, dev_t dev)
 
        bl_pipe_msg.bl_wq = &nn->bl_wq;
        memset(msg, 0, sizeof(*msg));
-       msg->data = kzalloc(1 + sizeof(bl_umount_request), GFP_NOFS);
+       msg->len = sizeof(bl_msg) + bl_msg.totallen;
+       msg->data = kzalloc(msg->len, GFP_NOFS);
        if (!msg->data)
                goto out;
 
@@ -66,7 +67,6 @@ static void dev_remove(struct net *net, dev_t dev)
        memcpy(msg->data, &bl_msg, sizeof(bl_msg));
        dataptr = (uint8_t *) msg->data;
        memcpy(&dataptr[sizeof(bl_msg)], &bl_umount_request, sizeof(bl_umount_request));
-       msg->len = sizeof(bl_msg) + bl_msg.totallen;
 
        add_wait_queue(&nn->bl_wq, &wq);
        if (rpc_queue_upcall(nn->bl_device_pipe, msg) < 0) {
index dc0f98dfa71773bd467a1b6891b2f916b696b734..c516da5873fd12df0d3c9877b2c3189423c0dec4 100644 (file)
@@ -726,9 +726,9 @@ out1:
        return ret;
 }
 
-static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data)
+static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data, size_t datalen)
 {
-       return key_instantiate_and_link(key, data, strlen(data) + 1,
+       return key_instantiate_and_link(key, data, datalen,
                                        id_resolver_cache->thread_keyring,
                                        authkey);
 }
@@ -738,6 +738,7 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
                struct key *key, struct key *authkey)
 {
        char id_str[NFS_UINT_MAXLEN];
+       size_t len;
        int ret = -ENOKEY;
 
        /* ret = -ENOKEY */
@@ -747,13 +748,15 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
        case IDMAP_CONV_NAMETOID:
                if (strcmp(upcall->im_name, im->im_name) != 0)
                        break;
-               sprintf(id_str, "%d", im->im_id);
-               ret = nfs_idmap_instantiate(key, authkey, id_str);
+               /* Note: here we store the NUL terminator too */
+               len = sprintf(id_str, "%d", im->im_id) + 1;
+               ret = nfs_idmap_instantiate(key, authkey, id_str, len);
                break;
        case IDMAP_CONV_IDTONAME:
                if (upcall->im_id != im->im_id)
                        break;
-               ret = nfs_idmap_instantiate(key, authkey, im->im_name);
+               len = strlen(im->im_name);
+               ret = nfs_idmap_instantiate(key, authkey, im->im_name, len);
                break;
        default:
                ret = -EINVAL;
index 49eeb044c109c0bb3c3878db7b8b60a780b50f97..4fb234d3aefb240f3d067523bda6df467336d2d0 100644 (file)
@@ -129,7 +129,6 @@ static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo)
 {
        if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
                return;
-       clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
        pnfs_return_layout(inode);
 }
 
index b2671cb0f901b8e904ee4b91961d2029e12fb2dc..26431cf62ddbc393fd5fe1e432742be37d06e12e 100644 (file)
@@ -2632,7 +2632,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
        int status;
 
        if (pnfs_ld_layoutret_on_setattr(inode))
-               pnfs_return_layout(inode);
+               pnfs_commit_and_return_layout(inode);
 
        nfs_fattr_init(fattr);
        
@@ -6416,22 +6416,8 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
 static void nfs4_layoutcommit_release(void *calldata)
 {
        struct nfs4_layoutcommit_data *data = calldata;
-       struct pnfs_layout_segment *lseg, *tmp;
-       unsigned long *bitlock = &NFS_I(data->args.inode)->flags;
 
        pnfs_cleanup_layoutcommit(data);
-       /* Matched by references in pnfs_set_layoutcommit */
-       list_for_each_entry_safe(lseg, tmp, &data->lseg_list, pls_lc_list) {
-               list_del_init(&lseg->pls_lc_list);
-               if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT,
-                                      &lseg->pls_flags))
-                       pnfs_put_lseg(lseg);
-       }
-
-       clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
-       smp_mb__after_clear_bit();
-       wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
-
        put_rpccred(data->cred);
        kfree(data);
 }
index 48ac5aad62589cd7140f55a52d5ee63f31e743b5..4bdffe0ba025228803b65d4fe54ab5cb0adda0ed 100644 (file)
@@ -417,6 +417,16 @@ should_free_lseg(struct pnfs_layout_range *lseg_range,
               lo_seg_intersecting(lseg_range, recall_range);
 }
 
+static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
+               struct list_head *tmp_list)
+{
+       if (!atomic_dec_and_test(&lseg->pls_refcount))
+               return false;
+       pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
+       list_add(&lseg->pls_list, tmp_list);
+       return true;
+}
+
 /* Returns 1 if lseg is removed from list, 0 otherwise */
 static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
                             struct list_head *tmp_list)
@@ -430,11 +440,8 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
                 */
                dprintk("%s: lseg %p ref %d\n", __func__, lseg,
                        atomic_read(&lseg->pls_refcount));
-               if (atomic_dec_and_test(&lseg->pls_refcount)) {
-                       pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
-                       list_add(&lseg->pls_list, tmp_list);
+               if (pnfs_lseg_dec_and_remove_zero(lseg, tmp_list))
                        rv = 1;
-               }
        }
        return rv;
 }
@@ -777,6 +784,21 @@ send_layoutget(struct pnfs_layout_hdr *lo,
        return lseg;
 }
 
+static void pnfs_clear_layoutcommit(struct inode *inode,
+               struct list_head *head)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+       struct pnfs_layout_segment *lseg, *tmp;
+
+       if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
+               return;
+       list_for_each_entry_safe(lseg, tmp, &nfsi->layout->plh_segs, pls_list) {
+               if (!test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
+                       continue;
+               pnfs_lseg_dec_and_remove_zero(lseg, head);
+       }
+}
+
 /*
  * Initiates a LAYOUTRETURN(FILE), and removes the pnfs_layout_hdr
  * when the layout segment list is empty.
@@ -808,6 +830,7 @@ _pnfs_return_layout(struct inode *ino)
        /* Reference matched in nfs4_layoutreturn_release */
        pnfs_get_layout_hdr(lo);
        empty = list_empty(&lo->plh_segs);
+       pnfs_clear_layoutcommit(ino, &tmp_list);
        pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
        /* Don't send a LAYOUTRETURN if list was initially empty */
        if (empty) {
@@ -820,8 +843,6 @@ _pnfs_return_layout(struct inode *ino)
        spin_unlock(&ino->i_lock);
        pnfs_free_lseg_list(&tmp_list);
 
-       WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags));
-
        lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
        if (unlikely(lrp == NULL)) {
                status = -ENOMEM;
@@ -845,6 +866,33 @@ out:
 }
 EXPORT_SYMBOL_GPL(_pnfs_return_layout);
 
+int
+pnfs_commit_and_return_layout(struct inode *inode)
+{
+       struct pnfs_layout_hdr *lo;
+       int ret;
+
+       spin_lock(&inode->i_lock);
+       lo = NFS_I(inode)->layout;
+       if (lo == NULL) {
+               spin_unlock(&inode->i_lock);
+               return 0;
+       }
+       pnfs_get_layout_hdr(lo);
+       /* Block new layoutgets and read/write to ds */
+       lo->plh_block_lgets++;
+       spin_unlock(&inode->i_lock);
+       filemap_fdatawait(inode->i_mapping);
+       ret = pnfs_layoutcommit_inode(inode, true);
+       if (ret == 0)
+               ret = _pnfs_return_layout(inode);
+       spin_lock(&inode->i_lock);
+       lo->plh_block_lgets--;
+       spin_unlock(&inode->i_lock);
+       pnfs_put_layout_hdr(lo);
+       return ret;
+}
+
 bool pnfs_roc(struct inode *ino)
 {
        struct pnfs_layout_hdr *lo;
@@ -1458,7 +1506,6 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data)
        dprintk("pnfs write error = %d\n", hdr->pnfs_error);
        if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags &
            PNFS_LAYOUTRET_ON_ERROR) {
-               clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags);
                pnfs_return_layout(hdr->inode);
        }
        if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
@@ -1613,7 +1660,6 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
        dprintk("pnfs read error = %d\n", hdr->pnfs_error);
        if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags &
            PNFS_LAYOUTRET_ON_ERROR) {
-               clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags);
                pnfs_return_layout(hdr->inode);
        }
        if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
@@ -1746,11 +1792,27 @@ static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
 
        list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
                if (lseg->pls_range.iomode == IOMODE_RW &&
-                   test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
+                   test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
                        list_add(&lseg->pls_lc_list, listp);
        }
 }
 
+static void pnfs_list_write_lseg_done(struct inode *inode, struct list_head *listp)
+{
+       struct pnfs_layout_segment *lseg, *tmp;
+       unsigned long *bitlock = &NFS_I(inode)->flags;
+
+       /* Matched by references in pnfs_set_layoutcommit */
+       list_for_each_entry_safe(lseg, tmp, listp, pls_lc_list) {
+               list_del_init(&lseg->pls_lc_list);
+               pnfs_put_lseg(lseg);
+       }
+
+       clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
+       smp_mb__after_clear_bit();
+       wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
+}
+
 void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
 {
        pnfs_layout_io_set_failed(lseg->pls_layout, lseg->pls_range.iomode);
@@ -1795,6 +1857,7 @@ void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data)
 
        if (nfss->pnfs_curr_ld->cleanup_layoutcommit)
                nfss->pnfs_curr_ld->cleanup_layoutcommit(data);
+       pnfs_list_write_lseg_done(data->args.inode, &data->lseg_list);
 }
 
 /*
index 94ba804177483d3c78694ae1708e95a2d34048d5..f5f8a470a647c7dc2f3a475e3e852d1aa7c97f5e 100644 (file)
@@ -219,6 +219,7 @@ void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
 void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
 int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
 int _pnfs_return_layout(struct inode *);
+int pnfs_commit_and_return_layout(struct inode *);
 void pnfs_ld_write_done(struct nfs_write_data *);
 void pnfs_ld_read_done(struct nfs_read_data *);
 struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
@@ -407,6 +408,11 @@ static inline int pnfs_return_layout(struct inode *ino)
        return 0;
 }
 
+static inline int pnfs_commit_and_return_layout(struct inode *inode)
+{
+       return 0;
+}
+
 static inline bool
 pnfs_ld_layoutret_on_setattr(struct inode *inode)
 {
index 17b32b7224574207fba2ee5384474b69d6abcc99..2f8a29db0f1bed59a8300d64038ebe4404d611a6 100644 (file)
@@ -294,6 +294,7 @@ struct file_system_type nfs_fs_type = {
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("nfs");
 EXPORT_SYMBOL_GPL(nfs_fs_type);
 
 struct file_system_type nfs_xdev_fs_type = {
@@ -333,6 +334,8 @@ struct file_system_type nfs4_fs_type = {
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("nfs4");
+MODULE_ALIAS("nfs4");
 EXPORT_SYMBOL_GPL(nfs4_fs_type);
 
 static int __init register_nfs4_fs(void)
@@ -2717,6 +2720,5 @@ module_param(send_implementation_id, ushort, 0644);
 MODULE_PARM_DESC(send_implementation_id,
                "Send implementation ID with NFSv4.1 exchange_id");
 MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
-MODULE_ALIAS("nfs4");
 
 #endif /* CONFIG_NFS_V4 */
index 16d39c6c4fbb56b11c25ac8927b8913b1a928a15..2e27430b9070fc6ca71a56432409b85f465f5d0a 100644 (file)
@@ -230,37 +230,6 @@ static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
                __nfs4_file_put_access(fp, oflag);
 }
 
-static inline int get_new_stid(struct nfs4_stid *stid)
-{
-       static int min_stateid = 0;
-       struct idr *stateids = &stid->sc_client->cl_stateids;
-       int new_stid;
-       int error;
-
-       error = idr_get_new_above(stateids, stid, min_stateid, &new_stid);
-       /*
-        * Note: the necessary preallocation was done in
-        * nfs4_alloc_stateid().  The idr code caps the number of
-        * preallocations that can exist at a time, but the state lock
-        * prevents anyone from using ours before we get here:
-        */
-       WARN_ON_ONCE(error);
-       /*
-        * It shouldn't be a problem to reuse an opaque stateid value.
-        * I don't think it is for 4.1.  But with 4.0 I worry that, for
-        * example, a stray write retransmission could be accepted by
-        * the server when it should have been rejected.  Therefore,
-        * adopt a trick from the sctp code to attempt to maximize the
-        * amount of time until an id is reused, by ensuring they always
-        * "increase" (mod INT_MAX):
-        */
-
-       min_stateid = new_stid+1;
-       if (min_stateid == INT_MAX)
-               min_stateid = 0;
-       return new_stid;
-}
-
 static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct
 kmem_cache *slab)
 {
@@ -273,9 +242,8 @@ kmem_cache *slab)
        if (!stid)
                return NULL;
 
-       if (!idr_pre_get(stateids, GFP_KERNEL))
-               goto out_free;
-       if (idr_get_new_above(stateids, stid, min_stateid, &new_id))
+       new_id = idr_alloc(stateids, stid, min_stateid, 0, GFP_KERNEL);
+       if (new_id < 0)
                goto out_free;
        stid->sc_client = cl;
        stid->sc_type = 0;
index 62c1ee128aebafbd82e70863e57caa74de804e13..ca05f6dc3544b4c216eb369d9e01fe7a48f0e90a 100644 (file)
@@ -102,7 +102,8 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
 {
        if (rp->c_type == RC_REPLBUFF)
                kfree(rp->c_replvec.iov_base);
-       hlist_del(&rp->c_hash);
+       if (!hlist_unhashed(&rp->c_hash))
+               hlist_del(&rp->c_hash);
        list_del(&rp->c_lru);
        --num_drc_entries;
        kmem_cache_free(drc_slab, rp);
@@ -118,6 +119,10 @@ nfsd_reply_cache_free(struct svc_cacherep *rp)
 
 int nfsd_reply_cache_init(void)
 {
+       INIT_LIST_HEAD(&lru_head);
+       max_drc_entries = nfsd_cache_size_limit();
+       num_drc_entries = 0;
+
        register_shrinker(&nfsd_reply_cache_shrinker);
        drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
                                        0, 0, NULL);
@@ -128,10 +133,6 @@ int nfsd_reply_cache_init(void)
        if (!cache_hash)
                goto out_nomem;
 
-       INIT_LIST_HEAD(&lru_head);
-       max_drc_entries = nfsd_cache_size_limit();
-       num_drc_entries = 0;
-
        return 0;
 out_nomem:
        printk(KERN_ERR "nfsd: failed to allocate reply cache\n");
index 13a21c8fca490884e05e832d1a657daf9d1af58f..5bee0313dffd718d557bd3b01cdb0a2321d59f02 100644 (file)
@@ -177,7 +177,7 @@ static int export_features_open(struct inode *inode, struct file *file)
        return single_open(file, export_features_show, NULL);
 }
 
-static struct file_operations export_features_operations = {
+static const struct file_operations export_features_operations = {
        .open           = export_features_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -196,7 +196,7 @@ static int supported_enctypes_open(struct inode *inode, struct file *file)
        return single_open(file, supported_enctypes_show, NULL);
 }
 
-static struct file_operations supported_enctypes_ops = {
+static const struct file_operations supported_enctypes_ops = {
        .open           = supported_enctypes_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -1090,6 +1090,7 @@ static struct file_system_type nfsd_fs_type = {
        .mount          = nfsd_mount,
        .kill_sb        = nfsd_umount,
 };
+MODULE_ALIAS_FS("nfsd");
 
 #ifdef CONFIG_PROC_FS
 static int create_proc_exports_entry(void)
index 2a7eb536de0bec80dfbfd7d981139f2e925e644e..2b2e2396a86913b4d4e69c376852ded82dd9be3a 100644 (file)
@@ -1013,6 +1013,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        int                     host_err;
        int                     stable = *stablep;
        int                     use_wgather;
+       loff_t                  pos = offset;
 
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
@@ -1025,7 +1026,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
        /* Write the data. */
        oldfs = get_fs(); set_fs(KERNEL_DS);
-       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
+       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos);
        set_fs(oldfs);
        if (host_err < 0)
                goto out_nfserr;
index 3c991dc84f2f2df6f8c9dccd922d8edbf1ff32a5..c7d1f9f18b094fb1f281fb0dfcb6b53328dc72fe 100644 (file)
@@ -1361,6 +1361,7 @@ struct file_system_type nilfs_fs_type = {
        .kill_sb  = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("nilfs2");
 
 static void nilfs_inode_init_once(void *obj)
 {
index e0f7c1241a6adb60e03034bb118586407a24e37c..1db6d886cbf25f472b1aaeb18eb554ccacbbe059 100644 (file)
@@ -287,9 +287,6 @@ static int inotify_release(struct inode *ignored, struct file *file)
 
        pr_debug("%s: group=%p\n", __func__, group);
 
-       if (file->f_flags & FASYNC)
-               fsnotify_fasync(-1, file, 0);
-
        /* free this group, matching get was inotify_init->fsnotify_obtain_group */
        fsnotify_destroy_group(group);
 
index 5b2d4f0853acfad180c03d9c10764b3199e31089..1da4b81e6f76984ad7b5c9b52237d24c2fd1894f 100644 (file)
@@ -2129,7 +2129,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        BUG_ON(iocb->ki_pos != pos);
 
-       sb_start_write(inode->i_sb);
        mutex_lock(&inode->i_mutex);
        ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
        mutex_unlock(&inode->i_mutex);
@@ -2138,7 +2137,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                if (err < 0)
                        ret = err;
        }
-       sb_end_write(inode->i_sb);
        return ret;
 }
 
index 4a8289f8b16c87495e8e6b94fccc6f83c5643c7e..82650d52d9168ee4f1e1b4282813afdaca5c7ec6 100644 (file)
@@ -3079,6 +3079,7 @@ static struct file_system_type ntfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ntfs");
 
 /* Stable names for the slab caches. */
 static const char ntfs_index_ctx_cache_name[] = "ntfs_index_ctx_cache";
index 4c5fc8d77dc26e8ee9f4238b03dc95c785945398..12bafb7265ceb8d2a13e8a1fb3aa86a73149a43e 100644 (file)
@@ -640,6 +640,7 @@ static struct file_system_type dlmfs_fs_type = {
        .mount          = dlmfs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("ocfs2_dlmfs");
 
 static int __init init_dlmfs_fs(void)
 {
index 6474cb44004d753d14e9af4648270432dc9f58f2..8a7509f9e6f5e0f49438876228a8e887ac2cdeb1 100644 (file)
@@ -2248,8 +2248,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        if (iocb->ki_left == 0)
                return 0;
 
-       sb_start_write(inode->i_sb);
-
        appending = file->f_flags & O_APPEND ? 1 : 0;
        direct_io = file->f_flags & O_DIRECT ? 1 : 0;
 
@@ -2423,7 +2421,6 @@ out_sems:
                ocfs2_iocb_clear_sem_locked(iocb);
 
        mutex_unlock(&inode->i_mutex);
-       sb_end_write(inode->i_sb);
 
        if (written)
                ret = written;
@@ -2468,8 +2465,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
                        out->f_path.dentry->d_name.len,
                        out->f_path.dentry->d_name.name, len);
 
-       if (pipe->inode)
-               mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT);
+       pipe_lock(pipe);
 
        splice_from_pipe_begin(&sd);
        do {
@@ -2489,8 +2485,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
        } while (ret > 0);
        splice_from_pipe_end(pipe, &sd);
 
-       if (pipe->inode)
-               mutex_unlock(&pipe->inode->i_mutex);
+       pipe_unlock(pipe);
 
        if (sd.num_spliced)
                ret = sd.num_spliced;
index 9b6910dec4ba79623027455e9833f4892ce3e0ea..01b85165552b75f1cf2e17893bea1054eb19ff81 100644 (file)
@@ -1266,6 +1266,7 @@ static struct file_system_type ocfs2_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
        .next           = NULL
 };
+MODULE_ALIAS_FS("ocfs2");
 
 static int ocfs2_check_set_options(struct super_block *sb,
                                   struct mount_options *options)
index 25d715c7c87abdd373918da6a42489332c88e3c0..d8b0afde2179cc4c4d790ed5a5632a0620cc6ca9 100644 (file)
@@ -572,6 +572,7 @@ static struct file_system_type omfs_fs_type = {
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("omfs");
 
 static int __init init_omfs_fs(void)
 {
index ae47fa7efb9d9306b6dbb2167f7fa3840164219e..75885ffde44e58a967799d3b461181e74bb8fd9c 100644 (file)
@@ -432,6 +432,7 @@ static struct file_system_type openprom_fs_type = {
        .mount          = openprom_mount,
        .kill_sb        = kill_anon_super,
 };
+MODULE_ALIAS_FS("openpromfs");
 
 static void op_inode_init_once(void *data)
 {
index 64a494cef0a00be57d0800637b71caf2537c2694..a029a14bacf1ff5d304caa6cf9471468fd3d39c0 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -25,6 +25,8 @@
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
+#include "internal.h"
+
 /*
  * The max size that a non-root user is allowed to grow the pipe. Can
  * be set by root in /proc/sys/fs/pipe-max-size
@@ -53,8 +55,8 @@ unsigned int pipe_min_size = PAGE_SIZE;
 
 static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
 {
-       if (pipe->inode)
-               mutex_lock_nested(&pipe->inode->i_mutex, subclass);
+       if (pipe->files)
+               mutex_lock_nested(&pipe->mutex, subclass);
 }
 
 void pipe_lock(struct pipe_inode_info *pipe)
@@ -68,11 +70,21 @@ EXPORT_SYMBOL(pipe_lock);
 
 void pipe_unlock(struct pipe_inode_info *pipe)
 {
-       if (pipe->inode)
-               mutex_unlock(&pipe->inode->i_mutex);
+       if (pipe->files)
+               mutex_unlock(&pipe->mutex);
 }
 EXPORT_SYMBOL(pipe_unlock);
 
+static inline void __pipe_lock(struct pipe_inode_info *pipe)
+{
+       mutex_lock_nested(&pipe->mutex, I_MUTEX_PARENT);
+}
+
+static inline void __pipe_unlock(struct pipe_inode_info *pipe)
+{
+       mutex_unlock(&pipe->mutex);
+}
+
 void pipe_double_lock(struct pipe_inode_info *pipe1,
                      struct pipe_inode_info *pipe2)
 {
@@ -361,8 +373,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
           unsigned long nr_segs, loff_t pos)
 {
        struct file *filp = iocb->ki_filp;
-       struct inode *inode = file_inode(filp);
-       struct pipe_inode_info *pipe;
+       struct pipe_inode_info *pipe = filp->private_data;
        int do_wakeup;
        ssize_t ret;
        struct iovec *iov = (struct iovec *)_iov;
@@ -375,8 +386,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
 
        do_wakeup = 0;
        ret = 0;
-       mutex_lock(&inode->i_mutex);
-       pipe = inode->i_pipe;
+       __pipe_lock(pipe);
        for (;;) {
                int bufs = pipe->nrbufs;
                if (bufs) {
@@ -464,7 +474,7 @@ redo:
                }
                pipe_wait(pipe);
        }
-       mutex_unlock(&inode->i_mutex);
+       __pipe_unlock(pipe);
 
        /* Signal writers asynchronously that there is more room. */
        if (do_wakeup) {
@@ -486,8 +496,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
            unsigned long nr_segs, loff_t ppos)
 {
        struct file *filp = iocb->ki_filp;
-       struct inode *inode = file_inode(filp);
-       struct pipe_inode_info *pipe;
+       struct pipe_inode_info *pipe = filp->private_data;
        ssize_t ret;
        int do_wakeup;
        struct iovec *iov = (struct iovec *)_iov;
@@ -501,8 +510,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
 
        do_wakeup = 0;
        ret = 0;
-       mutex_lock(&inode->i_mutex);
-       pipe = inode->i_pipe;
+       __pipe_lock(pipe);
 
        if (!pipe->readers) {
                send_sig(SIGPIPE, current, 0);
@@ -649,7 +657,7 @@ redo2:
                pipe->waiting_writers--;
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       __pipe_unlock(pipe);
        if (do_wakeup) {
                wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
                kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
@@ -662,29 +670,14 @@ out:
        return ret;
 }
 
-static ssize_t
-bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
-{
-       return -EBADF;
-}
-
-static ssize_t
-bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
-          loff_t *ppos)
-{
-       return -EBADF;
-}
-
 static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-       struct inode *inode = file_inode(filp);
-       struct pipe_inode_info *pipe;
+       struct pipe_inode_info *pipe = filp->private_data;
        int count, buf, nrbufs;
 
        switch (cmd) {
                case FIONREAD:
-                       mutex_lock(&inode->i_mutex);
-                       pipe = inode->i_pipe;
+                       __pipe_lock(pipe);
                        count = 0;
                        buf = pipe->curbuf;
                        nrbufs = pipe->nrbufs;
@@ -692,7 +685,7 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                                count += pipe->bufs[buf].len;
                                buf = (buf+1) & (pipe->buffers - 1);
                        }
-                       mutex_unlock(&inode->i_mutex);
+                       __pipe_unlock(pipe);
 
                        return put_user(count, (int __user *)arg);
                default:
@@ -705,8 +698,7 @@ static unsigned int
 pipe_poll(struct file *filp, poll_table *wait)
 {
        unsigned int mask;
-       struct inode *inode = file_inode(filp);
-       struct pipe_inode_info *pipe = inode->i_pipe;
+       struct pipe_inode_info *pipe = filp->private_data;
        int nrbufs;
 
        poll_wait(filp, &pipe->wait, wait);
@@ -734,194 +726,56 @@ pipe_poll(struct file *filp, poll_table *wait)
 }
 
 static int
-pipe_release(struct inode *inode, int decr, int decw)
+pipe_release(struct inode *inode, struct file *file)
 {
-       struct pipe_inode_info *pipe;
+       struct pipe_inode_info *pipe = inode->i_pipe;
+       int kill = 0;
 
-       mutex_lock(&inode->i_mutex);
-       pipe = inode->i_pipe;
-       pipe->readers -= decr;
-       pipe->writers -= decw;
+       __pipe_lock(pipe);
+       if (file->f_mode & FMODE_READ)
+               pipe->readers--;
+       if (file->f_mode & FMODE_WRITE)
+               pipe->writers--;
 
-       if (!pipe->readers && !pipe->writers) {
-               free_pipe_info(inode);
-       } else {
+       if (pipe->readers || pipe->writers) {
                wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP);
                kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
                kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
        }
-       mutex_unlock(&inode->i_mutex);
-
-       return 0;
-}
-
-static int
-pipe_read_fasync(int fd, struct file *filp, int on)
-{
-       struct inode *inode = file_inode(filp);
-       int retval;
-
-       mutex_lock(&inode->i_mutex);
-       retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
-       mutex_unlock(&inode->i_mutex);
-
-       return retval;
-}
-
-
-static int
-pipe_write_fasync(int fd, struct file *filp, int on)
-{
-       struct inode *inode = file_inode(filp);
-       int retval;
+       spin_lock(&inode->i_lock);
+       if (!--pipe->files) {
+               inode->i_pipe = NULL;
+               kill = 1;
+       }
+       spin_unlock(&inode->i_lock);
+       __pipe_unlock(pipe);
 
-       mutex_lock(&inode->i_mutex);
-       retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
-       mutex_unlock(&inode->i_mutex);
+       if (kill)
+               free_pipe_info(pipe);
 
-       return retval;
+       return 0;
 }
 
-
 static int
-pipe_rdwr_fasync(int fd, struct file *filp, int on)
+pipe_fasync(int fd, struct file *filp, int on)
 {
-       struct inode *inode = file_inode(filp);
-       struct pipe_inode_info *pipe = inode->i_pipe;
-       int retval;
+       struct pipe_inode_info *pipe = filp->private_data;
+       int retval = 0;
 
-       mutex_lock(&inode->i_mutex);
-       retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
-       if (retval >= 0) {
+       __pipe_lock(pipe);
+       if (filp->f_mode & FMODE_READ)
+               retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
+       if ((filp->f_mode & FMODE_WRITE) && retval >= 0) {
                retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
-               if (retval < 0) /* this can happen only if on == T */
+               if (retval < 0 && (filp->f_mode & FMODE_READ))
+                       /* this can happen only if on == T */
                        fasync_helper(-1, filp, 0, &pipe->fasync_readers);
        }
-       mutex_unlock(&inode->i_mutex);
+       __pipe_unlock(pipe);
        return retval;
 }
 
-
-static int
-pipe_read_release(struct inode *inode, struct file *filp)
-{
-       return pipe_release(inode, 1, 0);
-}
-
-static int
-pipe_write_release(struct inode *inode, struct file *filp)
-{
-       return pipe_release(inode, 0, 1);
-}
-
-static int
-pipe_rdwr_release(struct inode *inode, struct file *filp)
-{
-       int decr, decw;
-
-       decr = (filp->f_mode & FMODE_READ) != 0;
-       decw = (filp->f_mode & FMODE_WRITE) != 0;
-       return pipe_release(inode, decr, decw);
-}
-
-static int
-pipe_read_open(struct inode *inode, struct file *filp)
-{
-       int ret = -ENOENT;
-
-       mutex_lock(&inode->i_mutex);
-
-       if (inode->i_pipe) {
-               ret = 0;
-               inode->i_pipe->readers++;
-       }
-
-       mutex_unlock(&inode->i_mutex);
-
-       return ret;
-}
-
-static int
-pipe_write_open(struct inode *inode, struct file *filp)
-{
-       int ret = -ENOENT;
-
-       mutex_lock(&inode->i_mutex);
-
-       if (inode->i_pipe) {
-               ret = 0;
-               inode->i_pipe->writers++;
-       }
-
-       mutex_unlock(&inode->i_mutex);
-
-       return ret;
-}
-
-static int
-pipe_rdwr_open(struct inode *inode, struct file *filp)
-{
-       int ret = -ENOENT;
-
-       mutex_lock(&inode->i_mutex);
-
-       if (inode->i_pipe) {
-               ret = 0;
-               if (filp->f_mode & FMODE_READ)
-                       inode->i_pipe->readers++;
-               if (filp->f_mode & FMODE_WRITE)
-                       inode->i_pipe->writers++;
-       }
-
-       mutex_unlock(&inode->i_mutex);
-
-       return ret;
-}
-
-/*
- * The file_operations structs are not static because they
- * are also used in linux/fs/fifo.c to do operations on FIFOs.
- *
- * Pipes reuse fifos' file_operations structs.
- */
-const struct file_operations read_pipefifo_fops = {
-       .llseek         = no_llseek,
-       .read           = do_sync_read,
-       .aio_read       = pipe_read,
-       .write          = bad_pipe_w,
-       .poll           = pipe_poll,
-       .unlocked_ioctl = pipe_ioctl,
-       .open           = pipe_read_open,
-       .release        = pipe_read_release,
-       .fasync         = pipe_read_fasync,
-};
-
-const struct file_operations write_pipefifo_fops = {
-       .llseek         = no_llseek,
-       .read           = bad_pipe_r,
-       .write          = do_sync_write,
-       .aio_write      = pipe_write,
-       .poll           = pipe_poll,
-       .unlocked_ioctl = pipe_ioctl,
-       .open           = pipe_write_open,
-       .release        = pipe_write_release,
-       .fasync         = pipe_write_fasync,
-};
-
-const struct file_operations rdwr_pipefifo_fops = {
-       .llseek         = no_llseek,
-       .read           = do_sync_read,
-       .aio_read       = pipe_read,
-       .write          = do_sync_write,
-       .aio_write      = pipe_write,
-       .poll           = pipe_poll,
-       .unlocked_ioctl = pipe_ioctl,
-       .open           = pipe_rdwr_open,
-       .release        = pipe_rdwr_release,
-       .fasync         = pipe_rdwr_fasync,
-};
-
-struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
+struct pipe_inode_info *alloc_pipe_info(void)
 {
        struct pipe_inode_info *pipe;
 
@@ -931,8 +785,8 @@ struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
                if (pipe->bufs) {
                        init_waitqueue_head(&pipe->wait);
                        pipe->r_counter = pipe->w_counter = 1;
-                       pipe->inode = inode;
                        pipe->buffers = PIPE_DEF_BUFFERS;
+                       mutex_init(&pipe->mutex);
                        return pipe;
                }
                kfree(pipe);
@@ -941,7 +795,7 @@ struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
        return NULL;
 }
 
-void __free_pipe_info(struct pipe_inode_info *pipe)
+void free_pipe_info(struct pipe_inode_info *pipe)
 {
        int i;
 
@@ -956,12 +810,6 @@ void __free_pipe_info(struct pipe_inode_info *pipe)
        kfree(pipe);
 }
 
-void free_pipe_info(struct inode *inode)
-{
-       __free_pipe_info(inode->i_pipe);
-       inode->i_pipe = NULL;
-}
-
 static struct vfsmount *pipe_mnt __read_mostly;
 
 /*
@@ -987,13 +835,14 @@ static struct inode * get_pipe_inode(void)
 
        inode->i_ino = get_next_ino();
 
-       pipe = alloc_pipe_info(inode);
+       pipe = alloc_pipe_info();
        if (!pipe)
                goto fail_iput;
-       inode->i_pipe = pipe;
 
+       inode->i_pipe = pipe;
+       pipe->files = 2;
        pipe->readers = pipe->writers = 1;
-       inode->i_fop = &rdwr_pipefifo_fops;
+       inode->i_fop = &pipefifo_fops;
 
        /*
         * Mark the inode dirty from the very beginning,
@@ -1036,17 +885,19 @@ int create_pipe_files(struct file **res, int flags)
        d_instantiate(path.dentry, inode);
 
        err = -ENFILE;
-       f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops);
+       f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops);
        if (IS_ERR(f))
                goto err_dentry;
 
        f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
+       f->private_data = inode->i_pipe;
 
-       res[0] = alloc_file(&path, FMODE_READ, &read_pipefifo_fops);
+       res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops);
        if (IS_ERR(res[0]))
                goto err_file;
 
        path_get(&path);
+       res[0]->private_data = inode->i_pipe;
        res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
        res[1] = f;
        return 0;
@@ -1054,12 +905,12 @@ int create_pipe_files(struct file **res, int flags)
 err_file:
        put_filp(f);
 err_dentry:
-       free_pipe_info(inode);
+       free_pipe_info(inode->i_pipe);
        path_put(&path);
        return err;
 
 err_inode:
-       free_pipe_info(inode);
+       free_pipe_info(inode->i_pipe);
        iput(inode);
        return err;
 }
@@ -1141,6 +992,168 @@ SYSCALL_DEFINE1(pipe, int __user *, fildes)
        return sys_pipe2(fildes, 0);
 }
 
+static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt)
+{
+       int cur = *cnt; 
+
+       while (cur == *cnt) {
+               pipe_wait(pipe);
+               if (signal_pending(current))
+                       break;
+       }
+       return cur == *cnt ? -ERESTARTSYS : 0;
+}
+
+static void wake_up_partner(struct pipe_inode_info *pipe)
+{
+       wake_up_interruptible(&pipe->wait);
+}
+
+static int fifo_open(struct inode *inode, struct file *filp)
+{
+       struct pipe_inode_info *pipe;
+       bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
+       int kill = 0;
+       int ret;
+
+       filp->f_version = 0;
+
+       spin_lock(&inode->i_lock);
+       if (inode->i_pipe) {
+               pipe = inode->i_pipe;
+               pipe->files++;
+               spin_unlock(&inode->i_lock);
+       } else {
+               spin_unlock(&inode->i_lock);
+               pipe = alloc_pipe_info();
+               if (!pipe)
+                       return -ENOMEM;
+               pipe->files = 1;
+               spin_lock(&inode->i_lock);
+               if (unlikely(inode->i_pipe)) {
+                       inode->i_pipe->files++;
+                       spin_unlock(&inode->i_lock);
+                       free_pipe_info(pipe);
+                       pipe = inode->i_pipe;
+               } else {
+                       inode->i_pipe = pipe;
+                       spin_unlock(&inode->i_lock);
+               }
+       }
+       filp->private_data = pipe;
+       /* OK, we have a pipe and it's pinned down */
+
+       __pipe_lock(pipe);
+
+       /* We can only do regular read/write on fifos */
+       filp->f_mode &= (FMODE_READ | FMODE_WRITE);
+
+       switch (filp->f_mode) {
+       case FMODE_READ:
+       /*
+        *  O_RDONLY
+        *  POSIX.1 says that O_NONBLOCK means return with the FIFO
+        *  opened, even when there is no process writing the FIFO.
+        */
+               pipe->r_counter++;
+               if (pipe->readers++ == 0)
+                       wake_up_partner(pipe);
+
+               if (!is_pipe && !pipe->writers) {
+                       if ((filp->f_flags & O_NONBLOCK)) {
+                               /* suppress POLLHUP until we have
+                                * seen a writer */
+                               filp->f_version = pipe->w_counter;
+                       } else {
+                               if (wait_for_partner(pipe, &pipe->w_counter))
+                                       goto err_rd;
+                       }
+               }
+               break;
+       
+       case FMODE_WRITE:
+       /*
+        *  O_WRONLY
+        *  POSIX.1 says that O_NONBLOCK means return -1 with
+        *  errno=ENXIO when there is no process reading the FIFO.
+        */
+               ret = -ENXIO;
+               if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers)
+                       goto err;
+
+               pipe->w_counter++;
+               if (!pipe->writers++)
+                       wake_up_partner(pipe);
+
+               if (!is_pipe && !pipe->readers) {
+                       if (wait_for_partner(pipe, &pipe->r_counter))
+                               goto err_wr;
+               }
+               break;
+       
+       case FMODE_READ | FMODE_WRITE:
+       /*
+        *  O_RDWR
+        *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
+        *  This implementation will NEVER block on a O_RDWR open, since
+        *  the process can at least talk to itself.
+        */
+
+               pipe->readers++;
+               pipe->writers++;
+               pipe->r_counter++;
+               pipe->w_counter++;
+               if (pipe->readers == 1 || pipe->writers == 1)
+                       wake_up_partner(pipe);
+               break;
+
+       default:
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Ok! */
+       __pipe_unlock(pipe);
+       return 0;
+
+err_rd:
+       if (!--pipe->readers)
+               wake_up_interruptible(&pipe->wait);
+       ret = -ERESTARTSYS;
+       goto err;
+
+err_wr:
+       if (!--pipe->writers)
+               wake_up_interruptible(&pipe->wait);
+       ret = -ERESTARTSYS;
+       goto err;
+
+err:
+       spin_lock(&inode->i_lock);
+       if (!--pipe->files) {
+               inode->i_pipe = NULL;
+               kill = 1;
+       }
+       spin_unlock(&inode->i_lock);
+       __pipe_unlock(pipe);
+       if (kill)
+               free_pipe_info(pipe);
+       return ret;
+}
+
+const struct file_operations pipefifo_fops = {
+       .open           = fifo_open,
+       .llseek         = no_llseek,
+       .read           = do_sync_read,
+       .aio_read       = pipe_read,
+       .write          = do_sync_write,
+       .aio_write      = pipe_write,
+       .poll           = pipe_poll,
+       .unlocked_ioctl = pipe_ioctl,
+       .release        = pipe_release,
+       .fasync         = pipe_fasync,
+};
+
 /*
  * Allocate a new array of pipe buffers and copy the info over. Returns the
  * pipe size if successful, or return -ERROR on error.
@@ -1226,9 +1239,7 @@ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
  */
 struct pipe_inode_info *get_pipe_info(struct file *file)
 {
-       struct inode *i = file_inode(file);
-
-       return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL;
+       return file->f_op == &pipefifo_fops ? file->private_data : NULL;
 }
 
 long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -1240,7 +1251,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
        if (!pipe)
                return -EBADF;
 
-       mutex_lock(&pipe->inode->i_mutex);
+       __pipe_lock(pipe);
 
        switch (cmd) {
        case F_SETPIPE_SZ: {
@@ -1269,7 +1280,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
        }
 
 out:
-       mutex_unlock(&pipe->inode->i_mutex);
+       __pipe_unlock(pipe);
        return ret;
 }
 
index 3e000a51ac0d09556d184d26422a91d0bc4c0ff9..43617258fa6aab3bb9623b9509167f538bdc7386 100644 (file)
@@ -217,7 +217,7 @@ static struct mount *get_source(struct mount *dest,
  * @source_mnt: source mount.
  * @tree_list : list of heads of trees to be attached.
  */
-int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
+int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
                    struct mount *source_mnt, struct list_head *tree_list)
 {
        struct mount *m, *child;
@@ -225,7 +225,6 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
        struct mount *prev_dest_mnt = dest_mnt;
        struct mount *prev_src_mnt  = source_mnt;
        LIST_HEAD(tmp_list);
-       LIST_HEAD(umount_list);
 
        for (m = propagation_next(dest_mnt, dest_mnt); m;
                        m = propagation_next(m, dest_mnt)) {
@@ -244,8 +243,8 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
                        goto out;
                }
 
-               if (is_subdir(dest_dentry, m->mnt.mnt_root)) {
-                       mnt_set_mountpoint(m, dest_dentry, child);
+               if (is_subdir(dest_mp->m_dentry, m->mnt.mnt_root)) {
+                       mnt_set_mountpoint(m, dest_mp, child);
                        list_add_tail(&child->mnt_hash, tree_list);
                } else {
                        /*
@@ -261,10 +260,9 @@ out:
        br_write_lock(&vfsmount_lock);
        while (!list_empty(&tmp_list)) {
                child = list_first_entry(&tmp_list, struct mount, mnt_hash);
-               umount_tree(child, 0, &umount_list);
+               umount_tree(child, 0);
        }
        br_write_unlock(&vfsmount_lock);
-       release_mounts(&umount_list);
        return ret;
 }
 
index 19b853a3445cb907665b4403484984a0c525af68..9eb00ee65bbe42de026bf030def2609f94a2626d 100644 (file)
@@ -31,17 +31,16 @@ static inline void set_mnt_shared(struct mount *mnt)
 }
 
 void change_mnt_propagation(struct mount *, int);
-int propagate_mnt(struct mount *, struct dentry *, struct mount *,
+int propagate_mnt(struct mount *, struct mountpoint *, struct mount *,
                struct list_head *);
 int propagate_umount(struct list_head *);
 int propagate_mount_busy(struct mount *, int);
 void mnt_release_group_id(struct mount *);
 int get_dominating_id(struct mount *mnt, const struct path *root);
 unsigned int mnt_get_count(struct mount *mnt);
-void mnt_set_mountpoint(struct mount *, struct dentry *,
+void mnt_set_mountpoint(struct mount *, struct mountpoint *,
                        struct mount *);
-void release_mounts(struct list_head *);
-void umount_tree(struct mount *, int, struct list_head *);
+void umount_tree(struct mount *, int);
 struct mount *copy_tree(struct mount *, struct dentry *, int);
 bool is_path_reachable(struct mount *, struct dentry *,
                         const struct path *root);
index 69078c7cef1fa1443472f21bf4c98bb435fb7824..8281986693be137530e1cc7f8e063e892e4b3568 100644 (file)
@@ -404,6 +404,37 @@ static const struct file_operations proc_lstats_operations = {
 
 #endif
 
+#ifdef CONFIG_CGROUPS
+static int cgroup_open(struct inode *inode, struct file *file)
+{
+       struct pid *pid = PROC_I(inode)->pid;
+       return single_open(file, proc_cgroup_show, pid);
+}
+
+static const struct file_operations proc_cgroup_operations = {
+       .open           = cgroup_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+#endif
+
+#ifdef CONFIG_PROC_PID_CPUSET
+
+static int cpuset_open(struct inode *inode, struct file *file)
+{
+       struct pid *pid = PROC_I(inode)->pid;
+       return single_open(file, proc_cpuset_show, pid);
+}
+
+static const struct file_operations proc_cpuset_operations = {
+       .open           = cpuset_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+#endif
+
 static int proc_oom_score(struct task_struct *task, char *buffer)
 {
        unsigned long totalpages = totalram_pages + total_swap_pages;
@@ -1621,6 +1652,15 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
        return 0;
 }
 
+int pid_delete_dentry(const struct dentry *dentry)
+{
+       /* Is the task we represent dead?
+        * If so, then don't put the dentry on the lru list,
+        * kill it immediately.
+        */
+       return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
+}
+
 const struct dentry_operations pid_dentry_operations =
 {
        .d_revalidate   = pid_revalidate,
@@ -2794,7 +2834,7 @@ retry:
        return iter;
 }
 
-#define TGID_OFFSET (FIRST_PROCESS_ENTRY)
+#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1)
 
 static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
        struct tgid_iter iter)
@@ -2817,13 +2857,21 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
        struct tgid_iter iter;
        struct pid_namespace *ns;
        filldir_t __filldir;
+       loff_t pos = filp->f_pos;
 
-       if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET)
+       if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
                goto out;
 
-       ns = filp->f_dentry->d_sb->s_fs_info;
+       if (pos == TGID_OFFSET - 1) {
+               if (proc_fill_cache(filp, dirent, filldir, "self", 4,
+                                       NULL, NULL, NULL) < 0)
+                       goto out;
+               iter.tgid = 0;
+       } else {
+               iter.tgid = pos - TGID_OFFSET;
+       }
        iter.task = NULL;
-       iter.tgid = filp->f_pos - TGID_OFFSET;
+       ns = filp->f_dentry->d_sb->s_fs_info;
        for (iter = next_tgid(ns, iter);
             iter.task;
             iter.tgid += 1, iter = next_tgid(ns, iter)) {
index cbb1d47deda8c11ce81f2b32ffe2ec6b7841122b..7c047f256ae2ccb945aab10d8688d6305b5a0eb7 100644 (file)
@@ -11,4 +11,9 @@ extern const struct inode_operations proc_fdinfo_inode_operations;
 
 extern int proc_fd_permission(struct inode *inode, int mask);
 
+static inline int proc_fd(struct inode *inode)
+{
+       return PROC_I(inode)->fd;
+}
+
 #endif /* __PROCFS_FD_H__ */
index 4b3b3ffb52f14e234aa3ec99abde281ca41e1817..a2596afffae6dad430f8cb2727628e162c567876 100644 (file)
@@ -36,212 +36,6 @@ static int proc_match(unsigned int len, const char *name, struct proc_dir_entry
        return !memcmp(name, de->name, len);
 }
 
-/* buffer size is one page but our output routines use some slack for overruns */
-#define PROC_BLOCK_SIZE        (PAGE_SIZE - 1024)
-
-static ssize_t
-__proc_file_read(struct file *file, char __user *buf, size_t nbytes,
-              loff_t *ppos)
-{
-       struct inode * inode = file_inode(file);
-       char    *page;
-       ssize_t retval=0;
-       int     eof=0;
-       ssize_t n, count;
-       char    *start;
-       struct proc_dir_entry * dp;
-       unsigned long long pos;
-
-       /*
-        * Gaah, please just use "seq_file" instead. The legacy /proc
-        * interfaces cut loff_t down to off_t for reads, and ignore
-        * the offset entirely for writes..
-        */
-       pos = *ppos;
-       if (pos > MAX_NON_LFS)
-               return 0;
-       if (nbytes > MAX_NON_LFS - pos)
-               nbytes = MAX_NON_LFS - pos;
-
-       dp = PDE(inode);
-       if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
-               return -ENOMEM;
-
-       while ((nbytes > 0) && !eof) {
-               count = min_t(size_t, PROC_BLOCK_SIZE, nbytes);
-
-               start = NULL;
-               if (dp->read_proc) {
-                       /*
-                        * How to be a proc read function
-                        * ------------------------------
-                        * Prototype:
-                        *    int f(char *buffer, char **start, off_t offset,
-                        *          int count, int *peof, void *dat)
-                        *
-                        * Assume that the buffer is "count" bytes in size.
-                        *
-                        * If you know you have supplied all the data you
-                        * have, set *peof.
-                        *
-                        * You have three ways to return data:
-                        * 0) Leave *start = NULL.  (This is the default.)
-                        *    Put the data of the requested offset at that
-                        *    offset within the buffer.  Return the number (n)
-                        *    of bytes there are from the beginning of the
-                        *    buffer up to the last byte of data.  If the
-                        *    number of supplied bytes (= n - offset) is 
-                        *    greater than zero and you didn't signal eof
-                        *    and the reader is prepared to take more data
-                        *    you will be called again with the requested
-                        *    offset advanced by the number of bytes 
-                        *    absorbed.  This interface is useful for files
-                        *    no larger than the buffer.
-                        * 1) Set *start = an unsigned long value less than
-                        *    the buffer address but greater than zero.
-                        *    Put the data of the requested offset at the
-                        *    beginning of the buffer.  Return the number of
-                        *    bytes of data placed there.  If this number is
-                        *    greater than zero and you didn't signal eof
-                        *    and the reader is prepared to take more data
-                        *    you will be called again with the requested
-                        *    offset advanced by *start.  This interface is
-                        *    useful when you have a large file consisting
-                        *    of a series of blocks which you want to count
-                        *    and return as wholes.
-                        *    (Hack by Paul.Russell@rustcorp.com.au)
-                        * 2) Set *start = an address within the buffer.
-                        *    Put the data of the requested offset at *start.
-                        *    Return the number of bytes of data placed there.
-                        *    If this number is greater than zero and you
-                        *    didn't signal eof and the reader is prepared to
-                        *    take more data you will be called again with the
-                        *    requested offset advanced by the number of bytes
-                        *    absorbed.
-                        */
-                       n = dp->read_proc(page, &start, *ppos,
-                                         count, &eof, dp->data);
-               } else
-                       break;
-
-               if (n == 0)   /* end of file */
-                       break;
-               if (n < 0) {  /* error */
-                       if (retval == 0)
-                               retval = n;
-                       break;
-               }
-
-               if (start == NULL) {
-                       if (n > PAGE_SIZE)      /* Apparent buffer overflow */
-                               n = PAGE_SIZE;
-                       n -= *ppos;
-                       if (n <= 0)
-                               break;
-                       if (n > count)
-                               n = count;
-                       start = page + *ppos;
-               } else if (start < page) {
-                       if (n > PAGE_SIZE)      /* Apparent buffer overflow */
-                               n = PAGE_SIZE;
-                       if (n > count) {
-                               /*
-                                * Don't reduce n because doing so might
-                                * cut off part of a data block.
-                                */
-                               pr_warn("proc_file_read: count exceeded\n");
-                       }
-               } else /* start >= page */ {
-                       unsigned long startoff = (unsigned long)(start - page);
-                       if (n > (PAGE_SIZE - startoff)) /* buffer overflow? */
-                               n = PAGE_SIZE - startoff;
-                       if (n > count)
-                               n = count;
-               }
-               
-               n -= copy_to_user(buf, start < page ? page : start, n);
-               if (n == 0) {
-                       if (retval == 0)
-                               retval = -EFAULT;
-                       break;
-               }
-
-               *ppos += start < page ? (unsigned long)start : n;
-               nbytes -= n;
-               buf += n;
-               retval += n;
-       }
-       free_page((unsigned long) page);
-       return retval;
-}
-
-static ssize_t
-proc_file_read(struct file *file, char __user *buf, size_t nbytes,
-              loff_t *ppos)
-{
-       struct proc_dir_entry *pde = PDE(file_inode(file));
-       ssize_t rv = -EIO;
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
-       }
-       pde->pde_users++;
-       spin_unlock(&pde->pde_unload_lock);
-
-       rv = __proc_file_read(file, buf, nbytes, ppos);
-
-       pde_users_dec(pde);
-       return rv;
-}
-
-static ssize_t
-proc_file_write(struct file *file, const char __user *buffer,
-               size_t count, loff_t *ppos)
-{
-       struct proc_dir_entry *pde = PDE(file_inode(file));
-       ssize_t rv = -EIO;
-
-       if (pde->write_proc) {
-               spin_lock(&pde->pde_unload_lock);
-               if (!pde->proc_fops) {
-                       spin_unlock(&pde->pde_unload_lock);
-                       return rv;
-               }
-               pde->pde_users++;
-               spin_unlock(&pde->pde_unload_lock);
-
-               /* FIXME: does this routine need ppos?  probably... */
-               rv = pde->write_proc(file, buffer, count, pde->data);
-               pde_users_dec(pde);
-       }
-       return rv;
-}
-
-
-static loff_t
-proc_file_lseek(struct file *file, loff_t offset, int orig)
-{
-       loff_t retval = -EINVAL;
-       switch (orig) {
-       case 1:
-               offset += file->f_pos;
-       /* fallthrough */
-       case 0:
-               if (offset < 0 || offset > MAX_NON_LFS)
-                       break;
-               file->f_pos = retval = offset;
-       }
-       return retval;
-}
-
-static const struct file_operations proc_file_operations = {
-       .llseek         = proc_file_lseek,
-       .read           = proc_file_read,
-       .write          = proc_file_write,
-};
-
 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
 {
        struct inode *inode = dentry->d_inode;
@@ -371,7 +165,7 @@ void proc_free_inum(unsigned int inum)
 
 static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-       nd_set_link(nd, PDE(dentry->d_inode)->data);
+       nd_set_link(nd, __PDE_DATA(dentry->d_inode));
        return NULL;
 }
 
@@ -541,19 +335,17 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
                return ret;
 
        if (S_ISDIR(dp->mode)) {
-               if (dp->proc_iops == NULL) {
-                       dp->proc_fops = &proc_dir_operations;
-                       dp->proc_iops = &proc_dir_inode_operations;
-               }
+               dp->proc_fops = &proc_dir_operations;
+               dp->proc_iops = &proc_dir_inode_operations;
                dir->nlink++;
        } else if (S_ISLNK(dp->mode)) {
-               if (dp->proc_iops == NULL)
-                       dp->proc_iops = &proc_link_inode_operations;
+               dp->proc_iops = &proc_link_inode_operations;
        } else if (S_ISREG(dp->mode)) {
-               if (dp->proc_fops == NULL)
-                       dp->proc_fops = &proc_file_operations;
-               if (dp->proc_iops == NULL)
-                       dp->proc_iops = &proc_file_inode_operations;
+               BUG_ON(dp->proc_fops == NULL);
+               dp->proc_iops = &proc_file_inode_operations;
+       } else {
+               WARN_ON(1);
+               return -EINVAL;
        }
 
        spin_lock(&proc_subdir_lock);
@@ -636,13 +428,17 @@ struct proc_dir_entry *proc_symlink(const char *name,
 }
 EXPORT_SYMBOL(proc_symlink);
 
-struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
-               struct proc_dir_entry *parent)
+struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
+               struct proc_dir_entry *parent, void *data)
 {
        struct proc_dir_entry *ent;
 
+       if (mode == 0)
+               mode = S_IRUGO | S_IXUGO;
+
        ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
        if (ent) {
+               ent->data = data;
                if (proc_register(parent, ent) < 0) {
                        kfree(ent);
                        ent = NULL;
@@ -650,82 +446,39 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
        }
        return ent;
 }
-EXPORT_SYMBOL(proc_mkdir_mode);
+EXPORT_SYMBOL_GPL(proc_mkdir_data);
 
-struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
-               struct proc_dir_entry *parent)
+struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
+                                      struct proc_dir_entry *parent)
 {
-       struct proc_dir_entry *ent;
-
-       ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2);
-       if (ent) {
-               ent->data = net;
-               if (proc_register(parent, ent) < 0) {
-                       kfree(ent);
-                       ent = NULL;
-               }
-       }
-       return ent;
+       return proc_mkdir_data(name, mode, parent, NULL);
 }
-EXPORT_SYMBOL_GPL(proc_net_mkdir);
+EXPORT_SYMBOL(proc_mkdir_mode);
 
 struct proc_dir_entry *proc_mkdir(const char *name,
                struct proc_dir_entry *parent)
 {
-       return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
+       return proc_mkdir_data(name, 0, parent, NULL);
 }
 EXPORT_SYMBOL(proc_mkdir);
 
-struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode,
-                                        struct proc_dir_entry *parent)
-{
-       struct proc_dir_entry *ent;
-       nlink_t nlink;
-
-       if (S_ISDIR(mode)) {
-               if ((mode & S_IALLUGO) == 0)
-                       mode |= S_IRUGO | S_IXUGO;
-               nlink = 2;
-       } else {
-               if ((mode & S_IFMT) == 0)
-                       mode |= S_IFREG;
-               if ((mode & S_IALLUGO) == 0)
-                       mode |= S_IRUGO;
-               nlink = 1;
-       }
-
-       ent = __proc_create(&parent, name, mode, nlink);
-       if (ent) {
-               if (proc_register(parent, ent) < 0) {
-                       kfree(ent);
-                       ent = NULL;
-               }
-       }
-       return ent;
-}
-EXPORT_SYMBOL(create_proc_entry);
-
 struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
                                        struct proc_dir_entry *parent,
                                        const struct file_operations *proc_fops,
                                        void *data)
 {
        struct proc_dir_entry *pde;
-       nlink_t nlink;
+       if ((mode & S_IFMT) == 0)
+               mode |= S_IFREG;
 
-       if (S_ISDIR(mode)) {
-               if ((mode & S_IALLUGO) == 0)
-                       mode |= S_IRUGO | S_IXUGO;
-               nlink = 2;
-       } else {
-               if ((mode & S_IFMT) == 0)
-                       mode |= S_IFREG;
-               if ((mode & S_IALLUGO) == 0)
-                       mode |= S_IRUGO;
-               nlink = 1;
+       if (!S_ISREG(mode)) {
+               WARN_ON(1);     /* use proc_mkdir() */
+               return NULL;
        }
 
-       pde = __proc_create(&parent, name, mode, nlink);
+       if ((mode & S_IALLUGO) == 0)
+               mode |= S_IRUGO;
+       pde = __proc_create(&parent, name, mode, 1);
        if (!pde)
                goto out;
        pde->proc_fops = proc_fops;
@@ -739,6 +492,19 @@ out:
        return NULL;
 }
 EXPORT_SYMBOL(proc_create_data);
+void proc_set_size(struct proc_dir_entry *de, loff_t size)
+{
+       de->size = size;
+}
+EXPORT_SYMBOL(proc_set_size);
+
+void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
+{
+       de->uid = uid;
+       de->gid = gid;
+}
+EXPORT_SYMBOL(proc_set_user);
 
 static void free_proc_entry(struct proc_dir_entry *de)
 {
@@ -786,37 +552,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
                return;
        }
 
-       spin_lock(&de->pde_unload_lock);
-       /*
-        * Stop accepting new callers into module. If you're
-        * dynamically allocating ->proc_fops, save a pointer somewhere.
-        */
-       de->proc_fops = NULL;
-       /* Wait until all existing callers into module are done. */
-       if (de->pde_users > 0) {
-               DECLARE_COMPLETION_ONSTACK(c);
-
-               if (!de->pde_unload_completion)
-                       de->pde_unload_completion = &c;
-
-               spin_unlock(&de->pde_unload_lock);
-
-               wait_for_completion(de->pde_unload_completion);
-
-               spin_lock(&de->pde_unload_lock);
-       }
-
-       while (!list_empty(&de->pde_openers)) {
-               struct pde_opener *pdeo;
-
-               pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
-               list_del(&pdeo->lh);
-               spin_unlock(&de->pde_unload_lock);
-               pdeo->release(pdeo->inode, pdeo->file);
-               kfree(pdeo);
-               spin_lock(&de->pde_unload_lock);
-       }
-       spin_unlock(&de->pde_unload_lock);
+       proc_entry_rundown(de);
 
        if (S_ISDIR(de->mode))
                parent->nlink--;
@@ -827,3 +563,77 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
        pde_put(de);
 }
 EXPORT_SYMBOL(remove_proc_entry);
+
+int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
+{
+       struct proc_dir_entry **p;
+       struct proc_dir_entry *root = NULL, *de, *next;
+       const char *fn = name;
+       unsigned int len;
+
+       spin_lock(&proc_subdir_lock);
+       if (__xlate_proc_name(name, &parent, &fn) != 0) {
+               spin_unlock(&proc_subdir_lock);
+               return -ENOENT;
+       }
+       len = strlen(fn);
+
+       for (p = &parent->subdir; *p; p=&(*p)->next ) {
+               if (proc_match(len, fn, *p)) {
+                       root = *p;
+                       *p = root->next;
+                       root->next = NULL;
+                       break;
+               }
+       }
+       if (!root) {
+               spin_unlock(&proc_subdir_lock);
+               return -ENOENT;
+       }
+       de = root;
+       while (1) {
+               next = de->subdir;
+               if (next) {
+                       de->subdir = next->next;
+                       next->next = NULL;
+                       de = next;
+                       continue;
+               }
+               spin_unlock(&proc_subdir_lock);
+
+               proc_entry_rundown(de);
+               next = de->parent;
+               if (S_ISDIR(de->mode))
+                       next->nlink--;
+               de->nlink = 0;
+               if (de == root)
+                       break;
+               pde_put(de);
+
+               spin_lock(&proc_subdir_lock);
+               de = next;
+       }
+       pde_put(root);
+       return 0;
+}
+EXPORT_SYMBOL(remove_proc_subtree);
+
+void *proc_get_parent_data(const struct inode *inode)
+{
+       struct proc_dir_entry *de = PDE(inode);
+       return de->parent->data;
+}
+EXPORT_SYMBOL_GPL(proc_get_parent_data);
+
+void proc_remove(struct proc_dir_entry *de)
+{
+       if (de)
+               remove_proc_subtree(de->name, de->parent);
+}
+EXPORT_SYMBOL(proc_remove);
+
+void *PDE_DATA(const struct inode *inode)
+{
+       return __PDE_DATA(inode);
+}
+EXPORT_SYMBOL(PDE_DATA);
index a86aebc9ba7c252bbfa73907612b59c177fca202..073aea60cf8f0ed1ccce604ab0accd8b07dd96ba 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/mount.h>
+#include <linux/magic.h>
 
 #include <asm/uaccess.h>
 
@@ -50,8 +51,8 @@ static void proc_evict_inode(struct inode *inode)
                sysctl_head_put(head);
        }
        /* Release any associated namespace */
-       ns_ops = PROC_I(inode)->ns_ops;
-       ns = PROC_I(inode)->ns;
+       ns_ops = PROC_I(inode)->ns.ns_ops;
+       ns = PROC_I(inode)->ns.ns;
        if (ns_ops && ns)
                ns_ops->put(ns);
 }
@@ -72,8 +73,8 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
        ei->pde = NULL;
        ei->sysctl = NULL;
        ei->sysctl_entry = NULL;
-       ei->ns = NULL;
-       ei->ns_ops = NULL;
+       ei->ns.ns = NULL;
+       ei->ns.ns_ops = NULL;
        inode = &ei->vfs_inode;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
        return inode;
@@ -129,96 +130,100 @@ static const struct super_operations proc_sops = {
        .show_options   = proc_show_options,
 };
 
-static void __pde_users_dec(struct proc_dir_entry *pde)
+enum {BIAS = -1U<<31};
+
+static inline int use_pde(struct proc_dir_entry *pde)
+{
+       return atomic_inc_unless_negative(&pde->in_use);
+}
+
+static void unuse_pde(struct proc_dir_entry *pde)
 {
-       pde->pde_users--;
-       if (pde->pde_unload_completion && pde->pde_users == 0)
+       if (atomic_dec_return(&pde->in_use) == BIAS)
                complete(pde->pde_unload_completion);
 }
 
-void pde_users_dec(struct proc_dir_entry *pde)
+/* pde is locked */
+static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
 {
-       spin_lock(&pde->pde_unload_lock);
-       __pde_users_dec(pde);
-       spin_unlock(&pde->pde_unload_lock);
+       if (pdeo->closing) {
+               /* somebody else is doing that, just wait */
+               DECLARE_COMPLETION_ONSTACK(c);
+               pdeo->c = &c;
+               spin_unlock(&pde->pde_unload_lock);
+               wait_for_completion(&c);
+               spin_lock(&pde->pde_unload_lock);
+       } else {
+               struct file *file;
+               pdeo->closing = 1;
+               spin_unlock(&pde->pde_unload_lock);
+               file = pdeo->file;
+               pde->proc_fops->release(file_inode(file), file);
+               spin_lock(&pde->pde_unload_lock);
+               list_del_init(&pdeo->lh);
+               if (pdeo->c)
+                       complete(pdeo->c);
+               kfree(pdeo);
+       }
+}
+
+void proc_entry_rundown(struct proc_dir_entry *de)
+{
+       DECLARE_COMPLETION_ONSTACK(c);
+       /* Wait until all existing callers into module are done. */
+       de->pde_unload_completion = &c;
+       if (atomic_add_return(BIAS, &de->in_use) != BIAS)
+               wait_for_completion(&c);
+
+       spin_lock(&de->pde_unload_lock);
+       while (!list_empty(&de->pde_openers)) {
+               struct pde_opener *pdeo;
+               pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
+               close_pdeo(de, pdeo);
+       }
+       spin_unlock(&de->pde_unload_lock);
 }
 
 static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
 {
        struct proc_dir_entry *pde = PDE(file_inode(file));
        loff_t rv = -EINVAL;
-       loff_t (*llseek)(struct file *, loff_t, int);
-
-       spin_lock(&pde->pde_unload_lock);
-       /*
-        * remove_proc_entry() is going to delete PDE (as part of module
-        * cleanup sequence). No new callers into module allowed.
-        */
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               loff_t (*llseek)(struct file *, loff_t, int);
+               llseek = pde->proc_fops->llseek;
+               if (!llseek)
+                       llseek = default_llseek;
+               rv = llseek(file, offset, whence);
+               unuse_pde(pde);
        }
-       /*
-        * Bump refcount so that remove_proc_entry will wail for ->llseek to
-        * complete.
-        */
-       pde->pde_users++;
-       /*
-        * Save function pointer under lock, to protect against ->proc_fops
-        * NULL'ifying right after ->pde_unload_lock is dropped.
-        */
-       llseek = pde->proc_fops->llseek;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (!llseek)
-               llseek = default_llseek;
-       rv = llseek(file, offset, whence);
-
-       pde_users_dec(pde);
        return rv;
 }
 
 static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
+       ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
        struct proc_dir_entry *pde = PDE(file_inode(file));
        ssize_t rv = -EIO;
-       ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               read = pde->proc_fops->read;
+               if (read)
+                       rv = read(file, buf, count, ppos);
+               unuse_pde(pde);
        }
-       pde->pde_users++;
-       read = pde->proc_fops->read;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (read)
-               rv = read(file, buf, count, ppos);
-
-       pde_users_dec(pde);
        return rv;
 }
 
 static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
+       ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
        struct proc_dir_entry *pde = PDE(file_inode(file));
        ssize_t rv = -EIO;
-       ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               write = pde->proc_fops->write;
+               if (write)
+                       rv = write(file, buf, count, ppos);
+               unuse_pde(pde);
        }
-       pde->pde_users++;
-       write = pde->proc_fops->write;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (write)
-               rv = write(file, buf, count, ppos);
-
-       pde_users_dec(pde);
        return rv;
 }
 
@@ -227,20 +232,12 @@ static unsigned int proc_reg_poll(struct file *file, struct poll_table_struct *p
        struct proc_dir_entry *pde = PDE(file_inode(file));
        unsigned int rv = DEFAULT_POLLMASK;
        unsigned int (*poll)(struct file *, struct poll_table_struct *);
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               poll = pde->proc_fops->poll;
+               if (poll)
+                       rv = poll(file, pts);
+               unuse_pde(pde);
        }
-       pde->pde_users++;
-       poll = pde->proc_fops->poll;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (poll)
-               rv = poll(file, pts);
-
-       pde_users_dec(pde);
        return rv;
 }
 
@@ -249,20 +246,12 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
        struct proc_dir_entry *pde = PDE(file_inode(file));
        long rv = -ENOTTY;
        long (*ioctl)(struct file *, unsigned int, unsigned long);
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               ioctl = pde->proc_fops->unlocked_ioctl;
+               if (ioctl)
+                       rv = ioctl(file, cmd, arg);
+               unuse_pde(pde);
        }
-       pde->pde_users++;
-       ioctl = pde->proc_fops->unlocked_ioctl;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (ioctl)
-               rv = ioctl(file, cmd, arg);
-
-       pde_users_dec(pde);
        return rv;
 }
 
@@ -272,20 +261,12 @@ static long proc_reg_compat_ioctl(struct file *file, unsigned int cmd, unsigned
        struct proc_dir_entry *pde = PDE(file_inode(file));
        long rv = -ENOTTY;
        long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               compat_ioctl = pde->proc_fops->compat_ioctl;
+               if (compat_ioctl)
+                       rv = compat_ioctl(file, cmd, arg);
+               unuse_pde(pde);
        }
-       pde->pde_users++;
-       compat_ioctl = pde->proc_fops->compat_ioctl;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (compat_ioctl)
-               rv = compat_ioctl(file, cmd, arg);
-
-       pde_users_dec(pde);
        return rv;
 }
 #endif
@@ -295,20 +276,12 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
        struct proc_dir_entry *pde = PDE(file_inode(file));
        int rv = -EIO;
        int (*mmap)(struct file *, struct vm_area_struct *);
-
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
-               return rv;
+       if (use_pde(pde)) {
+               mmap = pde->proc_fops->mmap;
+               if (mmap)
+                       rv = mmap(file, vma);
+               unuse_pde(pde);
        }
-       pde->pde_users++;
-       mmap = pde->proc_fops->mmap;
-       spin_unlock(&pde->pde_unload_lock);
-
-       if (mmap)
-               rv = mmap(file, vma);
-
-       pde_users_dec(pde);
        return rv;
 }
 
@@ -330,91 +303,47 @@ static int proc_reg_open(struct inode *inode, struct file *file)
         * by hand in remove_proc_entry(). For this, save opener's credentials
         * for later.
         */
-       pdeo = kmalloc(sizeof(struct pde_opener), GFP_KERNEL);
+       pdeo = kzalloc(sizeof(struct pde_opener), GFP_KERNEL);
        if (!pdeo)
                return -ENOMEM;
 
-       spin_lock(&pde->pde_unload_lock);
-       if (!pde->proc_fops) {
-               spin_unlock(&pde->pde_unload_lock);
+       if (!use_pde(pde)) {
                kfree(pdeo);
                return -ENOENT;
        }
-       pde->pde_users++;
        open = pde->proc_fops->open;
        release = pde->proc_fops->release;
-       spin_unlock(&pde->pde_unload_lock);
 
        if (open)
                rv = open(inode, file);
 
-       spin_lock(&pde->pde_unload_lock);
        if (rv == 0 && release) {
                /* To know what to release. */
-               pdeo->inode = inode;
                pdeo->file = file;
                /* Strictly for "too late" ->release in proc_reg_release(). */
-               pdeo->release = release;
+               spin_lock(&pde->pde_unload_lock);
                list_add(&pdeo->lh, &pde->pde_openers);
+               spin_unlock(&pde->pde_unload_lock);
        } else
                kfree(pdeo);
-       __pde_users_dec(pde);
-       spin_unlock(&pde->pde_unload_lock);
-       return rv;
-}
-
-static struct pde_opener *find_pde_opener(struct proc_dir_entry *pde,
-                                       struct inode *inode, struct file *file)
-{
-       struct pde_opener *pdeo;
 
-       list_for_each_entry(pdeo, &pde->pde_openers, lh) {
-               if (pdeo->inode == inode && pdeo->file == file)
-                       return pdeo;
-       }
-       return NULL;
+       unuse_pde(pde);
+       return rv;
 }
 
 static int proc_reg_release(struct inode *inode, struct file *file)
 {
        struct proc_dir_entry *pde = PDE(inode);
-       int rv = 0;
-       int (*release)(struct inode *, struct file *);
        struct pde_opener *pdeo;
-
        spin_lock(&pde->pde_unload_lock);
-       pdeo = find_pde_opener(pde, inode, file);
-       if (!pde->proc_fops) {
-               /*
-                * Can't simply exit, __fput() will think that everything is OK,
-                * and move on to freeing struct file. remove_proc_entry() will
-                * find slacker in opener's list and will try to do non-trivial
-                * things with struct file. Therefore, remove opener from list.
-                *
-                * But if opener is removed from list, who will ->release it?
-                */
-               if (pdeo) {
-                       list_del(&pdeo->lh);
-                       spin_unlock(&pde->pde_unload_lock);
-                       rv = pdeo->release(inode, file);
-                       kfree(pdeo);
-               } else
-                       spin_unlock(&pde->pde_unload_lock);
-               return rv;
-       }
-       pde->pde_users++;
-       release = pde->proc_fops->release;
-       if (pdeo) {
-               list_del(&pdeo->lh);
-               kfree(pdeo);
+       list_for_each_entry(pdeo, &pde->pde_openers, lh) {
+               if (pdeo->file == file) {
+                       close_pdeo(pde, pdeo);
+                       break;
+               }
        }
        spin_unlock(&pde->pde_unload_lock);
-
-       if (release)
-               rv = release(inode, file);
-
-       pde_users_dec(pde);
-       return rv;
+       return 0;
 }
 
 static const struct file_operations proc_reg_file_ops = {
@@ -446,9 +375,10 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
 
 struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
 {
-       struct inode *inode = iget_locked(sb, de->low_ino);
+       struct inode *inode = new_inode_pseudo(sb);
 
-       if (inode && (inode->i_state & I_NEW)) {
+       if (inode) {
+               inode->i_ino = de->low_ino;
                inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
                PROC_I(inode)->pde = de;
 
@@ -461,8 +391,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
                        inode->i_size = de->size;
                if (de->nlink)
                        set_nlink(inode, de->nlink);
-               if (de->proc_iops)
-                       inode->i_op = de->proc_iops;
+               WARN_ON(!de->proc_iops);
+               inode->i_op = de->proc_iops;
                if (de->proc_fops) {
                        if (S_ISREG(inode->i_mode)) {
 #ifdef CONFIG_COMPAT
@@ -476,7 +406,6 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
                                inode->i_fop = de->proc_fops;
                        }
                }
-               unlock_new_inode(inode);
        } else
               pde_put(de);
        return inode;
@@ -506,5 +435,5 @@ int proc_fill_super(struct super_block *s)
                return -ENOMEM;
        }
 
-       return 0;
+       return proc_setup_self(s);
 }
index 85ff3a4598b348cbf30772aa69c44e082525a488..04255b6e96b77def4c2fa8ba5b5780868e0bb3d6 100644 (file)
@@ -1,4 +1,4 @@
-/* internal.h: internal procfs definitions
+/* Internal procfs definitions
  *
  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
@@ -9,80 +9,83 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
 #include <linux/binfmts.h>
-struct  ctl_table_header;
-struct  mempolicy;
 
-extern struct proc_dir_entry proc_root;
-extern void proc_self_init(void);
-#ifdef CONFIG_PROC_SYSCTL
-extern int proc_sys_init(void);
-extern void sysctl_head_put(struct ctl_table_header *head);
-#else
-static inline void proc_sys_init(void) { }
-static inline void sysctl_head_put(struct ctl_table_header *head) { }
-#endif
-#ifdef CONFIG_NET
-extern int proc_net_init(void);
-#else
-static inline int proc_net_init(void) { return 0; }
-#endif
+struct ctl_table_header;
+struct mempolicy;
 
-struct vmalloc_info {
-       unsigned long   used;
-       unsigned long   largest_chunk;
+/*
+ * This is not completely implemented yet. The idea is to
+ * create an in-memory tree (like the actual /proc filesystem
+ * tree) of these proc_dir_entries, so that we can dynamically
+ * add new files to /proc.
+ *
+ * The "next" pointer creates a linked list of one /proc directory,
+ * while parent/subdir create the directory structure (every
+ * /proc file has a parent, but "subdir" is NULL for all
+ * non-directory entries).
+ */
+struct proc_dir_entry {
+       unsigned int low_ino;
+       umode_t mode;
+       nlink_t nlink;
+       kuid_t uid;
+       kgid_t gid;
+       loff_t size;
+       const struct inode_operations *proc_iops;
+       const struct file_operations *proc_fops;
+       struct proc_dir_entry *next, *parent, *subdir;
+       void *data;
+       atomic_t count;         /* use count */
+       atomic_t in_use;        /* number of callers into module in progress; */
+                       /* negative -> it's going away RSN */
+       struct completion *pde_unload_completion;
+       struct list_head pde_openers;   /* who did ->open, but not ->release */
+       spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
+       u8 namelen;
+       char name[];
 };
 
-#ifdef CONFIG_MMU
-#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
-extern void get_vmalloc_info(struct vmalloc_info *vmi);
-#else
-
-#define VMALLOC_TOTAL 0UL
-#define get_vmalloc_info(vmi)                  \
-do {                                           \
-       (vmi)->used = 0;                        \
-       (vmi)->largest_chunk = 0;               \
-} while(0)
-#endif
-
-extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
-                               struct pid *pid, struct task_struct *task);
-extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
-                               struct pid *pid, struct task_struct *task);
-extern int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
-                               struct pid *pid, struct task_struct *task);
-extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
-                               struct pid *pid, struct task_struct *task);
-extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
-
-extern const struct file_operations proc_tid_children_operations;
-extern const struct file_operations proc_pid_maps_operations;
-extern const struct file_operations proc_tid_maps_operations;
-extern const struct file_operations proc_pid_numa_maps_operations;
-extern const struct file_operations proc_tid_numa_maps_operations;
-extern const struct file_operations proc_pid_smaps_operations;
-extern const struct file_operations proc_tid_smaps_operations;
-extern const struct file_operations proc_clear_refs_operations;
-extern const struct file_operations proc_pagemap_operations;
-extern const struct file_operations proc_net_operations;
-extern const struct inode_operations proc_net_inode_operations;
-extern const struct inode_operations proc_pid_link_inode_operations;
+union proc_op {
+       int (*proc_get_link)(struct dentry *, struct path *);
+       int (*proc_read)(struct task_struct *task, char *page);
+       int (*proc_show)(struct seq_file *m,
+               struct pid_namespace *ns, struct pid *pid,
+               struct task_struct *task);
+};
 
-struct proc_maps_private {
+struct proc_inode {
        struct pid *pid;
-       struct task_struct *task;
-#ifdef CONFIG_MMU
-       struct vm_area_struct *tail_vma;
-#endif
-#ifdef CONFIG_NUMA
-       struct mempolicy *task_mempolicy;
-#endif
+       int fd;
+       union proc_op op;
+       struct proc_dir_entry *pde;
+       struct ctl_table_header *sysctl;
+       struct ctl_table *sysctl_entry;
+       struct proc_ns ns;
+       struct inode vfs_inode;
 };
 
-void proc_init_inodecache(void);
+/*
+ * General functions
+ */
+static inline struct proc_inode *PROC_I(const struct inode *inode)
+{
+       return container_of(inode, struct proc_inode, vfs_inode);
+}
+
+static inline struct proc_dir_entry *PDE(const struct inode *inode)
+{
+       return PROC_I(inode)->pde;
+}
+
+static inline void *__PDE_DATA(const struct inode *inode)
+{
+       return PDE(inode)->data;
+}
 
 static inline struct pid *proc_pid(struct inode *inode)
 {
@@ -94,11 +97,6 @@ static inline struct task_struct *get_proc_task(struct inode *inode)
        return get_pid_task(proc_pid(inode), PIDTYPE_PID);
 }
 
-static inline int proc_fd(struct inode *inode)
-{
-       return PROC_I(inode)->fd;
-}
-
 static inline int task_dumpable(struct task_struct *task)
 {
        int dumpable = 0;
@@ -114,15 +112,6 @@ static inline int task_dumpable(struct task_struct *task)
        return 0;
 }
 
-static inline int pid_delete_dentry(const struct dentry * dentry)
-{
-       /* Is the task we represent dead?
-        * If so, then don't put the dentry on the lru list,
-        * kill it immediately.
-        */
-       return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
-}
-
 static inline unsigned name_to_int(struct dentry *dentry)
 {
        const char *name = dentry->d_name.name;
@@ -145,63 +134,186 @@ out:
        return ~0U;
 }
 
-struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino,
-               struct dentry *dentry);
-int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
-               filldir_t filldir);
+/*
+ * Offset of the first process in the /proc root directory..
+ */
+#define FIRST_PROCESS_ENTRY 256
 
-struct pde_opener {
-       struct inode *inode;
-       struct file *file;
-       int (*release)(struct inode *, struct file *);
-       struct list_head lh;
-};
-void pde_users_dec(struct proc_dir_entry *pde);
+/* Worst case buffer size needed for holding an integer. */
+#define PROC_NUMBUF 13
+
+/*
+ * array.c
+ */
+extern const struct file_operations proc_tid_children_operations;
+
+extern int proc_tid_stat(struct seq_file *, struct pid_namespace *,
+                        struct pid *, struct task_struct *);
+extern int proc_tgid_stat(struct seq_file *, struct pid_namespace *,
+                         struct pid *, struct task_struct *);
+extern int proc_pid_status(struct seq_file *, struct pid_namespace *,
+                          struct pid *, struct task_struct *);
+extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
+                         struct pid *, struct task_struct *);
 
+/*
+ * base.c
+ */
+extern const struct dentry_operations pid_dentry_operations;
+extern int pid_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int proc_setattr(struct dentry *, struct iattr *);
+extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *);
+extern int pid_revalidate(struct dentry *, unsigned int);
+extern int pid_delete_dentry(const struct dentry *);
+extern int proc_pid_readdir(struct file *, void *, filldir_t);
+extern struct dentry *proc_pid_lookup(struct inode *, struct dentry *, unsigned int);
+extern loff_t mem_lseek(struct file *, loff_t, int);
+
+/* Lookups */
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
+                                    struct task_struct *, const void *);
+extern int proc_fill_cache(struct file *, void *, filldir_t, const char *, int,
+                          instantiate_t, struct task_struct *, const void *);
+
+/*
+ * generic.c
+ */
 extern spinlock_t proc_subdir_lock;
 
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int);
-int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
-unsigned long task_vsize(struct mm_struct *);
-unsigned long task_statm(struct mm_struct *,
-       unsigned long *, unsigned long *, unsigned long *, unsigned long *);
-void task_mem(struct seq_file *, struct mm_struct *);
+extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
+extern struct dentry *proc_lookup_de(struct proc_dir_entry *, struct inode *,
+                                    struct dentry *);
+extern int proc_readdir(struct file *, void *, filldir_t);
+extern int proc_readdir_de(struct proc_dir_entry *, struct file *, void *, filldir_t);
 
 static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
 {
        atomic_inc(&pde->count);
        return pde;
 }
-void pde_put(struct proc_dir_entry *pde);
+extern void pde_put(struct proc_dir_entry *);
 
-int proc_fill_super(struct super_block *);
-struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
-int proc_remount(struct super_block *sb, int *flags, char *data);
+/*
+ * inode.c
+ */
+struct pde_opener {
+       struct file *file;
+       struct list_head lh;
+       int closing;
+       struct completion *c;
+};
+
+extern const struct inode_operations proc_pid_link_inode_operations;
+
+extern void proc_init_inodecache(void);
+extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
+extern int proc_fill_super(struct super_block *);
+extern void proc_entry_rundown(struct proc_dir_entry *);
 
 /*
- * These are generic /proc routines that use the internal
- * "struct proc_dir_entry" tree to traverse the filesystem.
- *
- * The /proc root directory has extended versions to take care
- * of the /proc/<pid> subdirectories.
+ * mmu.c
  */
-int proc_readdir(struct file *, void *, filldir_t);
-struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
+struct vmalloc_info {
+       unsigned long   used;
+       unsigned long   largest_chunk;
+};
 
+#ifdef CONFIG_MMU
+#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
+extern void get_vmalloc_info(struct vmalloc_info *);
 
+#else
+#define VMALLOC_TOTAL 0UL
+static inline void get_vmalloc_info(struct vmalloc_info *vmi)
+{
+       vmi->used = 0;
+       vmi->largest_chunk = 0;
+}
+#endif
 
-/* Lookups */
-typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
-                               struct task_struct *, const void *);
-int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-       const char *name, int len,
-       instantiate_t instantiate, struct task_struct *task, const void *ptr);
-int pid_revalidate(struct dentry *dentry, unsigned int flags);
-struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task);
-extern const struct dentry_operations pid_dentry_operations;
-int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
-int proc_setattr(struct dentry *dentry, struct iattr *attr);
+/*
+ * proc_devtree.c
+ */
+#ifdef CONFIG_PROC_DEVICETREE
+extern void proc_device_tree_init(void);
+#endif
 
+/*
+ * proc_namespaces.c
+ */
 extern const struct inode_operations proc_ns_dir_inode_operations;
 extern const struct file_operations proc_ns_dir_operations;
 
+/*
+ * proc_net.c
+ */
+extern const struct file_operations proc_net_operations;
+extern const struct inode_operations proc_net_inode_operations;
+
+#ifdef CONFIG_NET
+extern int proc_net_init(void);
+#else
+static inline int proc_net_init(void) { return 0; }
+#endif
+
+/*
+ * proc_self.c
+ */
+extern int proc_setup_self(struct super_block *);
+
+/*
+ * proc_sysctl.c
+ */
+#ifdef CONFIG_PROC_SYSCTL
+extern int proc_sys_init(void);
+extern void sysctl_head_put(struct ctl_table_header *);
+#else
+static inline void proc_sys_init(void) { }
+static inline void sysctl_head_put(struct ctl_table_header *head) { }
+#endif
+
+/*
+ * proc_tty.c
+ */
+#ifdef CONFIG_TTY
+extern void proc_tty_init(void);
+#else
+static inline void proc_tty_init(void) {}
+#endif
+
+/*
+ * root.c
+ */
+extern struct proc_dir_entry proc_root;
+
+extern void proc_self_init(void);
+extern int proc_remount(struct super_block *, int *, char *);
+
+/*
+ * task_[no]mmu.c
+ */
+struct proc_maps_private {
+       struct pid *pid;
+       struct task_struct *task;
+#ifdef CONFIG_MMU
+       struct vm_area_struct *tail_vma;
+#endif
+#ifdef CONFIG_NUMA
+       struct mempolicy *task_mempolicy;
+#endif
+};
+
+extern const struct file_operations proc_pid_maps_operations;
+extern const struct file_operations proc_tid_maps_operations;
+extern const struct file_operations proc_pid_numa_maps_operations;
+extern const struct file_operations proc_tid_numa_maps_operations;
+extern const struct file_operations proc_pid_smaps_operations;
+extern const struct file_operations proc_tid_smaps_operations;
+extern const struct file_operations proc_clear_refs_operations;
+extern const struct file_operations proc_pagemap_operations;
+
+extern unsigned long task_vsize(struct mm_struct *);
+extern unsigned long task_statm(struct mm_struct *,
+                               unsigned long *, unsigned long *,
+                               unsigned long *, unsigned long *);
+extern void task_mem(struct seq_file *, struct mm_struct *);
index eda6f017f272755e2a5bfdbe73fae33c231394a2..13cf87c4686fccd1a29fe10f229172e9927cdade 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
+#include <linux/kcore.h>
 #include <linux/user.h>
 #include <linux/capability.h>
 #include <linux/elf.h>
@@ -27,6 +28,7 @@
 #include <linux/ioport.h>
 #include <linux/memory.h>
 #include <asm/sections.h>
+#include "internal.h"
 
 #define CORE_STR "CORE"
 
index b7a47196c8c3577e9cda96125a0157444128a7be..54bdc6701e9fd785ddc14c277a48ff455683d773 100644 (file)
@@ -51,7 +51,7 @@ static int ns_delete_dentry(const struct dentry *dentry)
 static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
 {
        struct inode *inode = dentry->d_inode;
-       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
+       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns.ns_ops;
 
        return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
                ns_ops->name, inode->i_ino);
@@ -95,8 +95,8 @@ static struct dentry *proc_ns_get_dentry(struct super_block *sb,
                inode->i_op = &ns_inode_operations;
                inode->i_mode = S_IFREG | S_IRUGO;
                inode->i_fop = &ns_file_operations;
-               ei->ns_ops = ns_ops;
-               ei->ns = ns;
+               ei->ns.ns_ops = ns_ops;
+               ei->ns.ns = ns;
                unlock_new_inode(inode);
        } else {
                ns_ops->put(ns);
@@ -118,7 +118,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
        struct super_block *sb = inode->i_sb;
        struct proc_inode *ei = PROC_I(inode);
        struct task_struct *task;
-       struct dentry *ns_dentry;
+       struct path ns_path;
        void *error = ERR_PTR(-EACCES);
 
        task = get_proc_task(inode);
@@ -128,14 +128,14 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
                goto out_put_task;
 
-       ns_dentry = proc_ns_get_dentry(sb, task, ei->ns_ops);
-       if (IS_ERR(ns_dentry)) {
-               error = ERR_CAST(ns_dentry);
+       ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops);
+       if (IS_ERR(ns_path.dentry)) {
+               error = ERR_CAST(ns_path.dentry);
                goto out_put_task;
        }
 
-       dput(nd->path.dentry);
-       nd->path.dentry = ns_dentry;
+       ns_path.mnt = mntget(nd->path.mnt);
+       nd_jump_link(nd, &ns_path);
        error = NULL;
 
 out_put_task:
@@ -148,7 +148,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
 {
        struct inode *inode = dentry->d_inode;
        struct proc_inode *ei = PROC_I(inode);
-       const struct proc_ns_operations *ns_ops = ei->ns_ops;
+       const struct proc_ns_operations *ns_ops = ei->ns.ns_ops;
        struct task_struct *task;
        void *ns;
        char name[50];
@@ -202,7 +202,7 @@ static struct dentry *proc_ns_instantiate(struct inode *dir,
        ei = PROC_I(inode);
        inode->i_mode = S_IFLNK|S_IRWXUGO;
        inode->i_op = &proc_ns_link_inode_operations;
-       ei->ns_ops = ns_ops;
+       ei->ns.ns_ops = ns_ops;
 
        d_set_d_op(dentry, &pid_dentry_operations);
        d_add(dentry, inode);
@@ -337,6 +337,11 @@ out_invalid:
        return ERR_PTR(-EINVAL);
 }
 
+struct proc_ns *get_proc_ns(struct inode *inode)
+{
+       return &PROC_I(inode)->ns;
+}
+
 bool proc_ns_inode(struct inode *inode)
 {
        return inode->i_fop == &ns_file_operations;
index 30b590f5bd356f088e0df909c0adcf44aae3f801..505afc950e0acf906b0043f396b26211189ff786 100644 (file)
@@ -41,7 +41,7 @@ static int property_proc_show(struct seq_file *m, void *v)
 
 static int property_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, property_proc_show, PDE(inode)->data);
+       return single_open(file, property_proc_show, __PDE_DATA(inode));
 }
 
 static const struct file_operations property_proc_fops = {
index b4ac6572474f7e4e7dafa5fde369f773a3b55cc2..986e83220d56e57524b533acb8e6a52a6cffe612 100644 (file)
 
 #include "internal.h"
 
+static inline struct net *PDE_NET(struct proc_dir_entry *pde)
+{
+       return pde->parent->data;
+}
 
 static struct net *get_proc_net(const struct inode *inode)
 {
index c6e9fac26bace4e9b63bd57dce624589dc67dfd7..20834b3c8ea3e312dbaffe5347d99dbfb3eef154 100644 (file)
@@ -137,6 +137,8 @@ static void proc_kill_sb(struct super_block *sb)
        struct pid_namespace *ns;
 
        ns = (struct pid_namespace *)sb->s_fs_info;
+       if (ns->proc_self)
+               dput(ns->proc_self);
        kill_anon_super(sb);
        put_pid_ns(ns);
 }
index aa5cc3bff14063bba66a093cb7f68bd734e71593..6b6a993b5c25a0ccb277bcf53b0c19489582f316 100644 (file)
@@ -1,6 +1,8 @@
-#include <linux/proc_fs.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/pid_namespace.h>
+#include "internal.h"
 
 /*
  * /proc/self:
@@ -48,12 +50,43 @@ static const struct inode_operations proc_self_inode_operations = {
        .put_link       = proc_self_put_link,
 };
 
-void __init proc_self_init(void)
+static unsigned self_inum;
+
+int proc_setup_self(struct super_block *s)
 {
-       struct proc_dir_entry *proc_self_symlink;
-       mode_t mode;
+       struct inode *root_inode = s->s_root->d_inode;
+       struct pid_namespace *ns = s->s_fs_info;
+       struct dentry *self;
+       
+       mutex_lock(&root_inode->i_mutex);
+       self = d_alloc_name(s->s_root, "self");
+       if (self) {
+               struct inode *inode = new_inode_pseudo(s);
+               if (inode) {
+                       inode->i_ino = self_inum;
+                       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+                       inode->i_mode = S_IFLNK | S_IRWXUGO;
+                       inode->i_uid = GLOBAL_ROOT_UID;
+                       inode->i_gid = GLOBAL_ROOT_GID;
+                       inode->i_op = &proc_self_inode_operations;
+                       d_add(self, inode);
+               } else {
+                       dput(self);
+                       self = ERR_PTR(-ENOMEM);
+               }
+       } else {
+               self = ERR_PTR(-ENOMEM);
+       }
+       mutex_unlock(&root_inode->i_mutex);
+       if (IS_ERR(self)) {
+               pr_err("proc_fill_super: can't allocate /proc/self\n");
+               return PTR_ERR(self);
+       }
+       ns->proc_self = self;
+       return 0;
+}
 
-       mode = S_IFLNK | S_IRWXUGO;
-       proc_self_symlink = proc_create("self", mode, NULL, NULL );
-       proc_self_symlink->proc_iops = &proc_self_inode_operations;
+void __init proc_self_init(void)
+{
+       proc_alloc_inum(&self_inum);
 }
index b870f740ab5a5bb2bf92451fe3b71a81d1f16a17..17f7e080d7ff6c5c301c6b71bd1c793b1439357c 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/mm.h>
-#include <linux/proc_fs.h>
+#include <linux/kcore.h>
 #include <linux/user.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
@@ -22,6 +22,7 @@
 #include <linux/list.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include "internal.h"
 
 /* List representing chunks of contiguous memory areas and their offsets in
  * vmcore file.
@@ -698,7 +699,7 @@ void vmcore_cleanup(void)
        struct list_head *pos, *next;
 
        if (proc_vmcore) {
-               remove_proc_entry(proc_vmcore->name, proc_vmcore->parent);
+               proc_remove(proc_vmcore);
                proc_vmcore = NULL;
        }
 
index 43098bb5723af2890acaaa8d2f3a86a37fc7b811..2e8caa62da78a71cc1ee46ce49634aab9408a779 100644 (file)
@@ -412,6 +412,7 @@ static struct file_system_type qnx4_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("qnx4");
 
 static int __init init_qnx4_fs(void)
 {
index 57199a52a3510688c09f25553dc4557de3b65696..8d941edfefa156bedb93a1a074ccda0e9a042fad 100644 (file)
@@ -672,6 +672,7 @@ static struct file_system_type qnx6_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("qnx6");
 
 static int __init init_qnx6_fs(void)
 {
index 05ae3c97f7a5fc552e771f9cf7312e4b61cffc1f..3e64169ef52710ff11f9c7f8c44ee3c910cbd321 100644 (file)
@@ -1439,8 +1439,11 @@ static void __dquot_initialize(struct inode *inode, int type)
                         * did a write before quota was turned on
                         */
                        rsv = inode_get_rsv_space(inode);
-                       if (unlikely(rsv))
+                       if (unlikely(rsv)) {
+                               spin_lock(&dq_data_lock);
                                dquot_resv_space(inode->i_dquot[cnt], rsv);
+                               spin_unlock(&dq_data_lock);
+                       }
                }
        }
 out_err:
index a698eff457fb6e510c0543c9b762cc8c8d702f23..a1f4d44cbc03e4ab9e64bcc4f035d8702a8104c6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/splice.h>
 #include <linux/compat.h>
 #include "read_write.h"
+#include "internal.h"
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -417,6 +418,30 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
 
 EXPORT_SYMBOL(do_sync_write);
 
+ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+{
+       mm_segment_t old_fs;
+       const char __user *p;
+       ssize_t ret;
+
+       old_fs = get_fs();
+       set_fs(get_ds());
+       p = (__force const char __user *)buf;
+       if (count > MAX_RW_COUNT)
+               count =  MAX_RW_COUNT;
+       if (file->f_op->write)
+               ret = file->f_op->write(file, p, count, pos);
+       else
+               ret = do_sync_write(file, p, count, pos);
+       set_fs(old_fs);
+       if (ret > 0) {
+               fsnotify_modify(file);
+               add_wchar(current, ret);
+       }
+       inc_syscw(current);
+       return ret;
+}
+
 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
 {
        ssize_t ret;
@@ -431,6 +456,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
        ret = rw_verify_area(WRITE, file, pos, count);
        if (ret >= 0) {
                count = ret;
+               file_start_write(file);
                if (file->f_op->write)
                        ret = file->f_op->write(file, buf, count, pos);
                else
@@ -440,6 +466,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
                        add_wchar(current, ret);
                }
                inc_syscw(current);
+               file_end_write(file);
        }
 
        return ret;
@@ -564,7 +591,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
 }
 EXPORT_SYMBOL(iov_shorten);
 
-ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
+static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
                unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
 {
        struct kiocb kiocb;
@@ -589,7 +616,7 @@ ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
 }
 
 /* Do it by hand, with file-ops */
-ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
+static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
                unsigned long nr_segs, loff_t *ppos, io_fn_t fn)
 {
        struct iovec *vector = iov;
@@ -731,6 +758,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
        } else {
                fn = (io_fn_t)file->f_op->write;
                fnv = file->f_op->aio_write;
+               file_start_write(file);
        }
 
        if (fnv)
@@ -739,6 +767,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
        else
                ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
 
+       if (type != READ)
+               file_end_write(file);
+
 out:
        if (iov != iovstack)
                kfree(iov);
@@ -869,6 +900,201 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
+
+static ssize_t compat_do_readv_writev(int type, struct file *file,
+                              const struct compat_iovec __user *uvector,
+                              unsigned long nr_segs, loff_t *pos)
+{
+       compat_ssize_t tot_len;
+       struct iovec iovstack[UIO_FASTIOV];
+       struct iovec *iov = iovstack;
+       ssize_t ret;
+       io_fn_t fn;
+       iov_fn_t fnv;
+
+       ret = -EINVAL;
+       if (!file->f_op)
+               goto out;
+
+       ret = -EFAULT;
+       if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+               goto out;
+
+       ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
+                                              UIO_FASTIOV, iovstack, &iov);
+       if (ret <= 0)
+               goto out;
+
+       tot_len = ret;
+       ret = rw_verify_area(type, file, pos, tot_len);
+       if (ret < 0)
+               goto out;
+
+       fnv = NULL;
+       if (type == READ) {
+               fn = file->f_op->read;
+               fnv = file->f_op->aio_read;
+       } else {
+               fn = (io_fn_t)file->f_op->write;
+               fnv = file->f_op->aio_write;
+               file_start_write(file);
+       }
+
+       if (fnv)
+               ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
+                                               pos, fnv);
+       else
+               ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
+
+       if (type != READ)
+               file_end_write(file);
+
+out:
+       if (iov != iovstack)
+               kfree(iov);
+       if ((ret + (type == READ)) > 0) {
+               if (type == READ)
+                       fsnotify_access(file);
+               else
+                       fsnotify_modify(file);
+       }
+       return ret;
+}
+
+static size_t compat_readv(struct file *file,
+                          const struct compat_iovec __user *vec,
+                          unsigned long vlen, loff_t *pos)
+{
+       ssize_t ret = -EBADF;
+
+       if (!(file->f_mode & FMODE_READ))
+               goto out;
+
+       ret = -EINVAL;
+       if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
+               goto out;
+
+       ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
+
+out:
+       if (ret > 0)
+               add_rchar(current, ret);
+       inc_syscr(current);
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen)
+{
+       struct fd f = fdget(fd);
+       ssize_t ret;
+       loff_t pos;
+
+       if (!f.file)
+               return -EBADF;
+       pos = f.file->f_pos;
+       ret = compat_readv(f.file, vec, vlen, &pos);
+       f.file->f_pos = pos;
+       fdput(f);
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, loff_t, pos)
+{
+       struct fd f;
+       ssize_t ret;
+
+       if (pos < 0)
+               return -EINVAL;
+       f = fdget(fd);
+       if (!f.file)
+               return -EBADF;
+       ret = -ESPIPE;
+       if (f.file->f_mode & FMODE_PREAD)
+               ret = compat_readv(f.file, vec, vlen, &pos);
+       fdput(f);
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, u32, pos_low, u32, pos_high)
+{
+       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+       return compat_sys_preadv64(fd, vec, vlen, pos);
+}
+
+static size_t compat_writev(struct file *file,
+                           const struct compat_iovec __user *vec,
+                           unsigned long vlen, loff_t *pos)
+{
+       ssize_t ret = -EBADF;
+
+       if (!(file->f_mode & FMODE_WRITE))
+               goto out;
+
+       ret = -EINVAL;
+       if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
+               goto out;
+
+       ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
+
+out:
+       if (ret > 0)
+               add_wchar(current, ret);
+       inc_syscw(current);
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd,
+               const struct compat_iovec __user *, vec,
+               unsigned long, vlen)
+{
+       struct fd f = fdget(fd);
+       ssize_t ret;
+       loff_t pos;
+
+       if (!f.file)
+               return -EBADF;
+       pos = f.file->f_pos;
+       ret = compat_writev(f.file, vec, vlen, &pos);
+       f.file->f_pos = pos;
+       fdput(f);
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, loff_t, pos)
+{
+       struct fd f;
+       ssize_t ret;
+
+       if (pos < 0)
+               return -EINVAL;
+       f = fdget(fd);
+       if (!f.file)
+               return -EBADF;
+       ret = -ESPIPE;
+       if (f.file->f_mode & FMODE_PWRITE)
+               ret = compat_writev(f.file, vec, vlen, &pos);
+       fdput(f);
+       return ret;
+}
+
+COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd,
+               const struct compat_iovec __user *,vec,
+               unsigned long, vlen, u32, pos_low, u32, pos_high)
+{
+       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+       return compat_sys_pwritev64(fd, vec, vlen, pos);
+}
+#endif
+
 ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count,
                    loff_t max)
 {
index d3e00ef674203930b0a0d190fb6b10a0d12b6032..b98780664ffa7dd3bf89d62711f5f2988cb6053c 100644 (file)
@@ -8,9 +8,5 @@ typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
                unsigned long, loff_t);
 
-ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
-               unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn);
-ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
-               unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
 ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count,
                    loff_t max);
index 6165bd4784f6ab1f08cf3076759ebe4eebc9616a..dcaafcfc23b007c845f490a4f293cc485c324b51 100644 (file)
@@ -234,68 +234,9 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
        return ret;
 }
 
-/* Write @count bytes at position @ppos in a file indicated by @file
-   from the buffer @buf.
-
-   generic_file_write() is only appropriate for filesystems that are not seeking to optimize performance and want
-   something simple that works.  It is not for serious use by general purpose filesystems, excepting the one that it was
-   written for (ext2/3).  This is for several reasons:
-
-   * It has no understanding of any filesystem specific optimizations.
-
-   * It enters the filesystem repeatedly for each page that is written.
-
-   * It depends on reiserfs_get_block() function which if implemented by reiserfs performs costly search_by_key
-   * operation for each page it is supplied with. By contrast reiserfs_file_write() feeds as much as possible at a time
-   * to reiserfs which allows for fewer tree traversals.
-
-   * Each indirect pointer insertion takes a lot of cpu, because it involves memory moves inside of blocks.
-
-   * Asking the block allocation code for blocks one at a time is slightly less efficient.
-
-   All of these reasons for not using only generic file write were understood back when reiserfs was first miscoded to
-   use it, but we were in a hurry to make code freeze, and so it couldn't be revised then.  This new code should make
-   things right finally.
-
-   Future Features: providing search_by_key with hints.
-
-*/
-static ssize_t reiserfs_file_write(struct file *file,  /* the file we are going to write into */
-                                  const char __user * buf,     /*  pointer to user supplied data
-                                                                  (in userspace) */
-                                  size_t count,        /* amount of bytes to write */
-                                  loff_t * ppos        /* pointer to position in file that we start writing at. Should be updated to
-                                                        * new current position before returning. */
-                                  )
-{
-       struct inode *inode = file_inode(file); // Inode of the file that we are writing to.
-       /* To simplify coding at this time, we store
-          locked pages in array for now */
-       struct reiserfs_transaction_handle th;
-       th.t_trans_id = 0;
-
-       /* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items
-       * lying around (most of the disk, in fact). Despite the filesystem
-       * now being a v3.6 format, the old items still can't support large
-       * file sizes. Catch this case here, as the rest of the VFS layer is
-       * oblivious to the different limitations between old and new items.
-       * reiserfs_setattr catches this for truncates. This chunk is lifted
-       * from generic_write_checks. */
-       if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 &&
-           *ppos + count > MAX_NON_LFS) {
-               if (*ppos >= MAX_NON_LFS) {
-                       return -EFBIG;
-               }
-               if (count > MAX_NON_LFS - (unsigned long)*ppos)
-                       count = MAX_NON_LFS - (unsigned long)*ppos;
-       }
-
-       return do_sync_write(file, buf, count, ppos);
-}
-
 const struct file_operations reiserfs_file_operations = {
        .read = do_sync_read,
-       .write = reiserfs_file_write,
+       .write = do_sync_write,
        .unlocked_ioctl = reiserfs_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = reiserfs_compat_ioctl,
index 9cc0740adffa1cc7f6672b22215fd910505f0bda..33532f79b4f714923ec951fa5fb75d1758fbfda3 100644 (file)
@@ -394,20 +394,24 @@ static int set_sb(struct super_block *sb, void *data)
        return -ENOENT;
 }
 
+struct reiserfs_seq_private {
+       struct super_block *sb;
+       int (*show) (struct seq_file *, struct super_block *);
+};
+
 static void *r_start(struct seq_file *m, loff_t * pos)
 {
-       struct proc_dir_entry *de = m->private;
-       struct super_block *s = de->parent->data;
+       struct reiserfs_seq_private *priv = m->private;
        loff_t l = *pos;
 
        if (l)
                return NULL;
 
-       if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, s)))
+       if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb)))
                return NULL;
 
-       up_write(&s->s_umount);
-       return s;
+       up_write(&priv->sb->s_umount);
+       return priv->sb;
 }
 
 static void *r_next(struct seq_file *m, void *v, loff_t * pos)
@@ -426,9 +430,8 @@ static void r_stop(struct seq_file *m, void *v)
 
 static int r_show(struct seq_file *m, void *v)
 {
-       struct proc_dir_entry *de = m->private;
-       int (*show) (struct seq_file *, struct super_block *) = de->data;
-       return show(m, v);
+       struct reiserfs_seq_private *priv = m->private;
+       return priv->show(m, v);
 }
 
 static const struct seq_operations r_ops = {
@@ -440,11 +443,15 @@ static const struct seq_operations r_ops = {
 
 static int r_open(struct inode *inode, struct file *file)
 {
-       int ret = seq_open(file, &r_ops);
+       struct reiserfs_seq_private *priv;
+       int ret = seq_open_private(file, &r_ops,
+                                  sizeof(struct reiserfs_seq_private));
 
        if (!ret) {
                struct seq_file *m = file->private_data;
-               m->private = PDE(inode);
+               priv = m->private;
+               priv->sb = proc_get_parent_data(inode);
+               priv->show = PDE_DATA(inode);
        }
        return ret;
 }
@@ -453,7 +460,7 @@ static const struct file_operations r_file_operations = {
        .open = r_open,
        .read = seq_read,
        .llseek = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_private,
        .owner = THIS_MODULE,
 };
 
@@ -479,9 +486,8 @@ int reiserfs_proc_info_init(struct super_block *sb)
                *s = '!';
 
        spin_lock_init(&__PINFO(sb).lock);
-       REISERFS_SB(sb)->procdir = proc_mkdir(b, proc_info_root);
+       REISERFS_SB(sb)->procdir = proc_mkdir_data(b, 0, proc_info_root, sb);
        if (REISERFS_SB(sb)->procdir) {
-               REISERFS_SB(sb)->procdir->data = sb;
                add_file(sb, "version", show_version);
                add_file(sb, "super", show_super);
                add_file(sb, "per-level", show_per_level);
@@ -499,29 +505,17 @@ int reiserfs_proc_info_init(struct super_block *sb)
 int reiserfs_proc_info_done(struct super_block *sb)
 {
        struct proc_dir_entry *de = REISERFS_SB(sb)->procdir;
-       char b[BDEVNAME_SIZE];
-       char *s;
+       if (de) {
+               char b[BDEVNAME_SIZE];
+               char *s;
 
-       /* Some block devices use /'s */
-       strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE);
-       s = strchr(b, '/');
-       if (s)
-               *s = '!';
+               /* Some block devices use /'s */
+               strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE);
+               s = strchr(b, '/');
+               if (s)
+                       *s = '!';
 
-       if (de) {
-               remove_proc_entry("journal", de);
-               remove_proc_entry("oidmap", de);
-               remove_proc_entry("on-disk-super", de);
-               remove_proc_entry("bitmap", de);
-               remove_proc_entry("per-level", de);
-               remove_proc_entry("super", de);
-               remove_proc_entry("version", de);
-       }
-       spin_lock(&__PINFO(sb).lock);
-       __PINFO(sb).exiting = 1;
-       spin_unlock(&__PINFO(sb).lock);
-       if (proc_info_root) {
-               remove_proc_entry(b, proc_info_root);
+               remove_proc_subtree(b, proc_info_root);
                REISERFS_SB(sb)->procdir = NULL;
        }
        return 0;
index 418bdc3a57da4e11092477fa1b3cbf2e37f71422..f8a23c3078f87d5eda59c30d55cea7ecc94b9273 100644 (file)
@@ -1147,8 +1147,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options,   /* strin
                                                         "on filesystem root.");
                                        return 0;
                                }
-                               qf_names[qtype] =
-                                   kmalloc(strlen(arg) + 1, GFP_KERNEL);
+                               qf_names[qtype] = kstrdup(arg, GFP_KERNEL);
                                if (!qf_names[qtype]) {
                                        reiserfs_warning(s, "reiserfs-2502",
                                                         "not enough memory "
@@ -1156,7 +1155,6 @@ static int reiserfs_parse_options(struct super_block *s, char *options,   /* strin
                                                         "quotafile name.");
                                        return 0;
                                }
-                               strcpy(qf_names[qtype], arg);
                                if (qtype == USRQUOTA)
                                        *mount_options |= 1 << REISERFS_USRQUOTA;
                                else
@@ -2434,6 +2432,7 @@ struct file_system_type reiserfs_fs_type = {
        .kill_sb = reiserfs_kill_sb,
        .fs_flags = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("reiserfs");
 
 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
 MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
index 7e8d3a80bdab1dcfce41d121cb074e58bf850679..15cbc41ee3653133c6e7001aec75e754582362e6 100644 (file)
@@ -599,6 +599,7 @@ static struct file_system_type romfs_fs_type = {
        .kill_sb        = romfs_kill_sb,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("romfs");
 
 /*
  * inode storage initialiser
index 38bb59f3f2add2aad3ad19af5086f00911ce2f66..774c1eb7f1c926c73a7018ae47d9cfb03f75da76 100644 (file)
@@ -599,6 +599,24 @@ int single_open(struct file *file, int (*show)(struct seq_file *, void *),
 }
 EXPORT_SYMBOL(single_open);
 
+int single_open_size(struct file *file, int (*show)(struct seq_file *, void *),
+               void *data, size_t size)
+{
+       char *buf = kmalloc(size, GFP_KERNEL);
+       int ret;
+       if (!buf)
+               return -ENOMEM;
+       ret = single_open(file, show, data);
+       if (ret) {
+               kfree(buf);
+               return ret;
+       }
+       ((struct seq_file *)file->private_data)->buf = buf;
+       ((struct seq_file *)file->private_data)->size = size;
+       return 0;
+}
+EXPORT_SYMBOL(single_open_size);
+
 int single_release(struct inode *inode, struct file *file)
 {
        const struct seq_operations *op = ((struct seq_file *)file->private_data)->op;
index 718bd0056384688af6ead056156574638c0be6e9..45e645b15d9271bb43485d8946303aeb3a32cd4e 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/security.h>
 #include <linux/gfp.h>
 #include <linux/socket.h>
+#include "internal.h"
 
 /*
  * Attempt to steal a page from a pipe buffer. This should perhaps go into
@@ -217,7 +218,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
                        page_nr++;
                        ret += buf->len;
 
-                       if (pipe->inode)
+                       if (pipe->files)
                                do_wakeup = 1;
 
                        if (!--spd->nr_pages)
@@ -827,7 +828,7 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
                        ops->release(pipe, buf);
                        pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1);
                        pipe->nrbufs--;
-                       if (pipe->inode)
+                       if (pipe->files)
                                sd->need_wakeup = true;
                }
 
@@ -999,8 +1000,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
        };
        ssize_t ret;
 
-       sb_start_write(inode->i_sb);
-
        pipe_lock(pipe);
 
        splice_from_pipe_begin(&sd);
@@ -1036,7 +1035,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                        *ppos += ret;
                balance_dirty_pages_ratelimited(mapping);
        }
-       sb_end_write(inode->i_sb);
 
        return ret;
 }
@@ -1048,9 +1046,10 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
 {
        int ret;
        void *data;
+       loff_t tmp = sd->pos;
 
        data = buf->ops->map(pipe, buf, 0);
-       ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos);
+       ret = __kernel_write(sd->u.file, data + buf->offset, sd->len, &tmp);
        buf->ops->unmap(pipe, buf, data);
 
        return ret;
@@ -1115,7 +1114,10 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        else
                splice_write = default_file_splice_write;
 
-       return splice_write(pipe, out, ppos, len, flags);
+       file_start_write(out);
+       ret = splice_write(pipe, out, ppos, len, flags);
+       file_end_write(out);
+       return ret;
 }
 
 /*
@@ -1181,7 +1183,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
         */
        pipe = current->splice_pipe;
        if (unlikely(!pipe)) {
-               pipe = alloc_pipe_info(NULL);
+               pipe = alloc_pipe_info();
                if (!pipe)
                        return -ENOMEM;
 
index 260e3928d4f52bb94076e0025f5fd8bef08bb1c3..60553a9053ca82b7264862e8168b61df0ce7de89 100644 (file)
@@ -489,6 +489,7 @@ static struct file_system_type squashfs_fs_type = {
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV
 };
+MODULE_ALIAS_FS("squashfs");
 
 static const struct super_operations squashfs_super_ops = {
        .alloc_inode = squashfs_alloc_inode,
index a38e87bdd78dcb6fa112f954b30a93de9dc06420..d0c6a007ce835cf869fac695eb5445b34be6d814 100644 (file)
@@ -545,6 +545,7 @@ static struct file_system_type sysv_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("sysv");
 
 static struct file_system_type v7_fs_type = {
        .owner          = THIS_MODULE,
@@ -553,6 +554,8 @@ static struct file_system_type v7_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("v7");
+MODULE_ALIAS("v7");
 
 static int __init init_sysv_fs(void)
 {
@@ -586,5 +589,4 @@ static void __exit exit_sysv_fs(void)
 
 module_init(init_sysv_fs)
 module_exit(exit_sysv_fs)
-MODULE_ALIAS("v7");
 MODULE_LICENSE("GPL");
index ddc0f6ae65e9992af3dc689ad61021e86c5e40a1..ac838b844936cdc29be5f3eff7192e9cb9a15582 100644 (file)
@@ -2174,6 +2174,7 @@ static struct file_system_type ubifs_fs_type = {
        .mount   = ubifs_mount,
        .kill_sb = kill_ubifs_super,
 };
+MODULE_ALIAS_FS("ubifs");
 
 /*
  * Inode slab cache constructor.
index bc5b30a819e82e8622d2ead088c52ef5cf7c268e..9ac4057a86c90f64a84ea2cee0b92e4f549ac01a 100644 (file)
@@ -118,6 +118,7 @@ static struct file_system_type udf_fstype = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("udf");
 
 static struct kmem_cache *udf_inode_cachep;
 
index dc8e3a861d0fcddc79d3113b179672d7b59978e8..329f2f53b7ed655b2ef525331f7c75a714d58de9 100644 (file)
@@ -1500,6 +1500,7 @@ static struct file_system_type ufs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ufs");
 
 static int __init init_ufs_fs(void)
 {
index 4e8f0df82d025e6bc38615a94d254bf003c24972..8459b5d8cb71ceaa98ff64990cae8d4daaf6f1b1 100644 (file)
@@ -1334,6 +1334,12 @@ _xfs_buf_ioapply(
        int             size;
        int             i;
 
+       /*
+        * Make sure we capture only current IO errors rather than stale errors
+        * left over from previous use of the buffer (e.g. failed readahead).
+        */
+       bp->b_error = 0;
+
        if (bp->b_flags & XBF_WRITE) {
                if (bp->b_flags & XBF_SYNCIO)
                        rw = WRITE_SYNC;
index f03bf1a456fbcacf43cc4999124a5d9072d733f0..3800128d2171b916a0d0652699bf72c9b6cf3ab7 100644 (file)
@@ -775,8 +775,6 @@ xfs_file_aio_write(
        if (ocount == 0)
                return 0;
 
-       sb_start_write(inode->i_sb);
-
        if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
                ret = -EIO;
                goto out;
@@ -800,7 +798,6 @@ xfs_file_aio_write(
        }
 
 out:
-       sb_end_write(inode->i_sb);
        return ret;
 }
 
index 912d83d8860a984a938b604f3e2447c3e390ce89..5a30dd899d2b32c38dbc1fc552e323d233f33e50 100644 (file)
@@ -325,7 +325,7 @@ xfs_iomap_eof_want_preallocate(
  * rather than falling short due to things like stripe unit/width alignment of
  * real extents.
  */
-STATIC int
+STATIC xfs_fsblock_t
 xfs_iomap_eof_prealloc_initial_size(
        struct xfs_mount        *mp,
        struct xfs_inode        *ip,
@@ -413,7 +413,7 @@ xfs_iomap_prealloc_size(
                 * have a large file on a small filesystem and the above
                 * lowspace thresholds are smaller than MAXEXTLEN.
                 */
-               while (alloc_blocks >= freesp)
+               while (alloc_blocks && alloc_blocks >= freesp)
                        alloc_blocks >>= 4;
        }
 
index c407121873b4763984f21870723e6e517b03f23c..ea341cea68cbfc5a7798810f0239ff34bfedfb09 100644 (file)
@@ -1561,6 +1561,7 @@ static struct file_system_type xfs_fs_type = {
        .kill_sb                = kill_block_super,
        .fs_flags               = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("xfs");
 
 STATIC int __init
 xfs_init_zones(void)
index e65278f560c40593e5a3f6fd8b520d5fce3f4468..22ba56e834e279c55d439a97144498457609f349 100644 (file)
@@ -437,11 +437,9 @@ void acpi_remove_dir(struct acpi_device *);
  */
 struct acpi_bus_type {
        struct list_head list;
-       struct bus_type *bus;
-       /* For general devices under the bus */
+       const char *name;
+       bool (*match)(struct device *dev);
        int (*find_device) (struct device *, acpi_handle *);
-       /* For bridges, such as PCI root bridge, IDE controller */
-       int (*find_bridge) (struct device *, acpi_handle *);
        void (*setup)(struct device *);
        void (*cleanup)(struct device *);
 };
index 555d0337ad955bbdccd6a7f5b261e9d0777462c3..b327b5a9296d36fb6c31fd26e382488fd0b45cbb 100644 (file)
@@ -235,6 +235,9 @@ extern void acpi_processor_unregister_performance(struct
          if a _PPC object exists, rmmod is disallowed then */
 int acpi_processor_notify_smm(struct module *calling_module);
 
+/* parsing the _P* objects. */
+extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
+
 /* for communication between multiple parts of the processor kernel module */
 DECLARE_PER_CPU(struct acpi_processor *, processors);
 extern struct acpi_processor_errata errata;
index 1ced6413ea0345580830394554e0ed2b69ba1224..33bd2de3bc1e930da34dcb8b6007825807ddacb3 100644 (file)
@@ -136,12 +136,6 @@ static inline void atomic_dec(atomic_t *v)
 #define atomic_xchg(ptr, v)            (xchg(&(ptr)->counter, (v)))
 #define atomic_cmpxchg(v, old, new)    (cmpxchg(&((v)->counter), (old), (new)))
 
-#define cmpxchg_local(ptr, o, n)                                              \
-       ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
-                       (unsigned long)(n), sizeof(*(ptr))))
-
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-
 static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 {
   int c, old;
index 14883026015dc50be00508f8eccf9cf805ea0ef4..811fb1e9b06131303d41f07797becb024e61d77f 100644 (file)
@@ -92,6 +92,16 @@ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  */
 #include <asm-generic/cmpxchg-local.h>
 
+#ifndef cmpxchg_local
+#define cmpxchg_local(ptr, o, n)                                              \
+       ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
+                       (unsigned long)(n), sizeof(*(ptr))))
+#endif
+
+#ifndef cmpxchg64_local
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#endif
+
 #define cmpxchg(ptr, o, n)     cmpxchg_local((ptr), (o), (n))
 #define cmpxchg64(ptr, o, n)   cmpxchg64_local((ptr), (o), (n))
 
index 2d94d7413d71cc02483bae57219007bb6f30dd28..60c33f14408f31499a43dd51464d7578206d4370 100644 (file)
@@ -1022,7 +1022,7 @@ struct drm_info_list {
 struct drm_info_node {
        struct list_head list;
        struct drm_minor *minor;
-       struct drm_info_list *info_ent;
+       const struct drm_info_list *info_ent;
        struct dentry *dent;
 };
 
@@ -1546,8 +1546,7 @@ extern struct idr drm_minors_idr;
 extern struct drm_local_map *drm_getsarea(struct drm_device *dev);
 
                                /* Proc support (drm_proc.h) */
-extern int drm_proc_init(struct drm_minor *minor, int minor_id,
-                        struct proc_dir_entry *root);
+extern int drm_proc_init(struct drm_minor *minor, struct proc_dir_entry *root);
 extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root);
 
                                /* Debugfs support */
index 8839b3a246608989089582f7a20cd237d4f177cd..e3e0d651c6cab54b51745a242a844b142a64bc71 100644 (file)
@@ -443,12 +443,12 @@ struct drm_crtc {
  * @dpms: set power state (see drm_crtc_funcs above)
  * @save: save connector state
  * @restore: restore connector state
- * @reset: reset connector after state has been invalidate (e.g. resume)
+ * @reset: reset connector after state has been invalidated (e.g. resume)
  * @detect: is this connector active?
  * @fill_modes: fill mode list for this connector
- * @set_property: property for this connector may need update
+ * @set_property: property for this connector may need an update
  * @destroy: make object go away
- * @force: notify the driver the connector is forced on
+ * @force: notify the driver that the connector is forced on
  *
  * Each CRTC may have one or more connectors attached to it.  The functions
  * below allow the core DRM code to control connectors, enumerate available modes,
index a386b0b654cced33e17eb6a7917a935c76ff1de5..918e8fe2f5e9b3f07d49fbf9f71252c60f318692 100644 (file)
        {0x1002, 0x9908, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9909, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x990A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
-       {0x1002, 0x990F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x990B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x990C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x990D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x990E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x990F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9910, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9913, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9917, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9993, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9994, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9996, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9998, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9999, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x999A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x999B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x99A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x99A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x99A4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
index c3a09149f7939c8e44c28b1984700daad21e1e23..70cf138690e9184678b1dea1aa9a23dd1a10a487 100644 (file)
@@ -118,5 +118,6 @@ extern int prepare_bprm_creds(struct linux_binprm *bprm);
 extern void install_exec_creds(struct linux_binprm *bprm);
 extern void set_binfmt(struct linux_binfmt *new);
 extern void free_bprm(struct linux_binprm *);
+extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t);
 
 #endif /* _LINUX_BINFMTS_H */
index 900af5964f5543f6dd1b5308419e93c70cb0ca07..68f2157b71d4376dd9a08327dc358b71a0301fff 100644 (file)
@@ -42,7 +42,7 @@ extern int cgroupstats_build(struct cgroupstats *stats,
 extern int cgroup_load_subsys(struct cgroup_subsys *ss);
 extern void cgroup_unload_subsys(struct cgroup_subsys *ss);
 
-extern const struct file_operations proc_cgroup_operations;
+extern int proc_cgroup_show(struct seq_file *, void *);
 
 /* Define the enumeration of all builtin cgroup subsystems */
 #define SUBSYS(_x) _x ## _subsys_id,
index 8c8a60d294079af6f7488536cf33e8cbb070d58e..22b637c5ecae5b6ebad60953d38bf373329a4f41 100644 (file)
@@ -64,10 +64,9 @@ extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
 extern int cpuset_memory_pressure_enabled;
 extern void __cpuset_memory_pressure_bump(void);
 
-extern const struct file_operations proc_cpuset_operations;
-struct seq_file;
 extern void cpuset_task_status_allowed(struct seq_file *m,
                                        struct task_struct *task);
+extern int proc_cpuset_show(struct seq_file *, void *);
 
 extern int cpuset_mem_spread_node(void);
 extern int cpuset_slab_spread_node(void);
index 2224a8c0cb6404974c217cfb825576c4fcf9665a..8d5ab998a222565c44df58930b70dafa38381a6b 100644 (file)
@@ -6,9 +6,8 @@
 #define ECRYPTFS_VERSION_MINOR 0x04
 #define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
 /* These flags indicate which features are supported by the kernel
- * module; userspace tools such as the mount helper read
- * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
- * how to behave. */
+ * module; userspace tools such as the mount helper read the feature
+ * bits from a sysfs handle in order to determine how to behave. */
 #define ECRYPTFS_VERSIONING_PASSPHRASE            0x00000001
 #define ECRYPTFS_VERSIONING_PUBKEY                0x00000002
 #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
 #define ECRYPTFS_VERSIONING_HMAC                  0x00000080
 #define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION   0x00000100
 #define ECRYPTFS_VERSIONING_GCM                   0x00000200
-#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
-                                 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
-                                 | ECRYPTFS_VERSIONING_PUBKEY \
-                                 | ECRYPTFS_VERSIONING_XATTR \
-                                 | ECRYPTFS_VERSIONING_MULTKEY \
-                                 | ECRYPTFS_VERSIONING_DEVMISC \
-                                 | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION)
 #define ECRYPTFS_MAX_PASSWORD_LENGTH 64
 #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
 #define ECRYPTFS_SALT_SIZE 8
index 4fd4999ccb5bf3386db3c27fec3f0f1d4a048b42..0b763276f6199a255d304b572e0c414c90252056 100644 (file)
@@ -561,7 +561,6 @@ struct csrow_info {
 
        u32 ue_count;           /* Uncorrectable Errors for this csrow */
        u32 ce_count;           /* Correctable Errors for this csrow */
-       u32 nr_pages;           /* combined pages count of all channels */
 
        struct mem_ctl_info *mci;       /* the parent */
 
@@ -676,11 +675,11 @@ struct mem_ctl_info {
         * sees memory sticks ("dimms"), and the ones that sees memory ranks.
         * All old memory controllers enumerate memories per rank, but most
         * of the recent drivers enumerate memories per DIMM, instead.
-        * When the memory controller is per rank, mem_is_per_rank is true.
+        * When the memory controller is per rank, csbased is true.
         */
        unsigned n_layers;
        struct edac_mc_layer *layers;
-       bool mem_is_per_rank;
+       bool csbased;
 
        /*
         * DIMM info. Will eventually remove the entire csrows_info some day
@@ -741,8 +740,6 @@ struct mem_ctl_info {
        u32 fake_inject_ue;
        u16 fake_inject_count;
 #endif
-       __u8 csbased : 1,       /* csrow-based memory controller */
-            __resv  : 7;
 };
 
 #endif
index 74a907b8b950c5c7d8e2e736003258429f01abf0..b1f28b02ede60b309311523e711de6445896c052 100644 (file)
@@ -1825,6 +1825,8 @@ struct file_system_type {
        struct lock_class_key i_mutex_dir_key;
 };
 
+#define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME)
+
 extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
        void *data, int (*fill_super)(struct super_block *, void *, int));
 extern struct dentry *mount_bdev(struct file_system_type *fs_type,
@@ -2078,7 +2080,6 @@ extern int sync_filesystem(struct super_block *);
 extern const struct file_operations def_blk_fops;
 extern const struct file_operations def_chr_fops;
 extern const struct file_operations bad_sock_fops;
-extern const struct file_operations def_fifo_fops;
 #ifdef CONFIG_BLOCK
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
@@ -2150,10 +2151,6 @@ extern void init_special_inode(struct inode *, umode_t, dev_t);
 extern void make_bad_inode(struct inode *);
 extern int is_bad_inode(struct inode *);
 
-extern const struct file_operations read_pipefifo_fops;
-extern const struct file_operations write_pipefifo_fops;
-extern const struct file_operations rdwr_pipefifo_fops;
-
 #ifdef CONFIG_BLOCK
 /*
  * return READ, READA, or WRITE
@@ -2221,6 +2218,20 @@ static inline struct inode *file_inode(struct file *f)
        return f->f_inode;
 }
 
+static inline void file_start_write(struct file *file)
+{
+       if (!S_ISREG(file_inode(file)->i_mode))
+               return;
+       __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true);
+}
+
+static inline void file_end_write(struct file *file)
+{
+       if (!S_ISREG(file_inode(file)->i_mode))
+               return;
+       __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE);
+}
+
 /*
  * get_write_access() gets write permission for a file.
  * put_write_access() releases this write permission.
index 29eb805ea4a6b2c98236bbd0f24cc00a45ec53df..c1d6555d2567468f86a6c1b6d745d927f1a25815 100644 (file)
 
 #ifdef CONFIG_PREEMPT_COUNT
 # define preemptible() (preempt_count() == 0 && !irqs_disabled())
-# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
 # define preemptible() 0
-# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
 #if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
index 61c97ae22e01881d7e1744401e52705c7986fb99..f09a0ae4d858557c8bc7c071c34cd5ec46c29043 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
 #define GOLDEN_RATIO_PRIME_32 0x9e370001UL
@@ -31,7 +32,7 @@
 #error Wordsize not 32 or 64
 #endif
 
-static inline u64 hash_64(u64 val, unsigned int bits)
+static __always_inline u64 hash_64(u64 val, unsigned int bits)
 {
        u64 hash = val;
 
index f027f7a63511bbdcd0daf459e5dce65434117dcf..99e379b74398e645e060f523cd29f8c5dca4dab3 100644 (file)
@@ -15,6 +15,9 @@
 
 #include <linux/types.h>
 
+/* For key_map array */
+#define MXT_NUM_GPIO           4
+
 /* Orient */
 #define MXT_NORMAL             0x0
 #define MXT_DIAGONAL           0x1
@@ -39,6 +42,8 @@ struct mxt_platform_data {
        unsigned int voltage;
        unsigned char orient;
        unsigned long irqflags;
+       bool is_tp;
+       const unsigned int key_map[MXT_NUM_GPIO];
 };
 
 #endif /* __LINUX_ATMEL_MXT_TS_H */
index a6f38b5c34e47d000f73483b6a8b3967a7c2f39e..2640c7e99e51c65489d817ee9a44f6205a2cb0ad 100644 (file)
@@ -73,8 +73,6 @@ struct idr {
  */
 
 void *idr_find_slowpath(struct idr *idp, int id);
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
 void idr_preload(gfp_t gfp_mask);
 int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
 int idr_for_each(struct idr *idp,
@@ -99,7 +97,7 @@ static inline void idr_preload_end(void)
 
 /**
  * idr_find - return pointer for given id
- * @idp: idr handle
+ * @idr: idr handle
  * @id: lookup key
  *
  * Return the pointer given the id it has been registered with.  A %NULL
@@ -119,19 +117,6 @@ static inline void *idr_find(struct idr *idr, int id)
        return idr_find_slowpath(idr, id);
 }
 
-/**
- * idr_get_new - allocate new idr entry
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @id: pointer to the allocated handle
- *
- * Simple wrapper around idr_get_new_above() w/ @starting_id of zero.
- */
-static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
-{
-       return idr_get_new_above(idp, ptr, 0, id);
-}
-
 /**
  * idr_for_each_entry - iterate over an idr's elements of a given type
  * @idp:     idr handle
@@ -143,7 +128,56 @@ static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
             entry != NULL;                                             \
             ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
 
-void __idr_remove_all(struct idr *idp);        /* don't use */
+/*
+ * Don't use the following functions.  These exist only to suppress
+ * deprecated warnings on EXPORT_SYMBOL()s.
+ */
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask);
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
+void __idr_remove_all(struct idr *idp);
+
+/**
+ * idr_pre_get - reserve resources for idr allocation
+ * @idp:       idr handle
+ * @gfp_mask:  memory allocation flags
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+{
+       return __idr_pre_get(idp, gfp_mask);
+}
+
+/**
+ * idr_get_new_above - allocate new idr entry above or equal to a start id
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @starting_id: id to start search at
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr,
+                                                int starting_id, int *id)
+{
+       return __idr_get_new_above(idp, ptr, starting_id, id);
+}
+
+/**
+ * idr_get_new - allocate new idr entry
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id)
+{
+       return __idr_get_new_above(idp, ptr, 0, id);
+}
 
 /**
  * idr_remove_all - remove all ids from the given idr tree
index 1f86a97ab2e2016407e68fe352bba3b4d018880d..8bd12be0b02f875f1182e9fdcaee69598bc8e083 100644 (file)
@@ -227,14 +227,17 @@ struct st_sensor_data {
 };
 
 #ifdef CONFIG_IIO_BUFFER
+irqreturn_t st_sensors_trigger_handler(int irq, void *p);
+
+int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
+#endif
+
+#ifdef CONFIG_IIO_TRIGGER
 int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
                                const struct iio_trigger_ops *trigger_ops);
 
 void st_sensors_deallocate_trigger(struct iio_dev *indio_dev);
 
-irqreturn_t st_sensors_trigger_handler(int irq, void *p);
-
-int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
 #else
 static inline int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
                                const struct iio_trigger_ops *trigger_ops)
index f5dbce50466e6546fc72f4084ed0d0c91d91fe1e..66017028dcb3d0aebf70aa7281e7758a42bcb3bf 100644 (file)
@@ -37,7 +37,7 @@ void irq_work_sync(struct irq_work *work);
 #ifdef CONFIG_IRQ_WORK
 bool irq_work_needs_cpu(void);
 #else
-static bool irq_work_needs_cpu(void) { return false; }
+static inline bool irq_work_needs_cpu(void) { return false; }
 #endif
 
 #endif /* _LINUX_IRQ_WORK_H */
diff --git a/include/linux/kcore.h b/include/linux/kcore.h
new file mode 100644 (file)
index 0000000..d927622
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * /proc/kcore definitions
+ */
+#ifndef _LINUX_KCORE_H
+#define _LINUX_KCORE_H
+
+enum kcore_type {
+       KCORE_TEXT,
+       KCORE_VMALLOC,
+       KCORE_RAM,
+       KCORE_VMEMMAP,
+       KCORE_OTHER,
+};
+
+struct kcore_list {
+       struct list_head list;
+       unsigned long addr;
+       size_t size;
+       int type;
+};
+
+struct vmcore {
+       struct list_head list;
+       unsigned long long paddr;
+       unsigned long long size;
+       loff_t offset;
+};
+
+#ifdef CONFIG_PROC_KCORE
+extern void kclist_add(struct kcore_list *, void *, size_t, int type);
+#else
+static inline
+void kclist_add(struct kcore_list *new, void *addr, size_t size, int type)
+{
+}
+#endif
+
+#endif /* _LINUX_KCORE_H */
index 80d36874689b40da26a3107ba509a8ca10dc74da..79fdd80a42d4f001157bc70b9570aa5eda0b8f6c 100644 (file)
@@ -390,7 +390,6 @@ extern struct pid *session_of_pgrp(struct pid *pgrp);
 unsigned long int_sqrt(unsigned long);
 
 extern void bust_spinlocks(int yes);
-extern void wake_up_klogd(void);
 extern int oops_in_progress;           /* If set, an oops, panic(), BUG() or die() is in progress */
 extern int panic_timeout;
 extern int panic_on_oops;
index d991cc147c98f81fbca56ca0cbdf6a6b62aa6c3e..6a1f8df9144bcfd5c1af3e9cbad600fe61749c29 100644 (file)
@@ -667,7 +667,9 @@ static inline void hlist_move_list(struct hlist_head *old,
             pos = n)
 
 #define hlist_entry_safe(ptr, type, member) \
-       (ptr) ? hlist_entry(ptr, type, member) : NULL
+       ({ typeof(ptr) ____ptr = (ptr); \
+          ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+       })
 
 /**
  * hlist_for_each_entry        - iterate over list of given type
index a4d13d7cd00187cf2928de2d651d486388078224..3bbda22721ea083cc35251e399a37742b72c8bae 100644 (file)
@@ -221,6 +221,7 @@ struct palmas_clk_platform_data {
 };
 
 struct palmas_platform_data {
+       int irq_flags;
        int gpio_base;
 
        /* bit value to be loaded to the POWER_CTRL register */
index aaceab402ec53a35fdbe3eb57ebe6aeb90610753..6d309032dc0ddc7da95e8a1b6b20b275fef0b7bb 100644 (file)
@@ -323,5 +323,6 @@ int tps65912_device_init(struct tps65912 *tps65912);
 void tps65912_device_exit(struct tps65912 *tps65912);
 int tps65912_irq_init(struct tps65912 *tps65912, int irq,
                        struct tps65912_platform_data *pdata);
+int tps65912_irq_exit(struct tps65912 *tps65912);
 
 #endif /*  __LINUX_MFD_TPS65912_H */
index b132067e9e997252c2fa19bf5c4be3c48b0f8f87..867aa23f93704b04154d9ff958990e3b635abc50 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef __MFD_WM831X_AUXADC_H__
 #define __MFD_WM831X_AUXADC_H__
 
+struct wm831x;
+
 /*
  * R16429 (0x402D) - AuxADC Data
  */
index 4a3b83a776148eb2ace611436b38ab42e931450e..76c22648436f22dad8ee59cec7f69ee984322a47 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/irqdomain.h>
 #include <linux/list.h>
 #include <linux/regmap.h>
+#include <linux/mfd/wm831x/auxadc.h>
 
 /*
  * Register values.
@@ -355,7 +356,6 @@ enum wm831x_parent {
 };
 
 struct wm831x;
-enum wm831x_auxadc;
 
 typedef int (*wm831x_auxadc_read_fn)(struct wm831x *wm831x,
                                     enum wm831x_auxadc input);
index ede274957e05b59e61725f85f0c4acff7b482f33..c74092eebf5c9da5a052168b8885c75290efa2d2 100644 (file)
@@ -527,7 +527,7 @@ static inline int zone_is_oom_locked(const struct zone *zone)
        return test_bit(ZONE_OOM_LOCKED, &zone->flags);
 }
 
-static inline unsigned zone_end_pfn(const struct zone *zone)
+static inline unsigned long zone_end_pfn(const struct zone *zone)
 {
        return zone->zone_start_pfn + zone->spanned_pages;
 }
index 7ccb3c59ed605d592fcd0663680b41427a218e7d..ef52d9c91459e0204e31c98483922b7ab95b1ebb 100644 (file)
@@ -187,6 +187,13 @@ typedef enum {
  * This happens with the Renesas AG-AND chips, possibly others.
  */
 #define BBT_AUTO_REFRESH       0x00000080
+/*
+ * Chip requires ready check on read (for auto-incremented sequential read).
+ * True only for small page devices; large page devices do not support
+ * autoincrement.
+ */
+#define NAND_NEED_READRDY      0x00000100
+
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE  0x00000200
 
index f14943d55315695e36186a75c5db56f07407dd20..f80af86743425ca6219c8c2cfc5b180f2325c85b 100644 (file)
@@ -24,8 +24,8 @@
 #define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
 #define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
 
-#define FB_SYNC_DATA_ENABLE_HIGH_ACT   (1 << 6)
-#define FB_SYNC_DOTCLK_FAILING_ACT     (1 << 7) /* failing/negtive edge sampling */
+#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT        (1 << 6)
+#define MXSFB_SYNC_DOTCLK_FAILING_ACT  (1 << 7) /* failing/negtive edge sampling */
 
 struct mxsfb_platform_data {
        struct fb_videomode *mode_list;
@@ -44,6 +44,9 @@ struct mxsfb_platform_data {
                                 * allocated. If specified,fb_size must also be specified.
                                 * fb_phys must be unused by Linux.
                                 */
+       u32 sync;               /* sync mask, contains MXSFB specifics not
+                                * carried in fb_info->var.sync
+                                */
 };
 
 #endif /* __LINUX_MXSFB_H */
index ef9acd3c84506fcd3525166501387445181e92c0..01d25e6fc792472692f6e601de77a7b83fe69734 100644 (file)
@@ -854,6 +854,8 @@ type_pf_tresize(struct ip_set *set, bool retried)
 retry:
        ret = 0;
        htable_bits++;
+       pr_debug("attempt to resize set %s from %u to %u, t %p\n",
+                set->name, orig->htable_bits, htable_bits, orig);
        if (!htable_bits) {
                /* In case we have plenty of memory :-) */
                pr_warning("Cannot increase the hashsize of set %s further\n",
@@ -873,7 +875,7 @@ retry:
                        data = ahash_tdata(n, j);
                        m = hbucket(t, HKEY(data, h->initval, htable_bits));
                        ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0,
-                                               type_pf_data_timeout(data));
+                                               ip_set_timeout_get(type_pf_data_timeout(data)));
                        if (ret < 0) {
                                read_unlock_bh(&set->lock);
                                ahash_destroy(t);
index a8696bbdfbc477b95c06693f815a49354ae16054..b3740527571aa9fc6ef6449e589d1edbe17aeb3e 100644 (file)
@@ -80,7 +80,11 @@ extern struct nubus_board* nubus_boards;
 
 /* Generic NuBus interface functions, modelled after the PCI interface */
 void nubus_scan_bus(void);
+#ifdef CONFIG_PROC_FS
 extern void nubus_proc_init(void);
+#else
+static inline void nubus_proc_init(void) {}
+#endif
 int get_nubus_list(char *buf);
 int nubus_proc_attach_device(struct nubus_dev *dev);
 int nubus_proc_detach_device(struct nubus_dev *dev);
index c25cccaa555a420b5cc6fd26d5e83a89937470a6..4fa3b0b9b071358a779c4448d874e3dffe57900d 100644 (file)
@@ -137,6 +137,34 @@ enum {
        NVME_LBAF_RP_DEGRADED   = 3,
 };
 
+struct nvme_smart_log {
+       __u8                    critical_warning;
+       __u8                    temperature[2];
+       __u8                    avail_spare;
+       __u8                    spare_thresh;
+       __u8                    percent_used;
+       __u8                    rsvd6[26];
+       __u8                    data_units_read[16];
+       __u8                    data_units_written[16];
+       __u8                    host_reads[16];
+       __u8                    host_writes[16];
+       __u8                    ctrl_busy_time[16];
+       __u8                    power_cycles[16];
+       __u8                    power_on_hours[16];
+       __u8                    unsafe_shutdowns[16];
+       __u8                    media_errors[16];
+       __u8                    num_err_log_entries[16];
+       __u8                    rsvd192[320];
+};
+
+enum {
+       NVME_SMART_CRIT_SPARE           = 1 << 0,
+       NVME_SMART_CRIT_TEMPERATURE     = 1 << 1,
+       NVME_SMART_CRIT_RELIABILITY     = 1 << 2,
+       NVME_SMART_CRIT_MEDIA           = 1 << 3,
+       NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4,
+};
+
 struct nvme_lba_range_type {
        __u8                    type;
        __u8                    attributes;
index a0f129284948e86bde078d794dd35fbe37629acd..2d25ff8fe39aad527cfb1ab2c3a8287a62a32e70 100644 (file)
@@ -540,4 +540,14 @@ static inline int of_property_read_u32(const struct device_node *np,
        return of_property_read_u32_array(np, propname, out_value, 1);
 }
 
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE)
+extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
+extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
+extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
+                                        struct property *prop);
+extern void proc_device_tree_update_prop(struct proc_dir_entry *pde,
+                                        struct property *newprop,
+                                        struct property *oldprop);
+#endif
+
 #endif /* _LINUX_OF_H */
index e47ee462c2f2e69a8cbef4ef3a3d7bfc873cb51f..1d795df6f4cfdb53575efe2fd756015c0ad363de 100644 (file)
@@ -799,6 +799,12 @@ static inline int __perf_event_disable(void *info)                 { return -1; }
 static inline void perf_event_task_tick(void)                          { }
 #endif
 
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+extern void perf_restore_debug_store(void);
+#else
+static inline void perf_restore_debug_store(void)                      { }
+#endif
+
 #define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))
 
 /*
index 215e5e3dda1063e955c93fa566b46de16f6c8dc3..5524f8cfa95052843ca5fc74e2e4c168661aa183 100644 (file)
@@ -28,6 +28,7 @@ struct pid_namespace {
        struct pid_namespace *parent;
 #ifdef CONFIG_PROC_FS
        struct vfsmount *proc_mnt;
+       struct dentry *proc_self;
 #endif
 #ifdef CONFIG_BSD_PROCESS_ACCT
        struct bsd_acct_struct *bacct;
index ad1a427b5267b3faef96444289eacbaf62880f75..b8809fef61f5093445b773da85e416cf99e92094 100644 (file)
@@ -27,6 +27,7 @@ struct pipe_buffer {
 
 /**
  *     struct pipe_inode_info - a linux kernel pipe
+ *     @mutex: mutex protecting the whole thing
  *     @wait: reader/writer wait point in case of empty/full pipe
  *     @nrbufs: the number of non-empty pipe buffers in this pipe
  *     @buffers: total number of buffers (should be a power of 2)
@@ -34,26 +35,27 @@ struct pipe_buffer {
  *     @tmp_page: cached released page
  *     @readers: number of current readers of this pipe
  *     @writers: number of current writers of this pipe
+ *     @files: number of struct file refering this pipe (protected by ->i_lock)
  *     @waiting_writers: number of writers blocked waiting for room
  *     @r_counter: reader counter
  *     @w_counter: writer counter
  *     @fasync_readers: reader side fasync
  *     @fasync_writers: writer side fasync
- *     @inode: inode this pipe is attached to
  *     @bufs: the circular array of pipe buffers
  **/
 struct pipe_inode_info {
+       struct mutex mutex;
        wait_queue_head_t wait;
        unsigned int nrbufs, curbuf, buffers;
        unsigned int readers;
        unsigned int writers;
+       unsigned int files;
        unsigned int waiting_writers;
        unsigned int r_counter;
        unsigned int w_counter;
        struct page *tmp_page;
        struct fasync_struct *fasync_readers;
        struct fasync_struct *fasync_writers;
-       struct inode *inode;
        struct pipe_buffer *bufs;
 };
 
@@ -144,9 +146,8 @@ int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct pipe_inode_info *pipe);
 
-struct pipe_inode_info * alloc_pipe_info(struct inode * inode);
-void free_pipe_info(struct inode * inode);
-void __free_pipe_info(struct pipe_inode_info *);
+struct pipe_inode_info *alloc_pipe_info(void);
+void free_pipe_info(struct pipe_inode_info *);
 
 /* Generic pipe buffer ops functions */
 void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
index 1249a54d17e0ab471501919dbdc8d63e27658c35..822171fcb1c82bd110472975d63fd4c2ed5fe8f2 100644 (file)
@@ -134,6 +134,8 @@ extern int printk_delay_msec;
 extern int dmesg_restrict;
 extern int kptr_restrict;
 
+extern void wake_up_klogd(void);
+
 void log_buf_kexec_setup(void);
 void __init setup_log_buf(int early);
 #else
@@ -162,6 +164,10 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies,
        return false;
 }
 
+static inline void wake_up_klogd(void)
+{
+}
+
 static inline void log_buf_kexec_setup(void)
 {
 }
index 8307f2f94d860f46139b6a20d6795a9186704c19..608e60a74c3c124293bb3db038d3a1e8ba804432 100644 (file)
-#ifndef _LINUX_PROC_FS_H
-#define _LINUX_PROC_FS_H
-
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-#include <linux/magic.h>
-#include <linux/atomic.h>
-
-struct net;
-struct completion;
-struct mm_struct;
-
 /*
  * The proc filesystem constants/structures
  */
+#ifndef _LINUX_PROC_FS_H
+#define _LINUX_PROC_FS_H
 
-/*
- * Offset of the first process in the /proc root directory..
- */
-#define FIRST_PROCESS_ENTRY 256
-
-/* Worst case buffer size needed for holding an integer. */
-#define PROC_NUMBUF 13
-
-/*
- * We always define these enumerators
- */
-
-enum {
-       PROC_ROOT_INO           = 1,
-       PROC_IPC_INIT_INO       = 0xEFFFFFFFU,
-       PROC_UTS_INIT_INO       = 0xEFFFFFFEU,
-       PROC_USER_INIT_INO      = 0xEFFFFFFDU,
-       PROC_PID_INIT_INO       = 0xEFFFFFFCU,
-};
-
-/*
- * This is not completely implemented yet. The idea is to
- * create an in-memory tree (like the actual /proc filesystem
- * tree) of these proc_dir_entries, so that we can dynamically
- * add new files to /proc.
- *
- * The "next" pointer creates a linked list of one /proc directory,
- * while parent/subdir create the directory structure (every
- * /proc file has a parent, but "subdir" is NULL for all
- * non-directory entries).
- */
-
-typedef        int (read_proc_t)(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
-typedef        int (write_proc_t)(struct file *file, const char __user *buffer,
-                          unsigned long count, void *data);
-
-struct proc_dir_entry {
-       unsigned int low_ino;
-       umode_t mode;
-       nlink_t nlink;
-       kuid_t uid;
-       kgid_t gid;
-       loff_t size;
-       const struct inode_operations *proc_iops;
-       /*
-        * NULL ->proc_fops means "PDE is going away RSN" or
-        * "PDE is just created". In either case, e.g. ->read_proc won't be
-        * called because it's too late or too early, respectively.
-        *
-        * If you're allocating ->proc_fops dynamically, save a pointer
-        * somewhere.
-        */
-       const struct file_operations *proc_fops;
-       struct proc_dir_entry *next, *parent, *subdir;
-       void *data;
-       read_proc_t *read_proc;
-       write_proc_t *write_proc;
-       atomic_t count;         /* use count */
-       int pde_users;  /* number of callers into module in progress */
-       struct completion *pde_unload_completion;
-       struct list_head pde_openers;   /* who did ->open, but not ->release */
-       spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
-       u8 namelen;
-       char name[];
-};
-
-enum kcore_type {
-       KCORE_TEXT,
-       KCORE_VMALLOC,
-       KCORE_RAM,
-       KCORE_VMEMMAP,
-       KCORE_OTHER,
-};
-
-struct kcore_list {
-       struct list_head list;
-       unsigned long addr;
-       size_t size;
-       int type;
-};
+#include <linux/types.h>
+#include <linux/fs.h>
 
-struct vmcore {
-       struct list_head list;
-       unsigned long long paddr;
-       unsigned long long size;
-       loff_t offset;
-};
+struct proc_dir_entry;
 
 #ifdef CONFIG_PROC_FS
 
 extern void proc_root_init(void);
-
-void proc_flush_task(struct task_struct *task);
-
-extern struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode,
-                                               struct proc_dir_entry *parent);
-struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
-                               struct proc_dir_entry *parent,
-                               const struct file_operations *proc_fops,
-                               void *data);
-extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
-
-struct pid_namespace;
-
-extern int pid_ns_prepare_proc(struct pid_namespace *ns);
-extern void pid_ns_release_proc(struct pid_namespace *ns);
-
-/*
- * proc_tty.c
- */
-struct tty_driver;
-#ifdef CONFIG_TTY
-extern void proc_tty_init(void);
-#else
-static inline void proc_tty_init(void)
-{ }
-#endif
-extern void proc_tty_register_driver(struct tty_driver *driver);
-extern void proc_tty_unregister_driver(struct tty_driver *driver);
-
-/*
- * proc_devtree.c
- */
-#ifdef CONFIG_PROC_DEVICETREE
-struct device_node;
-struct property;
-extern void proc_device_tree_init(void);
-extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
-extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
-extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
-                                        struct property *prop);
-extern void proc_device_tree_update_prop(struct proc_dir_entry *pde,
-                                        struct property *newprop,
-                                        struct property *oldprop);
-#endif /* CONFIG_PROC_DEVICETREE */
+extern void proc_flush_task(struct task_struct *);
 
 extern struct proc_dir_entry *proc_symlink(const char *,
                struct proc_dir_entry *, const char *);
-extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
-extern struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
-                       struct proc_dir_entry *parent);
-
-static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode,
-       struct proc_dir_entry *parent, const struct file_operations *proc_fops)
+extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *);
+extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t,
+                                             struct proc_dir_entry *, void *);
+extern struct proc_dir_entry *proc_mkdir_mode(const char *, umode_t,
+                                             struct proc_dir_entry *);
+extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
+                                              struct proc_dir_entry *,
+                                              const struct file_operations *,
+                                              void *);
+
+static inline struct proc_dir_entry *proc_create(
+       const char *name, umode_t mode, struct proc_dir_entry *parent,
+       const struct file_operations *proc_fops)
 {
        return proc_create_data(name, mode, parent, proc_fops, NULL);
 }
 
-static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
-       umode_t mode, struct proc_dir_entry *base, 
-       read_proc_t *read_proc, void * data)
-{
-       struct proc_dir_entry *res=create_proc_entry(name,mode,base);
-       if (res) {
-               res->read_proc=read_proc;
-               res->data=data;
-       }
-       return res;
-}
-extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
-       struct proc_dir_entry *parent);
-
-extern struct file *proc_ns_fget(int fd);
-extern bool proc_ns_inode(struct inode *inode);
+extern void proc_set_size(struct proc_dir_entry *, loff_t);
+extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t);
+extern void *PDE_DATA(const struct inode *);
+extern void *proc_get_parent_data(const struct inode *);
+extern void proc_remove(struct proc_dir_entry *);
+extern void remove_proc_entry(const char *, struct proc_dir_entry *);
+extern int remove_proc_subtree(const char *, struct proc_dir_entry *);
 
-extern int proc_alloc_inum(unsigned int *pino);
-extern void proc_free_inum(unsigned int inum);
-#else
+#else /* CONFIG_PROC_FS */
 
 static inline void proc_flush_task(struct task_struct *task)
 {
 }
 
-static inline struct proc_dir_entry *create_proc_entry(const char *name,
-       umode_t mode, struct proc_dir_entry *parent) { return NULL; }
-
-#define proc_create(name, mode, parent, fops)  ({ (void)(mode), NULL; })
-
-static inline struct proc_dir_entry *proc_create_data(const char *name,
-       umode_t mode, struct proc_dir_entry *parent,
-       const struct file_operations *proc_fops, void *data)
-{
-       return NULL;
-}
-#define remove_proc_entry(name, parent) do {} while (0)
-
 static inline struct proc_dir_entry *proc_symlink(const char *name,
-               struct proc_dir_entry *parent,const char *dest) {return NULL;}
+               struct proc_dir_entry *parent,const char *dest) { return NULL;}
 static inline struct proc_dir_entry *proc_mkdir(const char *name,
        struct proc_dir_entry *parent) {return NULL;}
+static inline struct proc_dir_entry *proc_mkdir_data(const char *name,
+       umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; }
 static inline struct proc_dir_entry *proc_mkdir_mode(const char *name,
        umode_t mode, struct proc_dir_entry *parent) { return NULL; }
+#define proc_create(name, mode, parent, proc_fops) ({NULL;})
+#define proc_create_data(name, mode, parent, proc_fops, data) ({NULL;})
 
-static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
-       umode_t mode, struct proc_dir_entry *base, 
-       read_proc_t *read_proc, void * data) { return NULL; }
-
-struct tty_driver;
-static inline void proc_tty_register_driver(struct tty_driver *driver) {};
-static inline void proc_tty_unregister_driver(struct tty_driver *driver) {};
+static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {}
+static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {}
+static inline void *PDE_DATA(const struct inode *inode) {BUG(); return NULL;}
+static inline void *proc_get_parent_data(const struct inode *inode) { BUG(); return NULL; }
 
-static inline int pid_ns_prepare_proc(struct pid_namespace *ns)
-{
-       return 0;
-}
-
-static inline void pid_ns_release_proc(struct pid_namespace *ns)
-{
-}
-
-static inline struct file *proc_ns_fget(int fd)
-{
-       return ERR_PTR(-EINVAL);
-}
-
-static inline bool proc_ns_inode(struct inode *inode)
-{
-       return false;
-}
+static inline void proc_remove(struct proc_dir_entry *de) {}
+#define remove_proc_entry(name, parent) do {} while (0)
+static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; }
 
-static inline int proc_alloc_inum(unsigned int *inum)
-{
-       *inum = 1;
-       return 0;
-}
-static inline void proc_free_inum(unsigned int inum)
-{
-}
 #endif /* CONFIG_PROC_FS */
 
-#if !defined(CONFIG_PROC_KCORE)
-static inline void
-kclist_add(struct kcore_list *new, void *addr, size_t size, int type)
+static inline struct proc_dir_entry *proc_net_mkdir(
+       struct net *net, const char *name, struct proc_dir_entry *parent)
 {
+       return proc_mkdir_data(name, 0, parent, net);
 }
-#else
-extern void kclist_add(struct kcore_list *, void *, size_t, int type);
-#endif
-
-struct nsproxy;
-struct proc_ns_operations {
-       const char *name;
-       int type;
-       void *(*get)(struct task_struct *task);
-       void (*put)(void *ns);
-       int (*install)(struct nsproxy *nsproxy, void *ns);
-       unsigned int (*inum)(void *ns);
-};
-extern const struct proc_ns_operations netns_operations;
-extern const struct proc_ns_operations utsns_operations;
-extern const struct proc_ns_operations ipcns_operations;
-extern const struct proc_ns_operations pidns_operations;
-extern const struct proc_ns_operations userns_operations;
-extern const struct proc_ns_operations mntns_operations;
-
-union proc_op {
-       int (*proc_get_link)(struct dentry *, struct path *);
-       int (*proc_read)(struct task_struct *task, char *page);
-       int (*proc_show)(struct seq_file *m,
-               struct pid_namespace *ns, struct pid *pid,
-               struct task_struct *task);
-};
-
-struct ctl_table_header;
-struct ctl_table;
-
-struct proc_inode {
-       struct pid *pid;
-       int fd;
-       union proc_op op;
-       struct proc_dir_entry *pde;
-       struct ctl_table_header *sysctl;
-       struct ctl_table *sysctl_entry;
-       void *ns;
-       const struct proc_ns_operations *ns_ops;
-       struct inode vfs_inode;
-};
-
-static inline struct proc_inode *PROC_I(const struct inode *inode)
-{
-       return container_of(inode, struct proc_inode, vfs_inode);
-}
-
-static inline struct proc_dir_entry *PDE(const struct inode *inode)
-{
-       return PROC_I(inode)->pde;
-}
-
-static inline struct net *PDE_NET(struct proc_dir_entry *pde)
-{
-       return pde->parent->data;
-}
-
-#include <linux/signal.h>
 
-void render_sigset_t(struct seq_file *m, const char *header, sigset_t *set);
 #endif /* _LINUX_PROC_FS_H */
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
new file mode 100644 (file)
index 0000000..34a1e10
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * procfs namespace bits
+ */
+#ifndef _LINUX_PROC_NS_H
+#define _LINUX_PROC_NS_H
+
+struct pid_namespace;
+struct nsproxy;
+
+struct proc_ns_operations {
+       const char *name;
+       int type;
+       void *(*get)(struct task_struct *task);
+       void (*put)(void *ns);
+       int (*install)(struct nsproxy *nsproxy, void *ns);
+       unsigned int (*inum)(void *ns);
+};
+
+struct proc_ns {
+       void *ns;
+       const struct proc_ns_operations *ns_ops;
+};
+
+extern const struct proc_ns_operations netns_operations;
+extern const struct proc_ns_operations utsns_operations;
+extern const struct proc_ns_operations ipcns_operations;
+extern const struct proc_ns_operations pidns_operations;
+extern const struct proc_ns_operations userns_operations;
+extern const struct proc_ns_operations mntns_operations;
+
+/*
+ * We always define these enumerators
+ */
+enum {
+       PROC_ROOT_INO           = 1,
+       PROC_IPC_INIT_INO       = 0xEFFFFFFFU,
+       PROC_UTS_INIT_INO       = 0xEFFFFFFEU,
+       PROC_USER_INIT_INO      = 0xEFFFFFFDU,
+       PROC_PID_INIT_INO       = 0xEFFFFFFCU,
+};
+
+#ifdef CONFIG_PROC_FS
+
+extern int pid_ns_prepare_proc(struct pid_namespace *ns);
+extern void pid_ns_release_proc(struct pid_namespace *ns);
+extern struct file *proc_ns_fget(int fd);
+extern struct proc_ns *get_proc_ns(struct inode *);
+extern int proc_alloc_inum(unsigned int *pino);
+extern void proc_free_inum(unsigned int inum);
+extern bool proc_ns_inode(struct inode *inode);
+
+#else /* CONFIG_PROC_FS */
+
+static inline int pid_ns_prepare_proc(struct pid_namespace *ns) { return 0; }
+static inline void pid_ns_release_proc(struct pid_namespace *ns) {}
+
+static inline struct file *proc_ns_fget(int fd)
+{
+       return ERR_PTR(-EINVAL);
+}
+
+static inline struct proc_ns *get_proc_ns(struct inode *inode) { return NULL; }
+
+static inline int proc_alloc_inum(unsigned int *inum)
+{
+       *inum = 1;
+       return 0;
+}
+static inline void proc_free_inum(unsigned int inum) {}
+static inline bool proc_ns_inode(struct inode *inode) { return false; }
+
+#endif /* CONFIG_PROC_FS */
+
+#endif /* _LINUX_PROC_NS_H */
index 21123902366d8eb2b9b9be26b78e98e8c9badf13..aaad3861beb875bd498dd07c7672affab50e0c92 100644 (file)
@@ -18,10 +18,10 @@ struct pt_regs;
 struct notifier_block;
 
 #if defined(CONFIG_PROFILING) && defined(CONFIG_PROC_FS)
-void create_prof_cpu_mask(struct proc_dir_entry *de);
+void create_prof_cpu_mask(void);
 int create_proc_profile(void);
 #else
-static inline void create_prof_cpu_mask(struct proc_dir_entry *de)
+static inline void create_prof_cpu_mask(void)
 {
 }
 
index 23070fd83872004cdb91367ef1857c0d6ca04a52..7df93f52db089afb7f65ca574e89ee4996714d08 100644 (file)
@@ -199,6 +199,8 @@ enum regulator_type {
  *                output when using regulator_set_voltage_sel_regmap
  * @enable_reg: Register for control when using regmap enable/disable ops
  * @enable_mask: Mask for control when using regmap enable/disable ops
+ * @bypass_reg: Register for control when using regmap set_bypass
+ * @bypass_mask: Mask for control when using regmap set_bypass
  *
  * @enable_time: Time taken for initial enable of regulator (in uS).
  */
index 5ae8456d967010b8cb35b1d861d28a487e2103ba..c23099413ad6c03b935826d6680388cc3976ce81 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/cgroup.h>
+#include <linux/errno.h>
 
 /*
  * The core object. the cgroup that wishes to account for some
index 68a04a343cadecc121ae9dc2515fa4c3d83a6105..2da29ac178fc25ccf01fca81552bf9f515e3c945 100644 (file)
@@ -123,6 +123,7 @@ static inline int seq_nodemask_list(struct seq_file *m, nodemask_t *mask)
 }
 
 int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
+int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t);
 int single_release(struct inode *, struct file *);
 void *__seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_open_private(struct file *, const struct seq_operations *, int);
index a2dcb94ea49de76e81bc6c9d200b555d4cbbba04..1135e3696e8187298b19eb14cb0c0892d39b6d53 100644 (file)
@@ -434,4 +434,9 @@ void signals_init(void);
 int restore_altstack(const stack_t __user *);
 int __save_altstack(stack_t __user *, unsigned long);
 
+#ifdef CONFIG_PROC_FS
+struct seq_file;
+extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
+#endif
+
 #endif /* _LINUX_SIGNAL_H */
index 821c7f45d2a7357085c757c2309177e443b34990..441f5bfdab8ea476749bb512d2c7deeed7399a83 100644 (file)
@@ -500,7 +500,7 @@ struct sk_buff {
        union {
                __u32           mark;
                __u32           dropcount;
-               __u32           avail_size;
+               __u32           reserved_tailroom;
        };
 
        sk_buff_data_t          inner_transport_header;
@@ -1288,11 +1288,13 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
         * do not lose pfmemalloc information as the pages would not be
         * allocated using __GFP_MEMALLOC.
         */
-       if (page->pfmemalloc && !page->mapping)
-               skb->pfmemalloc = true;
        frag->page.p              = page;
        frag->page_offset         = off;
        skb_frag_size_set(frag, size);
+
+       page = compound_head(page);
+       if (page->pfmemalloc && !page->mapping)
+               skb->pfmemalloc = true;
 }
 
 /**
@@ -1447,7 +1449,10 @@ static inline int skb_tailroom(const struct sk_buff *skb)
  */
 static inline int skb_availroom(const struct sk_buff *skb)
 {
-       return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
+       if (skb_is_nonlinear(skb))
+               return 0;
+
+       return skb->end - skb->tail - skb->reserved_tailroom;
 }
 
 /**
index c65dee059913c8d429a614bf3c9b16e088369216..13e929679550ab4967b72a73e544dbf531f74004 100644 (file)
@@ -24,6 +24,9 @@ struct smpboot_thread_data;
  *                     parked (cpu offline)
  * @unpark:            Optional unpark function, called when the thread is
  *                     unparked (cpu online)
+ * @pre_unpark:                Optional unpark function, called before the thread is
+ *                     unparked (cpu online). This is not guaranteed to be
+ *                     called on the target cpu of the thread. Careful!
  * @selfparking:       Thread is not parked by the park function.
  * @thread_comm:       The base name of the thread
  */
@@ -37,6 +40,7 @@ struct smp_hotplug_thread {
        void                            (*cleanup)(unsigned int cpu, bool online);
        void                            (*park)(unsigned int cpu);
        void                            (*unpark)(unsigned int cpu);
+       void                            (*pre_unpark)(unsigned int cpu);
        bool                            selfparking;
        const char                      *thread_comm;
 };
index f0bd7f90a90d45d3aeeb3aed8bc2d2f8295c8be0..e3c0ae9bb1faf876afca191701e481ecc30a4f1b 100644 (file)
@@ -44,7 +44,7 @@
 /* Adding event notification support elements */
 #define THERMAL_GENL_FAMILY_NAME                "thermal_event"
 #define THERMAL_GENL_VERSION                    0x01
-#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_group"
+#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_grp"
 
 /* Default Thermal Governor */
 #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
index c75d886b03078dce545a10ea83ac654e0a4335c4..e014fb1a84bd1a27658d69f09c2eeef1b51988fd 100644 (file)
@@ -658,5 +658,12 @@ do {                                                                       \
        finish_wait(&wq, &__wait);                                      \
 } while (0)
 
+#ifdef CONFIG_PROC_FS
+extern void proc_tty_register_driver(struct tty_driver *);
+extern void proc_tty_unregister_driver(struct tty_driver *);
+#else
+static inline void proc_tty_register_driver(struct tty_driver *d) {}
+static inline void proc_tty_unregister_driver(struct tty_driver *d) {}
+#endif
 
 #endif
index 9d81de123c9017f4463ba4fa09a61b8b7425a8bf..42278bbf7a882d90360d141db9c8cc1b1eca1719 100644 (file)
@@ -68,6 +68,7 @@ struct udp_sock {
         * For encapsulation sockets.
         */
        int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
+       void (*encap_destroy)(struct sock *sk);
 };
 
 static inline struct udp_sock *udp_sk(const struct sock *sk)
index 3b8f9d4fc3fe7df42af02fda48f83379b24e77ca..cc25b70af33c0b641caa53422c5faacc929809a7 100644 (file)
@@ -127,6 +127,7 @@ struct cdc_ncm_ctx {
        u16 connected;
 };
 
+extern u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf);
 extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting);
 extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
 extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign);
index 3c671c1b37f65350c7f18a6afac3e6a7c594a820..8860594d6364b30f4a5e1c2d4b64be63a28d2a9a 100644 (file)
@@ -60,7 +60,7 @@ struct usb_configuration;
  * @name: For diagnostics, identifies the function.
  * @strings: tables of strings, keyed by identifiers assigned during bind()
  *     and by language IDs provided in control requests
- * @descriptors: Table of full (or low) speed descriptors, using interface and
+ * @fs_descriptors: Table of full (or low) speed descriptors, using interface and
  *     string identifiers assigned during @bind().  If this pointer is null,
  *     the function will not be available at full speed (or at low speed).
  * @hs_descriptors: Table of high speed descriptors, using interface and
@@ -290,6 +290,7 @@ enum {
  *     after function notifications
  * @resume: Notifies configuration when the host restarts USB traffic,
  *     before function notifications
+ * @gadget_driver: Gadget driver controlling this driver
  *
  * Devices default to reporting self powered operation.  Devices which rely
  * on bus powered operation should report this in their @bind method.
index ef9be7e1e1906ea05d1cfef7c6fe58f7ef4ceab3..1819b59aab2a697aa573cbf8fe4e1081292dc713 100644 (file)
@@ -66,6 +66,7 @@
  *     port.
  * @flags: usb serial port flags
  * @write_wait: a wait_queue_head_t used by the port.
+ * @delta_msr_wait: modem-status-change wait queue
  * @work: work queue entry for the line discipline waking up.
  * @throttled: nonzero if the read urb is inactive to throttle the device
  * @throttle_req: nonzero if the tty wants to throttle us
@@ -112,6 +113,7 @@ struct usb_serial_port {
 
        unsigned long           flags;
        wait_queue_head_t       write_wait;
+       wait_queue_head_t       delta_msr_wait;
        struct work_struct      work;
        char                    throttled;
        char                    throttle_req;
index 6f033a415ecb85caa0291a58940922b5d6304419..5c295c26ad37c8d743020ca4bab5996bc52f4df2 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+#if IS_ENABLED(CONFIG_USB_ULPI)
 struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops,
                                        unsigned int flags);
+#else
+static inline struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops,
+                                             unsigned int flags)
+{
+       return NULL;
+}
+#endif
 
 #ifdef CONFIG_USB_ULPI_VIEWPORT
 /* access ops for controllers with a viewport register */
index 9531beee09b55342fec2266e5d9c9bba41248c2d..ea81f0ef649227c2bd0991d715aa95bef964be58 100644 (file)
@@ -226,7 +226,6 @@ struct bt_sock_list {
        struct hlist_head head;
        rwlock_t          lock;
 #ifdef CONFIG_PROC_FS
-        struct file_operations   fops;
         int (* custom_seq_show)(struct seq_file *, void *);
 #endif
 };
@@ -319,7 +318,7 @@ extern void hci_sock_cleanup(void);
 extern int bt_sysfs_init(void);
 extern void bt_sysfs_cleanup(void);
 
-extern int  bt_procfs_init(struct module* module, struct net *net, const char *name,
+extern int  bt_procfs_init(struct net *net, const char *name,
                           struct bt_sock_list* sk_list,
                           int (* seq_show)(struct seq_file *, void *));
 extern void bt_procfs_cleanup(struct net *net, const char *name);
index 853cda11e518be98cbcf0d4bd5fa9270c804d2f5..1f8fd109e2254f10118929fe96e073bbceb13f5a 100644 (file)
@@ -413,13 +413,15 @@ static inline int dst_neigh_output(struct dst_entry *dst, struct neighbour *n,
 
 static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
 {
-       return dst->ops->neigh_lookup(dst, NULL, daddr);
+       struct neighbour *n = dst->ops->neigh_lookup(dst, NULL, daddr);
+       return IS_ERR(n) ? NULL : n;
 }
 
 static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst,
                                                     struct sk_buff *skb)
 {
-       return dst->ops->neigh_lookup(dst, skb, NULL);
+       struct neighbour *n =  dst->ops->neigh_lookup(dst, skb, NULL);
+       return IS_ERR(n) ? NULL : n;
 }
 
 static inline void dst_link_failure(struct sk_buff *skb)
index 80461c1ae9efcceea9875000629f62608c6e699e..bb8271d487b7bea10861c6548dde50d0964c4a20 100644 (file)
@@ -9,6 +9,7 @@ struct flow_keys {
                __be32 ports;
                __be16 port16[2];
        };
+       u16 thoff;
        u8 ip_proto;
 };
 
index 76c3fe5ecc2e6ed9fcf1b81be7dbd3d3dc258d73..0a1dcc2fa2f58c5be1f177f579fa4fa57c138dfd 100644 (file)
@@ -43,6 +43,13 @@ struct inet_frag_queue {
 
 #define INETFRAGS_HASHSZ               64
 
+/* averaged:
+ * max_depth = default ipfrag_high_thresh / INETFRAGS_HASHSZ /
+ *            rounded up (SKB_TRUELEN(0) + sizeof(struct ipq or
+ *            struct frag_queue))
+ */
+#define INETFRAGS_MAXDEPTH             128
+
 struct inet_frags {
        struct hlist_head       hash[INETFRAGS_HASHSZ];
        /* This rwlock is a global lock (seperate per IPv4, IPv6 and
@@ -76,6 +83,8 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
 struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
                struct inet_frags *f, void *key, unsigned int hash)
        __releases(&f->lock);
+void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
+                                  const char *prefix);
 
 static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
 {
index 9497be1ad4c0c5cdf4fe2df49b79fa5f66a255f8..e49db91593a953422b0ce0a15c0eb0902ee33c56 100644 (file)
@@ -152,18 +152,16 @@ struct fib_result_nl {
 };
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
-
 #define FIB_RES_NH(res)                ((res).fi->fib_nh[(res).nh_sel])
-
-#define FIB_TABLE_HASHSZ 2
-
 #else /* CONFIG_IP_ROUTE_MULTIPATH */
-
 #define FIB_RES_NH(res)                ((res).fi->fib_nh[0])
+#endif /* CONFIG_IP_ROUTE_MULTIPATH */
 
+#ifdef CONFIG_IP_MULTIPLE_TABLES
 #define FIB_TABLE_HASHSZ 256
-
-#endif /* CONFIG_IP_ROUTE_MULTIPATH */
+#else
+#define FIB_TABLE_HASHSZ 2
+#endif
 
 extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
 
index 68c69d54d39281ee033d765a1b9b66567c55d06f..fce8e6b66d558d8ff8bb629c4da5e358113a675e 100644 (file)
@@ -976,6 +976,7 @@ struct netns_ipvs {
        int                     sysctl_sync_retries;
        int                     sysctl_nat_icmp_send;
        int                     sysctl_pmtu_disc;
+       int                     sysctl_backup_only;
 
        /* ip_vs_lblc */
        int                     sysctl_lblc_expiration;
@@ -1067,6 +1068,12 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
        return ipvs->sysctl_pmtu_disc;
 }
 
+static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
+{
+       return ipvs->sync_state & IP_VS_STATE_BACKUP &&
+              ipvs->sysctl_backup_only;
+}
+
 #else
 
 static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
@@ -1114,6 +1121,11 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
        return 1;
 }
 
+static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
+{
+       return 0;
+}
+
 #endif
 
 /*
index fd19625ff99db290fd289b3caf18f32c9b72ffc3..982141c15200d1fc60b144a2ca6ba53c0d320200 100644 (file)
@@ -77,15 +77,11 @@ static inline void tunnel_ip_select_ident(struct sk_buff *skb,
 {
        struct iphdr *iph = ip_hdr(skb);
 
-       if (iph->frag_off & htons(IP_DF))
-               iph->id = 0;
-       else {
-               /* Use inner packet iph-id if possible. */
-               if (skb->protocol == htons(ETH_P_IP) && old_iph->id)
-                       iph->id = old_iph->id;
-               else
-                       __ip_select_ident(iph, dst,
-                                         (skb_shinfo(skb)->gso_segs ?: 1) - 1);
-       }
+       /* Use inner packet iph-id if possible. */
+       if (skb->protocol == htons(ETH_P_IP) && old_iph->id)
+               iph->id = old_iph->id;
+       else
+               __ip_select_ident(iph, dst,
+                                 (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 }
 #endif
index d178c26a55588743dbfa9509d1712935b70e3f9b..be95b9262801880f7a835f7954f14c1f0c1e2397 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/skbuff.h>
 #include <linux/ieee80211.h>
 #include <linux/timer.h>
+#include <linux/seq_file.h>
+
 /* print_ssid() is intended to be used in debug (and possibly error)
  * messages. It should never be used for passing ssid to user space. */
 const char *print_ssid(char *buf, const char *ssid, u8 ssid_len);
@@ -75,7 +77,7 @@ struct lib80211_crypto_ops {
 
        /* procfs handler for printing out key information and possible
         * statistics */
-       char *(*print_stats) (char *p, void *priv);
+       void (*print_stats) (struct seq_file *m, void *priv);
 
        /* Crypto specific flag get/set for configuration settings */
        unsigned long (*get_flags) (void *priv);
index 23f2e98d4b654dbd497def51219cbe0806c23cb8..cf0694d4ad60f62be703eaec51db142b9c5c4e29 100644 (file)
@@ -1045,6 +1045,10 @@ static inline bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
        if (sysctl_tcp_low_latency || !tp->ucopy.task)
                return false;
 
+       if (skb->len <= tcp_hdrlen(skb) &&
+           skb_queue_len(&tp->ucopy.prequeue) == 0)
+               return false;
+
        __skb_queue_tail(&tp->ucopy.prequeue, skb);
        tp->ucopy.memory += skb->truesize;
        if (tp->ucopy.memory > sk->sk_rcvbuf) {
index 2b6956e9853dd576d47af629e4635c24c92c9c97..755243572219da23383d1bab92ff42584766ba8c 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/seq_file.h>
 #include <scsi/scsi.h>
 
 struct request_queue;
@@ -340,7 +341,8 @@ struct scsi_host_template {
         *
         * Status: OBSOLETE
         */
-       int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
+       int (*show_info)(struct seq_file *, struct Scsi_Host *);
+       int (*write_info)(struct Scsi_Host *, char *, int);
 
        /*
         * This is an optional routine that allows the transport to become
@@ -375,7 +377,7 @@ struct scsi_host_template {
 
        /*
         * Used to store the procfs directory if a driver implements the
-        * proc_info method.
+        * show_info method.
         */
        struct proc_dir_entry *proc_dir;
 
index 11b6ca3e0873c4795fc3b8e8214e5503e6ba16d4..df2f9a0bba6ab78ad93f8ceb7aa240bf6cf329ec 100644 (file)
@@ -107,10 +107,12 @@ struct acct_v3
 #define ACORE          0x08    /* ... dumped core */
 #define AXSIG          0x10    /* ... was killed by a signal */
 
-#ifdef __BIG_ENDIAN
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
 #define ACCT_BYTEORDER 0x80    /* accounting file is big endian */
-#else
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
 #define ACCT_BYTEORDER 0x00    /* accounting file is little endian */
+#else
+#error unspecified endianness
 #endif
 
 #ifndef __KERNEL__
index 86fa7a71336a1cc2ea007c7410e3ede14807ec4c..bb2554f7fbd12a677015d48703ccf681357e84c6 100644 (file)
@@ -62,9 +62,9 @@ struct io_event {
        __s64           res2;           /* secondary result */
 };
 
-#if defined(__LITTLE_ENDIAN)
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
 #define PADDED(x,y)    x, y
-#elif defined(__BIG_ENDIAN)
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
 #define PADDED(x,y)    y, x
 #else
 #error edit for your odd byteorder.
index 93f5fa94a431c167d70902ce6ded5a2275215b53..afafd703ad92b1595a5c7c326883fe89816f920f 100644 (file)
@@ -33,9 +33,11 @@ enum {
        PACKET_DIAG_TX_RING,
        PACKET_DIAG_FANOUT,
 
-       PACKET_DIAG_MAX,
+       __PACKET_DIAG_MAX,
 };
 
+#define PACKET_DIAG_MAX (__PACKET_DIAG_MAX - 1)
+
 struct packet_diag_info {
        __u32   pdi_index;
        __u32   pdi_version;
index ee753536ab7088350a147e1743805985a6b01ac0..fe1a5406d4d93cdf6012d11ab7315f014b552ede 100644 (file)
@@ -145,16 +145,18 @@ typedef struct mdp_superblock_s {
        __u32 failed_disks;     /*  4 Number of failed disks                  */
        __u32 spare_disks;      /*  5 Number of spare disks                   */
        __u32 sb_csum;          /*  6 checksum of the whole superblock        */
-#ifdef __BIG_ENDIAN
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
        __u32 events_hi;        /*  7 high-order of superblock update count   */
        __u32 events_lo;        /*  8 low-order of superblock update count    */
        __u32 cp_events_hi;     /*  9 high-order of checkpoint update count   */
        __u32 cp_events_lo;     /* 10 low-order of checkpoint update count    */
-#else
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
        __u32 events_lo;        /*  7 low-order of superblock update count    */
        __u32 events_hi;        /*  8 high-order of superblock update count   */
        __u32 cp_events_lo;     /*  9 low-order of checkpoint update count    */
        __u32 cp_events_hi;     /* 10 high-order of checkpoint update count   */
+#else
+#error unspecified endianness
 #endif
        __u32 recovery_cp;      /* 11 recovery checkpoint sector count        */
        /* There are only valid for minor_version > 90 */
index b6a23a483d740d635f50bf2ab5261510396e5dff..74c2bf7211f85ed0a55f82987d690cd6bc9aad7c 100644 (file)
 #define PORT_8250_CIR  23      /* CIR infrared port, has its own driver */
 #define PORT_XR17V35X  24      /* Exar XR17V35x UARTs */
 #define PORT_BRCM_TRUMANAGE    25
-#define PORT_MAX_8250  25      /* max port ID */
+#define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */
+#define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */
+#define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
+#define PORT_MAX_8250  28      /* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
index b8a24941db21e82b11d80d0912c057a54bcf7742..b9e2a6a7446f077e528dd15fac8e8d97f0d9a232 100644 (file)
@@ -39,9 +39,11 @@ enum {
        UNIX_DIAG_MEMINFO,
        UNIX_DIAG_SHUTDOWN,
 
-       UNIX_DIAG_MAX,
+       __UNIX_DIAG_MAX,
 };
 
+#define UNIX_DIAG_MAX (__UNIX_DIAG_MAX - 1)
+
 struct unix_diag_vfs {
        __u32   udiag_vfs_ino;
        __u32   udiag_vfs_dev;
index 28447f1594fa3fcf5a3a337cf34b4671528a424f..8deb22672ada5ea98247a3a2dbb7a6131dede1b2 100644 (file)
@@ -30,7 +30,6 @@
  */
 #define ATMEL_LCDC_WIRING_BGR  0
 #define ATMEL_LCDC_WIRING_RGB  1
-#define ATMEL_LCDC_WIRING_RGB555       2
 
 
  /* LCD Controller info data structure, stored in device platform_data */
@@ -62,6 +61,7 @@ struct atmel_lcdfb_info {
        void (*atmel_lcdfb_power_control)(int on);
        struct fb_monspecs      *default_monspecs;
        u32                     pseudo_palette[16];
+       bool                    have_intensity_bit;
 };
 
 #define ATMEL_LCDC_DMABADDR1   0x00
index 22616cd434bc7d91d157074eb0cf9c9ce9b9f0f0..5341d7232c3ac083c2f87c8a3e1098a9c5e8d601 100644 (file)
@@ -28,10 +28,6 @@ config BUILDTIME_EXTABLE_SORT
 
 menu "General setup"
 
-config EXPERIMENTAL
-       bool
-       default y
-
 config BROKEN
        bool
 
index 58170f18912d885e9fcd76b2892c4866beda577d..1a4718e500fe78238de84cc872eb559706dfbb5e 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/utsname.h>
 #include <generated/utsrelease.h>
 #include <linux/version.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 
 #ifndef CONFIG_KALLSYMS
 #define version(a) Version_ ## a
index e5c4f609f22c2a902789e710756aa117f40cf5cc..3953fda2e8bd182edcc76f790523e48f2698b962 100644 (file)
@@ -840,7 +840,8 @@ out_putfd:
                fd = error;
        }
        mutex_unlock(&root->d_inode->i_mutex);
-       mnt_drop_write(mnt);
+       if (!ro)
+               mnt_drop_write(mnt);
 out_putname:
        putname(name);
        return fd;
index 950572f9d7963858d46e01998fea00e14024f26b..31cd1bf6af271771e67bdf6e29eb306371d3d130 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -820,15 +820,17 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
        struct msg_msg *copy = NULL;
        unsigned long copy_number = 0;
 
+       ns = current->nsproxy->ipc_ns;
+
        if (msqid < 0 || (long) bufsz < 0)
                return -EINVAL;
        if (msgflg & MSG_COPY) {
-               copy = prepare_copy(buf, bufsz, msgflg, &msgtyp, &copy_number);
+               copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax),
+                                   msgflg, &msgtyp, &copy_number);
                if (IS_ERR(copy))
                        return PTR_ERR(copy);
        }
        mode = convert_mode(&msgtyp, msgflg);
-       ns = current->nsproxy->ipc_ns;
 
        msq = msg_lock_check(ns, msqid);
        if (IS_ERR(msq)) {
index ebfcbfa8b7f25a4193dcfd196963e4b87428a6e6..8f0201735f16c6ceaf6b8eda9b4840c76b5e18bd 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/msg.h>
 #include <linux/ipc_namespace.h>
 #include <linux/utsname.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 #include <asm/uaccess.h>
 
 #include "util.h"
@@ -117,9 +117,6 @@ struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
        if (alen > DATALEN_MSG)
                alen = DATALEN_MSG;
 
-       dst->next = NULL;
-       dst->security = NULL;
-
        memcpy(dst + 1, src + 1, alen);
 
        len -= alen;
index 7c1fa451b0b0d75ae5265fea8fbe1193cb865223..7ee61bf449332bbb556f4742e72c8f54c8111d89 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/user_namespace.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 
 #include "util.h"
 
index 464a8abd779fb0bc54b861bc5f4bb29347686dbe..b6db68131a0e937182a100124b8396caacb73151 100644 (file)
@@ -964,7 +964,7 @@ static int sysvipc_proc_open(struct inode *inode, struct file *file)
        seq = file->private_data;
        seq->private = iter;
 
-       iter->iface = PDE(inode)->data;
+       iter->iface = PDE_DATA(inode);
        iter->ns    = get_ipc_ns(current->nsproxy->ipc_ns);
 out:
        return ret;
index b9bd7f098ee5d17fc8fa41bb823b80e0b94df3d6..85389fe2abd0a95bf99d4abe6b1de63e09351c4c 100644 (file)
@@ -543,6 +543,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
         * Kernel segment override to datasegment and write it
         * to the accounting file.
         */
+       file_start_write(file);
        fs = get_fs();
        set_fs(KERNEL_DS);
        /*
@@ -554,6 +555,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
                               sizeof(acct_t), &file->f_pos);
        current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
        set_fs(fs);
+       file_end_write(file);
 out:
        revert_creds(orig_cred);
 }
index a32f9432666cc9f0f736ca24639a58fc45557ce8..d5cffe80b4697c8c70acc0643d109a410547e299 100644 (file)
@@ -4769,7 +4769,7 @@ out:
  */
 
 /* TODO: Use a proper seq_file iterator */
-static int proc_cgroup_show(struct seq_file *m, void *v)
+int proc_cgroup_show(struct seq_file *m, void *v)
 {
        struct pid *pid;
        struct task_struct *tsk;
@@ -4821,19 +4821,6 @@ out:
        return retval;
 }
 
-static int cgroup_open(struct inode *inode, struct file *file)
-{
-       struct pid *pid = PROC_I(inode)->pid;
-       return single_open(file, proc_cgroup_show, pid);
-}
-
-const struct file_operations proc_cgroup_operations = {
-       .open           = cgroup_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
 /* Display information about each subsystem and each hierarchy */
 static int proc_cgroupstats_show(struct seq_file *m, void *v)
 {
index 42e8fa075eed011d1577b5b2d40d5ef1e7df73f4..c18b1f1ae515a73cf0fe404d413ddcc4bc8f847d 100644 (file)
@@ -79,7 +79,7 @@ static int __init ikconfig_init(void)
        if (!entry)
                return -ENOMEM;
 
-       entry->size = kernel_config_data_size;
+       proc_set_size(entry, kernel_config_data_size);
 
        return 0;
 }
index 4f9dfe43ecbd777d7bf03bed72c5da566e952b62..1b6f615be58727c30f38546dee58f91d3e683037 100644 (file)
@@ -2666,7 +2666,7 @@ void __cpuset_memory_pressure_bump(void)
  *    and we take cpuset_mutex, keeping cpuset_attach() from changing it
  *    anyway.
  */
-static int proc_cpuset_show(struct seq_file *m, void *unused_v)
+int proc_cpuset_show(struct seq_file *m, void *unused_v)
 {
        struct pid *pid;
        struct task_struct *tsk;
@@ -2700,19 +2700,6 @@ out_free:
 out:
        return retval;
 }
-
-static int cpuset_open(struct inode *inode, struct file *file)
-{
-       struct pid *pid = PROC_I(inode)->pid;
-       return single_open(file, proc_cpuset_show, pid);
-}
-
-const struct file_operations proc_cpuset_operations = {
-       .open           = cpuset_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
 #endif /* CONFIG_PROC_PID_CPUSET */
 
 /* Display task mems_allowed in /proc/<pid>/status file. */
index b0cd86501c30db1a1320d284f2d52eb1ec499f2b..59412d037eed2a81163483b89fb38d9feb30623a 100644 (file)
@@ -4434,12 +4434,15 @@ static void perf_event_task_event(struct perf_task_event *task_event)
                        if (ctxn < 0)
                                goto next;
                        ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
+                       if (ctx)
+                               perf_event_task_ctx(ctx, task_event);
                }
-               if (ctx)
-                       perf_event_task_ctx(ctx, task_event);
 next:
                put_cpu_ptr(pmu->pmu_cpu_context);
        }
+       if (task_event->task_ctx)
+               perf_event_task_ctx(task_event->task_ctx, task_event);
+
        rcu_read_unlock();
 }
 
@@ -5647,6 +5650,7 @@ static void perf_swevent_init_hrtimer(struct perf_event *event)
                event->attr.sample_period = NSEC_PER_SEC / freq;
                hwc->sample_period = event->attr.sample_period;
                local64_set(&hwc->period_left, hwc->sample_period);
+               hwc->last_period = hwc->sample_period;
                event->attr.freq = 0;
        }
 }
index 51e485ca993560015dbb56701fd249637afc721c..cd9e9e799bd2db051b37b65a37122095e3732933 100644 (file)
@@ -847,7 +847,7 @@ void do_exit(long code)
                exit_io_context(tsk);
 
        if (tsk->splice_pipe)
-               __free_pipe_info(tsk->splice_pipe);
+               free_pipe_info(tsk->splice_pipe);
 
        if (tsk->task_frag.page)
                put_page(tsk->task_frag.page);
index 8d932b1c9056af738e2903bf813bcbd035ed3892..1766d324d5e35c38ca3910ea237857c0600d1a02 100644 (file)
@@ -1141,6 +1141,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
                return ERR_PTR(-EINVAL);
 
+       if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
+               return ERR_PTR(-EINVAL);
+
        /*
         * Thread groups must share signals as well, and detached threads
         * can only be started up within the thread group.
@@ -1807,7 +1810,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
         * If unsharing a user namespace must also unshare the thread.
         */
        if (unshare_flags & CLONE_NEWUSER)
-               unshare_flags |= CLONE_THREAD;
+               unshare_flags |= CLONE_THREAD | CLONE_FS;
        /*
         * If unsharing a pid namespace must also unshare the thread.
         */
index f0090a993dab1e3d43fd202e05bd904aefc05f2a..b26dcfc02c9489b3ca00bfd076f2208bb4964366 100644 (file)
@@ -223,7 +223,8 @@ static void drop_futex_key_refs(union futex_key *key)
  * @rw:                mapping needs to be read/write (values: VERIFY_READ,
  *              VERIFY_WRITE)
  *
- * Returns a negative error code or 0
+ * Return: a negative error code or 0
+ *
  * The key words are stored in *key on success.
  *
  * For shared mappings, it's (page->index, file_inode(vma->vm_file),
@@ -705,9 +706,9 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
  *                     be "current" except in the case of requeue pi.
  * @set_waiters:       force setting the FUTEX_WAITERS bit (1) or not (0)
  *
- * Returns:
- *  0 - ready to wait
- *  1 - acquired the lock
+ * Return:
+ *  0 - ready to wait;
+ *  1 - acquired the lock;
  * <0 - error
  *
  * The hb->lock and futex_key refs shall be held by the caller.
@@ -1191,9 +1192,9 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
  * then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit.
  * hb1 and hb2 must be held by the caller.
  *
- * Returns:
- *  0 - failed to acquire the lock atomicly
- *  1 - acquired the lock
+ * Return:
+ *  0 - failed to acquire the lock atomically;
+ *  1 - acquired the lock;
  * <0 - error
  */
 static int futex_proxy_trylock_atomic(u32 __user *pifutex,
@@ -1254,8 +1255,8 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
  * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire
  * uaddr2 atomically on behalf of the top waiter.
  *
- * Returns:
- * >=0 - on success, the number of tasks requeued or woken
+ * Return:
+ * >=0 - on success, the number of tasks requeued or woken;
  *  <0 - on error
  */
 static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
@@ -1536,8 +1537,8 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
  * The q->lock_ptr must not be held by the caller. A call to unqueue_me() must
  * be paired with exactly one earlier call to queue_me().
  *
- * Returns:
- *   1 - if the futex_q was still queued (and we removed unqueued it)
+ * Return:
+ *   1 - if the futex_q was still queued (and we removed unqueued it);
  *   0 - if the futex_q was already removed by the waking thread
  */
 static int unqueue_me(struct futex_q *q)
@@ -1707,9 +1708,9 @@ static long futex_wait_restart(struct restart_block *restart);
  * the pi_state owner as well as handle race conditions that may allow us to
  * acquire the lock. Must be called with the hb lock held.
  *
- * Returns:
- *  1 - success, lock taken
- *  0 - success, lock not taken
+ * Return:
+ *  1 - success, lock taken;
+ *  0 - success, lock not taken;
  * <0 - on error (-EFAULT)
  */
 static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
@@ -1824,8 +1825,8 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
  * Return with the hb lock held and a q.key reference on success, and unlocked
  * with no q.key reference on failure.
  *
- * Returns:
- *  0 - uaddr contains val and hb has been locked
+ * Return:
+ *  0 - uaddr contains val and hb has been locked;
  * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked
  */
 static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
@@ -2203,9 +2204,9 @@ pi_faulted:
  * the wakeup and return the appropriate error code to the caller.  Must be
  * called with the hb lock held.
  *
- * Returns
- *  0 - no early wakeup detected
- * <0 - -ETIMEDOUT or -ERESTARTNOINTR
+ * Return:
+ *  0 = no early wakeup detected;
+ * <0 = -ETIMEDOUT or -ERESTARTNOINTR
  */
 static inline
 int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
@@ -2247,7 +2248,6 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  * @val:       the expected value of uaddr
  * @abs_time:  absolute timeout
  * @bitset:    32 bit wakeup bitset set by userspace, defaults to all
- * @clockrt:   whether to use CLOCK_REALTIME (1) or CLOCK_MONOTONIC (0)
  * @uaddr2:    the pi futex we will take prior to returning to user-space
  *
  * The caller will wait on uaddr and will be requeued by futex_requeue() to
@@ -2258,7 +2258,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  * there was a need to.
  *
  * We call schedule in futex_wait_queue_me() when we enqueue and return there
- * via the following:
+ * via the following--
  * 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue()
  * 2) wakeup on uaddr2 after a requeue
  * 3) signal
@@ -2276,8 +2276,8 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  *
  * If 4 or 7, we cleanup and return with -ETIMEDOUT.
  *
- * Returns:
- *  0 - On success
+ * Return:
+ *  0 - On success;
  * <0 - On error
  */
 static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
index 397db02209ed11b74dca0ca562709399179d1eeb..19ed5c425c3b95e6d49ab8fb7bc7dd9717d2b570 100644 (file)
@@ -76,7 +76,7 @@ static int irq_affinity_list_proc_show(struct seq_file *m, void *v)
 static ssize_t write_irq_affinity(int type, struct file *file,
                const char __user *buffer, size_t count, loff_t *pos)
 {
-       unsigned int irq = (int)(long)PDE(file_inode(file))->data;
+       unsigned int irq = (int)(long)PDE_DATA(file_inode(file));
        cpumask_var_t new_value;
        int err;
 
@@ -131,17 +131,17 @@ static ssize_t irq_affinity_list_proc_write(struct file *file,
 
 static int irq_affinity_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_affinity_proc_show, PDE(inode)->data);
+       return single_open(file, irq_affinity_proc_show, PDE_DATA(inode));
 }
 
 static int irq_affinity_list_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_affinity_list_proc_show, PDE(inode)->data);
+       return single_open(file, irq_affinity_list_proc_show, PDE_DATA(inode));
 }
 
 static int irq_affinity_hint_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_affinity_hint_proc_show, PDE(inode)->data);
+       return single_open(file, irq_affinity_hint_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations irq_affinity_proc_fops = {
@@ -212,7 +212,7 @@ out:
 
 static int default_affinity_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, default_affinity_show, PDE(inode)->data);
+       return single_open(file, default_affinity_show, PDE_DATA(inode));
 }
 
 static const struct file_operations default_affinity_proc_fops = {
@@ -233,7 +233,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v)
 
 static int irq_node_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_node_proc_show, PDE(inode)->data);
+       return single_open(file, irq_node_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations irq_node_proc_fops = {
@@ -256,7 +256,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v)
 
 static int irq_spurious_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_spurious_proc_show, PDE(inode)->data);
+       return single_open(file, irq_spurious_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations irq_spurious_proc_fops = {
@@ -366,11 +366,7 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
 
 void unregister_handler_proc(unsigned int irq, struct irqaction *action)
 {
-       if (action->dir) {
-               struct irq_desc *desc = irq_to_desc(irq);
-
-               remove_proc_entry(action->dir->name, desc->dir);
-       }
+       proc_remove(action->dir);
 }
 
 static void register_default_affinity_proc(void)
index afc0456f227abe76788ac666f7c1239759b5096e..364ceab15f0cc09816fdd1b36b78814b06227991 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/pid_namespace.h>
 #include <net/net_namespace.h>
 #include <linux/ipc_namespace.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 #include <linux/file.h>
 #include <linux/syscalls.h>
 
@@ -241,7 +241,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
        const struct proc_ns_operations *ops;
        struct task_struct *tsk = current;
        struct nsproxy *new_nsproxy;
-       struct proc_inode *ei;
+       struct proc_ns *ei;
        struct file *file;
        int err;
 
@@ -250,7 +250,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
                return PTR_ERR(file);
 
        err = -EINVAL;
-       ei = PROC_I(file_inode(file));
+       ei = get_proc_ns(file_inode(file));
        ops = ei->ns_ops;
        if (nstype && (ops->type != nstype))
                goto out;
index 047dc62646389fd5abdf5fc63cb8db963a1a5b60..686255e2c39e4874a13d78051afc8f54c7d4ae63 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
 #include <linux/syscalls.h>
+#include <linux/proc_ns.h>
 #include <linux/proc_fs.h>
 
 #define pid_hashfn(nr, ns)     \
index c1c3dc1c60233f337a01ff13587f1a5a7f57f1cd..4af28a84906545765c1429461e166c4d362e765c 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/err.h>
 #include <linux/acct.h>
 #include <linux/slab.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 #include <linux/reboot.h>
 #include <linux/export.h>
 
index 0b31715f335a7a8ba1a846fe3b93fe71d97cd8d7..abbdd9e2ac82c423a3dc6c778632c37887241b41 100644 (file)
@@ -63,8 +63,6 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
 #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
 #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
 
-DECLARE_WAIT_QUEUE_HEAD(log_wait);
-
 int console_printk[4] = {
        DEFAULT_CONSOLE_LOGLEVEL,       /* console_loglevel */
        DEFAULT_MESSAGE_LOGLEVEL,       /* default_message_loglevel */
@@ -224,6 +222,7 @@ struct log {
 static DEFINE_RAW_SPINLOCK(logbuf_lock);
 
 #ifdef CONFIG_PRINTK
+DECLARE_WAIT_QUEUE_HEAD(log_wait);
 /* the next printk record to read by syslog(READ) or /proc/kmsg */
 static u64 syslog_seq;
 static u32 syslog_idx;
@@ -1957,45 +1956,6 @@ int is_console_locked(void)
        return console_locked;
 }
 
-/*
- * Delayed printk version, for scheduler-internal messages:
- */
-#define PRINTK_BUF_SIZE                512
-
-#define PRINTK_PENDING_WAKEUP  0x01
-#define PRINTK_PENDING_SCHED   0x02
-
-static DEFINE_PER_CPU(int, printk_pending);
-static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf);
-
-static void wake_up_klogd_work_func(struct irq_work *irq_work)
-{
-       int pending = __this_cpu_xchg(printk_pending, 0);
-
-       if (pending & PRINTK_PENDING_SCHED) {
-               char *buf = __get_cpu_var(printk_sched_buf);
-               printk(KERN_WARNING "[sched_delayed] %s", buf);
-       }
-
-       if (pending & PRINTK_PENDING_WAKEUP)
-               wake_up_interruptible(&log_wait);
-}
-
-static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = {
-       .func = wake_up_klogd_work_func,
-       .flags = IRQ_WORK_LAZY,
-};
-
-void wake_up_klogd(void)
-{
-       preempt_disable();
-       if (waitqueue_active(&log_wait)) {
-               this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
-               irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
-       }
-       preempt_enable();
-}
-
 static void console_cont_flush(char *text, size_t size)
 {
        unsigned long flags;
@@ -2458,6 +2418,44 @@ static int __init printk_late_init(void)
 late_initcall(printk_late_init);
 
 #if defined CONFIG_PRINTK
+/*
+ * Delayed printk version, for scheduler-internal messages:
+ */
+#define PRINTK_BUF_SIZE                512
+
+#define PRINTK_PENDING_WAKEUP  0x01
+#define PRINTK_PENDING_SCHED   0x02
+
+static DEFINE_PER_CPU(int, printk_pending);
+static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf);
+
+static void wake_up_klogd_work_func(struct irq_work *irq_work)
+{
+       int pending = __this_cpu_xchg(printk_pending, 0);
+
+       if (pending & PRINTK_PENDING_SCHED) {
+               char *buf = __get_cpu_var(printk_sched_buf);
+               printk(KERN_WARNING "[sched_delayed] %s", buf);
+       }
+
+       if (pending & PRINTK_PENDING_WAKEUP)
+               wake_up_interruptible(&log_wait);
+}
+
+static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = {
+       .func = wake_up_klogd_work_func,
+       .flags = IRQ_WORK_LAZY,
+};
+
+void wake_up_klogd(void)
+{
+       preempt_disable();
+       if (waitqueue_active(&log_wait)) {
+               this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
+               irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
+       }
+       preempt_enable();
+}
 
 int printk_sched(const char *fmt, ...)
 {
index dc3384ee874e4ed5a0344395757744adc268c9bc..0bf400737660d65a03280c23df130c9e17c776ea 100644 (file)
@@ -462,10 +462,10 @@ static const struct file_operations prof_cpu_mask_proc_fops = {
        .write          = prof_cpu_mask_proc_write,
 };
 
-void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir)
+void create_prof_cpu_mask(void)
 {
        /* create /proc/irq/prof_cpu_mask */
-       proc_create("prof_cpu_mask", 0600, root_irq_dir, &prof_cpu_mask_proc_fops);
+       proc_create("irq/prof_cpu_mask", 0600, NULL, &prof_cpu_mask_proc_fops);
 }
 
 /*
@@ -600,7 +600,7 @@ int __ref create_proc_profile(void) /* false positive from hotcpu_notifier */
                            NULL, &proc_profile_operations);
        if (!entry)
                return 0;
-       entry->size = (1+prof_len) * sizeof(atomic_t);
+       proc_set_size(entry, (1 + prof_len) * sizeof(atomic_t));
        hotcpu_notifier(profile_cpu_callback, 0);
        return 0;
 }
index e036eda1a9c9b422766447bf5006a70fde47155b..da98af347e8b6ed212e67086ae8576628c11d0dd 100644 (file)
@@ -130,16 +130,11 @@ static int schedstat_open(struct inode *inode, struct file *file)
        return seq_open(file, &schedstat_sops);
 }
 
-static int schedstat_release(struct inode *inode, struct file *file)
-{
-       return 0;
-};
-
 static const struct file_operations proc_schedstat_operations = {
        .open    = schedstat_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = schedstat_release,
+       .release = seq_release,
 };
 
 static int __init proc_schedstat_init(void)
index 2ec870a4c3c4faa2a6c30c0ee380d9fc9bd25de5..dd72567767d963ccb8ac2f3cfa4a824fa5f81b4e 100644 (file)
@@ -485,6 +485,9 @@ flush_signal_handlers(struct task_struct *t, int force_default)
                if (force_default || ka->sa.sa_handler != SIG_IGN)
                        ka->sa.sa_handler = SIG_DFL;
                ka->sa.sa_flags = 0;
+#ifdef __ARCH_HAS_SA_RESTORER
+               ka->sa.sa_restorer = NULL;
+#endif
                sigemptyset(&ka->sa.sa_mask);
                ka++;
        }
@@ -2682,7 +2685,7 @@ static int do_sigpending(void *set, unsigned long sigsetsize)
 /**
  *  sys_rt_sigpending - examine a pending signal that has been raised
  *                     while blocked
- *  @set: stores pending signals
+ *  @uset: stores pending signals
  *  @sigsetsize: size of sigset_t type or larger
  */
 SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
index b9bde572782932f24d8a3a9f3a4f0670cb07b633..8eaed9aa9cf0c1995520605af1de8ef3b9e95485 100644 (file)
@@ -131,7 +131,7 @@ static int smpboot_thread_fn(void *data)
                        continue;
                }
 
-               //BUG_ON(td->cpu != smp_processor_id());
+               BUG_ON(td->cpu != smp_processor_id());
 
                /* Check for state change setup */
                switch (td->status) {
@@ -209,6 +209,8 @@ static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cp
 {
        struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
 
+       if (ht->pre_unpark)
+               ht->pre_unpark(cpu);
        kthread_unpark(tsk);
 }
 
index b4d252fd195b927afd402977b64efb3faa7ed96f..14d7758074aadf4d1c43947ecef675e8bb6c044e 100644 (file)
@@ -323,18 +323,10 @@ void irq_enter(void)
 
 static inline void invoke_softirq(void)
 {
-       if (!force_irqthreads) {
-#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
+       if (!force_irqthreads)
                __do_softirq();
-#else
-               do_softirq();
-#endif
-       } else {
-               __local_bh_disable((unsigned long)__builtin_return_address(0),
-                               SOFTIRQ_OFFSET);
+       else
                wakeup_softirqd();
-               __local_bh_enable(SOFTIRQ_OFFSET);
-       }
 }
 
 /*
@@ -342,9 +334,15 @@ static inline void invoke_softirq(void)
  */
 void irq_exit(void)
 {
+#ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
+       local_irq_disable();
+#else
+       WARN_ON_ONCE(!irqs_disabled());
+#endif
+
        account_irq_exit_time(current);
        trace_hardirq_exit();
-       sub_preempt_count(IRQ_EXIT_OFFSET);
+       sub_preempt_count(HARDIRQ_OFFSET);
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
 
@@ -354,7 +352,6 @@ void irq_exit(void)
                tick_nohz_irq_exit();
 #endif
        rcu_irq_exit();
-       sched_preempt_enable_no_resched();
 }
 
 /*
index 95d178c62d5a8537c18fa2d6f1d947aed1a93448..c09f2955ae3055b42f1edde601ee1eb431bfc18a 100644 (file)
@@ -336,7 +336,7 @@ static struct smp_hotplug_thread cpu_stop_threads = {
        .create                 = cpu_stop_create,
        .setup                  = cpu_stop_unpark,
        .park                   = cpu_stop_park,
-       .unpark                 = cpu_stop_unpark,
+       .pre_unpark             = cpu_stop_unpark,
        .selfparking            = true,
 };
 
index 81f56445fba949790b34b7bf3f97383555134672..39c9c4a2949f3166b114f11534957ff2f6060565 100644 (file)
@@ -2185,9 +2185,8 @@ SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,
 
 char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
 
-static int __orderly_poweroff(void)
+static int __orderly_poweroff(bool force)
 {
-       int argc;
        char **argv;
        static char *envp[] = {
                "HOME=/",
@@ -2196,20 +2195,40 @@ static int __orderly_poweroff(void)
        };
        int ret;
 
-       argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc);
-       if (argv == NULL) {
+       argv = argv_split(GFP_KERNEL, poweroff_cmd, NULL);
+       if (argv) {
+               ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+               argv_free(argv);
+       } else {
                printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n",
-                      __func__, poweroff_cmd);
-               return -ENOMEM;
+                                        __func__, poweroff_cmd);
+               ret = -ENOMEM;
        }
 
-       ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_WAIT_EXEC,
-                                     NULL, NULL, NULL);
-       argv_free(argv);
+       if (ret && force) {
+               printk(KERN_WARNING "Failed to start orderly shutdown: "
+                                       "forcing the issue\n");
+               /*
+                * I guess this should try to kick off some daemon to sync and
+                * poweroff asap.  Or not even bother syncing if we're doing an
+                * emergency shutdown?
+                */
+               emergency_sync();
+               kernel_power_off();
+       }
 
        return ret;
 }
 
+static bool poweroff_force;
+
+static void poweroff_work_func(struct work_struct *work)
+{
+       __orderly_poweroff(poweroff_force);
+}
+
+static DECLARE_WORK(poweroff_work, poweroff_work_func);
+
 /**
  * orderly_poweroff - Trigger an orderly system poweroff
  * @force: force poweroff if command execution fails
@@ -2219,21 +2238,9 @@ static int __orderly_poweroff(void)
  */
 int orderly_poweroff(bool force)
 {
-       int ret = __orderly_poweroff();
-
-       if (ret && force) {
-               printk(KERN_WARNING "Failed to start orderly shutdown: "
-                      "forcing the issue\n");
-
-               /*
-                * I guess this should try to kick off some daemon to sync and
-                * poweroff asap.  Or not even bother syncing if we're doing an
-                * emergency shutdown?
-                */
-               emergency_sync();
-               kernel_power_off();
-       }
-
-       return ret;
+       if (force) /* do not override the pending "true" */
+               poweroff_force = true;
+       schedule_work(&poweroff_work);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(orderly_poweroff);
index 2fb8cb88df8d0296e655f320bc7d5cbce1a858c8..7f32fe0e52cd46489c8d90e4b85f9d74204aab16 100644 (file)
@@ -67,7 +67,8 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc)
  */
 int tick_check_broadcast_device(struct clock_event_device *dev)
 {
-       if ((tick_broadcast_device.evtdev &&
+       if ((dev->features & CLOCK_EVT_FEAT_DUMMY) ||
+           (tick_broadcast_device.evtdev &&
             tick_broadcast_device.evtdev->rating >= dev->rating) ||
             (dev->features & CLOCK_EVT_FEAT_C3STOP))
                return 0;
index 192473b22799032c5cb013868f778ad4bc30626a..fc382d6e2765d4a454a85aa5591c8edc452dccfb 100644 (file)
@@ -414,24 +414,28 @@ config PROBE_EVENTS
        def_bool n
 
 config DYNAMIC_FTRACE
-       bool "enable/disable ftrace tracepoints dynamically"
+       bool "enable/disable function tracing dynamically"
        depends on FUNCTION_TRACER
        depends on HAVE_DYNAMIC_FTRACE
        default y
        help
-          This option will modify all the calls to ftrace dynamically
-         (will patch them out of the binary image and replace them
-         with a No-Op instruction) as they are called. A table is
-         created to dynamically enable them again.
+         This option will modify all the calls to function tracing
+         dynamically (will patch them out of the binary image and
+         replace them with a No-Op instruction) on boot up. During
+         compile time, a table is made of all the locations that ftrace
+         can function trace, and this table is linked into the kernel
+         image. When this is enabled, functions can be individually
+         enabled, and the functions not enabled will not affect
+         performance of the system.
+
+         See the files in /sys/kernel/debug/tracing:
+           available_filter_functions
+           set_ftrace_filter
+           set_ftrace_notrace
 
          This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
          otherwise has native performance as long as no tracing is active.
 
-         The changes to the code are done by a kernel thread that
-         wakes up once a second and checks to see if any ftrace calls
-         were made. If so, it runs stop_machine (stops all CPUS)
-         and modifies the code to jump over the call to ftrace.
-
 config DYNAMIC_FTRACE_WITH_REGS
        def_bool y
        depends on DYNAMIC_FTRACE
index ab25b88aae56f4e22380766b02378669c8b05c57..6893d5a2bf086014f2919496ca7062c246935dad 100644 (file)
@@ -3104,8 +3104,8 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
                                        continue;
                        }
 
-                       hlist_del(&entry->node);
-                       call_rcu(&entry->rcu, ftrace_free_entry_rcu);
+                       hlist_del_rcu(&entry->node);
+                       call_rcu_sched(&entry->rcu, ftrace_free_entry_rcu);
                }
        }
        __disable_ftrace_function_probe();
index c2e2c23103742e3a3e53cf7b318aa0c804f5e1a8..4f1dade56981d6fe5d880e9f6caaf609ab1e9c02 100644 (file)
@@ -704,7 +704,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 void
 update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 {
-       struct ring_buffer *buf = tr->buffer;
+       struct ring_buffer *buf;
 
        if (trace_stop_count)
                return;
@@ -719,6 +719,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 
        arch_spin_lock(&ftrace_max_lock);
 
+       buf = tr->buffer;
        tr->buffer = max_tr.buffer;
        max_tr.buffer = buf;
 
@@ -2400,6 +2401,27 @@ static void test_ftrace_alive(struct seq_file *m)
        seq_printf(m, "#          MAY BE MISSING FUNCTION EVENTS\n");
 }
 
+#ifdef CONFIG_TRACER_MAX_TRACE
+static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter)
+{
+       if (iter->trace->allocated_snapshot)
+               seq_printf(m, "#\n# * Snapshot is allocated *\n#\n");
+       else
+               seq_printf(m, "#\n# * Snapshot is freed *\n#\n");
+
+       seq_printf(m, "# Snapshot commands:\n");
+       seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n");
+       seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n");
+       seq_printf(m, "#                      Takes a snapshot of the main buffer.\n");
+       seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate)\n");
+       seq_printf(m, "#                      (Doesn't have to be '2' works with any number that\n");
+       seq_printf(m, "#                       is not a '0' or '1')\n");
+}
+#else
+/* Should never be called */
+static inline void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { }
+#endif
+
 static int s_show(struct seq_file *m, void *v)
 {
        struct trace_iterator *iter = v;
@@ -2411,7 +2433,9 @@ static int s_show(struct seq_file *m, void *v)
                        seq_puts(m, "#\n");
                        test_ftrace_alive(m);
                }
-               if (iter->trace && iter->trace->print_header)
+               if (iter->snapshot && trace_empty(iter))
+                       print_snapshot_help(m, iter);
+               else if (iter->trace && iter->trace->print_header)
                        iter->trace->print_header(m);
                else
                        trace_default_header(m);
@@ -2857,11 +2881,25 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
        return -EINVAL;
 }
 
-static void set_tracer_flags(unsigned int mask, int enabled)
+/* Some tracers require overwrite to stay enabled */
+int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
+{
+       if (tracer->enabled && (mask & TRACE_ITER_OVERWRITE) && !set)
+               return -1;
+
+       return 0;
+}
+
+int set_tracer_flag(unsigned int mask, int enabled)
 {
        /* do nothing if flag is already set */
        if (!!(trace_flags & mask) == !!enabled)
-               return;
+               return 0;
+
+       /* Give the tracer a chance to approve the change */
+       if (current_trace->flag_changed)
+               if (current_trace->flag_changed(current_trace, mask, !!enabled))
+                       return -EINVAL;
 
        if (enabled)
                trace_flags |= mask;
@@ -2871,18 +2909,24 @@ static void set_tracer_flags(unsigned int mask, int enabled)
        if (mask == TRACE_ITER_RECORD_CMD)
                trace_event_enable_cmd_record(enabled);
 
-       if (mask == TRACE_ITER_OVERWRITE)
+       if (mask == TRACE_ITER_OVERWRITE) {
                ring_buffer_change_overwrite(global_trace.buffer, enabled);
+#ifdef CONFIG_TRACER_MAX_TRACE
+               ring_buffer_change_overwrite(max_tr.buffer, enabled);
+#endif
+       }
 
        if (mask == TRACE_ITER_PRINTK)
                trace_printk_start_stop_comm(enabled);
+
+       return 0;
 }
 
 static int trace_set_options(char *option)
 {
        char *cmp;
        int neg = 0;
-       int ret = 0;
+       int ret = -ENODEV;
        int i;
 
        cmp = strstrip(option);
@@ -2892,19 +2936,20 @@ static int trace_set_options(char *option)
                cmp += 2;
        }
 
+       mutex_lock(&trace_types_lock);
+
        for (i = 0; trace_options[i]; i++) {
                if (strcmp(cmp, trace_options[i]) == 0) {
-                       set_tracer_flags(1 << i, !neg);
+                       ret = set_tracer_flag(1 << i, !neg);
                        break;
                }
        }
 
        /* If no option could be set, test the specific tracer options */
-       if (!trace_options[i]) {
-               mutex_lock(&trace_types_lock);
+       if (!trace_options[i])
                ret = set_tracer_option(current_trace, cmp, neg);
-               mutex_unlock(&trace_types_lock);
-       }
+
+       mutex_unlock(&trace_types_lock);
 
        return ret;
 }
@@ -2914,6 +2959,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
                        size_t cnt, loff_t *ppos)
 {
        char buf[64];
+       int ret;
 
        if (cnt >= sizeof(buf))
                return -EINVAL;
@@ -2923,7 +2969,9 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
 
        buf[cnt] = 0;
 
-       trace_set_options(buf);
+       ret = trace_set_options(buf);
+       if (ret < 0)
+               return ret;
 
        *ppos += cnt;
 
@@ -3227,6 +3275,9 @@ static int tracing_set_tracer(const char *buf)
                goto out;
 
        trace_branch_disable();
+
+       current_trace->enabled = false;
+
        if (current_trace->reset)
                current_trace->reset(tr);
 
@@ -3271,6 +3322,7 @@ static int tracing_set_tracer(const char *buf)
        }
 
        current_trace = t;
+       current_trace->enabled = true;
        trace_branch_enable(tr);
  out:
        mutex_unlock(&trace_types_lock);
@@ -4144,8 +4196,6 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
        default:
                if (current_trace->allocated_snapshot)
                        tracing_reset_online_cpus(&max_tr);
-               else
-                       ret = -EINVAL;
                break;
        }
 
@@ -4759,7 +4809,13 @@ trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt,
 
        if (val != 0 && val != 1)
                return -EINVAL;
-       set_tracer_flags(1 << index, val);
+
+       mutex_lock(&trace_types_lock);
+       ret = set_tracer_flag(1 << index, val);
+       mutex_unlock(&trace_types_lock);
+
+       if (ret < 0)
+               return ret;
 
        *ppos += cnt;
 
index 57d7e5397d56da86f667e3139fb14703a99e8fcf..2081971367ea8e54d5b42e188c7aaaaee22c8f2a 100644 (file)
@@ -283,11 +283,15 @@ struct tracer {
        enum print_line_t       (*print_line)(struct trace_iterator *iter);
        /* If you handled the flag setting, return 0 */
        int                     (*set_flag)(u32 old_flags, u32 bit, int set);
+       /* Return 0 if OK with change, else return non-zero */
+       int                     (*flag_changed)(struct tracer *tracer,
+                                               u32 mask, int set);
        struct tracer           *next;
        struct tracer_flags     *flags;
        bool                    print_max;
        bool                    use_max_tr;
        bool                    allocated_snapshot;
+       bool                    enabled;
 };
 
 
@@ -943,6 +947,8 @@ extern const char *__stop___trace_bprintk_fmt[];
 
 void trace_printk_init_buffers(void);
 void trace_printk_start_comm(void);
+int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
+int set_tracer_flag(unsigned int mask, int enabled);
 
 #undef FTRACE_ENTRY
 #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter)    \
index 713a2cac48816461c0c0a5b11d5a854ea5c4b3d3..443b25b43b4f60f3b58102daab06c6150f01ad64 100644 (file)
@@ -32,7 +32,7 @@ enum {
 
 static int trace_type __read_mostly;
 
-static int save_lat_flag;
+static int save_flags;
 
 static void stop_irqsoff_tracer(struct trace_array *tr, int graph);
 static int start_irqsoff_tracer(struct trace_array *tr, int graph);
@@ -558,8 +558,11 @@ static void stop_irqsoff_tracer(struct trace_array *tr, int graph)
 
 static void __irqsoff_tracer_init(struct trace_array *tr)
 {
-       save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
-       trace_flags |= TRACE_ITER_LATENCY_FMT;
+       save_flags = trace_flags;
+
+       /* non overwrite screws up the latency tracers */
+       set_tracer_flag(TRACE_ITER_OVERWRITE, 1);
+       set_tracer_flag(TRACE_ITER_LATENCY_FMT, 1);
 
        tracing_max_latency = 0;
        irqsoff_trace = tr;
@@ -573,10 +576,13 @@ static void __irqsoff_tracer_init(struct trace_array *tr)
 
 static void irqsoff_tracer_reset(struct trace_array *tr)
 {
+       int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
+       int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
+
        stop_irqsoff_tracer(tr, is_graph());
 
-       if (!save_lat_flag)
-               trace_flags &= ~TRACE_ITER_LATENCY_FMT;
+       set_tracer_flag(TRACE_ITER_LATENCY_FMT, lat_flag);
+       set_tracer_flag(TRACE_ITER_OVERWRITE, overwrite_flag);
 }
 
 static void irqsoff_tracer_start(struct trace_array *tr)
@@ -609,6 +615,7 @@ static struct tracer irqsoff_tracer __read_mostly =
        .print_line     = irqsoff_print_line,
        .flags          = &tracer_flags,
        .set_flag       = irqsoff_set_flag,
+       .flag_changed   = trace_keep_overwrite,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_irqsoff,
 #endif
@@ -642,6 +649,7 @@ static struct tracer preemptoff_tracer __read_mostly =
        .print_line     = irqsoff_print_line,
        .flags          = &tracer_flags,
        .set_flag       = irqsoff_set_flag,
+       .flag_changed   = trace_keep_overwrite,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_preemptoff,
 #endif
@@ -677,6 +685,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
        .print_line     = irqsoff_print_line,
        .flags          = &tracer_flags,
        .set_flag       = irqsoff_set_flag,
+       .flag_changed   = trace_keep_overwrite,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_preemptirqsoff,
 #endif
index 75aa97fbe1a11120d93ed241e00ddbac5a51a55d..fde652c9a511c197d47822b66871ffb764f62539 100644 (file)
@@ -36,7 +36,7 @@ static void __wakeup_reset(struct trace_array *tr);
 static int wakeup_graph_entry(struct ftrace_graph_ent *trace);
 static void wakeup_graph_return(struct ftrace_graph_ret *trace);
 
-static int save_lat_flag;
+static int save_flags;
 
 #define TRACE_DISPLAY_GRAPH     1
 
@@ -540,8 +540,11 @@ static void stop_wakeup_tracer(struct trace_array *tr)
 
 static int __wakeup_tracer_init(struct trace_array *tr)
 {
-       save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
-       trace_flags |= TRACE_ITER_LATENCY_FMT;
+       save_flags = trace_flags;
+
+       /* non overwrite screws up the latency tracers */
+       set_tracer_flag(TRACE_ITER_OVERWRITE, 1);
+       set_tracer_flag(TRACE_ITER_LATENCY_FMT, 1);
 
        tracing_max_latency = 0;
        wakeup_trace = tr;
@@ -563,12 +566,15 @@ static int wakeup_rt_tracer_init(struct trace_array *tr)
 
 static void wakeup_tracer_reset(struct trace_array *tr)
 {
+       int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
+       int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
+
        stop_wakeup_tracer(tr);
        /* make sure we put back any tasks we are tracing */
        wakeup_reset(tr);
 
-       if (!save_lat_flag)
-               trace_flags &= ~TRACE_ITER_LATENCY_FMT;
+       set_tracer_flag(TRACE_ITER_LATENCY_FMT, lat_flag);
+       set_tracer_flag(TRACE_ITER_OVERWRITE, overwrite_flag);
 }
 
 static void wakeup_tracer_start(struct trace_array *tr)
@@ -594,6 +600,7 @@ static struct tracer wakeup_tracer __read_mostly =
        .print_line     = wakeup_print_line,
        .flags          = &tracer_flags,
        .set_flag       = wakeup_set_flag,
+       .flag_changed   = trace_keep_overwrite,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_wakeup,
 #endif
@@ -615,6 +622,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =
        .print_line     = wakeup_print_line,
        .flags          = &tracer_flags,
        .set_flag       = wakeup_set_flag,
+       .flag_changed   = trace_keep_overwrite,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_wakeup,
 #endif
index e81978e8c03b2b5f1a38d62248d8408fbfcd2d13..5bbb91988e69278f2cd012896db29688c9234476 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/export.h>
 #include <linux/user_namespace.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 
 /*
  * userns count is 1 for root user, 1 for init_uts_ns,
index 8b650837083e74f7c8bcac7b4f83081c448e36ed..51855f5f6311211c785373d52e990f879ec959fe 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/nsproxy.h>
 #include <linux/slab.h>
 #include <linux/user_namespace.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 #include <linux/highuid.h>
 #include <linux/cred.h>
 #include <linux/securebits.h>
@@ -21,6 +21,7 @@
 #include <linux/uaccess.h>
 #include <linux/ctype.h>
 #include <linux/projid.h>
+#include <linux/fs_struct.h>
 
 static struct kmem_cache *user_ns_cachep __read_mostly;
 
@@ -837,6 +838,9 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
        if (atomic_read(&current->mm->mm_users) > 1)
                return -EINVAL;
 
+       if (current->fs->users != 1)
+               return -EINVAL;
+
        if (!ns_capable(user_ns, CAP_SYS_ADMIN))
                return -EPERM;
 
index a47fc5de31136a7832df8754f0342b8937ad5268..2fc8576efaa8e7a5201d9334f6fb8452cc14226a 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/user_namespace.h>
-#include <linux/proc_fs.h>
+#include <linux/proc_ns.h>
 
 static struct uts_namespace *create_uts_ns(void)
 {
index 81f2457811eb346915b8c17e4ce5ed44a5de8c10..b48cd597145dd007b503d22755c481256f48867e 100644 (file)
@@ -457,11 +457,12 @@ static int worker_pool_assign_id(struct worker_pool *pool)
        int ret;
 
        mutex_lock(&worker_pool_idr_mutex);
-       idr_pre_get(&worker_pool_idr, GFP_KERNEL);
-       ret = idr_get_new(&worker_pool_idr, pool, &pool->id);
+       ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
+       if (ret >= 0)
+               pool->id = ret;
        mutex_unlock(&worker_pool_idr_mutex);
 
-       return ret;
+       return ret < 0 ? ret : 0;
 }
 
 /*
@@ -3446,28 +3447,34 @@ static void wq_unbind_fn(struct work_struct *work)
 
                spin_unlock_irq(&pool->lock);
                mutex_unlock(&pool->assoc_mutex);
-       }
 
-       /*
-        * Call schedule() so that we cross rq->lock and thus can guarantee
-        * sched callbacks see the %WORKER_UNBOUND flag.  This is necessary
-        * as scheduler callbacks may be invoked from other cpus.
-        */
-       schedule();
+               /*
+                * Call schedule() so that we cross rq->lock and thus can
+                * guarantee sched callbacks see the %WORKER_UNBOUND flag.
+                * This is necessary as scheduler callbacks may be invoked
+                * from other cpus.
+                */
+               schedule();
 
-       /*
-        * Sched callbacks are disabled now.  Zap nr_running.  After this,
-        * nr_running stays zero and need_more_worker() and keep_working()
-        * are always true as long as the worklist is not empty.  Pools on
-        * @cpu now behave as unbound (in terms of concurrency management)
-        * pools which are served by workers tied to the CPU.
-        *
-        * On return from this function, the current worker would trigger
-        * unbound chain execution of pending work items if other workers
-        * didn't already.
-        */
-       for_each_std_worker_pool(pool, cpu)
+               /*
+                * Sched callbacks are disabled now.  Zap nr_running.
+                * After this, nr_running stays zero and need_more_worker()
+                * and keep_working() are always true as long as the
+                * worklist is not empty.  This pool now behaves as an
+                * unbound (in terms of concurrency management) pool which
+                * are served by workers tied to the pool.
+                */
                atomic_set(&pool->nr_running, 0);
+
+               /*
+                * With concurrency management just turned off, a busy
+                * worker blocking could lead to lengthy stalls.  Kick off
+                * unbound chain execution of currently pending work items.
+                */
+               spin_lock_irq(&pool->lock);
+               wake_up_worker(pool);
+               spin_unlock_irq(&pool->lock);
+       }
 }
 
 /*
index 9681d54b95d127878405d5ff0afec6fcc575fbae..f8e0e536739832bdd05df68647e373788c060fda 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/printk.h>
 #include <linux/spinlock.h>
 #include <linux/tty.h>
 #include <linux/wait.h>
@@ -28,5 +29,3 @@ void __attribute__((weak)) bust_spinlocks(int yes)
                        wake_up_klogd();
        }
 }
-
-
index 5e396accd3d02a8dce6d06cc2d6020e311b308b0..d87a17a819d07a58bc8f1dd40f2d41ae499935c8 100644 (file)
@@ -862,17 +862,21 @@ static void check_unmap(struct dma_debug_entry *ref)
        entry = bucket_find_exact(bucket, ref);
 
        if (!entry) {
+               /* must drop lock before calling dma_mapping_error */
+               put_hash_bucket(bucket, &flags);
+
                if (dma_mapping_error(ref->dev, ref->dev_addr)) {
                        err_printk(ref->dev, NULL,
-                                  "DMA-API: device driver tries "
-                                  "to free an invalid DMA memory address\n");
-                       return;
+                                  "DMA-API: device driver tries to free an "
+                                  "invalid DMA memory address\n");
+               } else {
+                       err_printk(ref->dev, NULL,
+                                  "DMA-API: device driver tries to free DMA "
+                                  "memory it has not allocated [device "
+                                  "address=0x%016llx] [size=%llu bytes]\n",
+                                  ref->dev_addr, ref->size);
                }
-               err_printk(ref->dev, NULL, "DMA-API: device driver tries "
-                          "to free DMA memory it has not allocated "
-                          "[device address=0x%016llx] [size=%llu bytes]\n",
-                          ref->dev_addr, ref->size);
-               goto out;
+               return;
        }
 
        if (ref->size != entry->size) {
@@ -936,7 +940,6 @@ static void check_unmap(struct dma_debug_entry *ref)
        hash_bucket_del(entry);
        dma_entry_free(entry);
 
-out:
        put_hash_bucket(bucket, &flags);
 }
 
@@ -1082,13 +1085,27 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
        ref.dev = dev;
        ref.dev_addr = dma_addr;
        bucket = get_hash_bucket(&ref, &flags);
-       entry = bucket_find_exact(bucket, &ref);
 
-       if (!entry)
-               goto out;
+       list_for_each_entry(entry, &bucket->list, list) {
+               if (!exact_match(&ref, entry))
+                       continue;
+
+               /*
+                * The same physical address can be mapped multiple
+                * times. Without a hardware IOMMU this results in the
+                * same device addresses being put into the dma-debug
+                * hash multiple times too. This can result in false
+                * positives being reported. Therefore we implement a
+                * best-fit algorithm here which updates the first entry
+                * from the hash which fits the reference value and is
+                * not currently listed as being checked.
+                */
+               if (entry->map_err_type == MAP_ERR_NOT_CHECKED) {
+                       entry->map_err_type = MAP_ERR_CHECKED;
+                       break;
+               }
+       }
 
-       entry->map_err_type = MAP_ERR_CHECKED;
-out:
        put_hash_bucket(bucket, &flags);
 }
 EXPORT_SYMBOL(debug_dma_mapping_error);
index 73f4d53c02f3deaee2a0df5b2909a218b38a10e8..322e2816f2fb6fe67b512bb4329c49e7377c1591 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
        if (layer_idr)
                return get_from_free_list(layer_idr);
 
-       /* try to allocate directly from kmem_cache */
-       new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
+       /*
+        * Try to allocate directly from kmem_cache.  We want to try this
+        * before preload buffer; otherwise, non-preloading idr_alloc()
+        * users will end up taking advantage of preloading ones.  As the
+        * following is allowed to fail for preloaded cases, suppress
+        * warning this time.
+        */
+       new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
        if (new)
                return new;
 
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
         * Try to fetch one from the per-cpu preload buffer if in process
         * context.  See idr_preload() for details.
         */
-       if (in_interrupt())
-               return NULL;
-
-       preempt_disable();
-       new = __this_cpu_read(idr_preload_head);
-       if (new) {
-               __this_cpu_write(idr_preload_head, new->ary[0]);
-               __this_cpu_dec(idr_preload_cnt);
-               new->ary[0] = NULL;
+       if (!in_interrupt()) {
+               preempt_disable();
+               new = __this_cpu_read(idr_preload_head);
+               if (new) {
+                       __this_cpu_write(idr_preload_head, new->ary[0]);
+                       __this_cpu_dec(idr_preload_cnt);
+                       new->ary[0] = NULL;
+               }
+               preempt_enable();
+               if (new)
+                       return new;
        }
-       preempt_enable();
-       return new;
+
+       /*
+        * Both failed.  Try kmem_cache again w/o adding __GFP_NOWARN so
+        * that memory allocation failure warning is printed as intended.
+        */
+       return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
 }
 
 static void idr_layer_rcu_free(struct rcu_head *head)
@@ -184,20 +196,7 @@ static void idr_mark_full(struct idr_layer **pa, int id)
        }
 }
 
-/**
- * idr_pre_get - reserve resources for idr allocation
- * @idp:       idr handle
- * @gfp_mask:  memory allocation flags
- *
- * This function should be called prior to calling the idr_get_new* functions.
- * It preallocates enough memory to satisfy the worst possible allocation. The
- * caller should pass in GFP_KERNEL if possible.  This of course requires that
- * no spinning locks be held.
- *
- * If the system is REALLY out of memory this function returns %0,
- * otherwise %1.
- */
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask)
 {
        while (idp->id_free_cnt < MAX_IDR_FREE) {
                struct idr_layer *new;
@@ -208,13 +207,12 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
        }
        return 1;
 }
-EXPORT_SYMBOL(idr_pre_get);
+EXPORT_SYMBOL(__idr_pre_get);
 
 /**
  * sub_alloc - try to allocate an id without growing the tree depth
  * @idp: idr handle
  * @starting_id: id to start search at
- * @id: pointer to the allocated handle
  * @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer
  * @gfp_mask: allocation mask for idr_layer_alloc()
  * @layer_idr: optional idr passed to idr_layer_alloc()
@@ -376,25 +374,7 @@ static void idr_fill_slot(struct idr *idr, void *ptr, int id,
        idr_mark_full(pa, id);
 }
 
-/**
- * idr_get_new_above - allocate new idr entry above or equal to a start id
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @starting_id: id to start search at
- * @id: pointer to the allocated handle
- *
- * This is the allocate id function.  It should be called with any
- * required locks.
- *
- * If allocation from IDR's private freelist fails, idr_get_new_above() will
- * return %-EAGAIN.  The caller should retry the idr_pre_get() call to refill
- * IDR's preallocation and then retry the idr_get_new_above() call.
- *
- * If the idr is full idr_get_new_above() will return %-ENOSPC.
- *
- * @id returns a value in the range @starting_id ... %0x7fffffff
- */
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 {
        struct idr_layer *pa[MAX_IDR_LEVEL + 1];
        int rv;
@@ -407,7 +387,7 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
        *id = rv;
        return 0;
 }
-EXPORT_SYMBOL(idr_get_new_above);
+EXPORT_SYMBOL(__idr_get_new_above);
 
 /**
  * idr_preload - preload for idr_alloc()
@@ -569,8 +549,7 @@ void idr_remove(struct idr *idp, int id)
        struct idr_layer *p;
        struct idr_layer *to_free;
 
-       /* see comment in idr_find_slowpath() */
-       if (WARN_ON_ONCE(id < 0))
+       if (id < 0)
                return;
 
        sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
@@ -667,15 +646,7 @@ void *idr_find_slowpath(struct idr *idp, int id)
        int n;
        struct idr_layer *p;
 
-       /*
-        * If @id is negative, idr_find() used to ignore the sign bit and
-        * performed lookup with the rest of bits, which is weird and can
-        * lead to very obscure bugs.  We're now returning NULL for all
-        * negative IDs but just in case somebody was depending on the sign
-        * bit being ignored, let's trigger WARN_ON_ONCE() so that they can
-        * be detected and fixed.  WARN_ON_ONCE() can later be removed.
-        */
-       if (WARN_ON_ONCE(id < 0))
+       if (id < 0)
                return NULL;
 
        p = rcu_dereference_raw(idp->top);
@@ -824,8 +795,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
        int n;
        struct idr_layer *p, *old_p;
 
-       /* see comment in idr_find_slowpath() */
-       if (WARN_ON_ONCE(id < 0))
+       if (id < 0)
                return ERR_PTR(-EINVAL);
 
        p = idp->top;
@@ -918,7 +888,7 @@ static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)
 int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
 {
        /* allocate idr_layers */
-       if (!idr_pre_get(&ida->idr, gfp_mask))
+       if (!__idr_pre_get(&ida->idr, gfp_mask))
                return 0;
 
        /* allocate free_bitmap */
index 44b92cb6224f5f599f5f997da5b612b0f28a2ef9..eb4a04afea80a6a2e3d3954cf1b9f00a45faf4a9 100644 (file)
@@ -17,7 +17,7 @@ static int debugfs_errno_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
                        "%lld\n");
 
-static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+static struct dentry *debugfs_create_errno(const char *name, umode_t mode,
                                struct dentry *parent, int *value)
 {
        return debugfs_create_file(name, mode, parent, value, &fops_errno);
@@ -50,7 +50,7 @@ struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent,
                        struct notifier_err_inject *err_inject, int priority)
 {
        struct notifier_err_inject_action *action;
-       mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+       umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
        struct dentry *dir;
        struct dentry *actions_dir;
 
index 82a04d7ba99ea317aca1888c103f3bee32590bbb..08837db52d94f16b39a45a80eaa4fef774ef8b7b 100644 (file)
@@ -15,7 +15,7 @@ config XZ_DEC_X86
 
 config XZ_DEC_POWERPC
        bool "PowerPC BCJ filter decoder"
-       default y if POWERPC
+       default y if PPC
        select XZ_DEC_BCJ
 
 config XZ_DEC_IA64
index ae55c1e04d105016cf7c780398552e56a498e65a..3bea74f1ccfe1f1f5c134fd5c98767d620553b60 100644 (file)
@@ -286,8 +286,12 @@ config NR_QUICK
        default "1"
 
 config VIRT_TO_BUS
-       def_bool y
-       depends on HAVE_VIRT_TO_BUS
+       bool
+       help
+         An architecture should select this if it implements the
+         deprecated interface virt_to_bus().  All new architectures
+         should probably not select this.
+
 
 config MMU_NOTIFIER
        bool
index e1979fdca8055e8cae04d081606fdf2f16ba8224..cbde8842a37458ec87f6fef57c7cadd59c8b98e1 100644 (file)
@@ -2528,7 +2528,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        BUG_ON(iocb->ki_pos != pos);
 
-       sb_start_write(inode->i_sb);
        mutex_lock(&inode->i_mutex);
        ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
        mutex_unlock(&inode->i_mutex);
@@ -2540,7 +2539,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                if (err < 0 && ret > 0)
                        ret = err;
        }
-       sb_end_write(inode->i_sb);
        return ret;
 }
 EXPORT_SYMBOL(generic_file_aio_write);
index a912da6ddfd4a81e2c264a8da957376eac72c2ee..28fe26b64f8a746119d8111ad0f3beb9ef4751c2 100644 (file)
@@ -404,8 +404,6 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len,
        loff_t pos;
        ssize_t ret;
 
-       sb_start_write(inode->i_sb);
-
        mutex_lock(&inode->i_mutex);
 
        if (!access_ok(VERIFY_READ, buf, len)) {
@@ -439,7 +437,6 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len,
        current->backing_dev_info = NULL;
  out_up:
        mutex_unlock(&inode->i_mutex);
-       sb_end_write(inode->i_sb);
        return ret;
 }
 EXPORT_SYMBOL_GPL(xip_file_write);
index 0cd4c11488edf8c8fd33346e9b94e28fb3272aa1..4723ac8d2fc200d5990f830b6f4c8c0fd2a9bbcf 100644 (file)
@@ -129,7 +129,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        struct vm_area_struct *vma;
        int err = -EINVAL;
        int has_write_lock = 0;
-       vm_flags_t vm_flags;
+       vm_flags_t vm_flags = 0;
 
        if (prot)
                return err;
@@ -254,7 +254,8 @@ get_write_lock:
         */
 
 out:
-       vm_flags = vma->vm_flags;
+       if (vma)
+               vm_flags = vma->vm_flags;
        if (likely(!has_write_lock))
                up_read(&mm->mmap_sem);
        else
index 0a0be33bb1997f9b19d1800e906c97f7e5a18d38..ca9a7c6d7e973c5db4bbecd7e72139d5c9529b72 100644 (file)
@@ -2124,8 +2124,12 @@ int hugetlb_report_node_meminfo(int nid, char *buf)
 /* Return the number pages of memory we physically have, in PAGE_SIZE units. */
 unsigned long hugetlb_total_pages(void)
 {
-       struct hstate *h = &default_hstate;
-       return h->nr_huge_pages * pages_per_huge_page(h);
+       struct hstate *h;
+       unsigned long nr_total_pages = 0;
+
+       for_each_hstate(h)
+               nr_total_pages += h->nr_huge_pages * pages_per_huge_page(h);
+       return nr_total_pages;
 }
 
 static int hugetlb_acct_memory(struct hstate *h, long delta)
index 85bfd4c1634629dc35a2f671c43cd3e2d8c818cc..b6afe0c440d8b3e500f4a09e2875491c7d70199a 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -489,7 +489,7 @@ out:                page = NULL;
  */
 static inline int get_kpfn_nid(unsigned long kpfn)
 {
-       return ksm_merge_across_nodes ? 0 : pfn_to_nid(kpfn);
+       return ksm_merge_across_nodes ? 0 : NUMA(pfn_to_nid(kpfn));
 }
 
 static void remove_node_from_stable_tree(struct stable_node *stable_node)
index 53b8201b31eb6f21bf66a3ca26f07fbf39f21c65..2b552224f5cf7f8b0807d244963df29fbb245634 100644 (file)
@@ -3012,6 +3012,8 @@ void memcg_update_array_size(int num)
                memcg_limited_groups_array_size = memcg_caches_array_size(num);
 }
 
+static void kmem_cache_destroy_work_func(struct work_struct *w);
+
 int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
 {
        struct memcg_cache_params *cur_params = s->memcg_params;
@@ -3031,6 +3033,8 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
                        return -ENOMEM;
                }
 
+               INIT_WORK(&s->memcg_params->destroy,
+                               kmem_cache_destroy_work_func);
                s->memcg_params->is_root_cache = true;
 
                /*
@@ -3078,6 +3082,8 @@ int memcg_register_cache(struct mem_cgroup *memcg, struct kmem_cache *s,
        if (!s->memcg_params)
                return -ENOMEM;
 
+       INIT_WORK(&s->memcg_params->destroy,
+                       kmem_cache_destroy_work_func);
        if (memcg) {
                s->memcg_params->memcg = memcg;
                s->memcg_params->root_cache = root_cache;
@@ -3358,8 +3364,6 @@ static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
        list_for_each_entry(params, &memcg->memcg_slab_caches, list) {
                cachep = memcg_params_to_cache(params);
                cachep->memcg_params->dead = true;
-               INIT_WORK(&cachep->memcg_params->destroy,
-                                 kmem_cache_destroy_work_func);
                schedule_work(&cachep->memcg_params->destroy);
        }
        mutex_unlock(&memcg->slab_caches_mutex);
index b81a367b9f39bb056cc4127a674e8a3dd4d2567d..ee3765760818a6623f86e48a6d775d2d6c2a75a2 100644 (file)
@@ -1779,7 +1779,11 @@ void try_offline_node(int nid)
        for (i = 0; i < MAX_NR_ZONES; i++) {
                struct zone *zone = pgdat->node_zones + i;
 
-               if (zone->wait_table)
+               /*
+                * wait_table may be allocated from boot memory,
+                * here only free if it's allocated by vmalloc.
+                */
+               if (is_vmalloc_addr(zone->wait_table))
                        vfree(zone->wait_table);
        }
 
@@ -1801,7 +1805,7 @@ int __ref remove_memory(int nid, u64 start, u64 size)
        int retry = 1;
 
        start_pfn = PFN_DOWN(start);
-       end_pfn = start_pfn + PFN_DOWN(size);
+       end_pfn = PFN_UP(start + size - 1);
 
        /*
         * When CONFIG_MEMCG is on, one memory block may be used by other
index 31d26637b6587acac54e83ecc017ac063ec0d11d..74310017296ee02317b79a2c28b25ef303fc7720 100644 (file)
@@ -2390,9 +2390,9 @@ restart:
 
                                *mpol_new = *n->policy;
                                atomic_set(&mpol_new->refcnt, 1);
-                               sp_node_init(n_new, n->end, end, mpol_new);
-                               sp_insert(sp, n_new);
+                               sp_node_init(n_new, end, n->end, mpol_new);
                                n->end = start;
+                               sp_insert(sp, n_new);
                                n_new = NULL;
                                mpol_new = NULL;
                                break;
index 926b466497492f3f8463ebc623adc4fbddf9547a..fd26d0433509e2b5885c74249a9eb04828285180 100644 (file)
@@ -429,12 +429,6 @@ compat_process_vm_rw(compat_pid_t pid,
        if (flags != 0)
                return -EINVAL;
 
-       if (!access_ok(VERIFY_READ, lvec, liovcnt * sizeof(*lvec)))
-               goto out;
-
-       if (!access_ok(VERIFY_READ, rvec, riovcnt * sizeof(*rvec)))
-               goto out;
-
        if (vm_write)
                rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
                                                  UIO_FASTIOV, iovstack_l,
@@ -459,8 +453,6 @@ free_iovecs:
                kfree(iov_r);
        if (iov_l != iovstack_l)
                kfree(iov_l);
-
-out:
        return rc;
 }
 
index a18714469bf791299f0d60b1a38b9886fdf4dfff..85addcd9372b0d8abfbd277d332408900efdea1d 100644 (file)
@@ -86,13 +86,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 
        grp = &vlan_info->grp;
 
-       /* Take it out of our own structures, but be sure to interlock with
-        * HW accelerating devices or SW vlan input packet processing if
-        * VLAN is not 0 (leave it there for 802.1p).
-        */
-       if (vlan_id)
-               vlan_vid_del(real_dev, vlan_id);
-
        grp->nr_vlan_devs--;
 
        if (vlan->flags & VLAN_FLAG_MVRP)
@@ -114,6 +107,13 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
                vlan_gvrp_uninit_applicant(real_dev);
        }
 
+       /* Take it out of our own structures, but be sure to interlock with
+        * HW accelerating devices or SW vlan input packet processing if
+        * VLAN is not 0 (leave it there for 802.1p).
+        */
+       if (vlan_id)
+               vlan_vid_del(real_dev, vlan_id);
+
        /* Get rid of the vlan's reference to real_dev */
        dev_put(real_dev);
 }
index dc526ec965e45e6f219fe708836483e480bc9fde..1d0e89213a28e8e9200a2ead740c6980f9be46c5 100644 (file)
@@ -93,7 +93,7 @@ static const struct file_operations vlan_fops = {
 
 static int vlandev_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, vlandev_seq_show, PDE(inode)->data);
+       return single_open(file, vlandev_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations vlandev_fops = {
@@ -184,14 +184,9 @@ int vlan_proc_add_dev(struct net_device *vlandev)
  */
 int vlan_proc_rem_dev(struct net_device *vlandev)
 {
-       struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
-
        /** NOTE:  This will consume the memory pointed to by dent, it seems. */
-       if (vlan_dev_priv(vlandev)->dent) {
-               remove_proc_entry(vlan_dev_priv(vlandev)->dent->name,
-                                 vn->proc_vlan_dir);
-               vlan_dev_priv(vlandev)->dent = NULL;
-       }
+       proc_remove(vlan_dev_priv(vlandev)->dent);
+       vlan_dev_priv(vlandev)->dent = NULL;
        return 0;
 }
 
index 74dea377fe5b1ee2b111cd2b433647195a5ab782..de2e950a0a7a8724a06618b45334e0c544278f70 100644 (file)
@@ -655,7 +655,7 @@ static struct p9_trans_module p9_virtio_trans = {
        .create = p9_virtio_create,
        .close = p9_virtio_close,
        .request = p9_virtio_request,
-       //.zc_request = p9_virtio_zc_request,
+       .zc_request = p9_virtio_zc_request,
        .cancel = p9_virtio_cancel,
        /*
         * We leave one entry for input and one entry for response
index 6ac35ff0d6b9a82143e8171dfae4fc95a0176f30..bbb6461a4b7fbe9a9d2b2d957bca7974331d42aa 100644 (file)
@@ -385,7 +385,7 @@ static ssize_t proc_dev_atm_read(struct file *file, char __user *buf,
        page = get_zeroed_page(GFP_KERNEL);
        if (!page)
                return -ENOMEM;
-       dev = PDE(file_inode(file))->data;
+       dev = PDE_DATA(file_inode(file));
        if (!dev->ops->proc_read)
                length = -EINVAL;
        else {
index a0b253ecadaf6805106e74c943ed726a81f172bb..a5bb0a769eb927efff0408fa7dd6afbffcdf2ec0 100644 (file)
@@ -1288,7 +1288,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
 
        /* unpack the aggregated packets and process them one by one */
-       do {
+       while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
+                                        batadv_ogm_packet->tt_num_changes)) {
                tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
 
                batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
@@ -1299,8 +1300,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
 
                packet_pos = packet_buff + buff_pos;
                batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
-       } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
-                                          batadv_ogm_packet->tt_num_changes));
+       }
 
        kfree_skb(skb);
        return NET_RX_SUCCESS;
index d3ee69b35a78267f35b8ea4a9b32d367160eea21..438a8c56938e7f8162055f0c3310855838be993e 100644 (file)
@@ -617,7 +617,7 @@ static int bt_seq_open(struct inode *inode, struct file *file)
        struct bt_sock_list *sk_list;
        struct bt_seq_state *s;
 
-       sk_list = PDE(inode)->data;
+       sk_list = PDE_DATA(inode);
        s = __seq_open_private(file, &bt_seq_ops,
                               sizeof(struct bt_seq_state));
        if (!s)
@@ -627,26 +627,21 @@ static int bt_seq_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-int bt_procfs_init(struct module* module, struct net *net, const char *name,
+static const struct file_operations bt_fops = {
+       .open = bt_seq_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release_private
+};
+
+int bt_procfs_init(struct net *net, const char *name,
                   struct bt_sock_list* sk_list,
                   int (* seq_show)(struct seq_file *, void *))
 {
-       struct proc_dir_entry * pde;
-
        sk_list->custom_seq_show = seq_show;
 
-       sk_list->fops.owner     = module;
-       sk_list->fops.open      = bt_seq_open;
-       sk_list->fops.read      = seq_read;
-       sk_list->fops.llseek    = seq_lseek;
-       sk_list->fops.release   = seq_release_private;
-
-       pde = proc_create(name, 0, net->proc_net, &sk_list->fops);
-       if (!pde)
+       if (!proc_create_data(name, 0, net->proc_net, &bt_fops, sk_list))
                return -ENOMEM;
-
-       pde->data = sk_list;
-
        return 0;
 }
 
@@ -655,7 +650,7 @@ void bt_procfs_cleanup(struct net *net, const char *name)
        remove_proc_entry(name, net->proc_net);
 }
 #else
-int bt_procfs_init(struct module* module, struct net *net, const char *name,
+int bt_procfs_init(struct net *net, const char *name,
                   struct bt_sock_list* sk_list,
                   int (* seq_show)(struct seq_file *, void *))
 {
index e7154a58465f6b9136f527ab868024464d961564..d4686fb7e95747bcc219331b1323022e28328c3d 100644 (file)
@@ -234,7 +234,7 @@ int __init bnep_sock_init(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "bnep", &bnep_sk_list, NULL);
+       err = bt_procfs_init(&init_net, "bnep", &bnep_sk_list, NULL);
        if (err < 0) {
                BT_ERR("Failed to create BNEP proc file");
                bt_sock_unregister(BTPROTO_BNEP);
index a4a9d4b6816c43b3216eee038f961301978b5713..cd75e4d64b9093df7f3d07c711b43ba983779197 100644 (file)
@@ -539,7 +539,7 @@ static int cmtp_proc_show(struct seq_file *m, void *v)
 
 static int cmtp_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, cmtp_proc_show, PDE(inode)->data);
+       return single_open(file, cmtp_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations cmtp_proc_fops = {
index 1c57482112b6e5c1eebfa30ce1ac84375db737dd..03f26bf85d74f187d1d2ba5fb3e0766a27d22662 100644 (file)
@@ -245,7 +245,7 @@ int cmtp_init_sockets(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "cmtp", &cmtp_sk_list, NULL);
+       err = bt_procfs_init(&init_net, "cmtp", &cmtp_sk_list, NULL);
        if (err < 0) {
                BT_ERR("Failed to create CMTP proc file");
                bt_sock_unregister(BTPROTO_HIDP);
index 6a93614f2c49c4a7c498f20656ed2a0560de7c33..6ad23951c13359ed01c31b59669115909a155102 100644 (file)
@@ -1102,7 +1102,7 @@ int __init hci_sock_init(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "hci", &hci_sk_list, NULL);
+       err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL);
        if (err < 0) {
                BT_ERR("Failed to create HCI proc file");
                bt_sock_unregister(BTPROTO_HCI);
index 82a829d90b0f4a8f60013653bf0eed34237cb5b0..e7e04d4b9d99b8b6f4c23f89080e80693f806bbe 100644 (file)
@@ -284,7 +284,7 @@ int __init hidp_init_sockets(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "hidp", &hidp_sk_list, NULL);
+       err = bt_procfs_init(&init_net, "hidp", &hidp_sk_list, NULL);
        if (err < 0) {
                BT_ERR("Failed to create HIDP proc file");
                bt_sock_unregister(BTPROTO_HIDP);
index 1bcfb8422fdcf55096e9b4131e07eab63d5c365c..fe15960c02c35e05b807b03475b08fae0ac3a4e9 100644 (file)
@@ -1292,7 +1292,7 @@ int __init l2cap_init_sockets(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list,
+       err = bt_procfs_init(&init_net, "l2cap", &l2cap_sk_list,
                             NULL);
        if (err < 0) {
                BT_ERR("Failed to create L2CAP proc file");
index c23bae86263b6e98a21a8f69ae45190b827b2376..fda3bb4019a35e625c0d219a3c9418560058b340 100644 (file)
@@ -1036,7 +1036,7 @@ int __init rfcomm_init_sockets(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "rfcomm", &rfcomm_sk_list, NULL);
+       err = bt_procfs_init(&init_net, "rfcomm", &rfcomm_sk_list, NULL);
        if (err < 0) {
                BT_ERR("Failed to create RFCOMM proc file");
                bt_sock_unregister(BTPROTO_RFCOMM);
index 79d87d8d4f514f5529b57f1b89119a735d068f69..7e8dbaf8bc1064638c000a93de618b8a831fe6df 100644 (file)
@@ -359,6 +359,7 @@ static void __sco_sock_close(struct sock *sk)
                        sco_chan_del(sk, ECONNRESET);
                break;
 
+       case BT_CONNECT2:
        case BT_CONNECT:
        case BT_DISCONN:
                sco_chan_del(sk, ECONNRESET);
@@ -1082,7 +1083,7 @@ int __init sco_init(void)
                goto error;
        }
 
-       err = bt_procfs_init(THIS_MODULE, &init_net, "sco", &sco_sk_list, NULL);
+       err = bt_procfs_init(&init_net, "sco", &sco_sk_list, NULL);
        if (err < 0) {
                BT_ERR("Failed to create SCO proc file");
                bt_sock_unregister(BTPROTO_SCO);
index d5f1d3fd4b28df39473446defcbad23928d4cb2d..314c73ed418fc43e977c7d47e4bce88ea1104b53 100644 (file)
@@ -66,7 +66,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
                        goto out;
                }
 
-               mdst = br_mdb_get(br, skb);
+               mdst = br_mdb_get(br, skb, vid);
                if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
                        br_multicast_deliver(mdst, skb);
                else
index b0812c91c0f0ea6d4010722990a044c72d93ba36..bab338e6270df4604efe792f40025a40d7682347 100644 (file)
@@ -423,7 +423,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
                        return 0;
                br_warn(br, "adding interface %s with same address "
                       "as a received packet\n",
-                      source->dev->name);
+                      source ? source->dev->name : br->dev->name);
                fdb_delete(br, fdb);
        }
 
index 480330151898486eee3a42382c28f327021d111b..828e2bcc1f525570809b652c98e1c011b2850940 100644 (file)
@@ -97,7 +97,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
        if (is_broadcast_ether_addr(dest))
                skb2 = skb;
        else if (is_multicast_ether_addr(dest)) {
-               mdst = br_mdb_get(br, skb);
+               mdst = br_mdb_get(br, skb, vid);
                if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
                        if ((mdst && mdst->mglist) ||
                            br_multicast_is_router(br))
index 9f97b850fc65171cf87692cf87a3b2e29d906e0c..ee79f3f20383c9112ff2685ef10b6d69a1d40c97 100644 (file)
@@ -80,6 +80,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
                                port = p->port;
                                if (port) {
                                        struct br_mdb_entry e;
+                                       memset(&e, 0, sizeof(e));
                                        e.ifindex = port->dev->ifindex;
                                        e.state = p->state;
                                        if (p->addr.proto == htons(ETH_P_IP))
@@ -136,6 +137,7 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
                                break;
 
                        bpm = nlmsg_data(nlh);
+                       memset(bpm, 0, sizeof(*bpm));
                        bpm->ifindex = dev->ifindex;
                        if (br_mdb_fill_info(skb, cb, dev) < 0)
                                goto out;
@@ -171,6 +173,7 @@ static int nlmsg_populate_mdb_fill(struct sk_buff *skb,
                return -EMSGSIZE;
 
        bpm = nlmsg_data(nlh);
+       memset(bpm, 0, sizeof(*bpm));
        bpm->family  = AF_BRIDGE;
        bpm->ifindex = dev->ifindex;
        nest = nla_nest_start(skb, MDBA_MDB);
@@ -228,6 +231,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
 {
        struct br_mdb_entry entry;
 
+       memset(&entry, 0, sizeof(entry));
        entry.ifindex = port->dev->ifindex;
        entry.addr.proto = group->proto;
        entry.addr.u.ip4 = group->u.ip4;
index 10e6fce1bb62abb0987a98c167bf653356e088ac..923fbeaf7afdbb957afb732fc226c4fb669e6a2e 100644 (file)
@@ -132,7 +132,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get(
 #endif
 
 struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
-                                       struct sk_buff *skb)
+                                       struct sk_buff *skb, u16 vid)
 {
        struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
        struct br_ip ip;
@@ -144,6 +144,7 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
                return NULL;
 
        ip.proto = skb->protocol;
+       ip.vid = vid;
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
index 27aa3ee517ce56101e28fd37602356f1f43843ff..299fc5f40a26c12ef39786d8bc3885c0c96ca7be 100644 (file)
@@ -29,6 +29,7 @@ static inline size_t br_port_info_size(void)
                + nla_total_size(1)     /* IFLA_BRPORT_MODE */
                + nla_total_size(1)     /* IFLA_BRPORT_GUARD */
                + nla_total_size(1)     /* IFLA_BRPORT_PROTECT */
+               + nla_total_size(1)     /* IFLA_BRPORT_FAST_LEAVE */
                + 0;
 }
 
@@ -329,6 +330,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
        br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
        br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
        br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
+       br_set_port_flag(p, tb, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK);
 
        if (tb[IFLA_BRPORT_COST]) {
                err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
index 6d314c4e6bcbca8aa68da999e6117879cda9db12..3cbf5beb3d4be267fbea19a2fd81b7b09d3d6a0c 100644 (file)
@@ -442,7 +442,7 @@ extern int br_multicast_rcv(struct net_bridge *br,
                            struct net_bridge_port *port,
                            struct sk_buff *skb);
 extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
-                                              struct sk_buff *skb);
+                                              struct sk_buff *skb, u16 vid);
 extern void br_multicast_add_port(struct net_bridge_port *port);
 extern void br_multicast_del_port(struct net_bridge_port *port);
 extern void br_multicast_enable_port(struct net_bridge_port *port);
@@ -504,7 +504,7 @@ static inline int br_multicast_rcv(struct net_bridge *br,
 }
 
 static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
-                                                     struct sk_buff *skb)
+                                                     struct sk_buff *skb, u16 vid)
 {
        return NULL;
 }
index 1ae1d9cb278d4047083214ba0336dd846f4822a1..21760f0089749217e03790e02b49998fc5a7958c 100644 (file)
@@ -118,7 +118,7 @@ static struct caif_device_entry *caif_get(struct net_device *dev)
        return NULL;
 }
 
-void caif_flow_cb(struct sk_buff *skb)
+static void caif_flow_cb(struct sk_buff *skb)
 {
        struct caif_device_entry *caifd;
        void (*dtor)(struct sk_buff *skb) = NULL;
index 3ebc8cbc91fff419097799784dad4aa374ced101..ef8ebaa993cf3ca9c915f8d2a230a3d04af79c34 100644 (file)
@@ -81,8 +81,8 @@ static void cfusbl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
                layr->up->ctrlcmd(layr->up, ctrl, layr->id);
 }
 
-struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN],
-                                       u8 braddr[ETH_ALEN])
+static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN],
+                                     u8 braddr[ETH_ALEN])
 {
        struct cfusbl *this = kmalloc(sizeof(struct cfusbl), GFP_ATOMIC);
 
index 5dcb20076f394d2827cb0c4b5017161c66d27b9e..8f113e6ff32750d3809c3ab38117d6ad1ebc8f38 100644 (file)
@@ -226,7 +226,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 
 static int bcm_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, bcm_proc_show, PDE(inode)->data);
+       return single_open(file, bcm_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations bcm_proc_fops = {
index 1ab8c888f1024003b6dd4a60e1e7a1988bf94d25..b543470c8f8b5ef7e5196b7f895cf30a9b0db90e 100644 (file)
@@ -378,7 +378,7 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v)
 
 static int can_rcvlist_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, can_rcvlist_proc_show, PDE(inode)->data);
+       return single_open(file, can_rcvlist_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations can_rcvlist_proc_fops = {
index 69bc4bf89e3e79bb47eddcac63367913a8645ef0..4543b9aba40ce1a9e4565824624bcecba6c298cb 100644 (file)
@@ -654,6 +654,24 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
        return 0;
 }
 
+static int __decode_pgid(void **p, void *end, struct ceph_pg *pg)
+{
+       u8 v;
+
+       ceph_decode_need(p, end, 1+8+4+4, bad);
+       v = ceph_decode_8(p);
+       if (v != 1)
+               goto bad;
+       pg->pool = ceph_decode_64(p);
+       pg->seed = ceph_decode_32(p);
+       *p += 4; /* skip preferred */
+       return 0;
+
+bad:
+       dout("error decoding pgid\n");
+       return -EINVAL;
+}
+
 /*
  * decode a full map.
  */
@@ -745,13 +763,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
        for (i = 0; i < len; i++) {
                int n, j;
                struct ceph_pg pgid;
-               struct ceph_pg_v1 pgid_v1;
                struct ceph_pg_mapping *pg;
 
-               ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
-               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
-               pgid.pool = le32_to_cpu(pgid_v1.pool);
-               pgid.seed = le16_to_cpu(pgid_v1.ps);
+               err = __decode_pgid(p, end, &pgid);
+               if (err)
+                       goto bad;
+               ceph_decode_need(p, end, sizeof(u32), bad);
                n = ceph_decode_32(p);
                err = -EINVAL;
                if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
@@ -818,8 +835,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        u16 version;
 
        ceph_decode_16_safe(p, end, version, bad);
-       if (version > 6) {
-               pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
+       if (version != 6) {
+               pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
                goto bad;
        }
 
@@ -963,15 +980,14 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        while (len--) {
                struct ceph_pg_mapping *pg;
                int j;
-               struct ceph_pg_v1 pgid_v1;
                struct ceph_pg pgid;
                u32 pglen;
-               ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
-               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
-               pgid.pool = le32_to_cpu(pgid_v1.pool);
-               pgid.seed = le16_to_cpu(pgid_v1.ps);
-               pglen = ceph_decode_32(p);
 
+               err = __decode_pgid(p, end, &pgid);
+               if (err)
+                       goto bad;
+               ceph_decode_need(p, end, sizeof(u32), bad);
+               pglen = ceph_decode_32(p);
                if (pglen) {
                        ceph_decode_need(p, end, pglen*sizeof(u32), bad);
 
index a06a7a58dd1181b4134adf7cd95d4b1b5512cda3..b13e5c766c11359507a61bb9689c9841d660951a 100644 (file)
@@ -1545,7 +1545,6 @@ void net_enable_timestamp(void)
                return;
        }
 #endif
-       WARN_ON(in_interrupt());
        static_key_slow_inc(&netstamp_needed);
 }
 EXPORT_SYMBOL(net_enable_timestamp);
@@ -2219,9 +2218,9 @@ struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
        struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
        struct packet_offload *ptype;
        __be16 type = skb->protocol;
+       int vlan_depth = ETH_HLEN;
 
        while (type == htons(ETH_P_8021Q)) {
-               int vlan_depth = ETH_HLEN;
                struct vlan_hdr *vh;
 
                if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
@@ -3444,6 +3443,7 @@ ncls:
                }
                switch (rx_handler(&skb)) {
                case RX_HANDLER_CONSUMED:
+                       ret = NET_RX_SUCCESS;
                        goto unlock;
                case RX_HANDLER_ANOTHER:
                        goto another_round;
@@ -4103,7 +4103,7 @@ static void net_rx_action(struct softirq_action *h)
                 * Allow this to run for 2 jiffies since which will allow
                 * an average latency of 1.5/HZ.
                 */
-               if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))
+               if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit)))
                        goto softnet_break;
 
                local_irq_enable();
@@ -4780,7 +4780,7 @@ EXPORT_SYMBOL(dev_set_mac_address);
 /**
  *     dev_change_carrier - Change device carrier
  *     @dev: device
- *     @new_carries: new value
+ *     @new_carrier: new value
  *
  *     Change device carrier
  */
index 9d4c7201400d154ab2fd00ccfab4f22f8bddb5ff..e187bf06d673b0ec37d401a8389bba372a8fb3d9 100644 (file)
@@ -140,6 +140,8 @@ ipv6:
                        flow->ports = *ports;
        }
 
+       flow->thoff = (u16) nhoff;
+
        return true;
 }
 EXPORT_SYMBOL(skb_flow_dissect);
index 3863b8f639c50827dfdf4a0c6c26bd6284f39f58..537301a2c31fa1c1045c57ddef7e4dcf76eaa96f 100644 (file)
@@ -2714,7 +2714,7 @@ static int neigh_stat_seq_open(struct inode *inode, struct file *file)
 
        if (!ret) {
                struct seq_file *sf = file->private_data;
-               sf->private = PDE(inode)->data;
+               sf->private = PDE_DATA(inode);
        }
        return ret;
 };
index 80e271d9e64b36425d14eed4fdebed570f7a98f5..f976520367542a5fdfc9e609e16a5a696dd767ad 100644 (file)
@@ -10,7 +10,8 @@
 #include <linux/idr.h>
 #include <linux/rculist.h>
 #include <linux/nsproxy.h>
-#include <linux/proc_fs.h>
+#include <linux/fs.h>
+#include <linux/proc_ns.h>
 #include <linux/file.h>
 #include <linux/export.h>
 #include <linux/user_namespace.h>
@@ -336,7 +337,7 @@ EXPORT_SYMBOL_GPL(__put_net);
 
 struct net *get_net_ns_by_fd(int fd)
 {
-       struct proc_inode *ei;
+       struct proc_ns *ei;
        struct file *file;
        struct net *net;
 
@@ -344,7 +345,7 @@ struct net *get_net_ns_by_fd(int fd)
        if (IS_ERR(file))
                return ERR_CAST(file);
 
-       ei = PROC_I(file_inode(file));
+       ei = get_proc_ns(file_inode(file));
        if (ei->ns_ops == &netns_operations)
                net = get_net(ei->ns);
        else
index 6048fc1da1c2b3bd6e776e90e9437b4f65f89fcd..6c41e979dc884b7b34d79d03f2cb396669680773 100644 (file)
@@ -508,7 +508,7 @@ out:
 
 static int pgctrl_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pgctrl_show, PDE(inode)->data);
+       return single_open(file, pgctrl_show, PDE_DATA(inode));
 }
 
 static const struct file_operations pktgen_fops = {
@@ -1685,7 +1685,7 @@ static ssize_t pktgen_if_write(struct file *file,
 
 static int pktgen_if_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pktgen_if_show, PDE(inode)->data);
+       return single_open(file, pktgen_if_show, PDE_DATA(inode));
 }
 
 static const struct file_operations pktgen_if_fops = {
@@ -1823,7 +1823,7 @@ out:
 
 static int pktgen_thread_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, pktgen_thread_show, PDE(inode)->data);
+       return single_open(file, pktgen_thread_show, PDE_DATA(inode));
 }
 
 static const struct file_operations pktgen_thread_fops = {
@@ -1904,7 +1904,7 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *d
                        if (pkt_dev->odev != dev)
                                continue;
 
-                       remove_proc_entry(pkt_dev->entry->name, pn->proc_dir);
+                       proc_remove(pkt_dev->entry);
 
                        pkt_dev->entry = proc_create_data(dev->name, 0600,
                                                          pn->proc_dir,
@@ -3576,8 +3576,6 @@ static void _rem_dev_from_if_list(struct pktgen_thread *t,
 static int pktgen_remove_device(struct pktgen_thread *t,
                                struct pktgen_dev *pkt_dev)
 {
-       struct pktgen_net *pn = t->net;
-
        pr_debug("remove_device pkt_dev=%p\n", pkt_dev);
 
        if (pkt_dev->running) {
@@ -3597,7 +3595,7 @@ static int pktgen_remove_device(struct pktgen_thread *t,
        _rem_dev_from_if_list(t, pkt_dev);
 
        if (pkt_dev->entry)
-               remove_proc_entry(pkt_dev->entry->name, pn->proc_dir);
+               proc_remove(pkt_dev->entry);
 
 #ifdef CONFIG_XFRM
        free_SAs(pkt_dev);
index b376410ff2590f3e10897488fd6c092df70faa4c..5fb8d7e472941fede3595a3a4032cfc21fbe849b 100644 (file)
@@ -979,6 +979,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                         * report anything.
                         */
                        ivi.spoofchk = -1;
+                       memset(ivi.mac, 0, sizeof(ivi.mac));
                        if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
                                break;
                        vf_mac.vf =
@@ -2620,7 +2621,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);
 
                while (RTA_OK(attr, attrlen)) {
-                       unsigned int flavor = attr->rta_type;
+                       unsigned int flavor = attr->rta_type & NLA_TYPE_MASK;
                        if (flavor) {
                                if (flavor > rta_max[sz_idx])
                                        return -EINVAL;
index 1b588e23cf80b561632b9b5e16b851dff218a933..21291f1abcd6d0d228241b6771984d704bc1699e 100644 (file)
@@ -284,6 +284,7 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh,
        if (!netdev->dcbnl_ops->getpermhwaddr)
                return -EOPNOTSUPP;
 
+       memset(perm_addr, 0, sizeof(perm_addr));
        netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);
 
        return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr);
@@ -1042,6 +1043,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_getets) {
                struct ieee_ets ets;
+               memset(&ets, 0, sizeof(ets));
                err = ops->ieee_getets(netdev, &ets);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets))
@@ -1050,6 +1052,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_getmaxrate) {
                struct ieee_maxrate maxrate;
+               memset(&maxrate, 0, sizeof(maxrate));
                err = ops->ieee_getmaxrate(netdev, &maxrate);
                if (!err) {
                        err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE,
@@ -1061,6 +1064,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_getpfc) {
                struct ieee_pfc pfc;
+               memset(&pfc, 0, sizeof(pfc));
                err = ops->ieee_getpfc(netdev, &pfc);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc))
@@ -1094,6 +1098,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
        /* get peer info if available */
        if (ops->ieee_peer_getets) {
                struct ieee_ets ets;
+               memset(&ets, 0, sizeof(ets));
                err = ops->ieee_peer_getets(netdev, &ets);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets))
@@ -1102,6 +1107,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_peer_getpfc) {
                struct ieee_pfc pfc;
+               memset(&pfc, 0, sizeof(pfc));
                err = ops->ieee_peer_getpfc(netdev, &pfc);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc))
@@ -1280,6 +1286,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
        /* peer info if available */
        if (ops->cee_peer_getpg) {
                struct cee_pg pg;
+               memset(&pg, 0, sizeof(pg));
                err = ops->cee_peer_getpg(netdev, &pg);
                if (!err &&
                    nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg))
@@ -1288,6 +1295,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->cee_peer_getpfc) {
                struct cee_pfc pfc;
+               memset(&pfc, 0, sizeof(pfc));
                err = ops->cee_peer_getpfc(netdev, &pfc);
                if (!err &&
                    nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc))
index 8c2251fb0a3fb5ba9347710e4682bdb273d49af9..bba5f8336317a178c5c7c073acd3bbfafde0e6b9 100644 (file)
@@ -84,7 +84,7 @@
        (memcmp(addr1, addr2, length >> 3) == 0)
 
 /* local link, i.e. FE80::/10 */
-#define is_addr_link_local(a) (((a)->s6_addr16[0]) == 0x80FE)
+#define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80))
 
 /*
  * check whether we can compress the IID to 16 bits,
index 68f6a94f7661999095d9a02539aee956cd52e8cc..c929d9c1c4b60d719d60066f7ca06e4b7d296f59 100644 (file)
@@ -1333,8 +1333,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
                                iph->frag_off |= htons(IP_MF);
                        offset += (skb->len - skb->mac_len - iph->ihl * 4);
                } else  {
-                       if (!(iph->frag_off & htons(IP_DF)))
-                               iph->id = htons(id++);
+                       iph->id = htons(id++);
                }
                iph->tot_len = htons(skb->len - skb->mac_len);
                iph->check = 0;
index 7d1874be1df36282ca6c4d0ef3001d05686f335f..786d97aee751e2f2206b9e3b66398bc0995cc645 100644 (file)
@@ -735,6 +735,7 @@ EXPORT_SYMBOL(inet_csk_destroy_sock);
  * tcp/dccp_create_openreq_child().
  */
 void inet_csk_prepare_forced_close(struct sock *sk)
+       __releases(&sk->sk_lock.slock)
 {
        /* sk_clone_lock locked the socket and set refcnt to 2 */
        bh_unlock_sock(sk);
index 245ae078a07fa3d991d6bba6147aab7970f36c9a..f4fd23de9b13103b10351310aea08c47d0429d38 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/slab.h>
 
+#include <net/sock.h>
 #include <net/inet_frag.h>
 
 static void inet_frag_secret_rebuild(unsigned long dummy)
@@ -277,6 +278,7 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
        __releases(&f->lock)
 {
        struct inet_frag_queue *q;
+       int depth = 0;
 
        hlist_for_each_entry(q, &f->hash[hash], list) {
                if (q->net == nf && f->match(q, key)) {
@@ -284,9 +286,25 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
                        read_unlock(&f->lock);
                        return q;
                }
+               depth++;
        }
        read_unlock(&f->lock);
 
-       return inet_frag_create(nf, f, key);
+       if (depth <= INETFRAGS_MAXDEPTH)
+               return inet_frag_create(nf, f, key);
+       else
+               return ERR_PTR(-ENOBUFS);
 }
 EXPORT_SYMBOL(inet_frag_find);
+
+void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
+                                  const char *prefix)
+{
+       static const char msg[] = "inet_frag_find: Fragment hash bucket"
+               " list length grew over limit " __stringify(INETFRAGS_MAXDEPTH)
+               ". Dropping fragment.\n";
+
+       if (PTR_ERR(q) == -ENOBUFS)
+               LIMIT_NETDEBUG(KERN_WARNING "%s%s", prefix, msg);
+}
+EXPORT_SYMBOL(inet_frag_maybe_warn_overflow);
index b6d30acb600c5e306ba825ed394c252e4fe27a8b..a6445b843ef40774f2bf5014e6800e1f4fd86b3e 100644 (file)
@@ -292,14 +292,11 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
        hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
 
        q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
-       if (q == NULL)
-               goto out_nomem;
-
+       if (IS_ERR_OR_NULL(q)) {
+               inet_frag_maybe_warn_overflow(q, pr_fmt());
+               return NULL;
+       }
        return container_of(q, struct ipq, q);
-
-out_nomem:
-       LIMIT_NETDEBUG(KERN_ERR pr_fmt("ip_frag_create: no memory left !\n"));
-       return NULL;
 }
 
 /* Is the fragment too far ahead to be part of ipq? */
index d0ef0e674ec5c083ad719bcd2b8201c82c1116d5..91d66dbde9c05cd05c4e8489a4abd317b378230e 100644 (file)
@@ -798,10 +798,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
 
        if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
                gre_hlen = 0;
-               if (skb->protocol == htons(ETH_P_IP))
-                       tiph = (const struct iphdr *)skb->data;
-               else
-                       tiph = &tunnel->parms.iph;
+               tiph = (const struct iphdr *)skb->data;
        } else {
                gre_hlen = tunnel->hlen;
                tiph = &tunnel->parms.iph;
index 87abd3e2bd329d7ee3630cbc3ed4770d35e6370e..2bdf802e28e270c4717c06bc64469eab073f068d 100644 (file)
@@ -228,9 +228,11 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
                                        icmp_send(skb, ICMP_DEST_UNREACH,
                                                  ICMP_PROT_UNREACH, 0);
                                }
-                       } else
+                               kfree_skb(skb);
+                       } else {
                                IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS);
-                       kfree_skb(skb);
+                               consume_skb(skb);
+                       }
                }
        }
  out:
index f6289bf6f3325edc2c78541eca88e546e5ec97c9..ec7264514a82e0a130bf15ee01a9030596880921 100644 (file)
@@ -370,7 +370,6 @@ int ip_options_compile(struct net *net,
                                }
                                switch (optptr[3]&0xF) {
                                      case IPOPT_TS_TSONLY:
-                                       opt->ts = optptr - iph;
                                        if (skb)
                                                timeptr = &optptr[optptr[2]-1];
                                        opt->ts_needtime = 1;
@@ -381,7 +380,6 @@ int ip_options_compile(struct net *net,
                                                pp_ptr = optptr + 2;
                                                goto error;
                                        }
-                                       opt->ts = optptr - iph;
                                        if (rt)  {
                                                spec_dst_fill(&spec_dst, skb);
                                                memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
@@ -396,7 +394,6 @@ int ip_options_compile(struct net *net,
                                                pp_ptr = optptr + 2;
                                                goto error;
                                        }
-                                       opt->ts = optptr - iph;
                                        {
                                                __be32 addr;
                                                memcpy(&addr, &optptr[optptr[2]-1], 4);
@@ -423,18 +420,18 @@ int ip_options_compile(struct net *net,
                                        put_unaligned_be32(midtime, timeptr);
                                        opt->is_changed = 1;
                                }
-                       } else {
+                       } else if ((optptr[3]&0xF) != IPOPT_TS_PRESPEC) {
                                unsigned int overflow = optptr[3]>>4;
                                if (overflow == 15) {
                                        pp_ptr = optptr + 3;
                                        goto error;
                                }
-                               opt->ts = optptr - iph;
                                if (skb) {
                                        optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4);
                                        opt->is_changed = 1;
                                }
                        }
+                       opt->ts = optptr - iph;
                        break;
                      case IPOPT_RA:
                        if (optlen < 4) {
index 98cbc6877019428f7d3400632c1e81e50145a814..bf6c5cf31aed27ccba4aa25c4d049f0cc037e3cb 100644 (file)
@@ -1522,7 +1522,8 @@ static int __init ip_auto_config(void)
                }
        for (i++; i < CONF_NAMESERVERS_MAX; i++)
                if (ic_nameservers[i] != NONE)
-                       pr_cont(", nameserver%u=%pI4\n", i, &ic_nameservers[i]);
+                       pr_cont(", nameserver%u=%pI4", i, &ic_nameservers[i]);
+       pr_cont("\n");
 #endif /* !SILENT */
 
        return 0;
index ce2d43e1f09f6b4983e6635e6c2b48ca56fcf18b..0d755c50994b2ca01438158e033c020810a3e8af 100644 (file)
@@ -36,19 +36,6 @@ config NF_CONNTRACK_PROC_COMPAT
 
          If unsure, say Y.
 
-config IP_NF_QUEUE
-       tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
-       depends on NETFILTER_ADVANCED
-       help
-         Netfilter has the ability to queue packets to user space: the
-         netlink device can be used to access them using this driver.
-
-         This option enables the old IPv4-only "ip_queue" implementation
-         which has been obsoleted by the new "nfnetlink_queue" code (see
-         CONFIG_NETFILTER_NETLINK_QUEUE).
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_IPTABLES
        tristate "IP tables support (required for filtering/masq/NAT)"
        default m if NETFILTER_ADVANCED=n
index 5852b249054f28bbc78e30ec3bde2748919a7480..0b732efd32e20aa8e22e6c9bd5aa4edfb7e5516d 100644 (file)
@@ -105,7 +105,7 @@ clusterip_config_entry_put(struct clusterip_config *c)
                 * functions are also incrementing the refcount on their own,
                 * so it's safe to remove the entry even if it's in use. */
 #ifdef CONFIG_PROC_FS
-               remove_proc_entry(c->pde->name, c->pde->parent);
+               proc_remove(c->pde);
 #endif
                return;
        }
@@ -631,7 +631,7 @@ static int clusterip_proc_open(struct inode *inode, struct file *file)
 
        if (!ret) {
                struct seq_file *sf = file->private_data;
-               struct clusterip_config *c = PDE(inode)->data;
+               struct clusterip_config *c = PDE_DATA(inode);
 
                sf->private = c;
 
@@ -643,7 +643,7 @@ static int clusterip_proc_open(struct inode *inode, struct file *file)
 
 static int clusterip_proc_release(struct inode *inode, struct file *file)
 {
-       struct clusterip_config *c = PDE(inode)->data;
+       struct clusterip_config *c = PDE_DATA(inode);
        int ret;
 
        ret = seq_release(inode, file);
@@ -657,7 +657,7 @@ static int clusterip_proc_release(struct inode *inode, struct file *file)
 static ssize_t clusterip_proc_write(struct file *file, const char __user *input,
                                size_t size, loff_t *ofs)
 {
-       struct clusterip_config *c = PDE(file_inode(file))->data;
+       struct clusterip_config *c = PDE_DATA(file_inode(file));
 #define PROC_WRITELEN  10
        char buffer[PROC_WRITELEN+1];
        unsigned long nodenum;
@@ -736,7 +736,7 @@ static void __exit clusterip_tg_exit(void)
 {
        pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION);
 #ifdef CONFIG_PROC_FS
-       remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent);
+       proc_remove(clusterip_procdir);
 #endif
        nf_unregister_hook(&cip_arp_ops);
        xt_unregister_target(&clusterip_tg_reg);
index 47e854fcae24dd8c108e93a2b5a22801a68d7232..e22020790709dbde58759c771f47a69e883892e4 100644 (file)
@@ -775,7 +775,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
                         * Make sure that we have exactly size bytes
                         * available to the caller, no more, no less.
                         */
-                       skb->avail_size = size;
+                       skb->reserved_tailroom = skb->end - skb->tail - size;
                        return skb;
                }
                __kfree_skb(skb);
index a759e19496d2f57f508db27f21ab73b2b320523a..3bd55bad230ac7f822f4ea75eb280bc8ce0c07fc 100644 (file)
@@ -2059,11 +2059,8 @@ void tcp_enter_loss(struct sock *sk, int how)
        if (tcp_is_reno(tp))
                tcp_reset_reno_sack(tp);
 
-       if (!how) {
-               /* Push undo marker, if it was plain RTO and nothing
-                * was retransmitted. */
-               tp->undo_marker = tp->snd_una;
-       } else {
+       tp->undo_marker = tp->snd_una;
+       if (how) {
                tp->sacked_out = 0;
                tp->fackets_out = 0;
        }
@@ -5485,6 +5482,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                if (tcp_checksum_complete_user(sk, skb))
                                        goto csum_error;
 
+                               if ((int)skb->truesize > sk->sk_forward_alloc)
+                                       goto step5;
+
                                /* Predicted packet is in window by definition.
                                 * seq == rcv_nxt and rcv_wup <= rcv_nxt.
                                 * Hence, check seq<=rcv_wup reduces to:
@@ -5496,9 +5496,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 
                                tcp_rcv_rtt_measure_ts(sk, skb);
 
-                               if ((int)skb->truesize > sk->sk_forward_alloc)
-                                       goto step5;
-
                                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITS);
 
                                /* Bulk data transfer: receiver */
index 4a8ec457310fbd57e6b62e0a0f8ae6c22f2463fa..fc55a1c79bd9a5a21288af2584fc78542325a105 100644 (file)
@@ -274,13 +274,6 @@ static void tcp_v4_mtu_reduced(struct sock *sk)
        struct inet_sock *inet = inet_sk(sk);
        u32 mtu = tcp_sk(sk)->mtu_info;
 
-       /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
-        * send out by Linux are always <576bytes so they should go through
-        * unfragmented).
-        */
-       if (sk->sk_state == TCP_LISTEN)
-               return;
-
        dst = inet_csk_update_pmtu(sk, mtu);
        if (!dst)
                return;
@@ -408,6 +401,13 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
                        goto out;
 
                if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
+                       /* We are not interested in TCP_LISTEN and open_requests
+                        * (SYN-ACKs send out by Linux are always <576bytes so
+                        * they should go through unfragmented).
+                        */
+                       if (sk->sk_state == TCP_LISTEN)
+                               goto out;
+
                        tp->mtu_info = info;
                        if (!sock_owned_by_user(sk)) {
                                tcp_v4_mtu_reduced(sk);
@@ -2580,7 +2580,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v)
 
 int tcp_seq_open(struct inode *inode, struct file *file)
 {
-       struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
+       struct tcp_seq_afinfo *afinfo = PDE_DATA(inode);
        struct tcp_iter_state *s;
        int err;
 
index e2b4461074dab715af9c328fd1767f4a5caf8c97..5d0b4387cba6df401166a48f1e4cf3800d6ce6ff 100644 (file)
@@ -1298,7 +1298,6 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
        eat = min_t(int, len, skb_headlen(skb));
        if (eat) {
                __skb_pull(skb, eat);
-               skb->avail_size -= eat;
                len -= eat;
                if (!len)
                        return;
@@ -1810,8 +1809,11 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
                        goto send_now;
        }
 
-       /* Ok, it looks like it is advisable to defer.  */
-       tp->tso_deferred = 1 | (jiffies << 1);
+       /* Ok, it looks like it is advisable to defer.
+        * Do not rearm the timer if already set to not break TCP ACK clocking.
+        */
+       if (!tp->tso_deferred)
+               tp->tso_deferred = 1 | (jiffies << 1);
 
        return true;
 
index 265c42cf963c30cce55016bbf4ef0a13f57e6ec5..d27264318315371d64bf6f1732d20ceb0ec1c06e 100644 (file)
@@ -1762,9 +1762,16 @@ int udp_rcv(struct sk_buff *skb)
 
 void udp_destroy_sock(struct sock *sk)
 {
+       struct udp_sock *up = udp_sk(sk);
        bool slow = lock_sock_fast(sk);
        udp_flush_pending_frames(sk);
        unlock_sock_fast(sk, slow);
+       if (static_key_false(&udp_encap_needed) && up->encap_type) {
+               void (*encap_destroy)(struct sock *sk);
+               encap_destroy = ACCESS_ONCE(up->encap_destroy);
+               if (encap_destroy)
+                       encap_destroy(sk);
+       }
 }
 
 /*
@@ -2086,7 +2093,7 @@ static void udp_seq_stop(struct seq_file *seq, void *v)
 
 int udp_seq_open(struct inode *inode, struct file *file)
 {
-       struct udp_seq_afinfo *afinfo = PDE(inode)->data;
+       struct udp_seq_afinfo *afinfo = PDE_DATA(inode);
        struct udp_iter_state *s;
        int err;
 
index f2c7e615f902d861d99529536ecebff35fbd7fd5..26512250e095557e50fbee26cc5dcd65d12cc675 100644 (file)
@@ -4784,26 +4784,20 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
 
 static int __net_init addrconf_init_net(struct net *net)
 {
-       int err;
+       int err = -ENOMEM;
        struct ipv6_devconf *all, *dflt;
 
-       err = -ENOMEM;
-       all = &ipv6_devconf;
-       dflt = &ipv6_devconf_dflt;
+       all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
+       if (all == NULL)
+               goto err_alloc_all;
 
-       if (!net_eq(net, &init_net)) {
-               all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
-               if (all == NULL)
-                       goto err_alloc_all;
+       dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
+       if (dflt == NULL)
+               goto err_alloc_dflt;
 
-               dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
-               if (dflt == NULL)
-                       goto err_alloc_dflt;
-       } else {
-               /* these will be inherited by all namespaces */
-               dflt->autoconf = ipv6_defaults.autoconf;
-               dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
-       }
+       /* these will be inherited by all namespaces */
+       dflt->autoconf = ipv6_defaults.autoconf;
+       dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
 
        net->ipv6.devconf_all = all;
        net->ipv6.devconf_dflt = dflt;
index 5b10414e619e5020fa4285a1e20790bdf5a8e845..e33fe0ab2568ec5a750e846457ff52a6a3395c86 100644 (file)
@@ -241,9 +241,11 @@ resubmit:
                                icmpv6_send(skb, ICMPV6_PARAMPROB,
                                            ICMPV6_UNK_NEXTHDR, nhoff);
                        }
-               } else
+                       kfree_skb(skb);
+               } else {
                        IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
-               kfree_skb(skb);
+                       consume_skb(skb);
+               }
        }
        rcu_read_unlock();
        return 0;
@@ -279,7 +281,8 @@ int ip6_mc_input(struct sk_buff *skb)
         *      IPv6 multicast router mode is now supported ;)
         */
        if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
-           !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) &&
+           !(ipv6_addr_type(&hdr->daddr) &
+             (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
            likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
                /*
                 * Okay, we try to forward - split and duplicate
index 83acc1405a18dcef218625e8517431978393ac12..33608c610276d87e9845b75555fadc6771765606 100644 (file)
@@ -114,6 +114,7 @@ ip6t_dnpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
 static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
        {
                .name           = "SNPT",
+               .table          = "mangle",
                .target         = ip6t_snpt_tg,
                .targetsize     = sizeof(struct ip6t_npt_tginfo),
                .checkentry     = ip6t_npt_checkentry,
@@ -124,6 +125,7 @@ static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
        },
        {
                .name           = "DNPT",
+               .table          = "mangle",
                .target         = ip6t_dnpt_tg,
                .targetsize     = sizeof(struct ip6t_npt_tginfo),
                .checkentry     = ip6t_npt_checkentry,
index 54087e96d7b8c5b45b52ce1f26fdd54a134506d2..6700069949ddc81b13f7f0c2bc2622258b6fb2a4 100644 (file)
@@ -14,6 +14,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt) "IPv6-nf: " fmt
+
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -180,13 +182,11 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
 
        q = inet_frag_find(&net->nf_frag.frags, &nf_frags, &arg, hash);
        local_bh_enable();
-       if (q == NULL)
-               goto oom;
-
+       if (IS_ERR_OR_NULL(q)) {
+               inet_frag_maybe_warn_overflow(q, pr_fmt());
+               return NULL;
+       }
        return container_of(q, struct frag_queue, q);
-
-oom:
-       return NULL;
 }
 
 
index bbbe53a99b57fa920bcb36a9c16f42457a4fce14..537d9ee7209f91254d6b75446b8495a9679d1bf1 100644 (file)
@@ -247,7 +247,7 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
 
 static int snmp6_dev_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, snmp6_dev_seq_show, PDE(inode)->data);
+       return single_open(file, snmp6_dev_seq_show, PDE_DATA(inode));
 }
 
 static const struct file_operations snmp6_dev_seq_fops = {
@@ -287,8 +287,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
                return -ENOENT;
        if (!idev->stats.proc_dir_entry)
                return -EINVAL;
-       remove_proc_entry(idev->stats.proc_dir_entry->name,
-                         net->mib.proc_net_devsnmp6);
+       proc_remove(idev->stats.proc_dir_entry);
        idev->stats.proc_dir_entry = NULL;
        return 0;
 }
index 3c6a77290c6e87573cb07d081d878d5c03f9760c..196ab9347ad1df2bab5a9c98720a51e81773985c 100644 (file)
@@ -26,6 +26,9 @@
  *     YOSHIFUJI,H. @USAGI     Always remove fragment header to
  *                             calculate ICV correctly.
  */
+
+#define pr_fmt(fmt) "IPv6: " fmt
+
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -185,9 +188,10 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6
        hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
 
        q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
-       if (q == NULL)
+       if (IS_ERR_OR_NULL(q)) {
+               inet_frag_maybe_warn_overflow(q, pr_fmt());
                return NULL;
-
+       }
        return container_of(q, struct frag_queue, q);
 }
 
index 928266569689e7624cde4206f657df495a0bdd43..e5fe0041adfa389388060bffae7055db3508c407 100644 (file)
@@ -1915,7 +1915,8 @@ void rt6_purge_dflt_routers(struct net *net)
 restart:
        read_lock_bh(&table->tb6_lock);
        for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
-               if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
+               if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
+                   (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
                        dst_hold(&rt->dst);
                        read_unlock_bh(&table->tb6_lock);
                        ip6_del_rt(rt);
index 9b6460055df5683d70dea9d3f09d24c325ee89e7..f6d629fd6aee152aaff674a03db7a3dd0f194134 100644 (file)
@@ -389,6 +389,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        }
 
        if (type == ICMPV6_PKT_TOOBIG) {
+               /* We are not interested in TCP_LISTEN and open_requests
+                * (SYN-ACKs send out by Linux are always <576bytes so
+                * they should go through unfragmented).
+                */
+               if (sk->sk_state == TCP_LISTEN)
+                       goto out;
+
                tp->mtu_info = ntohl(info);
                if (!sock_owned_by_user(sk))
                        tcp_v6_mtu_reduced(sk);
index 599e1ba6d1ceaa6766d53eda020a69a0aa234e5b..d8e5e852fc7a08b26879c81a4ecaad0be2cf2f90 100644 (file)
@@ -1285,10 +1285,18 @@ do_confirm:
 
 void udpv6_destroy_sock(struct sock *sk)
 {
+       struct udp_sock *up = udp_sk(sk);
        lock_sock(sk);
        udp_v6_flush_pending_frames(sk);
        release_sock(sk);
 
+       if (static_key_false(&udpv6_encap_needed) && up->encap_type) {
+               void (*encap_destroy)(struct sock *sk);
+               encap_destroy = ACCESS_ONCE(up->encap_destroy);
+               if (encap_destroy)
+                       encap_destroy(sk);
+       }
+
        inet6_destroy_sock(sk);
 }
 
index d07e3a626446b3cab44e68b019f7870619699f75..d28e7f014cc639779a4557203b4b2ba2f7e63927 100644 (file)
@@ -2583,8 +2583,10 @@ bed:
                                    NULL, NULL, NULL);
 
                /* Check if the we got some results */
-               if (!self->cachedaddr)
-                       return -EAGAIN;         /* Didn't find any devices */
+               if (!self->cachedaddr) {
+                       err = -EAGAIN;          /* Didn't find any devices */
+                       goto out;
+               }
                daddr = self->cachedaddr;
                /* Cleanup */
                self->cachedaddr = 0;
index 9a5fd3c3e530c5dc82c04ccf04abf0f93b0f3a28..362ba47968e41de822122f9c215e012ba566cd59 100644 (file)
@@ -280,7 +280,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        struct tty_port *port = &self->port;
        DECLARE_WAITQUEUE(wait, current);
        int             retval;
-       int             do_clocal = 0, extra_count = 0;
+       int             do_clocal = 0;
        unsigned long   flags;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
@@ -289,8 +289,15 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
         * If non-blocking mode is set, or the port is not enabled,
         * then make the check up front and then exit.
         */
-       if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
-               /* nonblock mode is set or port is not enabled */
+       if (test_bit(TTY_IO_ERROR, &tty->flags)) {
+               port->flags |= ASYNC_NORMAL_ACTIVE;
+               return 0;
+       }
+
+       if (filp->f_flags & O_NONBLOCK) {
+               /* nonblock mode is set */
+               if (tty->termios.c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
                port->flags |= ASYNC_NORMAL_ACTIVE;
                IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
                return 0;
@@ -315,18 +322,16 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
              __FILE__, __LINE__, tty->driver->name, port->count);
 
        spin_lock_irqsave(&port->lock, flags);
-       if (!tty_hung_up_p(filp)) {
-               extra_count = 1;
+       if (!tty_hung_up_p(filp))
                port->count--;
-       }
-       spin_unlock_irqrestore(&port->lock, flags);
        port->blocked_open++;
+       spin_unlock_irqrestore(&port->lock, flags);
 
        while (1) {
                if (tty->termios.c_cflag & CBAUD)
                        tty_port_raise_dtr_rts(port);
 
-               current->state = TASK_INTERRUPTIBLE;
+               set_current_state(TASK_INTERRUPTIBLE);
 
                if (tty_hung_up_p(filp) ||
                    !test_bit(ASYNCB_INITIALIZED, &port->flags)) {
@@ -361,13 +366,11 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        __set_current_state(TASK_RUNNING);
        remove_wait_queue(&port->open_wait, &wait);
 
-       if (extra_count) {
-               /* ++ is not atomic, so this should be protected - Jean II */
-               spin_lock_irqsave(&port->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
+       if (!tty_hung_up_p(filp))
                port->count++;
-               spin_unlock_irqrestore(&port->lock, flags);
-       }
        port->blocked_open--;
+       spin_unlock_irqrestore(&port->lock, flags);
 
        IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
              __FILE__, __LINE__, tty->driver->name, port->count);
index e71e85ba2bf1c180b2038d62021283ddf7982b07..29340a9a6fb9937f9bc848ffda5c49c51cca47ee 100644 (file)
@@ -495,8 +495,11 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
 /*             case CS_ISO_8859_9: */
 /*             case CS_UNICODE: */
                default:
-                       IRDA_DEBUG(0, "%s(), charset %s, not supported\n",
-                                  __func__, ias_charset_types[charset]);
+                       IRDA_DEBUG(0, "%s(), charset [%d] %s, not supported\n",
+                                  __func__, charset,
+                                  charset < ARRAY_SIZE(ias_charset_types) ?
+                                       ias_charset_types[charset] :
+                                       "(unknown)");
 
                        /* Aborting, close connection! */
                        iriap_disconnect_request(self);
index 556fdafdd1ea3fb6d85b44c2e3efeb600b1839b8..8555f331ea60d4bca67cbe91390ed077f62a091e 100644 (file)
@@ -2201,7 +2201,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
                      XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW);
        xp->priority = pol->sadb_x_policy_priority;
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
        xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr);
        if (!xp->family) {
                err = -EINVAL;
@@ -2214,7 +2214,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
        if (xp->selector.sport)
                xp->selector.sport_mask = htons(0xffff);
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
        pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr);
        xp->selector.prefixlen_d = sa->sadb_address_prefixlen;
 
@@ -2315,7 +2315,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
 
        memset(&sel, 0, sizeof(sel));
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
        sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr);
        sel.prefixlen_s = sa->sadb_address_prefixlen;
        sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
@@ -2323,7 +2323,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
        if (sel.sport)
                sel.sport_mask = htons(0xffff);
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
        pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
        sel.prefixlen_d = sa->sadb_address_prefixlen;
        sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
index d36875f3427e82b7795012bebe8281318f983d22..8aecf5df66569a6ca0ae1b8921e20954d6812336 100644 (file)
@@ -114,7 +114,6 @@ struct l2tp_net {
 
 static void l2tp_session_set_header_len(struct l2tp_session *session, int version);
 static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
-static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
 
 static inline struct l2tp_net *l2tp_pernet(struct net *net)
 {
@@ -192,6 +191,7 @@ struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel)
        } else {
                /* Socket is owned by kernelspace */
                sk = tunnel->sock;
+               sock_hold(sk);
        }
 
 out:
@@ -210,6 +210,7 @@ void l2tp_tunnel_sock_put(struct sock *sk)
                }
                sock_put(sk);
        }
+       sock_put(sk);
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_put);
 
@@ -373,10 +374,8 @@ static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *sk
        struct sk_buff *skbp;
        struct sk_buff *tmp;
        u32 ns = L2TP_SKB_CB(skb)->ns;
-       struct l2tp_stats *sstats;
 
        spin_lock_bh(&session->reorder_q.lock);
-       sstats = &session->stats;
        skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
                if (L2TP_SKB_CB(skbp)->ns > ns) {
                        __skb_queue_before(&session->reorder_q, skbp, skb);
@@ -384,9 +383,7 @@ static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *sk
                                 "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
                                 session->name, ns, L2TP_SKB_CB(skbp)->ns,
                                 skb_queue_len(&session->reorder_q));
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_oos_packets++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_oos_packets);
                        goto out;
                }
        }
@@ -403,23 +400,16 @@ static void l2tp_recv_dequeue_skb(struct l2tp_session *session, struct sk_buff *
 {
        struct l2tp_tunnel *tunnel = session->tunnel;
        int length = L2TP_SKB_CB(skb)->length;
-       struct l2tp_stats *tstats, *sstats;
 
        /* We're about to requeue the skb, so return resources
         * to its current owner (a socket receive buffer).
         */
        skb_orphan(skb);
 
-       tstats = &tunnel->stats;
-       u64_stats_update_begin(&tstats->syncp);
-       sstats = &session->stats;
-       u64_stats_update_begin(&sstats->syncp);
-       tstats->rx_packets++;
-       tstats->rx_bytes += length;
-       sstats->rx_packets++;
-       sstats->rx_bytes += length;
-       u64_stats_update_end(&tstats->syncp);
-       u64_stats_update_end(&sstats->syncp);
+       atomic_long_inc(&tunnel->stats.rx_packets);
+       atomic_long_add(length, &tunnel->stats.rx_bytes);
+       atomic_long_inc(&session->stats.rx_packets);
+       atomic_long_add(length, &session->stats.rx_bytes);
 
        if (L2TP_SKB_CB(skb)->has_seq) {
                /* Bump our Nr */
@@ -450,7 +440,6 @@ static void l2tp_recv_dequeue(struct l2tp_session *session)
 {
        struct sk_buff *skb;
        struct sk_buff *tmp;
-       struct l2tp_stats *sstats;
 
        /* If the pkt at the head of the queue has the nr that we
         * expect to send up next, dequeue it and any other
@@ -458,13 +447,10 @@ static void l2tp_recv_dequeue(struct l2tp_session *session)
         */
 start:
        spin_lock_bh(&session->reorder_q.lock);
-       sstats = &session->stats;
        skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
                if (time_after(jiffies, L2TP_SKB_CB(skb)->expires)) {
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_seq_discards++;
-                       sstats->rx_errors++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
+                       atomic_long_inc(&session->stats.rx_errors);
                        l2tp_dbg(session, L2TP_MSG_SEQ,
                                 "%s: oos pkt %u len %d discarded (too old), waiting for %u, reorder_q_len=%d\n",
                                 session->name, L2TP_SKB_CB(skb)->ns,
@@ -623,7 +609,6 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
        struct l2tp_tunnel *tunnel = session->tunnel;
        int offset;
        u32 ns, nr;
-       struct l2tp_stats *sstats = &session->stats;
 
        /* The ref count is increased since we now hold a pointer to
         * the session. Take care to decrement the refcnt when exiting
@@ -640,9 +625,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                                  "%s: cookie mismatch (%u/%u). Discarding.\n",
                                  tunnel->name, tunnel->tunnel_id,
                                  session->session_id);
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_cookie_discards++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_cookie_discards);
                        goto discard;
                }
                ptr += session->peer_cookie_len;
@@ -711,9 +694,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                        l2tp_warn(session, L2TP_MSG_SEQ,
                                  "%s: recv data has no seq numbers when required. Discarding.\n",
                                  session->name);
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_seq_discards++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
                        goto discard;
                }
 
@@ -732,9 +713,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                        l2tp_warn(session, L2TP_MSG_SEQ,
                                  "%s: recv data has no seq numbers when required. Discarding.\n",
                                  session->name);
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_seq_discards++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
                        goto discard;
                }
        }
@@ -788,9 +767,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                         * packets
                         */
                        if (L2TP_SKB_CB(skb)->ns != session->nr) {
-                               u64_stats_update_begin(&sstats->syncp);
-                               sstats->rx_seq_discards++;
-                               u64_stats_update_end(&sstats->syncp);
+                               atomic_long_inc(&session->stats.rx_seq_discards);
                                l2tp_dbg(session, L2TP_MSG_SEQ,
                                         "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n",
                                         session->name, L2TP_SKB_CB(skb)->ns,
@@ -816,9 +793,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
        return;
 
 discard:
-       u64_stats_update_begin(&sstats->syncp);
-       sstats->rx_errors++;
-       u64_stats_update_end(&sstats->syncp);
+       atomic_long_inc(&session->stats.rx_errors);
        kfree_skb(skb);
 
        if (session->deref)
@@ -828,6 +803,23 @@ discard:
 }
 EXPORT_SYMBOL(l2tp_recv_common);
 
+/* Drop skbs from the session's reorder_q
+ */
+int l2tp_session_queue_purge(struct l2tp_session *session)
+{
+       struct sk_buff *skb = NULL;
+       BUG_ON(!session);
+       BUG_ON(session->magic != L2TP_SESSION_MAGIC);
+       while ((skb = skb_dequeue(&session->reorder_q))) {
+               atomic_long_inc(&session->stats.rx_errors);
+               kfree_skb(skb);
+               if (session->deref)
+                       (*session->deref)(session);
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(l2tp_session_queue_purge);
+
 /* Internal UDP receive frame. Do the real work of receiving an L2TP data frame
  * here. The skb is not on a list when we get here.
  * Returns 0 if the packet was a data packet and was successfully passed on.
@@ -843,7 +835,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
        u32 tunnel_id, session_id;
        u16 version;
        int length;
-       struct l2tp_stats *tstats;
 
        if (tunnel->sock && l2tp_verify_udp_checksum(tunnel->sock, skb))
                goto discard_bad_csum;
@@ -932,10 +923,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
 discard_bad_csum:
        LIMIT_NETDEBUG("%s: UDP: bad checksum\n", tunnel->name);
        UDP_INC_STATS_USER(tunnel->l2tp_net, UDP_MIB_INERRORS, 0);
-       tstats = &tunnel->stats;
-       u64_stats_update_begin(&tstats->syncp);
-       tstats->rx_errors++;
-       u64_stats_update_end(&tstats->syncp);
+       atomic_long_inc(&tunnel->stats.rx_errors);
        kfree_skb(skb);
 
        return 0;
@@ -1062,7 +1050,6 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
        struct l2tp_tunnel *tunnel = session->tunnel;
        unsigned int len = skb->len;
        int error;
-       struct l2tp_stats *tstats, *sstats;
 
        /* Debug */
        if (session->send_seq)
@@ -1091,21 +1078,15 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
                error = ip_queue_xmit(skb, fl);
 
        /* Update stats */
-       tstats = &tunnel->stats;
-       u64_stats_update_begin(&tstats->syncp);
-       sstats = &session->stats;
-       u64_stats_update_begin(&sstats->syncp);
        if (error >= 0) {
-               tstats->tx_packets++;
-               tstats->tx_bytes += len;
-               sstats->tx_packets++;
-               sstats->tx_bytes += len;
+               atomic_long_inc(&tunnel->stats.tx_packets);
+               atomic_long_add(len, &tunnel->stats.tx_bytes);
+               atomic_long_inc(&session->stats.tx_packets);
+               atomic_long_add(len, &session->stats.tx_bytes);
        } else {
-               tstats->tx_errors++;
-               sstats->tx_errors++;
+               atomic_long_inc(&tunnel->stats.tx_errors);
+               atomic_long_inc(&session->stats.tx_errors);
        }
-       u64_stats_update_end(&tstats->syncp);
-       u64_stats_update_end(&sstats->syncp);
 
        return 0;
 }
@@ -1282,6 +1263,7 @@ static void l2tp_tunnel_destruct(struct sock *sk)
                /* No longer an encapsulation socket. See net/ipv4/udp.c */
                (udp_sk(sk))->encap_type = 0;
                (udp_sk(sk))->encap_rcv = NULL;
+               (udp_sk(sk))->encap_destroy = NULL;
                break;
        case L2TP_ENCAPTYPE_IP:
                break;
@@ -1311,7 +1293,7 @@ end:
 
 /* When the tunnel is closed, all the attached sessions need to go too.
  */
-static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
+void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
 {
        int hash;
        struct hlist_node *walk;
@@ -1334,25 +1316,13 @@ again:
 
                        hlist_del_init(&session->hlist);
 
-                       /* Since we should hold the sock lock while
-                        * doing any unbinding, we need to release the
-                        * lock we're holding before taking that lock.
-                        * Hold a reference to the sock so it doesn't
-                        * disappear as we're jumping between locks.
-                        */
                        if (session->ref != NULL)
                                (*session->ref)(session);
 
                        write_unlock_bh(&tunnel->hlist_lock);
 
-                       if (tunnel->version != L2TP_HDR_VER_2) {
-                               struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
-
-                               spin_lock_bh(&pn->l2tp_session_hlist_lock);
-                               hlist_del_init_rcu(&session->global_hlist);
-                               spin_unlock_bh(&pn->l2tp_session_hlist_lock);
-                               synchronize_rcu();
-                       }
+                       __l2tp_session_unhash(session);
+                       l2tp_session_queue_purge(session);
 
                        if (session->session_close != NULL)
                                (*session->session_close)(session);
@@ -1360,6 +1330,8 @@ again:
                        if (session->deref != NULL)
                                (*session->deref)(session);
 
+                       l2tp_session_dec_refcount(session);
+
                        write_lock_bh(&tunnel->hlist_lock);
 
                        /* Now restart from the beginning of this hash
@@ -1372,6 +1344,17 @@ again:
        }
        write_unlock_bh(&tunnel->hlist_lock);
 }
+EXPORT_SYMBOL_GPL(l2tp_tunnel_closeall);
+
+/* Tunnel socket destroy hook for UDP encapsulation */
+static void l2tp_udp_encap_destroy(struct sock *sk)
+{
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+       if (tunnel) {
+               l2tp_tunnel_closeall(tunnel);
+               sock_put(sk);
+       }
+}
 
 /* Really kill the tunnel.
  * Come here only when all sessions have been cleared from the tunnel.
@@ -1397,19 +1380,21 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
                return;
 
        sock = sk->sk_socket;
-       BUG_ON(!sock);
 
-       /* If the tunnel socket was created directly by the kernel, use the
-        * sk_* API to release the socket now.  Otherwise go through the
-        * inet_* layer to shut the socket down, and let userspace close it.
+       /* If the tunnel socket was created by userspace, then go through the
+        * inet layer to shut the socket down, and let userspace close it.
+        * Otherwise, if we created the socket directly within the kernel, use
+        * the sk API to release it here.
         * In either case the tunnel resources are freed in the socket
         * destructor when the tunnel socket goes away.
         */
-       if (sock->file == NULL) {
-               kernel_sock_shutdown(sock, SHUT_RDWR);
-               sk_release_kernel(sk);
+       if (tunnel->fd >= 0) {
+               if (sock)
+                       inet_shutdown(sock, 2);
        } else {
-               inet_shutdown(sock, 2);
+               if (sock)
+                       kernel_sock_shutdown(sock, SHUT_RDWR);
+               sk_release_kernel(sk);
        }
 
        l2tp_tunnel_sock_put(sk);
@@ -1668,6 +1653,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
                /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
                udp_sk(sk)->encap_type = UDP_ENCAP_L2TPINUDP;
                udp_sk(sk)->encap_rcv = l2tp_udp_encap_recv;
+               udp_sk(sk)->encap_destroy = l2tp_udp_encap_destroy;
 #if IS_ENABLED(CONFIG_IPV6)
                if (sk->sk_family == PF_INET6)
                        udpv6_encap_enable();
@@ -1723,6 +1709,7 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
  */
 int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
 {
+       l2tp_tunnel_closeall(tunnel);
        return (false == queue_work(l2tp_wq, &tunnel->del_work));
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
@@ -1731,62 +1718,71 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
  */
 void l2tp_session_free(struct l2tp_session *session)
 {
-       struct l2tp_tunnel *tunnel;
+       struct l2tp_tunnel *tunnel = session->tunnel;
 
        BUG_ON(atomic_read(&session->ref_count) != 0);
 
-       tunnel = session->tunnel;
-       if (tunnel != NULL) {
+       if (tunnel) {
                BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+               if (session->session_id != 0)
+                       atomic_dec(&l2tp_session_count);
+               sock_put(tunnel->sock);
+               session->tunnel = NULL;
+               l2tp_tunnel_dec_refcount(tunnel);
+       }
+
+       kfree(session);
 
-               /* Delete the session from the hash */
+       return;
+}
+EXPORT_SYMBOL_GPL(l2tp_session_free);
+
+/* Remove an l2tp session from l2tp_core's hash lists.
+ * Provides a tidyup interface for pseudowire code which can't just route all
+ * shutdown via. l2tp_session_delete and a pseudowire-specific session_close
+ * callback.
+ */
+void __l2tp_session_unhash(struct l2tp_session *session)
+{
+       struct l2tp_tunnel *tunnel = session->tunnel;
+
+       /* Remove the session from core hashes */
+       if (tunnel) {
+               /* Remove from the per-tunnel hash */
                write_lock_bh(&tunnel->hlist_lock);
                hlist_del_init(&session->hlist);
                write_unlock_bh(&tunnel->hlist_lock);
 
-               /* Unlink from the global hash if not L2TPv2 */
+               /* For L2TPv3 we have a per-net hash: remove from there, too */
                if (tunnel->version != L2TP_HDR_VER_2) {
                        struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
-
                        spin_lock_bh(&pn->l2tp_session_hlist_lock);
                        hlist_del_init_rcu(&session->global_hlist);
                        spin_unlock_bh(&pn->l2tp_session_hlist_lock);
                        synchronize_rcu();
                }
-
-               if (session->session_id != 0)
-                       atomic_dec(&l2tp_session_count);
-
-               sock_put(tunnel->sock);
-
-               /* This will delete the tunnel context if this
-                * is the last session on the tunnel.
-                */
-               session->tunnel = NULL;
-               l2tp_tunnel_dec_refcount(tunnel);
        }
-
-       kfree(session);
-
-       return;
 }
-EXPORT_SYMBOL_GPL(l2tp_session_free);
+EXPORT_SYMBOL_GPL(__l2tp_session_unhash);
 
 /* This function is used by the netlink SESSION_DELETE command and by
    pseudowire modules.
  */
 int l2tp_session_delete(struct l2tp_session *session)
 {
+       if (session->ref)
+               (*session->ref)(session);
+       __l2tp_session_unhash(session);
+       l2tp_session_queue_purge(session);
        if (session->session_close != NULL)
                (*session->session_close)(session);
-
+       if (session->deref)
+               (*session->ref)(session);
        l2tp_session_dec_refcount(session);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(l2tp_session_delete);
 
-
 /* We come here whenever a session's send_seq, cookie_len or
  * l2specific_len parameters are set.
  */
index 8eb8f1d47f3ac2d6ce32ae287e120a93aa931b40..485a490fd990eeb91a3577e65844c17d1350f720 100644 (file)
@@ -36,16 +36,15 @@ enum {
 struct sk_buff;
 
 struct l2tp_stats {
-       u64                     tx_packets;
-       u64                     tx_bytes;
-       u64                     tx_errors;
-       u64                     rx_packets;
-       u64                     rx_bytes;
-       u64                     rx_seq_discards;
-       u64                     rx_oos_packets;
-       u64                     rx_errors;
-       u64                     rx_cookie_discards;
-       struct u64_stats_sync   syncp;
+       atomic_long_t           tx_packets;
+       atomic_long_t           tx_bytes;
+       atomic_long_t           tx_errors;
+       atomic_long_t           rx_packets;
+       atomic_long_t           rx_bytes;
+       atomic_long_t           rx_seq_discards;
+       atomic_long_t           rx_oos_packets;
+       atomic_long_t           rx_errors;
+       atomic_long_t           rx_cookie_discards;
 };
 
 struct l2tp_tunnel;
@@ -240,11 +239,14 @@ extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
 extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
 
 extern int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp);
+extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
 extern int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
 extern struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
+extern void __l2tp_session_unhash(struct l2tp_session *session);
 extern int l2tp_session_delete(struct l2tp_session *session);
 extern void l2tp_session_free(struct l2tp_session *session);
 extern void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb));
+extern int l2tp_session_queue_purge(struct l2tp_session *session);
 extern int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb);
 
 extern int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len);
index c3813bc84552cebc56691cae4eae3097b29d2160..072d7202e182ffa2125fe7de9c54c584626fdeb0 100644 (file)
@@ -146,14 +146,14 @@ static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
                   tunnel->sock ? atomic_read(&tunnel->sock->sk_refcnt) : 0,
                   atomic_read(&tunnel->ref_count));
 
-       seq_printf(m, " %08x rx %llu/%llu/%llu rx %llu/%llu/%llu\n",
+       seq_printf(m, " %08x rx %ld/%ld/%ld rx %ld/%ld/%ld\n",
                   tunnel->debug,
-                  (unsigned long long)tunnel->stats.tx_packets,
-                  (unsigned long long)tunnel->stats.tx_bytes,
-                  (unsigned long long)tunnel->stats.tx_errors,
-                  (unsigned long long)tunnel->stats.rx_packets,
-                  (unsigned long long)tunnel->stats.rx_bytes,
-                  (unsigned long long)tunnel->stats.rx_errors);
+                  atomic_long_read(&tunnel->stats.tx_packets),
+                  atomic_long_read(&tunnel->stats.tx_bytes),
+                  atomic_long_read(&tunnel->stats.tx_errors),
+                  atomic_long_read(&tunnel->stats.rx_packets),
+                  atomic_long_read(&tunnel->stats.rx_bytes),
+                  atomic_long_read(&tunnel->stats.rx_errors));
 
        if (tunnel->show != NULL)
                tunnel->show(m, tunnel);
@@ -203,14 +203,14 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
                seq_printf(m, "\n");
        }
 
-       seq_printf(m, "   %hu/%hu tx %llu/%llu/%llu rx %llu/%llu/%llu\n",
+       seq_printf(m, "   %hu/%hu tx %ld/%ld/%ld rx %ld/%ld/%ld\n",
                   session->nr, session->ns,
-                  (unsigned long long)session->stats.tx_packets,
-                  (unsigned long long)session->stats.tx_bytes,
-                  (unsigned long long)session->stats.tx_errors,
-                  (unsigned long long)session->stats.rx_packets,
-                  (unsigned long long)session->stats.rx_bytes,
-                  (unsigned long long)session->stats.rx_errors);
+                  atomic_long_read(&session->stats.tx_packets),
+                  atomic_long_read(&session->stats.tx_bytes),
+                  atomic_long_read(&session->stats.tx_errors),
+                  atomic_long_read(&session->stats.rx_packets),
+                  atomic_long_read(&session->stats.rx_bytes),
+                  atomic_long_read(&session->stats.rx_errors));
 
        if (session->show != NULL)
                session->show(m, session);
index 7f41b7051269539efa0780b618be0b60e7788e76..571db8dd2292a7c5b1f2e940073edce370b13699 100644 (file)
@@ -228,10 +228,16 @@ static void l2tp_ip_close(struct sock *sk, long timeout)
 static void l2tp_ip_destroy_sock(struct sock *sk)
 {
        struct sk_buff *skb;
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
 
        while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
                kfree_skb(skb);
 
+       if (tunnel) {
+               l2tp_tunnel_closeall(tunnel);
+               sock_put(sk);
+       }
+
        sk_refcnt_debug_dec(sk);
 }
 
index 41f2f8126ebc720933638f67eb800f17797987e7..c74f5a91ff6a3213209c23ff488f0b475a552857 100644 (file)
@@ -241,10 +241,17 @@ static void l2tp_ip6_close(struct sock *sk, long timeout)
 
 static void l2tp_ip6_destroy_sock(struct sock *sk)
 {
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+
        lock_sock(sk);
        ip6_flush_pending_frames(sk);
        release_sock(sk);
 
+       if (tunnel) {
+               l2tp_tunnel_closeall(tunnel);
+               sock_put(sk);
+       }
+
        inet6_destroy_sock(sk);
 }
 
index c1bab22db85e79765581079468a36231e5f3d608..0825ff26e113f3e2acdbbe2b88bd0f4fbfd92410 100644 (file)
@@ -246,8 +246,6 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
 #if IS_ENABLED(CONFIG_IPV6)
        struct ipv6_pinfo *np = NULL;
 #endif
-       struct l2tp_stats stats;
-       unsigned int start;
 
        hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags,
                          L2TP_CMD_TUNNEL_GET);
@@ -265,28 +263,22 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
        if (nest == NULL)
                goto nla_put_failure;
 
-       do {
-               start = u64_stats_fetch_begin(&tunnel->stats.syncp);
-               stats.tx_packets = tunnel->stats.tx_packets;
-               stats.tx_bytes = tunnel->stats.tx_bytes;
-               stats.tx_errors = tunnel->stats.tx_errors;
-               stats.rx_packets = tunnel->stats.rx_packets;
-               stats.rx_bytes = tunnel->stats.rx_bytes;
-               stats.rx_errors = tunnel->stats.rx_errors;
-               stats.rx_seq_discards = tunnel->stats.rx_seq_discards;
-               stats.rx_oos_packets = tunnel->stats.rx_oos_packets;
-       } while (u64_stats_fetch_retry(&tunnel->stats.syncp, start));
-
-       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS, stats.tx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_BYTES, stats.tx_bytes) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS, stats.tx_errors) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS, stats.rx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_BYTES, stats.rx_bytes) ||
+       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS,
+                   atomic_long_read(&tunnel->stats.tx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_BYTES,
+                   atomic_long_read(&tunnel->stats.tx_bytes)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS,
+                   atomic_long_read(&tunnel->stats.tx_errors)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS,
+                   atomic_long_read(&tunnel->stats.rx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_BYTES,
+                   atomic_long_read(&tunnel->stats.rx_bytes)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
-                       stats.rx_seq_discards) ||
+                   atomic_long_read(&tunnel->stats.rx_seq_discards)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
-                       stats.rx_oos_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS, stats.rx_errors))
+                   atomic_long_read(&tunnel->stats.rx_oos_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS,
+                   atomic_long_read(&tunnel->stats.rx_errors)))
                goto nla_put_failure;
        nla_nest_end(skb, nest);
 
@@ -612,8 +604,6 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
        struct nlattr *nest;
        struct l2tp_tunnel *tunnel = session->tunnel;
        struct sock *sk = NULL;
-       struct l2tp_stats stats;
-       unsigned int start;
 
        sk = tunnel->sock;
 
@@ -656,28 +646,22 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
        if (nest == NULL)
                goto nla_put_failure;
 
-       do {
-               start = u64_stats_fetch_begin(&session->stats.syncp);
-               stats.tx_packets = session->stats.tx_packets;
-               stats.tx_bytes = session->stats.tx_bytes;
-               stats.tx_errors = session->stats.tx_errors;
-               stats.rx_packets = session->stats.rx_packets;
-               stats.rx_bytes = session->stats.rx_bytes;
-               stats.rx_errors = session->stats.rx_errors;
-               stats.rx_seq_discards = session->stats.rx_seq_discards;
-               stats.rx_oos_packets = session->stats.rx_oos_packets;
-       } while (u64_stats_fetch_retry(&session->stats.syncp, start));
-
-       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS, stats.tx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_BYTES, stats.tx_bytes) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS, stats.tx_errors) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS, stats.rx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_BYTES, stats.rx_bytes) ||
+       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS,
+               atomic_long_read(&session->stats.tx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_BYTES,
+               atomic_long_read(&session->stats.tx_bytes)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS,
+               atomic_long_read(&session->stats.tx_errors)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS,
+               atomic_long_read(&session->stats.rx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_BYTES,
+               atomic_long_read(&session->stats.rx_bytes)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
-                       stats.rx_seq_discards) ||
+               atomic_long_read(&session->stats.rx_seq_discards)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
-                       stats.rx_oos_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS, stats.rx_errors))
+               atomic_long_read(&session->stats.rx_oos_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS,
+               atomic_long_read(&session->stats.rx_errors)))
                goto nla_put_failure;
        nla_nest_end(skb, nest);
 
index 3f4e3afc191a524d57c29659324ddc0ac6cd9c1e..637a341c1e2d1a466c68efcb50d7fc201198a15b 100644 (file)
@@ -97,6 +97,7 @@
 #include <net/ip.h>
 #include <net/udp.h>
 #include <net/xfrm.h>
+#include <net/inet_common.h>
 
 #include <asm/byteorder.h>
 #include <linux/atomic.h>
@@ -259,7 +260,7 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int
                          session->name);
 
                /* Not bound. Nothing we can do, so discard. */
-               session->stats.rx_errors++;
+               atomic_long_inc(&session->stats.rx_errors);
                kfree_skb(skb);
        }
 
@@ -355,6 +356,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
        l2tp_xmit_skb(session, skb, session->hdr_len);
 
        sock_put(ps->tunnel_sock);
+       sock_put(sk);
 
        return error;
 
@@ -446,34 +448,16 @@ static void pppol2tp_session_close(struct l2tp_session *session)
 {
        struct pppol2tp_session *ps = l2tp_session_priv(session);
        struct sock *sk = ps->sock;
-       struct sk_buff *skb;
+       struct socket *sock = sk->sk_socket;
 
        BUG_ON(session->magic != L2TP_SESSION_MAGIC);
 
-       if (session->session_id == 0)
-               goto out;
-
-       if (sk != NULL) {
-               lock_sock(sk);
-
-               if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
-                       pppox_unbind_sock(sk);
-                       sk->sk_state = PPPOX_DEAD;
-                       sk->sk_state_change(sk);
-               }
-
-               /* Purge any queued data */
-               skb_queue_purge(&sk->sk_receive_queue);
-               skb_queue_purge(&sk->sk_write_queue);
-               while ((skb = skb_dequeue(&session->reorder_q))) {
-                       kfree_skb(skb);
-                       sock_put(sk);
-               }
 
-               release_sock(sk);
+       if (sock) {
+               inet_shutdown(sock, 2);
+               /* Don't let the session go away before our socket does */
+               l2tp_session_inc_refcount(session);
        }
-
-out:
        return;
 }
 
@@ -482,19 +466,12 @@ out:
  */
 static void pppol2tp_session_destruct(struct sock *sk)
 {
-       struct l2tp_session *session;
-
-       if (sk->sk_user_data != NULL) {
-               session = sk->sk_user_data;
-               if (session == NULL)
-                       goto out;
-
+       struct l2tp_session *session = sk->sk_user_data;
+       if (session) {
                sk->sk_user_data = NULL;
                BUG_ON(session->magic != L2TP_SESSION_MAGIC);
                l2tp_session_dec_refcount(session);
        }
-
-out:
        return;
 }
 
@@ -524,16 +501,13 @@ static int pppol2tp_release(struct socket *sock)
        session = pppol2tp_sock_to_session(sk);
 
        /* Purge any queued data */
-       skb_queue_purge(&sk->sk_receive_queue);
-       skb_queue_purge(&sk->sk_write_queue);
        if (session != NULL) {
-               struct sk_buff *skb;
-               while ((skb = skb_dequeue(&session->reorder_q))) {
-                       kfree_skb(skb);
-                       sock_put(sk);
-               }
+               __l2tp_session_unhash(session);
+               l2tp_session_queue_purge(session);
                sock_put(sk);
        }
+       skb_queue_purge(&sk->sk_receive_queue);
+       skb_queue_purge(&sk->sk_write_queue);
 
        release_sock(sk);
 
@@ -879,18 +853,6 @@ out:
        return error;
 }
 
-/* Called when deleting sessions via the netlink interface.
- */
-static int pppol2tp_session_delete(struct l2tp_session *session)
-{
-       struct pppol2tp_session *ps = l2tp_session_priv(session);
-
-       if (ps->sock == NULL)
-               l2tp_session_dec_refcount(session);
-
-       return 0;
-}
-
 #endif /* CONFIG_L2TP_V3 */
 
 /* getname() support.
@@ -1024,14 +986,14 @@ end:
 static void pppol2tp_copy_stats(struct pppol2tp_ioc_stats *dest,
                                struct l2tp_stats *stats)
 {
-       dest->tx_packets = stats->tx_packets;
-       dest->tx_bytes = stats->tx_bytes;
-       dest->tx_errors = stats->tx_errors;
-       dest->rx_packets = stats->rx_packets;
-       dest->rx_bytes = stats->rx_bytes;
-       dest->rx_seq_discards = stats->rx_seq_discards;
-       dest->rx_oos_packets = stats->rx_oos_packets;
-       dest->rx_errors = stats->rx_errors;
+       dest->tx_packets = atomic_long_read(&stats->tx_packets);
+       dest->tx_bytes = atomic_long_read(&stats->tx_bytes);
+       dest->tx_errors = atomic_long_read(&stats->tx_errors);
+       dest->rx_packets = atomic_long_read(&stats->rx_packets);
+       dest->rx_bytes = atomic_long_read(&stats->rx_bytes);
+       dest->rx_seq_discards = atomic_long_read(&stats->rx_seq_discards);
+       dest->rx_oos_packets = atomic_long_read(&stats->rx_oos_packets);
+       dest->rx_errors = atomic_long_read(&stats->rx_errors);
 }
 
 /* Session ioctl helper.
@@ -1665,14 +1627,14 @@ static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
                   tunnel->name,
                   (tunnel == tunnel->sock->sk_user_data) ? 'Y' : 'N',
                   atomic_read(&tunnel->ref_count) - 1);
-       seq_printf(m, " %08x %llu/%llu/%llu %llu/%llu/%llu\n",
+       seq_printf(m, " %08x %ld/%ld/%ld %ld/%ld/%ld\n",
                   tunnel->debug,
-                  (unsigned long long)tunnel->stats.tx_packets,
-                  (unsigned long long)tunnel->stats.tx_bytes,
-                  (unsigned long long)tunnel->stats.tx_errors,
-                  (unsigned long long)tunnel->stats.rx_packets,
-                  (unsigned long long)tunnel->stats.rx_bytes,
-                  (unsigned long long)tunnel->stats.rx_errors);
+                  atomic_long_read(&tunnel->stats.tx_packets),
+                  atomic_long_read(&tunnel->stats.tx_bytes),
+                  atomic_long_read(&tunnel->stats.tx_errors),
+                  atomic_long_read(&tunnel->stats.rx_packets),
+                  atomic_long_read(&tunnel->stats.rx_bytes),
+                  atomic_long_read(&tunnel->stats.rx_errors));
 }
 
 static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
@@ -1707,14 +1669,14 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
                   session->lns_mode ? "LNS" : "LAC",
                   session->debug,
                   jiffies_to_msecs(session->reorder_timeout));
-       seq_printf(m, "   %hu/%hu %llu/%llu/%llu %llu/%llu/%llu\n",
+       seq_printf(m, "   %hu/%hu %ld/%ld/%ld %ld/%ld/%ld\n",
                   session->nr, session->ns,
-                  (unsigned long long)session->stats.tx_packets,
-                  (unsigned long long)session->stats.tx_bytes,
-                  (unsigned long long)session->stats.tx_errors,
-                  (unsigned long long)session->stats.rx_packets,
-                  (unsigned long long)session->stats.rx_bytes,
-                  (unsigned long long)session->stats.rx_errors);
+                  atomic_long_read(&session->stats.tx_packets),
+                  atomic_long_read(&session->stats.tx_bytes),
+                  atomic_long_read(&session->stats.tx_errors),
+                  atomic_long_read(&session->stats.rx_packets),
+                  atomic_long_read(&session->stats.rx_bytes),
+                  atomic_long_read(&session->stats.rx_errors));
 
        if (po)
                seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
@@ -1838,7 +1800,7 @@ static const struct pppox_proto pppol2tp_proto = {
 
 static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
        .session_create = pppol2tp_session_create,
-       .session_delete = pppol2tp_session_delete,
+       .session_delete = l2tp_session_delete,
 };
 
 #endif /* CONFIG_L2TP_V3 */
index 09d96a8f6c2c7c64679bef8062d7d87db75addc1..fb306814576affa7e636fa53353d29ba1e39b668 100644 (file)
@@ -3285,6 +3285,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
                                     struct cfg80211_chan_def *chandef)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_chanctx_conf *chanctx_conf;
        int ret = -ENODATA;
 
@@ -3293,6 +3294,16 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
        if (chanctx_conf) {
                *chandef = chanctx_conf->def;
                ret = 0;
+       } else if (local->open_count > 0 &&
+                  local->open_count == local->monitors &&
+                  sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+               if (local->use_chanctx)
+                       *chandef = local->monitor_chandef;
+               else
+                       cfg80211_chandef_create(chandef,
+                                               local->_oper_channel,
+                                               local->_oper_channel_type);
+               ret = 0;
        }
        rcu_read_unlock();
 
index 2c059e54e88575bf1364a17b9a9bc2f020c5a7a6..baaa8608e52de8d9d504f14a254bb7e6631b5f2e 100644 (file)
@@ -107,7 +107,7 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
 
        lockdep_assert_held(&local->mtx);
 
-       active = !list_empty(&local->chanctx_list);
+       active = !list_empty(&local->chanctx_list) || local->monitors;
 
        if (!local->ops->remain_on_channel) {
                list_for_each_entry(roc, &local->roc_list, list) {
@@ -541,6 +541,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 
                ieee80211_adjust_monitor_flags(sdata, 1);
                ieee80211_configure_filter(local);
+               mutex_lock(&local->mtx);
+               ieee80211_recalc_idle(local);
+               mutex_unlock(&local->mtx);
 
                netif_carrier_on(dev);
                break;
@@ -812,6 +815,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
                ieee80211_adjust_monitor_flags(sdata, -1);
                ieee80211_configure_filter(local);
+               mutex_lock(&local->mtx);
+               ieee80211_recalc_idle(local);
+               mutex_unlock(&local->mtx);
                break;
        case NL80211_IFTYPE_P2P_DEVICE:
                /* relies on synchronize_rcu() below */
index 9f6464f3e05f94e0025c4449b4a29e35bc185725..141577412d8407fc8b18ad354a34ad8de105f154 100644 (file)
@@ -647,6 +647,9 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
                our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) &
                                                                mask) >> shift;
 
+               if (our_mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED)
+                       continue;
+
                switch (ap_mcs) {
                default:
                        if (our_mcs <= ap_mcs)
@@ -3502,6 +3505,14 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
+       /*
+        * Stop timers before deleting work items, as timers
+        * could race and re-add the work-items. They will be
+        * re-established on connection.
+        */
+       del_timer_sync(&ifmgd->conn_mon_timer);
+       del_timer_sync(&ifmgd->bcn_mon_timer);
+
        /*
         * we need to use atomic bitops for the running bits
         * only because both timers might fire at the same
@@ -3516,13 +3527,9 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
        if (del_timer_sync(&ifmgd->timer))
                set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
 
-       cancel_work_sync(&ifmgd->chswitch_work);
        if (del_timer_sync(&ifmgd->chswitch_timer))
                set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
-
-       /* these will just be re-established on connection */
-       del_timer_sync(&ifmgd->conn_mon_timer);
-       del_timer_sync(&ifmgd->bcn_mon_timer);
+       cancel_work_sync(&ifmgd->chswitch_work);
 }
 
 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
@@ -4315,6 +4322,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
+       /*
+        * Make sure some work items will not run after this,
+        * they will not do anything but might not have been
+        * cancelled when disconnecting.
+        */
+       cancel_work_sync(&ifmgd->monitor_work);
+       cancel_work_sync(&ifmgd->beacon_connection_loss_work);
+       cancel_work_sync(&ifmgd->request_smps_work);
+       cancel_work_sync(&ifmgd->csa_connection_drop_work);
+       cancel_work_sync(&ifmgd->chswitch_work);
+
        mutex_lock(&ifmgd->mtx);
        if (ifmgd->assoc_data)
                ieee80211_destroy_assoc_data(sdata, false);
index de8548bf0a7f27cef20e06077d3c603ad22a7baa..8914d2d2881aab77c5741479d6dbf516db59e3b3 100644 (file)
@@ -1231,34 +1231,40 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
                if (local->queue_stop_reasons[q] ||
                    (!txpending && !skb_queue_empty(&local->pending[q]))) {
                        if (unlikely(info->flags &
-                                       IEEE80211_TX_INTFL_OFFCHAN_TX_OK &&
-                                    local->queue_stop_reasons[q] &
-                                       ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) {
+                                    IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
+                               if (local->queue_stop_reasons[q] &
+                                   ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
+                                       /*
+                                        * Drop off-channel frames if queues
+                                        * are stopped for any reason other
+                                        * than off-channel operation. Never
+                                        * queue them.
+                                        */
+                                       spin_unlock_irqrestore(
+                                               &local->queue_stop_reason_lock,
+                                               flags);
+                                       ieee80211_purge_tx_queue(&local->hw,
+                                                                skbs);
+                                       return true;
+                               }
+                       } else {
+
                                /*
-                                * Drop off-channel frames if queues are stopped
-                                * for any reason other than off-channel
-                                * operation. Never queue them.
+                                * Since queue is stopped, queue up frames for
+                                * later transmission from the tx-pending
+                                * tasklet when the queue is woken again.
                                 */
-                               spin_unlock_irqrestore(
-                                       &local->queue_stop_reason_lock, flags);
-                               ieee80211_purge_tx_queue(&local->hw, skbs);
-                               return true;
+                               if (txpending)
+                                       skb_queue_splice_init(skbs,
+                                                             &local->pending[q]);
+                               else
+                                       skb_queue_splice_tail_init(skbs,
+                                                                  &local->pending[q]);
+
+                               spin_unlock_irqrestore(&local->queue_stop_reason_lock,
+                                                      flags);
+                               return false;
                        }
-
-                       /*
-                        * Since queue is stopped, queue up frames for later
-                        * transmission from the tx-pending tasklet when the
-                        * queue is woken again.
-                        */
-                       if (txpending)
-                               skb_queue_splice_init(skbs, &local->pending[q]);
-                       else
-                               skb_queue_splice_tail_init(skbs,
-                                                          &local->pending[q]);
-
-                       spin_unlock_irqrestore(&local->queue_stop_reason_lock,
-                                              flags);
-                       return false;
                }
                spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
@@ -1844,9 +1850,24 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                }
 
                if (!is_multicast_ether_addr(skb->data)) {
+                       struct sta_info *next_hop;
+                       bool mpp_lookup = true;
+
                        mpath = mesh_path_lookup(sdata, skb->data);
-                       if (!mpath)
+                       if (mpath) {
+                               mpp_lookup = false;
+                               next_hop = rcu_dereference(mpath->next_hop);
+                               if (!next_hop ||
+                                   !(mpath->flags & (MESH_PATH_ACTIVE |
+                                                     MESH_PATH_RESOLVING)))
+                                       mpp_lookup = true;
+                       }
+
+                       if (mpp_lookup)
                                mppath = mpp_path_lookup(sdata, skb->data);
+
+                       if (mppath && mpath)
+                               mesh_path_del(mpath->sdata, mpath->dst);
                }
 
                /*
@@ -2350,9 +2371,9 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
        if (local->tim_in_locked_section) {
                __ieee80211_beacon_add_tim(sdata, ps, skb);
        } else {
-               spin_lock(&local->tim_lock);
+               spin_lock_bh(&local->tim_lock);
                __ieee80211_beacon_add_tim(sdata, ps, skb);
-               spin_unlock(&local->tim_lock);
+               spin_unlock_bh(&local->tim_lock);
        }
 
        return 0;
@@ -2724,7 +2745,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
                                cpu_to_le16(IEEE80211_FCTL_MOREDATA);
                }
 
-               sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
+               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
                if (!ieee80211_tx_prepare(sdata, &tx, skb))
                        break;
                dev_kfree_skb_any(skb);
index f82b2e606cfd53048d5e208855d0d18fb5539a74..1ba9dbc0e107cae96efdf58b4b18d7c4d38d9e6b 100644 (file)
@@ -1470,7 +1470,8 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
        if (ret == -EAGAIN)
                ret = 1;
 
-       return ret < 0 ? ret : ret > 0 ? 0 : -IPSET_ERR_EXIST;
+       return (ret < 0 && ret != -ENOTEMPTY) ? ret :
+               ret > 0 ? 0 : -IPSET_ERR_EXIST;
 }
 
 /* Get headed data of a set */
index 47edf5a40a5939d2401dc11baa89142b9bcd64b6..61f49d241712a77797829a294ee94fc10161306e 100644 (file)
@@ -1394,10 +1394,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
                        skb_reset_network_header(skb);
                        IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n",
                                &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, mtu);
-                       rcu_read_lock();
                        ipv4_update_pmtu(skb, dev_net(skb->dev),
                                         mtu, 0, 0, 0, 0);
-                       rcu_read_unlock();
                        /* Client uses PMTUD? */
                        if (!(cih->frag_off & htons(IP_DF)))
                                goto ignore_ipip;
@@ -1577,7 +1575,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
        }
        /* ipvs enabled in this netns ? */
        net = skb_net(skb);
-       if (!net_ipvs(net)->enable)
+       ipvs = net_ipvs(net);
+       if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
                return NF_ACCEPT;
 
        ip_vs_fill_iph_skb(af, skb, &iph);
@@ -1654,7 +1653,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
        }
 
        IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
-       ipvs = net_ipvs(net);
        /* Check the server status */
        if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
                /* the destination server is not available */
@@ -1815,13 +1813,15 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
 {
        int r;
        struct net *net;
+       struct netns_ipvs *ipvs;
 
        if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
                return NF_ACCEPT;
 
        /* ipvs enabled in this netns ? */
        net = skb_net(skb);
-       if (!net_ipvs(net)->enable)
+       ipvs = net_ipvs(net);
+       if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
                return NF_ACCEPT;
 
        return ip_vs_in_icmp(skb, &r, hooknum);
@@ -1835,6 +1835,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
 {
        int r;
        struct net *net;
+       struct netns_ipvs *ipvs;
        struct ip_vs_iphdr iphdr;
 
        ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr);
@@ -1843,7 +1844,8 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
 
        /* ipvs enabled in this netns ? */
        net = skb_net(skb);
-       if (!net_ipvs(net)->enable)
+       ipvs = net_ipvs(net);
+       if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
                return NF_ACCEPT;
 
        return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr);
index c68198bf9128abfb695571faed1e0390b036a4bb..9e2d1cccd1eb4c647b2ece3b2c3985edc0b5b32d 100644 (file)
@@ -1808,6 +1808,12 @@ static struct ctl_table vs_vars[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "backup_only",
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
 #ifdef CONFIG_IP_VS_DEBUG
        {
                .procname       = "debug_level",
@@ -3741,6 +3747,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net)
        tbl[idx++].data = &ipvs->sysctl_nat_icmp_send;
        ipvs->sysctl_pmtu_disc = 1;
        tbl[idx++].data = &ipvs->sysctl_pmtu_disc;
+       tbl[idx++].data = &ipvs->sysctl_backup_only;
 
 
        ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl);
index ae8ec6f2768888eec1fb8b8c68b4242eff033525..cd1d7298f7ba779de3e6654b85fafaf7cec58f8e 100644 (file)
@@ -906,7 +906,7 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
        sctp_chunkhdr_t _sctpch, *sch;
        unsigned char chunk_type;
        int event, next_state;
-       int ihl;
+       int ihl, cofs;
 
 #ifdef CONFIG_IP_VS_IPV6
        ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
@@ -914,8 +914,8 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
        ihl = ip_hdrlen(skb);
 #endif
 
-       sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t),
-                               sizeof(_sctpch), &_sctpch);
+       cofs = ihl + sizeof(sctp_sctphdr_t);
+       sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch);
        if (sch == NULL)
                return;
 
@@ -933,10 +933,12 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
         */
        if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
            (sch->type == SCTP_CID_COOKIE_ACK)) {
-               sch = skb_header_pointer(skb, (ihl + sizeof(sctp_sctphdr_t) +
-                               sch->length), sizeof(_sctpch), &_sctpch);
-               if (sch) {
-                       if (sch->type == SCTP_CID_ABORT)
+               int clen = ntohs(sch->length);
+
+               if (clen >= sizeof(sctp_chunkhdr_t)) {
+                       sch = skb_header_pointer(skb, cofs + ALIGN(clen, 4),
+                                                sizeof(_sctpch), &_sctpch);
+                       if (sch && sch->type == SCTP_CID_ABORT)
                                chunk_type = sch->type;
                }
        }
index a9740bd6fe543bc5d93a05296d9c0dd0260c340b..94b4b9853f60488a1aa9b12ff9e96cac3c90d4d2 100644 (file)
@@ -339,6 +339,13 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
 {
        const struct nf_conn_help *help;
        const struct nf_conntrack_helper *helper;
+       struct va_format vaf;
+       va_list args;
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
 
        /* Called from the helper function, this call never fails */
        help = nfct_help(ct);
@@ -347,7 +354,9 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
        helper = rcu_dereference(help->helper);
 
        nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL,
-                     "nf_ct_%s: dropping packet: %s ", helper->name, fmt);
+                     "nf_ct_%s: dropping packet: %pV ", helper->name, &vaf);
+
+       va_end(args);
 }
 EXPORT_SYMBOL_GPL(nf_ct_helper_log);
 
index 432f95780003f2e36a4d0fb08aaa10b900e052ff..ba65b2041eb4b7f747f7df605a049e7922b32a55 100644 (file)
@@ -969,6 +969,10 @@ static int __init nf_conntrack_proto_dccp_init(void)
 {
        int ret;
 
+       ret = register_pernet_subsys(&dccp_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
        ret = nf_ct_l4proto_register(&dccp_proto4);
        if (ret < 0)
                goto out_dccp4;
@@ -977,16 +981,12 @@ static int __init nf_conntrack_proto_dccp_init(void)
        if (ret < 0)
                goto out_dccp6;
 
-       ret = register_pernet_subsys(&dccp_net_ops);
-       if (ret < 0)
-               goto out_pernet;
-
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&dccp_proto6);
 out_dccp6:
        nf_ct_l4proto_unregister(&dccp_proto4);
 out_dccp4:
+       unregister_pernet_subsys(&dccp_net_ops);
+out_pernet:
        return ret;
 }
 
index bd7d01d9c7e77d0e8a3a1e50116f854bb4925e14..155ce9f8a0db047d0e100b1d0283b8b36cd6e082 100644 (file)
@@ -420,18 +420,18 @@ static int __init nf_ct_proto_gre_init(void)
 {
        int ret;
 
-       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
-       if (ret < 0)
-               goto out_gre4;
-
        ret = register_pernet_subsys(&proto_gre_net_ops);
        if (ret < 0)
                goto out_pernet;
 
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
+       if (ret < 0)
+               goto out_gre4;
+
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
 out_gre4:
+       unregister_pernet_subsys(&proto_gre_net_ops);
+out_pernet:
        return ret;
 }
 
index 480f616d59361e0fff4abf182dc9f35974606187..ec83536def9ab89aca0678ac7b7e02a5509b4f01 100644 (file)
@@ -888,6 +888,10 @@ static int __init nf_conntrack_proto_sctp_init(void)
 {
        int ret;
 
+       ret = register_pernet_subsys(&sctp_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
        ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4);
        if (ret < 0)
                goto out_sctp4;
@@ -896,16 +900,12 @@ static int __init nf_conntrack_proto_sctp_init(void)
        if (ret < 0)
                goto out_sctp6;
 
-       ret = register_pernet_subsys(&sctp_net_ops);
-       if (ret < 0)
-               goto out_pernet;
-
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
 out_sctp6:
        nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
 out_sctp4:
+       unregister_pernet_subsys(&sctp_net_ops);
+out_pernet:
        return ret;
 }
 
index 157489581c313b02456b18d0e3e886746a60671f..ca969f6273f77a58851858357c25285b9f22e10e 100644 (file)
@@ -371,6 +371,10 @@ static int __init nf_conntrack_proto_udplite_init(void)
 {
        int ret;
 
+       ret = register_pernet_subsys(&udplite_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
        ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite4);
        if (ret < 0)
                goto out_udplite4;
@@ -379,16 +383,12 @@ static int __init nf_conntrack_proto_udplite_init(void)
        if (ret < 0)
                goto out_udplite6;
 
-       ret = register_pernet_subsys(&udplite_net_ops);
-       if (ret < 0)
-               goto out_pernet;
-
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
 out_udplite6:
        nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
 out_udplite4:
+       unregister_pernet_subsys(&udplite_net_ops);
+out_pernet:
        return ret;
 }
 
index d578ec251712b011be829e01aba8f379fb6babd7..0b1b32cda3072d2867edd82c3154538194f606d6 100644 (file)
@@ -62,11 +62,6 @@ void nfnl_unlock(__u8 subsys_id)
 }
 EXPORT_SYMBOL_GPL(nfnl_unlock);
 
-static struct mutex *nfnl_get_lock(__u8 subsys_id)
-{
-       return &table[subsys_id].mutex;
-}
-
 int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
 {
        nfnl_lock(n->subsys_id);
@@ -199,7 +194,7 @@ replay:
                        rcu_read_unlock();
                        nfnl_lock(subsys_id);
                        if (rcu_dereference_protected(table[subsys_id].subsys,
-                               lockdep_is_held(nfnl_get_lock(subsys_id))) != ss ||
+                               lockdep_is_held(&table[subsys_id].mutex)) != ss ||
                            nfnetlink_find_client(type, ss) != nc)
                                err = -EAGAIN;
                        else if (nc->call)
index 858fd52c10408393a901a9afb686226638f32f07..1cb48540f86a96df1e1b26371e5d75589861562d 100644 (file)
@@ -112,7 +112,7 @@ instance_create(u_int16_t queue_num, int portid)
        inst->queue_num = queue_num;
        inst->peer_portid = portid;
        inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
-       inst->copy_range = 0xfffff;
+       inst->copy_range = 0xffff;
        inst->copy_mode = NFQNL_COPY_NONE;
        spin_lock_init(&inst->lock);
        INIT_LIST_HEAD(&inst->queue_list);
index 686c7715d777ba2b6792641b644b2ed7f51c1f9e..67fb7bff9bbc7041d383394610f4d9fc6a6303ca 100644 (file)
@@ -999,7 +999,7 @@ static int xt_table_open(struct inode *inode, struct file *file)
                           sizeof(struct xt_names_priv));
        if (!ret) {
                priv = ((struct seq_file *)file->private_data)->private;
-               priv->af = (unsigned long)PDE(inode)->data;
+               priv->af = (unsigned long)PDE_DATA(inode);
        }
        return ret;
 }
@@ -1147,7 +1147,7 @@ static int xt_match_open(struct inode *inode, struct file *file)
 
        seq = file->private_data;
        seq->private = trav;
-       trav->nfproto = (unsigned long)PDE(inode)->data;
+       trav->nfproto = (unsigned long)PDE_DATA(inode);
        return 0;
 }
 
@@ -1211,7 +1211,7 @@ static int xt_target_open(struct inode *inode, struct file *file)
 
        seq = file->private_data;
        seq->private = trav;
-       trav->nfproto = (unsigned long)PDE(inode)->data;
+       trav->nfproto = (unsigned long)PDE_DATA(inode);
        return 0;
 }
 
index ba92824086f3c3843c7158c5a5de86fe0db53dc4..3228d7f24eb4107ff717af4323e834af3e680797 100644 (file)
@@ -124,6 +124,9 @@ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
        const struct xt_audit_info *info = par->targinfo;
        struct audit_buffer *ab;
 
+       if (audit_enabled == 0)
+               goto errout;
+
        ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
        if (ab == NULL)
                goto errout;
index f330e8beaf69830c274257d48e2eb5cf91ffd834..905c328ed5a821873ebcc24f85c6d778015f0502 100644 (file)
@@ -107,6 +107,7 @@ struct xt_hashlimit_htable {
 
        /* seq_file stuff */
        struct proc_dir_entry *pde;
+       const char *name;
        struct net *net;
 
        struct hlist_head hash[0];      /* hashtable itself */
@@ -253,6 +254,11 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
        hinfo->count = 0;
        hinfo->family = family;
        hinfo->rnd_initialized = false;
+       hinfo->name = kstrdup(minfo->name, GFP_KERNEL);
+       if (!hinfo->name) {
+               vfree(hinfo);
+               return -ENOMEM;
+       }
        spin_lock_init(&hinfo->lock);
 
        hinfo->pde = proc_create_data(minfo->name, 0,
@@ -260,6 +266,7 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
                hashlimit_net->ipt_hashlimit : hashlimit_net->ip6t_hashlimit,
                &dl_file_ops, hinfo);
        if (hinfo->pde == NULL) {
+               kfree(hinfo->name);
                vfree(hinfo);
                return -ENOMEM;
        }
@@ -330,9 +337,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
                parent = hashlimit_net->ip6t_hashlimit;
 
        if(parent != NULL)
-               remove_proc_entry(hinfo->pde->name, parent);
+               remove_proc_entry(hinfo->name, parent);
 
        htable_selective_cleanup(hinfo, select_all);
+       kfree(hinfo->name);
        vfree(hinfo);
 }
 
@@ -344,7 +352,7 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net,
        struct xt_hashlimit_htable *hinfo;
 
        hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) {
-               if (!strcmp(name, hinfo->pde->name) &&
+               if (!strcmp(name, hinfo->name) &&
                    hinfo->family == family) {
                        hinfo->use++;
                        return hinfo;
@@ -841,7 +849,7 @@ static int dl_proc_open(struct inode *inode, struct file *file)
 
        if (!ret) {
                struct seq_file *sf = file->private_data;
-               sf->private = PDE(inode)->data;
+               sf->private = PDE_DATA(inode);
        }
        return ret;
 }
@@ -887,7 +895,7 @@ static void __net_exit hashlimit_proc_net_exit(struct net *net)
                pde = hashlimit_net->ip6t_hashlimit;
 
        hlist_for_each_entry(hinfo, &hashlimit_net->htables, node)
-               remove_proc_entry(hinfo->pde->name, pde);
+               remove_proc_entry(hinfo->name, pde);
 
        hashlimit_net->ipt_hashlimit = NULL;
        hashlimit_net->ip6t_hashlimit = NULL;
index d9cad315229d807174dd085f6ed4e7e2569bf48f..1e657cf715c478d9a9ec77411bf7536b14278d14 100644 (file)
@@ -401,8 +401,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
                ret = -ENOMEM;
                goto out;
        }
-       pde->uid = uid;
-       pde->gid = gid;
+       proc_set_user(pde, uid, gid);
 #endif
        spin_lock_bh(&recent_lock);
        list_add_tail(&t->list, &recent_net->tables);
@@ -525,14 +524,13 @@ static const struct seq_operations recent_seq_ops = {
 
 static int recent_seq_open(struct inode *inode, struct file *file)
 {
-       struct proc_dir_entry *pde = PDE(inode);
        struct recent_iter_state *st;
 
        st = __seq_open_private(file, &recent_seq_ops, sizeof(*st));
        if (st == NULL)
                return -ENOMEM;
 
-       st->table    = pde->data;
+       st->table    = PDE_DATA(inode);
        return 0;
 }
 
@@ -540,8 +538,7 @@ static ssize_t
 recent_mt_proc_write(struct file *file, const char __user *input,
                     size_t size, loff_t *loff)
 {
-       const struct proc_dir_entry *pde = PDE(file_inode(file));
-       struct recent_table *t = pde->data;
+       struct recent_table *t = PDE_DATA(file_inode(file));
        struct recent_entry *e;
        char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")];
        const char *c = buf;
index 847d495cd4de0bee797f994fcaf491ed6efb30ce..8a6c6ea466d874dd34afd2013bef4f777a47db42 100644 (file)
@@ -1189,8 +1189,6 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
        struct netlbl_unlhsh_walk_arg cb_arg;
        u32 skip_bkt = cb->args[0];
        u32 skip_chain = cb->args[1];
-       u32 skip_addr4 = cb->args[2];
-       u32 skip_addr6 = cb->args[3];
        u32 iter_bkt;
        u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
        struct netlbl_unlhsh_iface *iface;
@@ -1215,7 +1213,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
                                continue;
                        netlbl_af4list_foreach_rcu(addr4,
                                                   &iface->addr4_list) {
-                               if (iter_addr4++ < skip_addr4)
+                               if (iter_addr4++ < cb->args[2])
                                        continue;
                                if (netlbl_unlabel_staticlist_gen(
                                              NLBL_UNLABEL_C_STATICLIST,
@@ -1231,7 +1229,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
 #if IS_ENABLED(CONFIG_IPV6)
                        netlbl_af6list_foreach_rcu(addr6,
                                                   &iface->addr6_list) {
-                               if (iter_addr6++ < skip_addr6)
+                               if (iter_addr6++ < cb->args[3])
                                        continue;
                                if (netlbl_unlabel_staticlist_gen(
                                              NLBL_UNLABEL_C_STATICLIST,
@@ -1250,10 +1248,10 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
 
 unlabel_staticlist_return:
        rcu_read_unlock();
-       cb->args[0] = skip_bkt;
-       cb->args[1] = skip_chain;
-       cb->args[2] = skip_addr4;
-       cb->args[3] = skip_addr6;
+       cb->args[0] = iter_bkt;
+       cb->args[1] = iter_chain;
+       cb->args[2] = iter_addr4;
+       cb->args[3] = iter_addr6;
        return skb->len;
 }
 
@@ -1273,12 +1271,9 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
 {
        struct netlbl_unlhsh_walk_arg cb_arg;
        struct netlbl_unlhsh_iface *iface;
-       u32 skip_addr4 = cb->args[0];
-       u32 skip_addr6 = cb->args[1];
-       u32 iter_addr4 = 0;
+       u32 iter_addr4 = 0, iter_addr6 = 0;
        struct netlbl_af4list *addr4;
 #if IS_ENABLED(CONFIG_IPV6)
-       u32 iter_addr6 = 0;
        struct netlbl_af6list *addr6;
 #endif
 
@@ -1292,7 +1287,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
                goto unlabel_staticlistdef_return;
 
        netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
-               if (iter_addr4++ < skip_addr4)
+               if (iter_addr4++ < cb->args[0])
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                              iface,
@@ -1305,7 +1300,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
        }
 #if IS_ENABLED(CONFIG_IPV6)
        netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
-               if (iter_addr6++ < skip_addr6)
+               if (iter_addr6++ < cb->args[1])
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                              iface,
@@ -1320,8 +1315,8 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
 
 unlabel_staticlistdef_return:
        rcu_read_unlock();
-       cb->args[0] = skip_addr4;
-       cb->args[1] = skip_addr6;
+       cb->args[0] = iter_addr4;
+       cb->args[1] = iter_addr6;
        return skb->len;
 }
 
index f2aabb6f410582439604d7a3c0f379a5cd798621..5a55be3f17a54aa2acac3ce109c412c86c652b36 100644 (file)
@@ -142,6 +142,7 @@ int genl_register_mc_group(struct genl_family *family,
        int err = 0;
 
        BUG_ON(grp->name[0] == '\0');
+       BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL);
 
        genl_lock();
 
index 7f8266dd14cbc164a278aa3bbc0438c845fa0bf5..b530afadd76c6168a5374d27935b7d95180f8884 100644 (file)
@@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
        }
 }
 
-static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
+static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen,
+                                   int err)
 {
        struct sock *sk;
        struct hlist_node *tmp;
@@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
 
                                nfc_llcp_accept_unlink(accept_sk);
 
+                               if (err)
+                                       accept_sk->sk_err = err;
                                accept_sk->sk_state = LLCP_CLOSED;
+                               accept_sk->sk_state_change(sk);
 
                                bh_unlock_sock(accept_sk);
 
@@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
                        continue;
                }
 
+               if (err)
+                       sk->sk_err = err;
                sk->sk_state = LLCP_CLOSED;
+               sk->sk_state_change(sk);
 
                bh_unlock_sock(sk);
 
@@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
        }
 
        write_unlock(&local->sockets.lock);
+
+       /*
+        * If we want to keep the listening sockets alive,
+        * we don't touch the RAW ones.
+        */
+       if (listen == true)
+               return;
+
+       write_lock(&local->raw_sockets.lock);
+
+       sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
+               llcp_sock = nfc_llcp_sock(sk);
+
+               bh_lock_sock(sk);
+
+               nfc_llcp_socket_purge(llcp_sock);
+
+               if (err)
+                       sk->sk_err = err;
+               sk->sk_state = LLCP_CLOSED;
+               sk->sk_state_change(sk);
+
+               bh_unlock_sock(sk);
+
+               sock_orphan(sk);
+
+               sk_del_node_init(sk);
+       }
+
+       write_unlock(&local->raw_sockets.lock);
 }
 
 struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
@@ -142,20 +179,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
        return local;
 }
 
-static void local_release(struct kref *ref)
+static void local_cleanup(struct nfc_llcp_local *local, bool listen)
 {
-       struct nfc_llcp_local *local;
-
-       local = container_of(ref, struct nfc_llcp_local, ref);
-
-       list_del(&local->list);
-       nfc_llcp_socket_release(local, false);
+       nfc_llcp_socket_release(local, listen, ENXIO);
        del_timer_sync(&local->link_timer);
        skb_queue_purge(&local->tx_queue);
        cancel_work_sync(&local->tx_work);
        cancel_work_sync(&local->rx_work);
        cancel_work_sync(&local->timeout_work);
        kfree_skb(local->rx_pending);
+}
+
+static void local_release(struct kref *ref)
+{
+       struct nfc_llcp_local *local;
+
+       local = container_of(ref, struct nfc_llcp_local, ref);
+
+       list_del(&local->list);
+       local_cleanup(local, false);
        kfree(local);
 }
 
@@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
                return;
 
        /* Close and purge all existing sockets */
-       nfc_llcp_socket_release(local, true);
+       nfc_llcp_socket_release(local, true, 0);
 }
 
 void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
@@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
                return;
        }
 
+       local_cleanup(local, false);
+
        nfc_llcp_local_put(local);
 }
 
index 5332751943a9ec564befadda63a5a3749d7434c1..5c7cdf3f2a83b5a6a85033744121727ecddba70d 100644 (file)
@@ -278,6 +278,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
 
                        pr_debug("Returning sk state %d\n", sk->sk_state);
 
+                       sk_acceptq_removed(parent);
+
                        return sk;
                }
 
index ac2defeeba83ddbbb1ffcacb54deec0714fb85e0..d4d5363c7ba7868731cb9188ad9bc5ccd28b8304 100644 (file)
@@ -58,7 +58,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
 
        if (skb->ip_summed == CHECKSUM_COMPLETE)
                skb->csum = csum_sub(skb->csum, csum_partial(skb->data
-                                       + ETH_HLEN, VLAN_HLEN, 0));
+                                       + (2 * ETH_ALEN), VLAN_HLEN, 0));
 
        vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
        *current_tci = vhdr->h_vlan_TCI;
@@ -115,7 +115,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla
 
                if (skb->ip_summed == CHECKSUM_COMPLETE)
                        skb->csum = csum_add(skb->csum, csum_partial(skb->data
-                                       + ETH_HLEN, VLAN_HLEN, 0));
+                                       + (2 * ETH_ALEN), VLAN_HLEN, 0));
 
        }
        __vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
index e87a26506dbaecc3e09af9cc5c75a767bb303e95..a4b724708a1ab0b7d4aedffc07606b8fbfdac0a9 100644 (file)
@@ -394,6 +394,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 
        skb_copy_and_csum_dev(skb, nla_data(nla));
 
+       genlmsg_end(user_skb, upcall);
        err = genlmsg_unicast(net, user_skb, upcall_info->portid);
 
 out:
@@ -1690,6 +1691,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
        if (IS_ERR(vport))
                goto exit_unlock;
 
+       err = 0;
        reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
                                         OVS_VPORT_CMD_NEW);
        if (IS_ERR(reply)) {
@@ -1771,6 +1773,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
        if (IS_ERR(reply))
                goto exit_unlock;
 
+       err = 0;
        ovs_dp_detach_port(vport);
 
        genl_notify(reply, genl_info_net(info), info->snd_portid,
index 20605ecf100bda104dd5fa7c536787149f0b2ea8..fe0e4215c73d6045469ba006722ef223d43ebd66 100644 (file)
@@ -482,7 +482,11 @@ static __be16 parse_ethertype(struct sk_buff *skb)
                return htons(ETH_P_802_2);
 
        __skb_pull(skb, sizeof(struct llc_snap_hdr));
-       return llc->ethertype;
+
+       if (ntohs(llc->ethertype) >= 1536)
+               return llc->ethertype;
+
+       return htons(ETH_P_802_2);
 }
 
 static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
index 670cbc3518ded5930f900eaca7e0677835cf750b..2130d61c384a227e0d7f5093e285054497e8fb40 100644 (file)
@@ -43,8 +43,7 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 
        /* Make our own copy of the packet.  Otherwise we will mangle the
         * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
-        * (No one comes after us, since we tell handle_bridge() that we took
-        * the packet.) */
+        */
        skb = skb_share_check(skb, GFP_ATOMIC);
        if (unlikely(!skb))
                return;
index ba717cc038b3183fc24692e4b76cae8da6cbfbe4..f6b8132ce4cb7380a6bca860b4e50a2aa6756772 100644 (file)
@@ -325,8 +325,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
  * @skb: skb that was received
  *
  * Must be called with rcu_read_lock.  The packet cannot be shared and
- * skb->data should point to the Ethernet header.  The caller must have already
- * called compute_ip_summed() to initialize the checksumming fields.
+ * skb->data should point to the Ethernet header.
  */
 void ovs_vport_receive(struct vport *vport, struct sk_buff *skb)
 {
index f0a4658f3273e2e87bac1ae88058e1209ed3332a..aba232f9f3081968081edb0ed6ece382e954b653 100644 (file)
@@ -82,10 +82,7 @@ static void rds_message_purge(struct rds_message *rm)
 void rds_message_put(struct rds_message *rm)
 {
        rdsdebug("put rm %p ref %d\n", rm, atomic_read(&rm->m_refcount));
-       if (atomic_read(&rm->m_refcount) == 0) {
-printk(KERN_CRIT "danger refcount zero on %p\n", rm);
-WARN_ON(1);
-       }
+       WARN(!atomic_read(&rm->m_refcount), "danger refcount zero on %p\n", rm);
        if (atomic_dec_and_test(&rm->m_refcount)) {
                BUG_ON(!list_empty(&rm->m_sock_item));
                BUG_ON(!list_empty(&rm->m_conn_item));
@@ -197,6 +194,9 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp)
 {
        struct rds_message *rm;
 
+       if (extra_len > KMALLOC_MAX_SIZE - sizeof(struct rds_message))
+               return NULL;
+
        rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp);
        if (!rm)
                goto out;
index 7be790d60b900d30053256b2f6cb1753056b0ba3..73be187d389ed044c886d22e4960905283d9de87 100644 (file)
@@ -87,6 +87,7 @@ void rds_stats_info_copy(struct rds_info_iterator *iter,
        for (i = 0; i < nr; i++) {
                BUG_ON(strlen(names[i]) >= sizeof(ctr.name));
                strncpy(ctr.name, names[i], sizeof(ctr.name) - 1);
+               ctr.name[sizeof(ctr.name) - 1] = '\0';
                ctr.value = values[i];
 
                rds_info_copy(iter, &ctr, sizeof(ctr));
index e9a77f621c3dfc87d49ed534003a20ceb1d98f8d..d51852bba01c981c9f9834dad82cfbcfec904508 100644 (file)
@@ -298,6 +298,10 @@ static void qfq_update_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
            new_num_classes == q->max_agg_classes - 1) /* agg no more full */
                hlist_add_head(&agg->nonfull_next, &q->nonfull_aggs);
 
+       /* The next assignment may let
+        * agg->initial_budget > agg->budgetmax
+        * hold, we will take it into account in charge_actual_service().
+        */
        agg->budgetmax = new_num_classes * agg->lmax;
        new_agg_weight = agg->class_weight * new_num_classes;
        agg->inv_w = ONE_FP/new_agg_weight;
@@ -817,7 +821,7 @@ static void qfq_make_eligible(struct qfq_sched *q)
        unsigned long old_vslot = q->oldV >> q->min_slot_shift;
 
        if (vslot != old_vslot) {
-               unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1;
+               unsigned long mask = (1ULL << fls(vslot ^ old_vslot)) - 1;
                qfq_move_groups(q, mask, IR, ER);
                qfq_move_groups(q, mask, IB, EB);
        }
@@ -988,12 +992,23 @@ static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
 /* Update F according to the actual service received by the aggregate. */
 static inline void charge_actual_service(struct qfq_aggregate *agg)
 {
-       /* compute the service received by the aggregate */
-       u32 service_received = agg->initial_budget - agg->budget;
+       /* Compute the service received by the aggregate, taking into
+        * account that, after decreasing the number of classes in
+        * agg, it may happen that
+        * agg->initial_budget - agg->budget > agg->bugdetmax
+        */
+       u32 service_received = min(agg->budgetmax,
+                                  agg->initial_budget - agg->budget);
 
        agg->F = agg->S + (u64)service_received * agg->inv_w;
 }
 
+static inline void qfq_update_agg_ts(struct qfq_sched *q,
+                                    struct qfq_aggregate *agg,
+                                    enum update_reason reason);
+
+static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg);
+
 static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
 {
        struct qfq_sched *q = qdisc_priv(sch);
@@ -1021,7 +1036,7 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
                in_serv_agg->initial_budget = in_serv_agg->budget =
                        in_serv_agg->budgetmax;
 
-               if (!list_empty(&in_serv_agg->active))
+               if (!list_empty(&in_serv_agg->active)) {
                        /*
                         * Still active: reschedule for
                         * service. Possible optimization: if no other
@@ -1032,8 +1047,9 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
                         * handle it, we would need to maintain an
                         * extra num_active_aggs field.
                        */
-                       qfq_activate_agg(q, in_serv_agg, requeue);
-               else if (sch->q.qlen == 0) { /* no aggregate to serve */
+                       qfq_update_agg_ts(q, in_serv_agg, requeue);
+                       qfq_schedule_agg(q, in_serv_agg);
+               } else if (sch->q.qlen == 0) { /* no aggregate to serve */
                        q->in_serv_agg = NULL;
                        return NULL;
                }
@@ -1052,7 +1068,15 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
        qdisc_bstats_update(sch, skb);
 
        agg_dequeue(in_serv_agg, cl, len);
-       in_serv_agg->budget -= len;
+       /* If lmax is lowered, through qfq_change_class, for a class
+        * owning pending packets with larger size than the new value
+        * of lmax, then the following condition may hold.
+        */
+       if (unlikely(in_serv_agg->budget < len))
+               in_serv_agg->budget = 0;
+       else
+               in_serv_agg->budget -= len;
+
        q->V += (u64)len * IWSUM;
        pr_debug("qfq dequeue: len %u F %lld now %lld\n",
                 len, (unsigned long long) in_serv_agg->F,
@@ -1217,17 +1241,11 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        cl->deficit = agg->lmax;
        list_add_tail(&cl->alist, &agg->active);
 
-       if (list_first_entry(&agg->active, struct qfq_class, alist) != cl)
-               return err; /* aggregate was not empty, nothing else to do */
+       if (list_first_entry(&agg->active, struct qfq_class, alist) != cl ||
+           q->in_serv_agg == agg)
+               return err; /* non-empty or in service, nothing else to do */
 
-       /* recharge budget */
-       agg->initial_budget = agg->budget = agg->budgetmax;
-
-       qfq_update_agg_ts(q, agg, enqueue);
-       if (q->in_serv_agg == NULL)
-               q->in_serv_agg = agg;
-       else if (agg != q->in_serv_agg)
-               qfq_schedule_agg(q, agg);
+       qfq_activate_agg(q, agg, enqueue);
 
        return err;
 }
@@ -1261,7 +1279,8 @@ static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg)
                /* group was surely ineligible, remove */
                __clear_bit(grp->index, &q->bitmaps[IR]);
                __clear_bit(grp->index, &q->bitmaps[IB]);
-       } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+       } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V) &&
+                  q->in_serv_agg == NULL)
                q->V = roundedS;
 
        grp->S = roundedS;
@@ -1284,8 +1303,15 @@ skip_update:
 static void qfq_activate_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
                             enum update_reason reason)
 {
+       agg->initial_budget = agg->budget = agg->budgetmax; /* recharge budg. */
+
        qfq_update_agg_ts(q, agg, reason);
-       qfq_schedule_agg(q, agg);
+       if (q->in_serv_agg == NULL) { /* no aggr. in service or scheduled */
+               q->in_serv_agg = agg; /* start serving this aggregate */
+                /* update V: to be in service, agg must be eligible */
+               q->oldV = q->V = agg->S;
+       } else if (agg != q->in_serv_agg)
+               qfq_schedule_agg(q, agg);
 }
 
 static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
@@ -1357,8 +1383,6 @@ static void qfq_deactivate_agg(struct qfq_sched *q, struct qfq_aggregate *agg)
                        __set_bit(grp->index, &q->bitmaps[s]);
                }
        }
-
-       qfq_update_eligible(q);
 }
 
 static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
index 43cd0dd9149d42e2739985bd8bb4ea15c977de06..d2709e2b7be6642d47a691d27c983a937c7e8648 100644 (file)
@@ -1079,7 +1079,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
                        transports) {
 
                if (transport == active)
-                       break;
+                       continue;
                list_for_each_entry(chunk, &transport->transmitted,
                                transmitted_list) {
                        if (key == chunk->subh.data_hdr->tsn) {
index 2b3ef03c60984050d542834433bd9a1e0ef6645a..12ed45dbe75d6b779fd0dcf4d38f6126e23c03fb 100644 (file)
@@ -155,7 +155,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 
        /* SCTP-AUTH extensions*/
        INIT_LIST_HEAD(&ep->endpoint_shared_keys);
-       null_key = sctp_auth_shkey_create(0, GFP_KERNEL);
+       null_key = sctp_auth_shkey_create(0, gfp);
        if (!null_key)
                goto nomem;
 
index 5131fcfedb03c0b09e8c7e451341cebd82e49692..de1a0138317f482c028ce583c335501b14d9f917 100644 (file)
@@ -2082,7 +2082,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net,
        }
 
        /* Delete the tempory new association. */
-       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC, SCTP_ASOC(new_asoc));
        sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
 
        /* Restore association pointer to provide SCTP command interpeter
index c99458df3f3fd458eac2d5f5388b6fba6aed4e3a..b9070736b8d9a24383be81b1764d191e854d3e63 100644 (file)
@@ -5653,6 +5653,9 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
        if (len < sizeof(sctp_assoc_t))
                return -EINVAL;
 
+       /* Allow the struct to grow and fill in as much as possible */
+       len = min_t(size_t, len, sizeof(sas));
+
        if (copy_from_user(&sas, optval, len))
                return -EFAULT;
 
@@ -5686,9 +5689,6 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
        /* Mark beginning of a new observation period */
        asoc->stats.max_obs_rto = asoc->rto_min;
 
-       /* Allow the struct to grow and fill in as much as possible */
-       len = min_t(size_t, len, sizeof(sas));
-
        if (put_user(len, optlen))
                return -EFAULT;
 
index 442ad4ed6315fab99ec5b78d012e65a8236e2fae..825ea94415b39818f637b54c5abe112394edc322 100644 (file)
@@ -41,8 +41,6 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-#define MAX_KMALLOC_SIZE       131072
-
 static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
                                            __u16 out);
 
@@ -65,7 +63,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
        int size;
 
        size = sctp_ssnmap_size(in, out);
-       if (size <= MAX_KMALLOC_SIZE)
+       if (size <= KMALLOC_MAX_SIZE)
                retval = kmalloc(size, gfp);
        else
                retval = (struct sctp_ssnmap *)
@@ -82,7 +80,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
        return retval;
 
 fail_map:
-       if (size <= MAX_KMALLOC_SIZE)
+       if (size <= KMALLOC_MAX_SIZE)
                kfree(retval);
        else
                free_pages((unsigned long)retval, get_order(size));
@@ -124,7 +122,7 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map)
                int size;
 
                size = sctp_ssnmap_size(map->in.len, map->out.len);
-               if (size <= MAX_KMALLOC_SIZE)
+               if (size <= KMALLOC_MAX_SIZE)
                        kfree(map);
                else
                        free_pages((unsigned long)map, get_order(size));
index 5f25e0c92c31e48460536cd2bb0fc29549172b93..396c45174e5b696d90c6940d7aa0ce511c70293c 100644 (file)
@@ -51,7 +51,7 @@
 static void sctp_tsnmap_update(struct sctp_tsnmap *map);
 static void sctp_tsnmap_find_gap_ack(unsigned long *map, __u16 off,
                                     __u16 len, __u16 *start, __u16 *end);
-static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 gap);
+static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 size);
 
 /* Initialize a block of memory as a tsnmap.  */
 struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
@@ -124,7 +124,7 @@ int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn,
 
        gap = tsn - map->base_tsn;
 
-       if (gap >= map->len && !sctp_tsnmap_grow(map, gap))
+       if (gap >= map->len && !sctp_tsnmap_grow(map, gap + 1))
                return -ENOMEM;
 
        if (!sctp_tsnmap_has_gap(map) && gap == 0) {
@@ -360,23 +360,24 @@ __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
        return ngaps;
 }
 
-static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 gap)
+static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 size)
 {
        unsigned long *new;
        unsigned long inc;
        u16  len;
 
-       if (gap >= SCTP_TSN_MAP_SIZE)
+       if (size > SCTP_TSN_MAP_SIZE)
                return 0;
 
-       inc = ALIGN((gap - map->len),BITS_PER_LONG) + SCTP_TSN_MAP_INCREMENT;
+       inc = ALIGN((size - map->len), BITS_PER_LONG) + SCTP_TSN_MAP_INCREMENT;
        len = min_t(u16, map->len + inc, SCTP_TSN_MAP_SIZE);
 
        new = kzalloc(len>>3, GFP_ATOMIC);
        if (!new)
                return 0;
 
-       bitmap_copy(new, map->tsn_map, map->max_tsn_seen - map->base_tsn);
+       bitmap_copy(new, map->tsn_map,
+               map->max_tsn_seen - map->cumulative_tsn_ack_point);
        kfree(map->tsn_map);
        map->tsn_map = new;
        map->len = len;
index ada17464b65bf23a089c036fba47989a2a1d4b8b..0fd5b3d2df03158d17f0d356825209e571e419d7 100644 (file)
@@ -106,6 +106,7 @@ int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
 {
        struct sk_buff_head temp;
        struct sctp_ulpevent *event;
+       int event_eor = 0;
 
        /* Create an event from the incoming chunk. */
        event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, gfp);
@@ -127,10 +128,12 @@ int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
        /* Send event to the ULP.  'event' is the sctp_ulpevent for
         * very first SKB on the 'temp' list.
         */
-       if (event)
+       if (event) {
+               event_eor = (event->msg_flags & MSG_EOR) ? 1 : 0;
                sctp_ulpq_tail_event(ulpq, event);
+       }
 
-       return 0;
+       return event_eor;
 }
 
 /* Add a new event for propagation to the ULP.  */
@@ -540,14 +543,19 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq *ulpq)
                ctsn = cevent->tsn;
 
                switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
+               case SCTP_DATA_FIRST_FRAG:
+                       if (!first_frag)
+                               return NULL;
+                       goto done;
                case SCTP_DATA_MIDDLE_FRAG:
                        if (!first_frag) {
                                first_frag = pos;
                                next_tsn = ctsn + 1;
                                last_frag = pos;
-                       } else if (next_tsn == ctsn)
+                       } else if (next_tsn == ctsn) {
                                next_tsn++;
-                       else
+                               last_frag = pos;
+                       } else
                                goto done;
                        break;
                case SCTP_DATA_LAST_FRAG:
@@ -651,6 +659,14 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *ulpq)
                        } else
                                goto done;
                        break;
+
+               case SCTP_DATA_LAST_FRAG:
+                       if (!first_frag)
+                               return NULL;
+                       else
+                               goto done;
+                       break;
+
                default:
                        return NULL;
                }
@@ -962,20 +978,43 @@ static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq,
                struct sk_buff_head *list, __u16 needed)
 {
        __u16 freed = 0;
-       __u32 tsn;
-       struct sk_buff *skb;
+       __u32 tsn, last_tsn;
+       struct sk_buff *skb, *flist, *last;
        struct sctp_ulpevent *event;
        struct sctp_tsnmap *tsnmap;
 
        tsnmap = &ulpq->asoc->peer.tsn_map;
 
-       while ((skb = __skb_dequeue_tail(list)) != NULL) {
-               freed += skb_headlen(skb);
+       while ((skb = skb_peek_tail(list)) != NULL) {
                event = sctp_skb2event(skb);
                tsn = event->tsn;
 
+               /* Don't renege below the Cumulative TSN ACK Point. */
+               if (TSN_lte(tsn, sctp_tsnmap_get_ctsn(tsnmap)))
+                       break;
+
+               /* Events in ordering queue may have multiple fragments
+                * corresponding to additional TSNs.  Sum the total
+                * freed space; find the last TSN.
+                */
+               freed += skb_headlen(skb);
+               flist = skb_shinfo(skb)->frag_list;
+               for (last = flist; flist; flist = flist->next) {
+                       last = flist;
+                       freed += skb_headlen(last);
+               }
+               if (last)
+                       last_tsn = sctp_skb2event(last)->tsn;
+               else
+                       last_tsn = tsn;
+
+               /* Unlink the event, then renege all applicable TSNs. */
+               __skb_unlink(skb, list);
                sctp_ulpevent_free(event);
-               sctp_tsnmap_renege(tsnmap, tsn);
+               while (TSN_lte(tsn, last_tsn)) {
+                       sctp_tsnmap_renege(tsnmap, tsn);
+                       tsn++;
+               }
                if (freed >= needed)
                        return freed;
        }
@@ -1002,16 +1041,28 @@ void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
        struct sctp_ulpevent *event;
        struct sctp_association *asoc;
        struct sctp_sock *sp;
+       __u32 ctsn;
+       struct sk_buff *skb;
 
        asoc = ulpq->asoc;
        sp = sctp_sk(asoc->base.sk);
 
        /* If the association is already in Partial Delivery mode
-        * we have noting to do.
+        * we have nothing to do.
         */
        if (ulpq->pd_mode)
                return;
 
+       /* Data must be at or below the Cumulative TSN ACK Point to
+        * start partial delivery.
+        */
+       skb = skb_peek(&asoc->ulpq.reasm);
+       if (skb != NULL) {
+               ctsn = sctp_skb2event(skb)->tsn;
+               if (!TSN_lte(ctsn, sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map)))
+                       return;
+       }
+
        /* If the user enabled fragment interleave socket option,
         * multiple associations can enter partial delivery.
         * Otherwise, we can only enter partial delivery if the
@@ -1054,12 +1105,16 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
        }
        /* If able to free enough room, accept this chunk. */
        if (chunk && (freed >= needed)) {
-               __u32 tsn;
-               tsn = ntohl(chunk->subh.data_hdr->tsn);
-               sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport);
-               sctp_ulpq_tail_data(ulpq, chunk, gfp);
-
-               sctp_ulpq_partial_delivery(ulpq, gfp);
+               int retval;
+               retval = sctp_ulpq_tail_data(ulpq, chunk, gfp);
+               /*
+                * Enter partial delivery if chunk has not been
+                * delivered; otherwise, drain the reassembly queue.
+                */
+               if (retval <= 0)
+                       sctp_ulpq_partial_delivery(ulpq, gfp);
+               else if (retval == 1)
+                       sctp_ulpq_reasm_drain(ulpq);
        }
 
        sk_mem_reclaim(asoc->base.sk);
index 88f759adf3afba28af3b1a694220c18f5e895616..9663df63e3d166534cbfa71099110fbf89f00478 100644 (file)
@@ -1173,15 +1173,6 @@ static int sock_mmap(struct file *file, struct vm_area_struct *vma)
 
 static int sock_close(struct inode *inode, struct file *filp)
 {
-       /*
-        *      It was possible the inode is NULL we were
-        *      closing an unfinished socket.
-        */
-
-       if (!inode) {
-               printk(KERN_DEBUG "sock_close: NULL inode\n");
-               return 0;
-       }
        sock_release(SOCKET_I(inode));
        return 0;
 }
index f7d34e7b6f818ba52bec46795b83062cbdf5a71e..5ead60550895f848ba2348bba3bbbfc50ddea7ea 100644 (file)
@@ -447,17 +447,21 @@ static int rsc_parse(struct cache_detail *cd,
        else {
                int N, i;
 
+               /*
+                * NOTE: we skip uid_valid()/gid_valid() checks here:
+                * instead, * -1 id's are later mapped to the
+                * (export-specific) anonymous id by nfsd_setuser.
+                *
+                * (But supplementary gid's get no such special
+                * treatment so are checked for validity here.)
+                */
                /* uid */
                rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
-               if (!uid_valid(rsci.cred.cr_uid))
-                       goto out;
 
                /* gid */
                if (get_int(&mesg, &id))
                        goto out;
                rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
-               if (!gid_valid(rsci.cred.cr_gid))
-                       goto out;
 
                /* number of additional gid's */
                if (get_int(&mesg, &N))
index 25d58e766014bf751ba404cac60893b2cfc5ecf9..d9828b6799a3a17f424d5a119a9915f50c5b4601 100644 (file)
@@ -1461,7 +1461,7 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
 static ssize_t cache_read_procfs(struct file *filp, char __user *buf,
                                 size_t count, loff_t *ppos)
 {
-       struct cache_detail *cd = PDE(file_inode(filp))->data;
+       struct cache_detail *cd = PDE_DATA(file_inode(filp));
 
        return cache_read(filp, buf, count, ppos, cd);
 }
@@ -1469,14 +1469,14 @@ static ssize_t cache_read_procfs(struct file *filp, char __user *buf,
 static ssize_t cache_write_procfs(struct file *filp, const char __user *buf,
                                  size_t count, loff_t *ppos)
 {
-       struct cache_detail *cd = PDE(file_inode(filp))->data;
+       struct cache_detail *cd = PDE_DATA(file_inode(filp));
 
        return cache_write(filp, buf, count, ppos, cd);
 }
 
 static unsigned int cache_poll_procfs(struct file *filp, poll_table *wait)
 {
-       struct cache_detail *cd = PDE(file_inode(filp))->data;
+       struct cache_detail *cd = PDE_DATA(file_inode(filp));
 
        return cache_poll(filp, wait, cd);
 }
@@ -1485,21 +1485,21 @@ static long cache_ioctl_procfs(struct file *filp,
                               unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return cache_ioctl(inode, filp, cmd, arg, cd);
 }
 
 static int cache_open_procfs(struct inode *inode, struct file *filp)
 {
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return cache_open(inode, filp, cd);
 }
 
 static int cache_release_procfs(struct inode *inode, struct file *filp)
 {
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return cache_release(inode, filp, cd);
 }
@@ -1517,14 +1517,14 @@ static const struct file_operations cache_file_operations_procfs = {
 
 static int content_open_procfs(struct inode *inode, struct file *filp)
 {
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return content_open(inode, filp, cd);
 }
 
 static int content_release_procfs(struct inode *inode, struct file *filp)
 {
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return content_release(inode, filp, cd);
 }
@@ -1538,14 +1538,14 @@ static const struct file_operations content_file_operations_procfs = {
 
 static int open_flush_procfs(struct inode *inode, struct file *filp)
 {
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return open_flush(inode, filp, cd);
 }
 
 static int release_flush_procfs(struct inode *inode, struct file *filp)
 {
-       struct cache_detail *cd = PDE(inode)->data;
+       struct cache_detail *cd = PDE_DATA(inode);
 
        return release_flush(inode, filp, cd);
 }
@@ -1553,7 +1553,7 @@ static int release_flush_procfs(struct inode *inode, struct file *filp)
 static ssize_t read_flush_procfs(struct file *filp, char __user *buf,
                            size_t count, loff_t *ppos)
 {
-       struct cache_detail *cd = PDE(file_inode(filp))->data;
+       struct cache_detail *cd = PDE_DATA(file_inode(filp));
 
        return read_flush(filp, buf, count, ppos, cd);
 }
@@ -1562,7 +1562,7 @@ static ssize_t write_flush_procfs(struct file *filp,
                                  const char __user *buf,
                                  size_t count, loff_t *ppos)
 {
-       struct cache_detail *cd = PDE(file_inode(filp))->data;
+       struct cache_detail *cd = PDE_DATA(file_inode(filp));
 
        return write_flush(filp, buf, count, ppos, cd);
 }
index 7b9b40224a27768bb87014fdaa89d82413e7496f..a9129f8d70706f5e33ac8f39cb3ea8a3e5825ca2 100644 (file)
@@ -1174,6 +1174,8 @@ static struct file_system_type rpc_pipe_fs_type = {
        .mount          = rpc_mount,
        .kill_sb        = rpc_kill_sb,
 };
+MODULE_ALIAS_FS("rpc_pipefs");
+MODULE_ALIAS("rpc_pipefs");
 
 static void
 init_once(void *foo)
@@ -1218,6 +1220,3 @@ void unregister_rpc_pipefs(void)
        kmem_cache_destroy(rpc_inode_cachep);
        unregister_filesystem(&rpc_pipe_fs_type);
 }
-
-/* Make 'mount -t rpc_pipefs ...' autoload this module. */
-MODULE_ALIAS("rpc_pipefs");
index fb20f25ddec9b70c805ad65d675441d02b62055b..f8529fc8e54275c5b7b9809f0219f20608ffb472 100644 (file)
@@ -180,6 +180,8 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
                list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
        task->tk_waitqueue = queue;
        queue->qlen++;
+       /* barrier matches the read in rpc_wake_up_task_queue_locked() */
+       smp_wmb();
        rpc_set_queued(task);
 
        dprintk("RPC: %5u added to queue %p \"%s\"\n",
@@ -430,8 +432,11 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task
  */
 static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task)
 {
-       if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue)
-               __rpc_do_wake_up_task(queue, task);
+       if (RPC_IS_QUEUED(task)) {
+               smp_rmb();
+               if (task->tk_waitqueue == queue)
+                       __rpc_do_wake_up_task(queue, task);
+       }
 }
 
 /*
index bc2068ee795b95d7fdec5d57503ab3919ff3e97d..21b75cb08c039285100134281bbe8cbc7749b09a 100644 (file)
@@ -64,7 +64,7 @@ static int rpc_proc_show(struct seq_file *seq, void *v) {
 
 static int rpc_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, rpc_proc_show, PDE(inode)->data);
+       return single_open(file, rpc_proc_show, PDE_DATA(inode));
 }
 
 static const struct file_operations rpc_proc_fops = {
index c1d8476b76929b4300d967dd795aa6c2ce38f7a0..3d02130828da671066b40aa7dd769cf6a7bd4a74 100644 (file)
@@ -849,6 +849,14 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
                xs_tcp_shutdown(xprt);
 }
 
+static void xs_local_destroy(struct rpc_xprt *xprt)
+{
+       xs_close(xprt);
+       xs_free_peer_addresses(xprt);
+       xprt_free(xprt);
+       module_put(THIS_MODULE);
+}
+
 /**
  * xs_destroy - prepare to shutdown a transport
  * @xprt: doomed transport
@@ -862,10 +870,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
 
        cancel_delayed_work_sync(&transport->connect_worker);
 
-       xs_close(xprt);
-       xs_free_peer_addresses(xprt);
-       xprt_free(xprt);
-       module_put(THIS_MODULE);
+       xs_local_destroy(xprt);
 }
 
 static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -2482,7 +2487,7 @@ static struct rpc_xprt_ops xs_local_ops = {
        .send_request           = xs_local_send_request,
        .set_retrans_timeout    = xprt_set_retrans_timeout_def,
        .close                  = xs_close,
-       .destroy                = xs_destroy,
+       .destroy                = xs_local_destroy,
        .print_stats            = xs_local_print_stats,
 };
 
index 51be64f163ec166812660db8de26105b1c92eb46..971282b6f6a38fd056dd65d127b85f044b7c6041 100644 (file)
@@ -382,7 +382,7 @@ static void unix_sock_destructor(struct sock *sk)
 #endif
 }
 
-static int unix_release_sock(struct sock *sk, int embrion)
+static void unix_release_sock(struct sock *sk, int embrion)
 {
        struct unix_sock *u = unix_sk(sk);
        struct path path;
@@ -451,8 +451,6 @@ static int unix_release_sock(struct sock *sk, int embrion)
 
        if (unix_tot_inflight)
                unix_gc();              /* Garbage collect fds */
-
-       return 0;
 }
 
 static void init_peercred(struct sock *sk)
@@ -699,9 +697,10 @@ static int unix_release(struct socket *sock)
        if (!sk)
                return 0;
 
+       unix_release_sock(sk, 0);
        sock->sk = NULL;
 
-       return unix_release_sock(sk, 0);
+       return 0;
 }
 
 static int unix_autobind(struct socket *sock)
@@ -1413,8 +1412,8 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
        if (UNIXCB(skb).cred)
                return;
        if (test_bit(SOCK_PASSCRED, &sock->flags) ||
-           !other->sk_socket ||
-           test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
+           (other->sk_socket &&
+           test_bit(SOCK_PASSCRED, &other->sk_socket->flags))) {
                UNIXCB(skb).pid  = get_pid(task_tgid(current));
                UNIXCB(skb).cred = get_current_cred();
        }
index 5ffff039b0174eefb8f3967dc6f5307ea7cb2f8c..ea4155fe97334f91794dbb7a55f0dab28219c2a3 100644 (file)
@@ -367,8 +367,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
        rdev->wiphy.rts_threshold = (u32) -1;
        rdev->wiphy.coverage_class = 0;
 
-       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH |
-                              NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
+       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH;
 
        return &rdev->wiphy;
 }
index 1526c211db665ab3bf797aa981418b64d01d262d..dc0e59e53dbf3a3ea581ab5652cbac7d614e77ff 100644 (file)
@@ -430,24 +430,23 @@ static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
        return CCMP_TK_LEN;
 }
 
-static char *lib80211_ccmp_print_stats(char *p, void *priv)
+static void lib80211_ccmp_print_stats(struct seq_file *m, void *priv)
 {
        struct lib80211_ccmp_data *ccmp = priv;
 
-       p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-                    "tx_pn=%02x%02x%02x%02x%02x%02x "
-                    "rx_pn=%02x%02x%02x%02x%02x%02x "
-                    "format_errors=%d replays=%d decrypt_errors=%d\n",
-                    ccmp->key_idx, ccmp->key_set,
-                    ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2],
-                    ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5],
-                    ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2],
-                    ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5],
-                    ccmp->dot11RSNAStatsCCMPFormatErrors,
-                    ccmp->dot11RSNAStatsCCMPReplays,
-                    ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
-       return p;
+       seq_printf(m,
+                  "key[%d] alg=CCMP key_set=%d "
+                  "tx_pn=%02x%02x%02x%02x%02x%02x "
+                  "rx_pn=%02x%02x%02x%02x%02x%02x "
+                  "format_errors=%d replays=%d decrypt_errors=%d\n",
+                  ccmp->key_idx, ccmp->key_set,
+                  ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2],
+                  ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5],
+                  ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2],
+                  ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5],
+                  ccmp->dot11RSNAStatsCCMPFormatErrors,
+                  ccmp->dot11RSNAStatsCCMPReplays,
+                  ccmp->dot11RSNAStatsCCMPDecryptErrors);
 }
 
 static struct lib80211_crypto_ops lib80211_crypt_ccmp = {
index d475cfc8568f8616a98a567540f25bbbca6a0229..8c90ba79e56e33bfefba9b014d35f7d48bbe45ed 100644 (file)
@@ -703,30 +703,30 @@ static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
        return TKIP_KEY_LEN;
 }
 
-static char *lib80211_tkip_print_stats(char *p, void *priv)
+static void lib80211_tkip_print_stats(struct seq_file *m, void *priv)
 {
        struct lib80211_tkip_data *tkip = priv;
-       p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
-                    "tx_pn=%02x%02x%02x%02x%02x%02x "
-                    "rx_pn=%02x%02x%02x%02x%02x%02x "
-                    "replays=%d icv_errors=%d local_mic_failures=%d\n",
-                    tkip->key_idx, tkip->key_set,
-                    (tkip->tx_iv32 >> 24) & 0xff,
-                    (tkip->tx_iv32 >> 16) & 0xff,
-                    (tkip->tx_iv32 >> 8) & 0xff,
-                    tkip->tx_iv32 & 0xff,
-                    (tkip->tx_iv16 >> 8) & 0xff,
-                    tkip->tx_iv16 & 0xff,
-                    (tkip->rx_iv32 >> 24) & 0xff,
-                    (tkip->rx_iv32 >> 16) & 0xff,
-                    (tkip->rx_iv32 >> 8) & 0xff,
-                    tkip->rx_iv32 & 0xff,
-                    (tkip->rx_iv16 >> 8) & 0xff,
-                    tkip->rx_iv16 & 0xff,
-                    tkip->dot11RSNAStatsTKIPReplays,
-                    tkip->dot11RSNAStatsTKIPICVErrors,
-                    tkip->dot11RSNAStatsTKIPLocalMICFailures);
-       return p;
+       seq_printf(m,
+                  "key[%d] alg=TKIP key_set=%d "
+                  "tx_pn=%02x%02x%02x%02x%02x%02x "
+                  "rx_pn=%02x%02x%02x%02x%02x%02x "
+                  "replays=%d icv_errors=%d local_mic_failures=%d\n",
+                  tkip->key_idx, tkip->key_set,
+                  (tkip->tx_iv32 >> 24) & 0xff,
+                  (tkip->tx_iv32 >> 16) & 0xff,
+                  (tkip->tx_iv32 >> 8) & 0xff,
+                  tkip->tx_iv32 & 0xff,
+                  (tkip->tx_iv16 >> 8) & 0xff,
+                  tkip->tx_iv16 & 0xff,
+                  (tkip->rx_iv32 >> 24) & 0xff,
+                  (tkip->rx_iv32 >> 16) & 0xff,
+                  (tkip->rx_iv32 >> 8) & 0xff,
+                  tkip->rx_iv32 & 0xff,
+                  (tkip->rx_iv16 >> 8) & 0xff,
+                  tkip->rx_iv16 & 0xff,
+                  tkip->dot11RSNAStatsTKIPReplays,
+                  tkip->dot11RSNAStatsTKIPICVErrors,
+                  tkip->dot11RSNAStatsTKIPLocalMICFailures);
 }
 
 static struct lib80211_crypto_ops lib80211_crypt_tkip = {
index c1304018fc1c5e08247cc7882496a5688c3dcb85..1c292e4ea7b60682d5b1d3adf4bd62548de9ea72 100644 (file)
@@ -253,11 +253,10 @@ static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
        return wep->key_len;
 }
 
-static char *lib80211_wep_print_stats(char *p, void *priv)
+static void lib80211_wep_print_stats(struct seq_file *m, void *priv)
 {
        struct lib80211_wep_data *wep = priv;
-       p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
-       return p;
+       seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
 }
 
 static struct lib80211_crypto_ops lib80211_crypt_wep = {
index 35545ccc30fd0079acb1e848c4ecaff0cdc8b371..d44ab216c0ecd8b01d4386edf62cd07c3f2071db 100644 (file)
@@ -554,27 +554,8 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
        if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
            nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
                goto nla_put_failure;
-       if (chan->flags & IEEE80211_CHAN_RADAR) {
-               u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
-               if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
-                       goto nla_put_failure;
-               if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
-                               chan->dfs_state))
-                       goto nla_put_failure;
-               if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time))
-                       goto nla_put_failure;
-       }
-       if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
+       if ((chan->flags & IEEE80211_CHAN_RADAR) &&
+           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
                goto nla_put_failure;
 
        if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
@@ -900,9 +881,6 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
                    nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
                                c->max_interfaces))
                        goto nla_put_failure;
-               if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
-                               c->radar_detect_widths))
-                       goto nla_put_failure;
 
                nla_nest_end(msg, nl_combi);
        }
@@ -914,48 +892,6 @@ nla_put_failure:
        return -ENOBUFS;
 }
 
-#ifdef CONFIG_PM
-static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
-                                       struct sk_buff *msg)
-{
-       const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
-       struct nlattr *nl_tcp;
-
-       if (!tcp)
-               return 0;
-
-       nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
-       if (!nl_tcp)
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
-                       tcp->data_payload_max))
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
-                       tcp->data_payload_max))
-               return -ENOBUFS;
-
-       if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
-               return -ENOBUFS;
-
-       if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
-                               sizeof(*tcp->tok), tcp->tok))
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
-                       tcp->data_interval_max))
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
-                       tcp->wake_payload_max))
-               return -ENOBUFS;
-
-       nla_nest_end(msg, nl_tcp);
-       return 0;
-}
-#endif
-
 static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
                              struct cfg80211_registered_device *dev)
 {
@@ -1330,9 +1266,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
                                goto nla_put_failure;
                }
 
-               if (nl80211_send_wowlan_tcp_caps(dev, msg))
-                       goto nla_put_failure;
-
                nla_nest_end(msg, nl_wowlan);
        }
 #endif
@@ -1365,15 +1298,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
                        dev->wiphy.max_acl_mac_addrs))
                goto nla_put_failure;
 
-       if (dev->wiphy.extended_capabilities &&
-           (nla_put(msg, NL80211_ATTR_EXT_CAPA,
-                    dev->wiphy.extended_capabilities_len,
-                    dev->wiphy.extended_capabilities) ||
-            nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
-                    dev->wiphy.extended_capabilities_len,
-                    dev->wiphy.extended_capabilities_mask)))
-               goto nla_put_failure;
-
        return genlmsg_end(msg, hdr);
 
  nla_put_failure:
@@ -1383,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
 
 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
 {
-       int idx = 0;
+       int idx = 0, ret;
        int start = cb->args[0];
        struct cfg80211_registered_device *dev;
 
@@ -1393,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
                if (++idx <= start)
                        continue;
-               if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
-                                      cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                      dev) < 0) {
+               ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
+                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
+                                        dev);
+               if (ret < 0) {
+                       /*
+                        * If sending the wiphy data didn't fit (ENOBUFS or
+                        * EMSGSIZE returned), this SKB is still empty (so
+                        * it's not too big because another wiphy dataset is
+                        * already in the skb) and we've not tried to adjust
+                        * the dump allocation yet ... then adjust the alloc
+                        * size to be bigger, and return 1 but with the empty
+                        * skb. This results in an empty message being RX'ed
+                        * in userspace, but that is ignored.
+                        *
+                        * We can then retry with the larger buffer.
+                        */
+                       if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
+                           !skb->len &&
+                           cb->min_dump_alloc < 4096) {
+                               cb->min_dump_alloc = 4096;
+                               mutex_unlock(&cfg80211_mutex);
+                               return 1;
+                       }
                        idx--;
                        break;
                }
@@ -1412,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
        struct sk_buff *msg;
        struct cfg80211_registered_device *dev = info->user_ptr[0];
 
-       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       msg = nlmsg_new(4096, GFP_KERNEL);
        if (!msg)
                return -ENOMEM;
 
index 2ffde4631ae258262eeb0b8264bcc83d8a65822d..0917f047f2cfbf7e2ba86c453187b40db0e0146b 100644 (file)
@@ -187,7 +187,6 @@ static int x25_seq_forward_open(struct inode *inode, struct file *file)
 }
 
 static const struct file_operations x25_seq_socket_fops = {
-       .owner          = THIS_MODULE,
        .open           = x25_seq_socket_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -195,7 +194,6 @@ static const struct file_operations x25_seq_socket_fops = {
 };
 
 static const struct file_operations x25_seq_route_fops = {
-       .owner          = THIS_MODULE,
        .open           = x25_seq_route_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -203,55 +201,38 @@ static const struct file_operations x25_seq_route_fops = {
 };
 
 static const struct file_operations x25_seq_forward_fops = {
-       .owner          = THIS_MODULE,
        .open           = x25_seq_forward_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = seq_release,
 };
 
-static struct proc_dir_entry *x25_proc_dir;
-
 int __init x25_proc_init(void)
 {
-       struct proc_dir_entry *p;
-       int rc = -ENOMEM;
+       if (!proc_mkdir("x25", init_net.proc_net))
+               return -ENOMEM;
 
-       x25_proc_dir = proc_mkdir("x25", init_net.proc_net);
-       if (!x25_proc_dir)
+       if (!proc_create("x25/route", S_IRUGO, init_net.proc_net,
+                       &x25_seq_route_fops))
                goto out;
 
-       p = proc_create("route", S_IRUGO, x25_proc_dir, &x25_seq_route_fops);
-       if (!p)
-               goto out_route;
-
-       p = proc_create("socket", S_IRUGO, x25_proc_dir, &x25_seq_socket_fops);
-       if (!p)
-               goto out_socket;
+       if (!proc_create("x25/socket", S_IRUGO, init_net.proc_net,
+                       &x25_seq_socket_fops))
+               goto out;
 
-       p = proc_create("forward", S_IRUGO, x25_proc_dir,
-                       &x25_seq_forward_fops);
-       if (!p)
-               goto out_forward;
-       rc = 0;
+       if (!proc_create("x25/forward", S_IRUGO, init_net.proc_net,
+                       &x25_seq_forward_fops))
+               goto out;
+       return 0;
 
 out:
-       return rc;
-out_forward:
-       remove_proc_entry("socket", x25_proc_dir);
-out_socket:
-       remove_proc_entry("route", x25_proc_dir);
-out_route:
-       remove_proc_entry("x25", init_net.proc_net);
-       goto out;
+       remove_proc_subtree("x25", init_net.proc_net);
+       return -ENOMEM;
 }
 
 void __exit x25_proc_exit(void)
 {
-       remove_proc_entry("forward", x25_proc_dir);
-       remove_proc_entry("route", x25_proc_dir);
-       remove_proc_entry("socket", x25_proc_dir);
-       remove_proc_entry("x25", init_net.proc_net);
+       remove_proc_subtree("x25", init_net.proc_net);
 }
 
 #else /* CONFIG_PROC_FS */
index 25f216a841d5fcd734c4b234541aed998b561852..477d137c0557b8b70571d9e6e0873e2af221d53b 100644 (file)
@@ -14,7 +14,7 @@ kbuild-file := $(srctree)/$(obj)/Kbuild
 include $(kbuild-file)
 
 # called may set destination dir (when installing to asm/)
-_dst := $(or $(destination-y),$(dst),$(obj))
+_dst := $(if $(destination-y),$(destination-y),$(if $(dst),$(dst),$(obj)))
 
 old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
 ifneq ($(wildcard $(old-kbuild-file)),)
@@ -48,13 +48,14 @@ all-files     := $(header-y) $(genhdr-y) $(wrapper-files)
 output-files  := $(addprefix $(installdir)/, $(all-files))
 
 input-files   := $(foreach hdr, $(header-y), \
-                  $(or \
+                  $(if $(wildcard $(srcdir)/$(hdr)), \
                        $(wildcard $(srcdir)/$(hdr)), \
-                       $(wildcard $(oldsrcdir)/$(hdr)), \
-                       $(error Missing UAPI file $(srcdir)/$(hdr)) \
+                       $(if $(wildcard $(oldsrcdir)/$(hdr)), \
+                               $(wildcard $(oldsrcdir)/$(hdr)), \
+                               $(error Missing UAPI file $(srcdir)/$(hdr))) \
                   )) \
                 $(foreach hdr, $(genhdr-y), \
-                  $(or \
+                  $(if $(wildcard $(gendir)/$(hdr)), \
                        $(wildcard $(gendir)/$(hdr)), \
                        $(error Missing generated UAPI file $(gendir)/$(hdr)) \
                   ))
index 1c261763f4799180432f2162a096579007243203..d65fa7fa29ba1a53b1ef4fb6d76c7aeafb7da65a 100644 (file)
@@ -40,12 +40,12 @@ static long compat_keyctl_instantiate_key_iov(
                                           ARRAY_SIZE(iovstack),
                                           iovstack, &iov);
        if (ret < 0)
-               return ret;
+               goto err;
        if (ret == 0)
                goto no_payload_free;
 
        ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
-
+err:
        if (iov != iovstack)
                kfree(iov);
        return ret;
index 58dfe089094793030f56fdb895f6621e403e4157..42defae1e161632e93b13b8194af1a30a09f2492 100644 (file)
@@ -57,7 +57,7 @@ int install_user_keyrings(void)
 
        kenter("%p{%u}", user, uid);
 
-       if (user->uid_keyring) {
+       if (user->uid_keyring && user->session_keyring) {
                kleave(" = 0 [exist]");
                return 0;
        }
@@ -839,7 +839,7 @@ void key_change_session_keyring(struct callback_head *twork)
        new-> sgid      = old-> sgid;
        new->fsgid      = old->fsgid;
        new->user       = get_uid(old->user);
-       new->user_ns    = get_user_ns(new->user_ns);
+       new->user_ns    = get_user_ns(old->user_ns);
        new->group_info = get_group_info(old->group_info);
 
        new->securebits = old->securebits;
index 48665ecd119715359cc4ffa624afee5c4332dd57..8ab2951545170e6e81fb71fc7ee1e8cad5c2dd72 100644 (file)
@@ -310,7 +310,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
 
        if (old_ctx) {
                new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len,
-                                 GFP_KERNEL);
+                                 GFP_ATOMIC);
                if (!new_ctx)
                        return -ENOMEM;
 
index f89a0333b8134b25d71e53bed63acfe3643043dd..283862aebdc8376fa071422d03aa39dc39087b21 100644 (file)
@@ -2681,10 +2681,8 @@ out:
  * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
  *
  * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0.
  */
-int tomoyo_close_control(struct tomoyo_io_buffer *head)
+void tomoyo_close_control(struct tomoyo_io_buffer *head)
 {
        /*
         * If the file is /sys/kernel/security/tomoyo/query , decrement the
@@ -2694,7 +2692,6 @@ int tomoyo_close_control(struct tomoyo_io_buffer *head)
            atomic_dec_and_test(&tomoyo_query_observers))
                wake_up_all(&tomoyo_answer_wait);
        tomoyo_notify_gc(head, false);
-       return 0;
 }
 
 /**
index d4f166bc35085f9c83efd640ebdbc010740fb38f..b897d4862016ce51ba737cee7f86f07d95a28c65 100644 (file)
@@ -958,7 +958,7 @@ const struct tomoyo_path_info *tomoyo_path_matches_group
 (const struct tomoyo_path_info *pathname, const struct tomoyo_group *group);
 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
                                 struct path *path, const int flag);
-int tomoyo_close_control(struct tomoyo_io_buffer *head);
+void tomoyo_close_control(struct tomoyo_io_buffer *head);
 int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env);
 int tomoyo_execute_permission(struct tomoyo_request_info *r,
                              const struct tomoyo_path_info *filename);
index fcf32783b66bc564b90162cb7bb6b8fc0bc4db34..179a955b319df9f3952ee6d5e4ff22af13b7d76d 100644 (file)
@@ -143,14 +143,13 @@ static int tomoyo_open(struct inode *inode, struct file *file)
 /**
  * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface.
  *
- * @inode: Pointer to "struct inode".
  * @file:  Pointer to "struct file".
  *
- * Returns 0 on success, negative value otherwise.
  */
 static int tomoyo_release(struct inode *inode, struct file *file)
 {
-       return tomoyo_close_control(file->private_data);
+       tomoyo_close_control(file->private_data);
+       return 0;
 }
 
 /**
index 5bb97e7d325a21291f979e42d7f3dc668a3cff4d..3c9bd6b10a961e6d430d044a69fe643c0cdc07ba 100644 (file)
@@ -153,13 +153,6 @@ EXPORT_SYMBOL(snd_seq_root);
 struct snd_info_entry *snd_oss_root;
 #endif
 
-static void snd_remove_proc_entry(struct proc_dir_entry *parent,
-                                 struct proc_dir_entry *de)
-{
-       if (de)
-               remove_proc_entry(de->name, parent);
-}
-
 static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
 {
        struct snd_info_private_data *data;
@@ -310,12 +303,10 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
        struct snd_info_entry *entry;
        struct snd_info_private_data *data;
        struct snd_info_buffer *buffer;
-       struct proc_dir_entry *p;
        int mode, err;
 
        mutex_lock(&info_mutex);
-       p = PDE(inode);
-       entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
+       entry = PDE_DATA(inode);
        if (entry == NULL || ! entry->p) {
                mutex_unlock(&info_mutex);
                return -ENODEV;
@@ -582,7 +573,7 @@ int __exit snd_info_done(void)
 #ifdef CONFIG_SND_OSSEMUL
                snd_info_free_entry(snd_oss_root);
 #endif
-               snd_remove_proc_entry(NULL, snd_proc_root);
+               proc_remove(snd_proc_root);
        }
        return 0;
 }
@@ -644,7 +635,7 @@ void snd_info_card_id_change(struct snd_card *card)
 {
        mutex_lock(&info_mutex);
        if (card->proc_root_link) {
-               snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
+               proc_remove(card->proc_root_link);
                card->proc_root_link = NULL;
        }
        if (strcmp(card->id, card->proc_root->name))
@@ -663,10 +654,8 @@ void snd_info_card_disconnect(struct snd_card *card)
        if (!card)
                return;
        mutex_lock(&info_mutex);
-       if (card->proc_root_link) {
-               snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
-               card->proc_root_link = NULL;
-       }
+       proc_remove(card->proc_root_link);
+       card->proc_root_link = NULL;
        if (card->proc_root)
                snd_info_disconnect(card->proc_root);
        mutex_unlock(&info_mutex);
@@ -858,7 +847,7 @@ static void snd_info_disconnect(struct snd_info_entry *entry)
        list_del_init(&entry->list);
        root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
        snd_BUG_ON(!root);
-       snd_remove_proc_entry(root, entry->p);
+       proc_remove(entry->p);
        entry->p = NULL;
 }
 
@@ -959,15 +948,21 @@ int snd_info_register(struct snd_info_entry * entry)
                return -ENXIO;
        root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
        mutex_lock(&info_mutex);
-       p = create_proc_entry(entry->name, entry->mode, root);
-       if (!p) {
-               mutex_unlock(&info_mutex);
-               return -ENOMEM;
+       if (S_ISDIR(entry->mode)) {
+               p = proc_mkdir_mode(entry->name, entry->mode, root);
+               if (!p) {
+                       mutex_unlock(&info_mutex);
+                       return -ENOMEM;
+               }
+       } else {
+               p = proc_create_data(entry->name, entry->mode, root,
+                                       &snd_info_entry_operations, entry);
+               if (!p) {
+                       mutex_unlock(&info_mutex);
+                       return -ENOMEM;
+               }
+               proc_set_size(p, entry->size);
        }
-       if (!S_ISDIR(entry->mode))
-               p->proc_fops = &snd_info_entry_operations;
-       p->size = entry->size;
-       p->data = entry;
        entry->p = p;
        if (entry->parent)
                list_add_tail(&entry->list, &entry->parent->children);
index 066f5f3e3f4ca73b78be2a9b86c9baba4d47855b..c3908862bc8b63932aaa8724a50d7a5ae19a8cf3 100644 (file)
@@ -285,7 +285,12 @@ local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev
 static int
 note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-       struct seq_oss_synthinfo *info = &dp->synths[dev];
+       struct seq_oss_synthinfo *info;
+
+       if (!snd_seq_oss_synth_is_valid(dp, dev))
+               return -ENXIO;
+
+       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -340,7 +345,12 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
 static int
 note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-       struct seq_oss_synthinfo *info = &dp->synths[dev];
+       struct seq_oss_synthinfo *info;
+
+       if (!snd_seq_oss_synth_is_valid(dp, dev))
+               return -ENXIO;
+
+       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
index 160b1bd0cd62262931896573953e990736e4da52..24d44b2f61acda72453e5be78958aae15b8afccf 100644 (file)
@@ -290,10 +290,10 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
                        tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
                        err = snd_timer_open(&t, str, &tid, q->queue);
                }
-               if (err < 0) {
-                       snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
-                       return err;
-               }
+       }
+       if (err < 0) {
+               snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
+               return err;
        }
        t->callback = snd_seq_timer_interrupt;
        t->callback_data = q;
index 857586135d1820ee9310b2794716f4aef2c903eb..0097f3619faae2b955757a83377f171872b35b75 100644 (file)
@@ -213,7 +213,10 @@ static int slave_put(struct snd_kcontrol *kcontrol,
        }
        if (!changed)
                return 0;
-       return slave_put_val(slave, ucontrol);
+       err = slave_put_val(slave, ucontrol);
+       if (err < 0)
+               return err;
+       return 1;
 }
 
 static int slave_tlv_cmd(struct snd_kcontrol *kcontrol,
index c918313c2206910c7214ad4f2e65d78d750c6789..bac43b5b6e95be36ff5fe4fffb955c7b7a078fd9 100644 (file)
@@ -835,7 +835,7 @@ static void sq_reset(void)
        shared_resources_initialised = 0 ;
 }
 
-static int sq_fsync(struct file *filp, struct dentry *dentry)
+static int sq_fsync(void)
 {
        int rc = 0;
        int timeout = 5;
@@ -874,7 +874,7 @@ static int sq_release(struct inode *inode, struct file *file)
 
        if (file->f_mode & FMODE_WRITE) {
                if (write_sq.busy)
-                       rc = sq_fsync(file, file->f_path.dentry);
+                       rc = sq_fsync();
 
                sq_reset_output() ; /* make sure dma is stopped and all is quiet */
                write_sq_release_buffers();
@@ -1025,7 +1025,7 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
                */
                result = 0 ;
                if (file->f_mode & FMODE_WRITE) {
-                       result = sq_fsync(file, file->f_path.dentry);
+                       result = sq_fsync();
                        sq_reset_output() ;
                }
                /* if we are the shared resource owner then release them */
index 30bcfe470f8310fa7fa72cc1ddcf7ab4ba6a794c..4ff60a6427d9d8d3ea7cf095bc2766f2d49955fc 100644 (file)
@@ -545,6 +545,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
                case MIDI_PGM_CHANGE:
                        if (seq_mode == SEQ_2)
                        {
+                               if (chn > 15)
+                                       break;
+
                                synth_devs[dev]->chn_info[chn].pgm_num = p1;
                                if ((int) dev >= num_synths)
                                        synth_devs[dev]->set_instr(dev, chn, p1);
@@ -596,6 +599,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
                case MIDI_PITCH_BEND:
                        if (seq_mode == SEQ_2)
                        {
+                               if (chn > 15)
+                                       break;
+
                                synth_devs[dev]->chn_info[chn].bender_value = w14;
 
                                if ((int) dev < num_synths)
index 3536b076b529ab8c25edf1292a62e713e841b800..0aabfedeecbae241b6ab4e182713a3d2e85b82e8 100644 (file)
@@ -2549,7 +2549,7 @@ static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
 
 static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
 {
-       struct snd_card *card = asihpi->card;
+       struct snd_card *card;
        unsigned int idx = 0;
        unsigned int subindex = 0;
        int err;
@@ -2557,6 +2557,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
 
        if (snd_BUG_ON(!asihpi))
                return -EINVAL;
+       card = asihpi->card;
        strcpy(card->mixername, "Asihpi Mixer");
 
        err =
index 04b57383e8cbcb89212e2d63960242653e774b21..ecdf30eb5879ab4547e1e72b70bca366cb39ca78 100644 (file)
@@ -494,7 +494,7 @@ static unsigned int get_num_conns(struct hda_codec *codec, hda_nid_t nid)
 
 int snd_hda_get_num_raw_conns(struct hda_codec *codec, hda_nid_t nid)
 {
-       return get_num_conns(codec, nid) & AC_CLIST_LENGTH;
+       return snd_hda_get_raw_connections(codec, nid, NULL, 0);
 }
 
 /**
@@ -517,9 +517,6 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
        hda_nid_t prev_nid;
        int null_count = 0;
 
-       if (snd_BUG_ON(!conn_list || max_conns <= 0))
-               return -EINVAL;
-
        parm = get_num_conns(codec, nid);
        if (!parm)
                return 0;
@@ -545,7 +542,8 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
                                          AC_VERB_GET_CONNECT_LIST, 0);
                if (parm == -1 && codec->bus->rirb_error)
                        return -EIO;
-               conn_list[0] = parm & mask;
+               if (conn_list)
+                       conn_list[0] = parm & mask;
                return 1;
        }
 
@@ -580,14 +578,20 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
                                continue;
                        }
                        for (n = prev_nid + 1; n <= val; n++) {
+                               if (conn_list) {
+                                       if (conns >= max_conns)
+                                               return -ENOSPC;
+                                       conn_list[conns] = n;
+                               }
+                               conns++;
+                       }
+               } else {
+                       if (conn_list) {
                                if (conns >= max_conns)
                                        return -ENOSPC;
-                               conn_list[conns++] = n;
+                               conn_list[conns] = val;
                        }
-               } else {
-                       if (conns >= max_conns)
-                               return -ENOSPC;
-                       conn_list[conns++] = val;
+                       conns++;
                }
                prev_nid = val;
        }
@@ -3140,7 +3144,7 @@ static unsigned int convert_to_spdif_status(unsigned short val)
        if (val & AC_DIG1_PROFESSIONAL)
                sbits |= IEC958_AES0_PROFESSIONAL;
        if (sbits & IEC958_AES0_PROFESSIONAL) {
-               if (sbits & AC_DIG1_EMPHASIS)
+               if (val & AC_DIG1_EMPHASIS)
                        sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
        } else {
                if (val & AC_DIG1_EMPHASIS)
@@ -3334,6 +3338,8 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
                return -EBUSY;
        }
        spdif = snd_array_new(&codec->spdif_out);
+       if (!spdif)
+               return -ENOMEM;
        for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
                kctl = snd_ctl_new1(dig_mix, codec);
                if (!kctl)
@@ -3431,11 +3437,16 @@ static struct snd_kcontrol_new spdif_share_sw = {
 int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
                                  struct hda_multi_out *mout)
 {
+       struct snd_kcontrol *kctl;
+
        if (!mout->dig_out_nid)
                return 0;
+
+       kctl = snd_ctl_new1(&spdif_share_sw, mout);
+       if (!kctl)
+               return -ENOMEM;
        /* ATTENTION: here mout is passed as private_data, instead of codec */
-       return snd_hda_ctl_add(codec, mout->dig_out_nid,
-                             snd_ctl_new1(&spdif_share_sw, mout));
+       return snd_hda_ctl_add(codec, mout->dig_out_nid, kctl);
 }
 EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
 
index 78897d05d80f281d9bc8427a09a4da426f90dbe4..43c2ea5395618f9ca1c166c9125b006839714f6d 100644 (file)
@@ -995,6 +995,8 @@ enum {
        BAD_NO_EXTRA_SURR_DAC = 0x101,
        /* Primary DAC shared with main surrounds */
        BAD_SHARED_SURROUND = 0x100,
+       /* No independent HP possible */
+       BAD_NO_INDEP_HP = 0x40,
        /* Primary DAC shared with main CLFE */
        BAD_SHARED_CLFE = 0x10,
        /* Primary DAC shared with extra surrounds */
@@ -1392,6 +1394,43 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
        return snd_hda_get_path_idx(codec, path);
 }
 
+/* check whether the independent HP is available with the current config */
+static bool indep_hp_possible(struct hda_codec *codec)
+{
+       struct hda_gen_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       struct nid_path *path;
+       int i, idx;
+
+       if (cfg->line_out_type == AUTO_PIN_HP_OUT)
+               idx = spec->out_paths[0];
+       else
+               idx = spec->hp_paths[0];
+       path = snd_hda_get_path_from_idx(codec, idx);
+       if (!path)
+               return false;
+
+       /* assume no path conflicts unless aamix is involved */
+       if (!spec->mixer_nid || !is_nid_contained(path, spec->mixer_nid))
+               return true;
+
+       /* check whether output paths contain aamix */
+       for (i = 0; i < cfg->line_outs; i++) {
+               if (spec->out_paths[i] == idx)
+                       break;
+               path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
+               if (path && is_nid_contained(path, spec->mixer_nid))
+                       return false;
+       }
+       for (i = 0; i < cfg->speaker_outs; i++) {
+               path = snd_hda_get_path_from_idx(codec, spec->speaker_paths[i]);
+               if (path && is_nid_contained(path, spec->mixer_nid))
+                       return false;
+       }
+
+       return true;
+}
+
 /* fill the empty entries in the dac array for speaker/hp with the
  * shared dac pointed by the paths
  */
@@ -1545,6 +1584,9 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
                badness += BAD_MULTI_IO;
        }
 
+       if (spec->indep_hp && !indep_hp_possible(codec))
+               badness += BAD_NO_INDEP_HP;
+
        /* re-fill the shared DAC for speaker / headphone */
        if (cfg->line_out_type != AUTO_PIN_HP_OUT)
                refill_shared_dacs(codec, cfg->hp_outs,
@@ -1758,6 +1800,10 @@ static int parse_output_paths(struct hda_codec *codec)
                                cfg->speaker_pins, val);
        }
 
+       /* clear indep_hp flag if not available */
+       if (spec->indep_hp && !indep_hp_possible(codec))
+               spec->indep_hp = 0;
+
        kfree(best_cfg);
        return 0;
 }
index 4cea6bb6fade09c1dfcfadd0ecd2cdab798a134a..418bfc0eb0a3127234899aa6f84586feaa19eeef 100644 (file)
@@ -415,6 +415,8 @@ struct azx_dev {
        unsigned int opened :1;
        unsigned int running :1;
        unsigned int irq_pending :1;
+       unsigned int prepared:1;
+       unsigned int locked:1;
        /*
         * For VIA:
         *  A flag to ensure DMA position is 0
@@ -426,8 +428,25 @@ struct azx_dev {
 
        struct timecounter  azx_tc;
        struct cyclecounter azx_cc;
+
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+       struct mutex dsp_mutex;
+#endif
 };
 
+/* DSP lock helpers */
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+#define dsp_lock_init(dev)     mutex_init(&(dev)->dsp_mutex)
+#define dsp_lock(dev)          mutex_lock(&(dev)->dsp_mutex)
+#define dsp_unlock(dev)                mutex_unlock(&(dev)->dsp_mutex)
+#define dsp_is_locked(dev)     ((dev)->locked)
+#else
+#define dsp_lock_init(dev)     do {} while (0)
+#define dsp_lock(dev)          do {} while (0)
+#define dsp_unlock(dev)                do {} while (0)
+#define dsp_is_locked(dev)     0
+#endif
+
 /* CORB/RIRB */
 struct azx_rb {
        u32 *buf;               /* CORB/RIRB buffer
@@ -527,6 +546,10 @@ struct azx {
 
        /* card list (for power_save trigger) */
        struct list_head list;
+
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+       struct azx_dev saved_azx_dev;
+#endif
 };
 
 #define CREATE_TRACE_POINTS
@@ -1793,15 +1816,25 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
                dev = chip->capture_index_offset;
                nums = chip->capture_streams;
        }
-       for (i = 0; i < nums; i++, dev++)
-               if (!chip->azx_dev[dev].opened) {
-                       res = &chip->azx_dev[dev];
-                       if (res->assigned_key == key)
-                               break;
+       for (i = 0; i < nums; i++, dev++) {
+               struct azx_dev *azx_dev = &chip->azx_dev[dev];
+               dsp_lock(azx_dev);
+               if (!azx_dev->opened && !dsp_is_locked(azx_dev)) {
+                       res = azx_dev;
+                       if (res->assigned_key == key) {
+                               res->opened = 1;
+                               res->assigned_key = key;
+                               dsp_unlock(azx_dev);
+                               return azx_dev;
+                       }
                }
+               dsp_unlock(azx_dev);
+       }
        if (res) {
+               dsp_lock(res);
                res->opened = 1;
                res->assigned_key = key;
+               dsp_unlock(res);
        }
        return res;
 }
@@ -2009,6 +2042,12 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
        struct azx_dev *azx_dev = get_azx_dev(substream);
        int ret;
 
+       dsp_lock(azx_dev);
+       if (dsp_is_locked(azx_dev)) {
+               ret = -EBUSY;
+               goto unlock;
+       }
+
        mark_runtime_wc(chip, azx_dev, substream, false);
        azx_dev->bufsize = 0;
        azx_dev->period_bytes = 0;
@@ -2016,8 +2055,10 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
        ret = snd_pcm_lib_malloc_pages(substream,
                                        params_buffer_bytes(hw_params));
        if (ret < 0)
-               return ret;
+               goto unlock;
        mark_runtime_wc(chip, azx_dev, substream, true);
+ unlock:
+       dsp_unlock(azx_dev);
        return ret;
 }
 
@@ -2029,16 +2070,21 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
        struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
 
        /* reset BDL address */
-       azx_sd_writel(azx_dev, SD_BDLPL, 0);
-       azx_sd_writel(azx_dev, SD_BDLPU, 0);
-       azx_sd_writel(azx_dev, SD_CTL, 0);
-       azx_dev->bufsize = 0;
-       azx_dev->period_bytes = 0;
-       azx_dev->format_val = 0;
+       dsp_lock(azx_dev);
+       if (!dsp_is_locked(azx_dev)) {
+               azx_sd_writel(azx_dev, SD_BDLPL, 0);
+               azx_sd_writel(azx_dev, SD_BDLPU, 0);
+               azx_sd_writel(azx_dev, SD_CTL, 0);
+               azx_dev->bufsize = 0;
+               azx_dev->period_bytes = 0;
+               azx_dev->format_val = 0;
+       }
 
        snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
 
        mark_runtime_wc(chip, azx_dev, substream, false);
+       azx_dev->prepared = 0;
+       dsp_unlock(azx_dev);
        return snd_pcm_lib_free_pages(substream);
 }
 
@@ -2055,6 +2101,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
                snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
        unsigned short ctls = spdif ? spdif->ctls : 0;
 
+       dsp_lock(azx_dev);
+       if (dsp_is_locked(azx_dev)) {
+               err = -EBUSY;
+               goto unlock;
+       }
+
        azx_stream_reset(chip, azx_dev);
        format_val = snd_hda_calc_stream_format(runtime->rate,
                                                runtime->channels,
@@ -2065,7 +2117,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
                snd_printk(KERN_ERR SFX
                           "%s: invalid format_val, rate=%d, ch=%d, format=%d\n",
                           pci_name(chip->pci), runtime->rate, runtime->channels, runtime->format);
-               return -EINVAL;
+               err = -EINVAL;
+               goto unlock;
        }
 
        bufsize = snd_pcm_lib_buffer_bytes(substream);
@@ -2084,7 +2137,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
                azx_dev->no_period_wakeup = runtime->no_period_wakeup;
                err = azx_setup_periods(chip, substream, azx_dev);
                if (err < 0)
-                       return err;
+                       goto unlock;
        }
 
        /* wallclk has 24Mhz clock source */
@@ -2101,8 +2154,14 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
        if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
            stream_tag > chip->capture_streams)
                stream_tag -= chip->capture_streams;
-       return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
+       err = snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
                                     azx_dev->format_val, substream);
+
+ unlock:
+       if (!err)
+               azx_dev->prepared = 1;
+       dsp_unlock(azx_dev);
+       return err;
 }
 
 static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -2117,6 +2176,9 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        azx_dev = get_azx_dev(substream);
        trace_azx_pcm_trigger(chip, azx_dev, cmd);
 
+       if (dsp_is_locked(azx_dev) || !azx_dev->prepared)
+               return -EPIPE;
+
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                rstart = 1;
@@ -2621,17 +2683,27 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
        struct azx_dev *azx_dev;
        int err;
 
-       if (snd_hda_lock_devices(bus))
-               return -EBUSY;
+       azx_dev = azx_get_dsp_loader_dev(chip);
+
+       dsp_lock(azx_dev);
+       spin_lock_irq(&chip->reg_lock);
+       if (azx_dev->running || azx_dev->locked) {
+               spin_unlock_irq(&chip->reg_lock);
+               err = -EBUSY;
+               goto unlock;
+       }
+       azx_dev->prepared = 0;
+       chip->saved_azx_dev = *azx_dev;
+       azx_dev->locked = 1;
+       spin_unlock_irq(&chip->reg_lock);
 
        err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG,
                                  snd_dma_pci_data(chip->pci),
                                  byte_size, bufp);
        if (err < 0)
-               goto unlock;
+               goto err_alloc;
 
        mark_pages_wc(chip, bufp, true);
-       azx_dev = azx_get_dsp_loader_dev(chip);
        azx_dev->bufsize = byte_size;
        azx_dev->period_bytes = byte_size;
        azx_dev->format_val = format;
@@ -2649,13 +2721,20 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
                goto error;
 
        azx_setup_controller(chip, azx_dev);
+       dsp_unlock(azx_dev);
        return azx_dev->stream_tag;
 
  error:
        mark_pages_wc(chip, bufp, false);
        snd_dma_free_pages(bufp);
-unlock:
-       snd_hda_unlock_devices(bus);
+ err_alloc:
+       spin_lock_irq(&chip->reg_lock);
+       if (azx_dev->opened)
+               *azx_dev = chip->saved_azx_dev;
+       azx_dev->locked = 0;
+       spin_unlock_irq(&chip->reg_lock);
+ unlock:
+       dsp_unlock(azx_dev);
        return err;
 }
 
@@ -2677,9 +2756,10 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
        struct azx *chip = bus->private_data;
        struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
 
-       if (!dmab->area)
+       if (!dmab->area || !azx_dev->locked)
                return;
 
+       dsp_lock(azx_dev);
        /* reset BDL address */
        azx_sd_writel(azx_dev, SD_BDLPL, 0);
        azx_sd_writel(azx_dev, SD_BDLPU, 0);
@@ -2692,7 +2772,12 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
        snd_dma_free_pages(dmab);
        dmab->area = NULL;
 
-       snd_hda_unlock_devices(bus);
+       spin_lock_irq(&chip->reg_lock);
+       if (azx_dev->opened)
+               *azx_dev = chip->saved_azx_dev;
+       azx_dev->locked = 0;
+       spin_unlock_irq(&chip->reg_lock);
+       dsp_unlock(azx_dev);
 }
 #endif /* CONFIG_SND_HDA_DSP_LOADER */
 
@@ -3481,6 +3566,7 @@ static int azx_first_init(struct azx *chip)
        }
 
        for (i = 0; i < chip->num_streams; i++) {
+               dsp_lock_init(&chip->azx_dev[i]);
                /* allocate memory for the BDL for each stream */
                err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
                                          snd_dma_pci_data(chip->pci),
index db02c1e96b080c2525b313cc9fae11d2550af731..0792b5725f9c5e501886556ce68f1c383aef1460 100644 (file)
@@ -2298,6 +2298,11 @@ static int dspxfr_one_seg(struct hda_codec *codec,
        hda_frame_size_words = ((sample_rate_div == 0) ? 0 :
                        (num_chans * sample_rate_mul / sample_rate_div));
 
+       if (hda_frame_size_words == 0) {
+               snd_printdd(KERN_ERR "frmsz zero\n");
+               return -EINVAL;
+       }
+
        buffer_size_words = min(buffer_size_words,
                                (unsigned int)(UC_RANGE(chip_addx, 1) ?
                                65536 : 32768));
@@ -2308,8 +2313,7 @@ static int dspxfr_one_seg(struct hda_codec *codec,
                   chip_addx, hda_frame_size_words, num_chans,
                   sample_rate_mul, sample_rate_div, buffer_size_words);
 
-       if ((buffer_addx == NULL) || (hda_frame_size_words == 0) ||
-           (buffer_size_words < hda_frame_size_words)) {
+       if (buffer_size_words < hda_frame_size_words) {
                snd_printdd(KERN_ERR "dspxfr_one_seg:failed\n");
                return -EINVAL;
        }
@@ -3235,7 +3239,7 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val)
        struct ca0132_spec *spec = codec->spec;
        unsigned int tmp;
 
-       if (!dspload_is_loaded(codec))
+       if (spec->dsp_state != DSP_DOWNLOADED)
                return 0;
 
        /* if CrystalVoice if off, vipsource should be 0 */
@@ -4263,11 +4267,12 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
  */
 static void ca0132_setup_defaults(struct hda_codec *codec)
 {
+       struct ca0132_spec *spec = codec->spec;
        unsigned int tmp;
        int num_fx;
        int idx, i;
 
-       if (!dspload_is_loaded(codec))
+       if (spec->dsp_state != DSP_DOWNLOADED)
                return;
 
        /* out, in effects + voicefx */
@@ -4347,12 +4352,16 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
                return false;
 
        dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
-       dspload_image(codec, dsp_os_image, 0, 0, true, 0);
+       if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
+               pr_err("ca0132 dspload_image failed.\n");
+               goto exit_download;
+       }
+
        dsp_loaded = dspload_wait_loaded(codec);
 
+exit_download:
        release_firmware(fw_entry);
 
-
        return dsp_loaded;
 }
 
@@ -4363,16 +4372,13 @@ static void ca0132_download_dsp(struct hda_codec *codec)
 #ifndef CONFIG_SND_HDA_CODEC_CA0132_DSP
        return; /* NOP */
 #endif
-       spec->dsp_state = DSP_DOWNLOAD_INIT;
 
-       if (spec->dsp_state == DSP_DOWNLOAD_INIT) {
-               chipio_enable_clocks(codec);
-               spec->dsp_state = DSP_DOWNLOADING;
-               if (!ca0132_download_dsp_images(codec))
-                       spec->dsp_state = DSP_DOWNLOAD_FAILED;
-               else
-                       spec->dsp_state = DSP_DOWNLOADED;
-       }
+       chipio_enable_clocks(codec);
+       spec->dsp_state = DSP_DOWNLOADING;
+       if (!ca0132_download_dsp_images(codec))
+               spec->dsp_state = DSP_DOWNLOAD_FAILED;
+       else
+               spec->dsp_state = DSP_DOWNLOADED;
 
        if (spec->dsp_state == DSP_DOWNLOADED)
                ca0132_set_dsp_msr(codec, true);
index 72ebb8a36b135938593db795d255b27479a5231f..0d9c58f135606f8d422d5422d1742e76cf7f6572 100644 (file)
@@ -168,10 +168,10 @@ static void cs_automute(struct hda_codec *codec)
        snd_hda_gen_update_outputs(codec);
 
        if (spec->gpio_eapd_hp) {
-               unsigned int gpio = spec->gen.hp_jack_present ?
+               spec->gpio_data = spec->gen.hp_jack_present ?
                        spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
                snd_hda_codec_write(codec, 0x01, 0,
-                                   AC_VERB_SET_GPIO_DATA, gpio);
+                                   AC_VERB_SET_GPIO_DATA, spec->gpio_data);
        }
 }
 
@@ -506,6 +506,8 @@ static int patch_cs420x(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
 
+       spec->gen.automute_hook = cs_automute;
+
        snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
                           cs420x_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -893,6 +895,8 @@ static int patch_cs4210(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
 
+       spec->gen.automute_hook = cs_automute;
+
        snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
                           cs421x_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
index 941bf6c766ecf5f6ff2aa35e28e33563066c58ef..2a89d1eefeb6059623a985fea7cdb464dc4c7390 100644 (file)
@@ -1142,7 +1142,7 @@ static int patch_cxt5045(struct hda_codec *codec)
        }
 
        if (spec->beep_amp)
-               snd_hda_attach_beep_device(codec, spec->beep_amp);
+               snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
 
        return 0;
 }
@@ -1921,7 +1921,7 @@ static int patch_cxt5051(struct hda_codec *codec)
        }
 
        if (spec->beep_amp)
-               snd_hda_attach_beep_device(codec, spec->beep_amp);
+               snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
 
        return 0;
 }
@@ -3099,7 +3099,7 @@ static int patch_cxt5066(struct hda_codec *codec)
        }
 
        if (spec->beep_amp)
-               snd_hda_attach_beep_device(codec, spec->beep_amp);
+               snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
 
        return 0;
 }
@@ -3191,11 +3191,17 @@ static int cx_auto_build_controls(struct hda_codec *codec)
        return 0;
 }
 
+static void cx_auto_free(struct hda_codec *codec)
+{
+       snd_hda_detach_beep_device(codec);
+       snd_hda_gen_free(codec);
+}
+
 static const struct hda_codec_ops cx_auto_patch_ops = {
        .build_controls = cx_auto_build_controls,
        .build_pcms = snd_hda_gen_build_pcms,
        .init = snd_hda_gen_init,
-       .free = snd_hda_gen_free,
+       .free = cx_auto_free,
        .unsol_event = snd_hda_jack_unsol_event,
 #ifdef CONFIG_PM
        .check_power_status = snd_hda_gen_check_power_status,
@@ -3391,7 +3397,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
 
        codec->patch_ops = cx_auto_patch_ops;
        if (spec->beep_amp)
-               snd_hda_attach_beep_device(codec, spec->beep_amp);
+               snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
 
        /* Some laptops with Conexant chips show stalls in S3 resume,
         * which falls into the single-cmd mode.
index 2d4237bc0d8e5e85059b8771bad958ae10887ff5..563c24df4d6f03f393def96afcd8340ee4538180 100644 (file)
@@ -3163,6 +3163,7 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0290:
                spec->codec_variant = ALC269_TYPE_ALC280;
                break;
+       case 0x10ec0233:
        case 0x10ec0282:
        case 0x10ec0283:
                spec->codec_variant = ALC269_TYPE_ALC282;
@@ -3862,6 +3863,7 @@ static int patch_alc680(struct hda_codec *codec)
  */
 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
+       { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
index 83d5335ac348ee2c3b7a3f7e243f7d5ad8096045..dafe04ae8c72b6ba711d7f8dce4ac7878552b883 100644 (file)
@@ -815,6 +815,29 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
        return 0;
 }
 
+/* check whether a built-in speaker is included in parsed pins */
+static bool has_builtin_speaker(struct hda_codec *codec)
+{
+       struct sigmatel_spec *spec = codec->spec;
+       hda_nid_t *nid_pin;
+       int nids, i;
+
+       if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
+               nid_pin = spec->gen.autocfg.line_out_pins;
+               nids = spec->gen.autocfg.line_outs;
+       } else {
+               nid_pin = spec->gen.autocfg.speaker_pins;
+               nids = spec->gen.autocfg.speaker_outs;
+       }
+
+       for (i = 0; i < nids; i++) {
+               unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
+               if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
+                       return true;
+       }
+       return false;
+}
+
 /*
  * PC beep controls
  */
@@ -3890,6 +3913,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
                return err;
        }
 
+       /* Don't GPIO-mute speakers if there are no internal speakers, because
+        * the GPIO might be necessary for Headphone
+        */
+       if (spec->eapd_switch && !has_builtin_speaker(codec))
+               spec->eapd_switch = 0;
+
        codec->proc_widget_hook = stac92hd7x_proc_hook;
 
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
index 2ffdc35d5ffdca6ba5e1d1587feae59e6d08beaa..806407a3973e41784749f21c841628ad262c73f7 100644 (file)
@@ -2594,6 +2594,8 @@ static int snd_ice1712_create(struct snd_card *card,
        snd_ice1712_proc_init(ice);
        synchronize_irq(pci->irq);
 
+       card->private_data = ice;
+
        err = pci_request_regions(pci, "ICE1712");
        if (err < 0) {
                kfree(ice);
index b8d461db369f1f2952fb562f9ce78ddd74e5e069..b82bbf584146dc0b7c1bbaeb416a96f03f0d67af 100644 (file)
@@ -573,6 +573,13 @@ static const struct reg_default wm5102_sysclk_reva_patch[] = {
        { 0x025e, 0x0112 },
 };
 
+static const struct reg_default wm5102_sysclk_revb_patch[] = {
+       { 0x3081, 0x08FE },
+       { 0x3083, 0x00ED },
+       { 0x30C1, 0x08FE },
+       { 0x30C3, 0x00ED },
+};
+
 static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
@@ -587,6 +594,10 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
                patch = wm5102_sysclk_reva_patch;
                patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch);
                break;
+       default:
+               patch = wm5102_sysclk_revb_patch;
+               patch_size = ARRAY_SIZE(wm5102_sysclk_revb_patch);
+               break;
        }
 
        switch (event) {
@@ -755,7 +766,7 @@ SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
 
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
             ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
 SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
           ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
@@ -767,7 +778,7 @@ SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
                 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
                 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
index cd17b477781d8b370aa78eb2eadad86dcdd4cc31..cdeb301da1f69221f065ccf7f07bfa290e0e9dff 100644 (file)
@@ -213,9 +213,9 @@ ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
 
 SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
           ARIZONA_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
+SOC_SINGLE("HPOUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
           ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("OUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+SOC_SINGLE("HPOUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
           ARIZONA_OUT3_OSR_SHIFT, 1, 0),
 SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
           ARIZONA_OUT4_OSR_SHIFT, 1, 0),
@@ -226,9 +226,9 @@ SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
 
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
             ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("OUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+SOC_DOUBLE_R("HPOUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
             ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
             ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
@@ -240,10 +240,10 @@ SOC_DOUBLE_R("SPKDAT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_6L,
 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
                 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
                 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("OUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
                 ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
@@ -260,11 +260,11 @@ SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
                       ARIZONA_OUTPUT_PATH_CONFIG_1R,
                       ARIZONA_OUT1L_PGA_VOL_SHIFT,
                       0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
+SOC_DOUBLE_R_RANGE_TLV("HPOUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
                       ARIZONA_OUTPUT_PATH_CONFIG_2R,
                       ARIZONA_OUT2L_PGA_VOL_SHIFT,
                       0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("OUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+SOC_DOUBLE_R_RANGE_TLV("HPOUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
                       ARIZONA_OUTPUT_PATH_CONFIG_3R,
                       ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
 
index ec0efc1443ba770a6c40a2e18c90b117931823bd..0e8b3aaf6c8d698e9dad1f25fdccbabc9ee9f1ef 100644 (file)
@@ -1301,7 +1301,7 @@ static irqreturn_t wm8350_hpl_jack_handler(int irq, void *data)
        if (device_may_wakeup(wm8350->dev))
                pm_wakeup_event(wm8350->dev, 250);
 
-       schedule_delayed_work(&priv->hpl.work, 200);
+       schedule_delayed_work(&priv->hpl.work, msecs_to_jiffies(200));
 
        return IRQ_HANDLED;
 }
@@ -1318,7 +1318,7 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
        if (device_may_wakeup(wm8350->dev))
                pm_wakeup_event(wm8350->dev, 250);
 
-       schedule_delayed_work(&priv->hpr.work, 200);
+       schedule_delayed_work(&priv->hpr.work, msecs_to_jiffies(200));
 
        return IRQ_HANDLED;
 }
index 9bb9273259937770ac4f8b188b05f803a1079121..a64b93425ae3367051cba0ef0a5f59a233abd2ee 100644 (file)
@@ -53,8 +53,8 @@
  * using 2 wire for device control, so we cache them instead.
  */
 static const struct reg_default wm8960_reg_defaults[] = {
-       {  0x0, 0x0097 },
-       {  0x1, 0x0097 },
+       {  0x0, 0x00a7 },
+       {  0x1, 0x00a7 },
        {  0x2, 0x0000 },
        {  0x3, 0x0000 },
        {  0x4, 0x0000 },
@@ -323,8 +323,8 @@ SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
 SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
                   wm8960_rin, ARRAY_SIZE(wm8960_rin)),
 
-SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0),
+SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER1, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER1, 2, 0),
 
 SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
 SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
index c27069d24d77257d41039e1632f04ae2c33a57bd..729958713cd44723f7b07c1e6815d61e5adde587 100644 (file)
 
 #define TEGRA20_I2S_TIMING_NON_SYM_ENABLE              (1 << 12)
 #define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT     0
-#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7fff
+#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7ff
 #define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK      (TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
 
 /* Fields in TEGRA20_I2S_FIFO_SCR */
index 34dc47b9581c21e8700eab513265d5c4096ca794..a294d942b9f72aa7c7b2595ca05c98deb6ffe2b9 100644 (file)
 
 #define TEGRA30_I2S_TIMING_NON_SYM_ENABLE              (1 << 12)
 #define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT     0
-#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7fff
+#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7ff
 #define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK      (TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
 
 /* Fields in TEGRA30_I2S_OFFSET */
index e14903468051c0e761deebbd4a16343b062aa4af..b155137ee312a5105517718d483b2db322958943 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/file.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
@@ -23,14 +24,14 @@ static int do_mod_firmware_load(const char *fn, char **fp)
        if (l <= 0 || l > 131072)
        {
                printk(KERN_INFO "Invalid firmware '%s'\n", fn);
-               filp_close(filp, NULL);
+               fput(filp);
                return 0;
        }
        dp = vmalloc(l);
        if (dp == NULL)
        {
                printk(KERN_INFO "Out of memory loading '%s'.\n", fn);
-               filp_close(filp, NULL);
+               fput(filp);
                return 0;
        }
        pos = 0;
@@ -38,10 +39,10 @@ static int do_mod_firmware_load(const char *fn, char **fp)
        {
                printk(KERN_INFO "Failed to read '%s'.\n", fn);
                vfree(dp);
-               filp_close(filp, NULL);
+               fput(filp);
                return 0;
        }
-       filp_close(filp, NULL);
+       fput(filp);
        *fp = dp;
        return (int) l;
 }
index 803953a9bff338056795c888cecc9d7fb9c6daa2..2da8ad75fd96c7c0245dfca05c9997e5c3d355a1 100644 (file)
@@ -243,6 +243,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
                struct usb_interface_assoc_descriptor *assoc =
                        usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
 
+               if (!assoc) {
+                       /*
+                        * Firmware writers cannot count to three.  So to find
+                        * the IAD on the NuForce UDH-100, also check the next
+                        * interface.
+                        */
+                       struct usb_interface *iface =
+                               usb_ifnum_to_if(dev, ctrlif + 1);
+                       if (iface &&
+                           iface->intf_assoc &&
+                           iface->intf_assoc->bFunctionClass == USB_CLASS_AUDIO &&
+                           iface->intf_assoc->bFunctionProtocol == UAC_VERSION_2)
+                               assoc = iface->intf_assoc;
+               }
+
                if (!assoc) {
                        snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
                        return -EINVAL;
index 638e7f738018bf155d55b8ffecc1af5f9a1fc15b..ca4739c3f65021fdef6d8493fb11225ad2746fb1 100644 (file)
@@ -715,8 +715,9 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
                case UAC2_CLOCK_SELECTOR: {
                        struct uac_selector_unit_descriptor *d = p1;
                        /* call recursively to retrieve the channel info */
-                       if (check_input_term(state, d->baSourceID[0], term) < 0)
-                               return -ENODEV;
+                       err = check_input_term(state, d->baSourceID[0], term);
+                       if (err < 0)
+                               return err;
                        term->type = d->bDescriptorSubtype << 16; /* virtual type */
                        term->id = id;
                        term->name = uac_selector_unit_iSelector(d);
@@ -725,7 +726,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
                case UAC1_PROCESSING_UNIT:
                case UAC1_EXTENSION_UNIT:
                /* UAC2_PROCESSING_UNIT_V2 */
-               /* UAC2_EFFECT_UNIT */ {
+               /* UAC2_EFFECT_UNIT */
+               case UAC2_EXTENSION_UNIT_V2: {
                        struct uac_processing_unit_descriptor *d = p1;
 
                        if (state->mixer->protocol == UAC_VERSION_2 &&
@@ -1356,8 +1358,9 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
                return err;
 
        /* determine the input source type and name */
-       if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
-               return -EINVAL;
+       err = check_input_term(state, hdr->bSourceID, &iterm);
+       if (err < 0)
+               return err;
 
        master_bits = snd_usb_combine_bytes(bmaControls, csize);
        /* master configuration quirks */
@@ -2052,6 +2055,8 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
                        return parse_audio_extension_unit(state, unitid, p1);
                else /* UAC_VERSION_2 */
                        return parse_audio_processing_unit(state, unitid, p1);
+       case UAC2_EXTENSION_UNIT_V2:
+               return parse_audio_extension_unit(state, unitid, p1);
        default:
                snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
                return -EINVAL;
@@ -2118,7 +2123,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                        state.oterm.type = le16_to_cpu(desc->wTerminalType);
                        state.oterm.name = desc->iTerminal;
                        err = parse_audio_unit(&state, desc->bSourceID);
-                       if (err < 0)
+                       if (err < 0 && err != -EINVAL)
                                return err;
                } else { /* UAC_VERSION_2 */
                        struct uac2_output_terminal_descriptor *desc = p;
@@ -2130,12 +2135,12 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                        state.oterm.type = le16_to_cpu(desc->wTerminalType);
                        state.oterm.name = desc->iTerminal;
                        err = parse_audio_unit(&state, desc->bSourceID);
-                       if (err < 0)
+                       if (err < 0 && err != -EINVAL)
                                return err;
 
                        /* for UAC2, use the same approach to also add the clock selectors */
                        err = parse_audio_unit(&state, desc->bCSourceID);
-                       if (err < 0)
+                       if (err < 0 && err != -EINVAL)
                                return err;
                }
        }
index a20e32033431a38bc752e2d3476ecafe49e3c78f..0b0a90787db64b010277005c5a7980f60d8fbdbc 100644 (file)
@@ -122,7 +122,7 @@ export Q VERBOSE
 
 EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
 
-INCLUDES = -I. -I/usr/local/include $(CONFIG_INCLUDES)
+INCLUDES = -I. $(CONFIG_INCLUDES)
 
 # Set compile option CFLAGS if not set elsewhere
 CFLAGS ?= -g -Wall
index a2108ca1cc17ad02e331aa02adf1870cc56a07ba..bb74c79cd16ed2ad02dbd33ee5f791fb9de2b3c2 100644 (file)
@@ -95,7 +95,7 @@ ifeq ("$(origin DEBUG)", "command line")
   PERF_DEBUG = $(DEBUG)
 endif
 ifndef PERF_DEBUG
-  CFLAGS_OPTIMIZE = -O6 -D_FORTIFY_SOURCE=2
+  CFLAGS_OPTIMIZE = -O6
 endif
 
 ifdef PARSER_DEBUG
@@ -180,6 +180,12 @@ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-W
        CFLAGS := $(CFLAGS) -Wvolatile-register-var
 endif
 
+ifndef PERF_DEBUG
+       ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
+               CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
+       endif
+endif
+
 ### --- END CONFIGURATION SECTION ---
 
 ifeq ($(srctree),)
index a5223e6a7b432a0b04faf5ba5dfc130cd9ed150e..0fdc85269c4dc4c2bd72220526879a07e76679be 100644 (file)
@@ -1,6 +1,30 @@
 #ifndef BENCH_H
 #define BENCH_H
 
+/*
+ * The madvise transparent hugepage constants were added in glibc
+ * 2.13. For compatibility with older versions of glibc, define these
+ * tokens if they are not already defined.
+ *
+ * PA-RISC uses different madvise values from other architectures and
+ * needs to be special-cased.
+ */
+#ifdef __hppa__
+# ifndef MADV_HUGEPAGE
+#  define MADV_HUGEPAGE                67
+# endif
+# ifndef MADV_NOHUGEPAGE
+#  define MADV_NOHUGEPAGE      68
+# endif
+#else
+# ifndef MADV_HUGEPAGE
+#  define MADV_HUGEPAGE                14
+# endif
+# ifndef MADV_NOHUGEPAGE
+#  define MADV_NOHUGEPAGE      15
+# endif
+#endif
+
 extern int bench_numa(int argc, const char **argv, const char *prefix);
 extern int bench_sched_messaging(int argc, const char **argv, const char *prefix);
 extern int bench_sched_pipe(int argc, const char **argv, const char *prefix);
index 774c90713a53fe8a27f0561a8476d5c23748edab..f1a939ebc19c5d4aad0afbe1b96201aadbdb0511 100644 (file)
@@ -573,13 +573,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
                                         perf_event__synthesize_guest_os, tool);
        }
 
-       if (!opts->target.system_wide)
+       if (perf_target__has_task(&opts->target))
                err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
                                                  process_synthesized_event,
                                                  machine);
-       else
+       else if (perf_target__has_cpu(&opts->target))
                err = perf_event__synthesize_threads(tool, process_synthesized_event,
                                               machine);
+       else /* command specified */
+               err = 0;
 
        if (err != 0)
                goto out_delete_session;
index 38624686ee9a145ffaacbcfa063e5d985da750f0..226a4ae2f936ccaa228a5fad85bfd5318521ccd5 100644 (file)
@@ -208,8 +208,9 @@ static inline int script_browse(const char *script_opt __maybe_unused)
        return 0;
 }
 
-#define K_LEFT -1
-#define K_RIGHT -2
+#define K_LEFT  -1000
+#define K_RIGHT -2000
+#define K_SWITCH_INPUT_DATA -3000
 #endif
 
 #ifdef GTK2_SUPPORT
index 55433aa42c8f30cb8dbeeae537ce8ea0ad47965b..eabdce0a2daa0a0a2c5c882529617322ce6e8852 100644 (file)
@@ -143,7 +143,7 @@ struct strlist *strlist__new(bool dupstr, const char *list)
                slist->rblist.node_delete = strlist__node_delete;
 
                slist->dupstr    = dupstr;
-               if (slist && strlist__parse_list(slist, list) != 0)
+               if (list && strlist__parse_list(slist, list) != 0)
                        goto out_error;
        }
 
index 880cdd5dc63f44fb9197f09b41296b2bbde4cc5a..77edcdcc016bbe9e891dbee8ce27c5824caaae63 100644 (file)
@@ -125,6 +125,63 @@ test_open_unlink()
        ./open-unlink $file
 }
 
+# test that we can create a range of filenames
+test_valid_filenames()
+{
+       local attrs='\x07\x00\x00\x00'
+       local ret=0
+
+       local file_list="abc dump-type0-11-1-1362436005 1234 -"
+       for f in $file_list; do
+               local file=$efivarfs_mount/$f-$test_guid
+
+               printf "$attrs\x00" > $file
+
+               if [ ! -e $file ]; then
+                       echo "$file could not be created" >&2
+                       ret=1
+               else
+                       rm $file
+               fi
+       done
+
+       exit $ret
+}
+
+test_invalid_filenames()
+{
+       local attrs='\x07\x00\x00\x00'
+       local ret=0
+
+       local file_list="
+               -1234-1234-1234-123456789abc
+               foo
+               foo-bar
+               -foo-
+               foo-barbazba-foob-foob-foob-foobarbazfoo
+               foo-------------------------------------
+               -12345678-1234-1234-1234-123456789abc
+               a-12345678=1234-1234-1234-123456789abc
+               a-12345678-1234=1234-1234-123456789abc
+               a-12345678-1234-1234=1234-123456789abc
+               a-12345678-1234-1234-1234=123456789abc
+               1112345678-1234-1234-1234-123456789abc"
+
+       for f in $file_list; do
+               local file=$efivarfs_mount/$f
+
+               printf "$attrs\x00" 2>/dev/null > $file
+
+               if [ -e $file ]; then
+                       echo "Creating $file should have failed" >&2
+                       rm $file
+                       ret=1
+               fi
+       done
+
+       exit $ret
+}
+
 check_prereqs
 
 rc=0
@@ -135,5 +192,7 @@ run_test test_create_read
 run_test test_delete
 run_test test_zero_size_delete
 run_test test_open_unlink
+run_test test_valid_filenames
+run_test test_invalid_filenames
 
 exit $rc
index 8674b9ec14f69882f2e64e689581284bdfeced4b..fe1e66b6ef40bbb1e490edcf2476645d81b66d3f 100644 (file)
@@ -38,7 +38,7 @@
 #include <unistd.h>
 #include <tools/le_byteshift.h>
 
-#include "../../include/linux/usb/functionfs.h"
+#include "../../include/uapi/linux/usb/functionfs.h"
 
 
 /******************** Little Endian Handling ********************************/
index ce82b940195843827be4d22e710942b0683a4618..5ba005c00e2f76998694d202eca68452600ee5bf 100644 (file)
@@ -74,9 +74,12 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
                        u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
                        u64 redir_content;
 
-                       ASSERT(redir_index < IOAPIC_NUM_PINS);
+                       if (redir_index < IOAPIC_NUM_PINS)
+                               redir_content =
+                                       ioapic->redirtbl[redir_index].bits;
+                       else
+                               redir_content = ~0ULL;
 
-                       redir_content = ioapic->redirtbl[redir_index].bits;
                        result = (ioapic->ioregsel & 0x1) ?
                            (redir_content >> 32) & 0xffffffff :
                            redir_content & 0xffffffff;